Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: ppapi/examples/video_decode/video_decode.cc

Issue 9620024: Move ppapi/examples/gles2/ to ppapi/examples/video_decode (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <sstream> 8 #include <sstream>
9 #include <list> 9 #include <list>
10 #include <map> 10 #include <map>
11 #include <set> 11 #include <set>
12 #include <vector> 12 #include <vector>
13 13
14 #include "ppapi/c/dev/ppb_console_dev.h" 14 #include "ppapi/c/dev/ppb_console_dev.h"
15 #include "ppapi/c/pp_errors.h" 15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/c/ppb_opengles2.h" 16 #include "ppapi/c/ppb_opengles2.h"
17 #include "ppapi/cpp/dev/video_decoder_client_dev.h" 17 #include "ppapi/cpp/dev/video_decoder_client_dev.h"
18 #include "ppapi/cpp/dev/video_decoder_dev.h" 18 #include "ppapi/cpp/dev/video_decoder_dev.h"
19 #include "ppapi/cpp/graphics_3d.h" 19 #include "ppapi/cpp/graphics_3d.h"
20 #include "ppapi/cpp/graphics_3d_client.h" 20 #include "ppapi/cpp/graphics_3d_client.h"
21 #include "ppapi/cpp/instance.h" 21 #include "ppapi/cpp/instance.h"
22 #include "ppapi/cpp/module.h" 22 #include "ppapi/cpp/module.h"
23 #include "ppapi/cpp/rect.h" 23 #include "ppapi/cpp/rect.h"
24 #include "ppapi/cpp/var.h" 24 #include "ppapi/cpp/var.h"
25 #include "ppapi/examples/gles2/testdata.h" 25 #include "ppapi/examples/video_decode/testdata.h"
26 #include "ppapi/lib/gl/include/GLES2/gl2.h" 26 #include "ppapi/lib/gl/include/GLES2/gl2.h"
27 #include "ppapi/utility/completion_callback_factory.h" 27 #include "ppapi/utility/completion_callback_factory.h"
28 28
29 // Use assert as a poor-man's CHECK, even in non-debug mode. 29 // Use assert as a poor-man's CHECK, even in non-debug mode.
30 // Since <assert.h> redefines assert on every inclusion (it doesn't use 30 // Since <assert.h> redefines assert on every inclusion (it doesn't use
31 // include-guards), make sure this is the last file #include'd in this file. 31 // include-guards), make sure this is the last file #include'd in this file.
32 #undef NDEBUG 32 #undef NDEBUG
33 #include <assert.h> 33 #include <assert.h>
34 34
35 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a 35 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a
36 // function to preserve line number information in the failure message. 36 // function to preserve line number information in the failure message.
37 #define assertNoGLError() \ 37 #define assertNoGLError() \
38 assert(!gles2_if_->GetError(context_->pp_resource())); 38 assert(!gles2_if_->GetError(context_->pp_resource()));
39 39
40 namespace { 40 namespace {
41 41
42 class GLES2DemoInstance : public pp::Instance, 42 class VideoDecodeDemoInstance : public pp::Instance,
43 public pp::Graphics3DClient, 43 public pp::Graphics3DClient,
44 public pp::VideoDecoderClient_Dev { 44 public pp::VideoDecoderClient_Dev {
45 public: 45 public:
46 GLES2DemoInstance(PP_Instance instance, pp::Module* module); 46 VideoDecodeDemoInstance(PP_Instance instance, pp::Module* module);
47 virtual ~GLES2DemoInstance(); 47 virtual ~VideoDecodeDemoInstance();
48 48
49 // pp::Instance implementation (see PPP_Instance). 49 // pp::Instance implementation (see PPP_Instance).
50 virtual void DidChangeView(const pp::Rect& position, 50 virtual void DidChangeView(const pp::Rect& position,
51 const pp::Rect& clip_ignored); 51 const pp::Rect& clip_ignored);
52 52
53 // pp::Graphics3DClient implementation. 53 // pp::Graphics3DClient implementation.
54 virtual void Graphics3DContextLost() { 54 virtual void Graphics3DContextLost() {
55 // TODO(vrk/fischman): Properly reset after a lost graphics context. In 55 // TODO(vrk/fischman): Properly reset after a lost graphics context. In
56 // particular need to delete context_ and re-create textures. 56 // particular need to delete context_ and re-create textures.
57 // Probably have to recreate the decoder from scratch, because old textures 57 // Probably have to recreate the decoder from scratch, because old textures
(...skipping 10 matching lines...) Expand all
68 virtual void PictureReady(PP_Resource decoder, const PP_Picture_Dev& picture); 68 virtual void PictureReady(PP_Resource decoder, const PP_Picture_Dev& picture);
69 virtual void NotifyError(PP_Resource decoder, PP_VideoDecodeError_Dev error); 69 virtual void NotifyError(PP_Resource decoder, PP_VideoDecodeError_Dev error);
70 70
71 private: 71 private:
72 enum { kNumConcurrentDecodes = 7, 72 enum { kNumConcurrentDecodes = 7,
73 kNumDecoders = 2 }; // Baked into viewport rendering. 73 kNumDecoders = 2 }; // Baked into viewport rendering.
74 74
75 // A single decoder's client interface. 75 // A single decoder's client interface.
76 class DecoderClient { 76 class DecoderClient {
77 public: 77 public:
78 DecoderClient(GLES2DemoInstance* gles2, pp::VideoDecoder_Dev* decoder); 78 DecoderClient(VideoDecodeDemoInstance* gles2,
79 pp::VideoDecoder_Dev* decoder);
79 ~DecoderClient(); 80 ~DecoderClient();
80 81
81 void DecodeNextNALUs(); 82 void DecodeNextNALUs();
82 83
83 // Per-decoder implementation of part of pp::VideoDecoderClient_Dev. 84 // Per-decoder implementation of part of pp::VideoDecoderClient_Dev.
84 void ProvidePictureBuffers(uint32_t req_num_of_bufs, 85 void ProvidePictureBuffers(uint32_t req_num_of_bufs,
85 PP_Size dimensions); 86 PP_Size dimensions);
86 void DismissPictureBuffer(int32_t picture_buffer_id); 87 void DismissPictureBuffer(int32_t picture_buffer_id);
87 88
88 const PP_PictureBuffer_Dev& GetPictureBufferById(int id); 89 const PP_PictureBuffer_Dev& GetPictureBufferById(int id);
89 pp::VideoDecoder_Dev* decoder() { return decoder_; } 90 pp::VideoDecoder_Dev* decoder() { return decoder_; }
90 91
91 private: 92 private:
92 void DecodeNextNALU(); 93 void DecodeNextNALU();
93 static void GetNextNALUBoundary(size_t start_pos, size_t* end_pos); 94 static void GetNextNALUBoundary(size_t start_pos, size_t* end_pos);
94 void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id); 95 void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id);
95 void DecoderFlushDone(int32_t result); 96 void DecoderFlushDone(int32_t result);
96 97
97 GLES2DemoInstance* gles2_; 98 VideoDecodeDemoInstance* gles2_;
98 pp::VideoDecoder_Dev* decoder_; 99 pp::VideoDecoder_Dev* decoder_;
99 pp::CompletionCallbackFactory<DecoderClient> callback_factory_; 100 pp::CompletionCallbackFactory<DecoderClient> callback_factory_;
100 int next_picture_buffer_id_; 101 int next_picture_buffer_id_;
101 int next_bitstream_buffer_id_; 102 int next_bitstream_buffer_id_;
102 size_t encoded_data_next_pos_to_decode_; 103 size_t encoded_data_next_pos_to_decode_;
103 std::set<int> bitstream_ids_at_decoder_; 104 std::set<int> bitstream_ids_at_decoder_;
104 // Map of texture buffers indexed by buffer id. 105 // Map of texture buffers indexed by buffer id.
105 typedef std::map<int, PP_PictureBuffer_Dev> PictureBufferMap; 106 typedef std::map<int, PP_PictureBuffer_Dev> PictureBufferMap;
106 PictureBufferMap picture_buffers_by_id_; 107 PictureBufferMap picture_buffers_by_id_;
107 // Map of bitstream buffers indexed by id. 108 // Map of bitstream buffers indexed by id.
(...skipping 12 matching lines...) Expand all
120 void DeleteTexture(GLuint id); 121 void DeleteTexture(GLuint id);
121 void PaintFinished(int32_t result, PP_Resource decoder, 122 void PaintFinished(int32_t result, PP_Resource decoder,
122 int picture_buffer_id); 123 int picture_buffer_id);
123 124
124 // Log an error to the developer console and stderr (though the latter may be 125 // Log an error to the developer console and stderr (though the latter may be
125 // closed due to sandboxing or blackholed for other reasons) by creating a 126 // closed due to sandboxing or blackholed for other reasons) by creating a
126 // temporary of this type and streaming to it. Example usage: 127 // temporary of this type and streaming to it. Example usage:
127 // LogError(this).s() << "Hello world: " << 42; 128 // LogError(this).s() << "Hello world: " << 42;
128 class LogError { 129 class LogError {
129 public: 130 public:
130 LogError(GLES2DemoInstance* demo) : demo_(demo) {} 131 LogError(VideoDecodeDemoInstance* demo) : demo_(demo) {}
131 ~LogError() { 132 ~LogError() {
132 const std::string& msg = stream_.str(); 133 const std::string& msg = stream_.str();
133 demo_->console_if_->Log(demo_->pp_instance(), PP_LOGLEVEL_ERROR, 134 demo_->console_if_->Log(demo_->pp_instance(), PP_LOGLEVEL_ERROR,
134 pp::Var(msg).pp_var()); 135 pp::Var(msg).pp_var());
135 std::cerr << msg << std::endl; 136 std::cerr << msg << std::endl;
136 } 137 }
137 // Impl note: it would have been nicer to have LogError derive from 138 // Impl note: it would have been nicer to have LogError derive from
138 // std::ostringstream so that it can be streamed to directly, but lookup 139 // std::ostringstream so that it can be streamed to directly, but lookup
139 // rules turn streamed string literals to hex pointers on output. 140 // rules turn streamed string literals to hex pointers on output.
140 std::ostringstream& s() { return stream_; } 141 std::ostringstream& s() { return stream_; }
141 private: 142 private:
142 GLES2DemoInstance* demo_; // Unowned. 143 VideoDecodeDemoInstance* demo_; // Unowned.
143 std::ostringstream stream_; 144 std::ostringstream stream_;
144 }; 145 };
145 146
146 pp::Size plugin_size_; 147 pp::Size plugin_size_;
147 bool is_painting_; 148 bool is_painting_;
148 // When decode outpaces render, we queue up decoded pictures for later 149 // When decode outpaces render, we queue up decoded pictures for later
149 // painting. Elements are <decoder,picture>. 150 // painting. Elements are <decoder,picture>.
150 std::list<std::pair<PP_Resource, PP_Picture_Dev> > pictures_pending_paint_; 151 std::list<std::pair<PP_Resource, PP_Picture_Dev> > pictures_pending_paint_;
151 int num_frames_rendered_; 152 int num_frames_rendered_;
152 PP_TimeTicks first_frame_delivered_ticks_; 153 PP_TimeTicks first_frame_delivered_ticks_;
153 PP_TimeTicks last_swap_request_ticks_; 154 PP_TimeTicks last_swap_request_ticks_;
154 PP_TimeTicks swap_ticks_; 155 PP_TimeTicks swap_ticks_;
155 pp::CompletionCallbackFactory<GLES2DemoInstance> callback_factory_; 156 pp::CompletionCallbackFactory<VideoDecodeDemoInstance> callback_factory_;
156 157
157 // Unowned pointers. 158 // Unowned pointers.
158 const PPB_Console_Dev* console_if_; 159 const PPB_Console_Dev* console_if_;
159 const PPB_Core* core_if_; 160 const PPB_Core* core_if_;
160 const PPB_OpenGLES2* gles2_if_; 161 const PPB_OpenGLES2* gles2_if_;
161 162
162 // Owned data. 163 // Owned data.
163 pp::Graphics3D* context_; 164 pp::Graphics3D* context_;
164 typedef std::map<int, DecoderClient*> Decoders; 165 typedef std::map<int, DecoderClient*> Decoders;
165 Decoders video_decoders_; 166 Decoders video_decoders_;
166 }; 167 };
167 168
168 GLES2DemoInstance::DecoderClient::DecoderClient(GLES2DemoInstance* gles2, 169 VideoDecodeDemoInstance::DecoderClient::DecoderClient(
169 pp::VideoDecoder_Dev* decoder) 170 VideoDecodeDemoInstance* gles2, pp::VideoDecoder_Dev* decoder)
170 : gles2_(gles2), decoder_(decoder), callback_factory_(this), 171 : gles2_(gles2), decoder_(decoder), callback_factory_(this),
171 next_picture_buffer_id_(0), 172 next_picture_buffer_id_(0),
172 next_bitstream_buffer_id_(0), encoded_data_next_pos_to_decode_(0) { 173 next_bitstream_buffer_id_(0), encoded_data_next_pos_to_decode_(0) {
173 } 174 }
174 175
175 GLES2DemoInstance::DecoderClient::~DecoderClient() { 176 VideoDecodeDemoInstance::DecoderClient::~DecoderClient() {
176 delete decoder_; 177 delete decoder_;
177 decoder_ = NULL; 178 decoder_ = NULL;
178 179
179 for (BitstreamBufferMap::iterator it = bitstream_buffers_by_id_.begin(); 180 for (BitstreamBufferMap::iterator it = bitstream_buffers_by_id_.begin();
180 it != bitstream_buffers_by_id_.end(); ++it) { 181 it != bitstream_buffers_by_id_.end(); ++it) {
181 delete it->second; 182 delete it->second;
182 } 183 }
183 bitstream_buffers_by_id_.clear(); 184 bitstream_buffers_by_id_.clear();
184 185
185 for (PictureBufferMap::iterator it = picture_buffers_by_id_.begin(); 186 for (PictureBufferMap::iterator it = picture_buffers_by_id_.begin();
186 it != picture_buffers_by_id_.end(); ++it) { 187 it != picture_buffers_by_id_.end(); ++it) {
187 gles2_->DeleteTexture(it->second.texture_id); 188 gles2_->DeleteTexture(it->second.texture_id);
188 } 189 }
189 picture_buffers_by_id_.clear(); 190 picture_buffers_by_id_.clear();
190 } 191 }
191 192
192 GLES2DemoInstance::GLES2DemoInstance(PP_Instance instance, pp::Module* module) 193 VideoDecodeDemoInstance::VideoDecodeDemoInstance(PP_Instance instance,
194 pp::Module* module)
193 : pp::Instance(instance), pp::Graphics3DClient(this), 195 : pp::Instance(instance), pp::Graphics3DClient(this),
194 pp::VideoDecoderClient_Dev(this), 196 pp::VideoDecoderClient_Dev(this),
195 num_frames_rendered_(0), 197 num_frames_rendered_(0),
196 first_frame_delivered_ticks_(-1), 198 first_frame_delivered_ticks_(-1),
197 swap_ticks_(0), 199 swap_ticks_(0),
198 callback_factory_(this), 200 callback_factory_(this),
199 context_(NULL) { 201 context_(NULL) {
200 assert((console_if_ = static_cast<const PPB_Console_Dev*>( 202 assert((console_if_ = static_cast<const PPB_Console_Dev*>(
201 module->GetBrowserInterface(PPB_CONSOLE_DEV_INTERFACE)))); 203 module->GetBrowserInterface(PPB_CONSOLE_DEV_INTERFACE))));
202 assert((core_if_ = static_cast<const PPB_Core*>( 204 assert((core_if_ = static_cast<const PPB_Core*>(
203 module->GetBrowserInterface(PPB_CORE_INTERFACE)))); 205 module->GetBrowserInterface(PPB_CORE_INTERFACE))));
204 assert((gles2_if_ = static_cast<const PPB_OpenGLES2*>( 206 assert((gles2_if_ = static_cast<const PPB_OpenGLES2*>(
205 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)))); 207 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE))));
206 } 208 }
207 209
208 GLES2DemoInstance::~GLES2DemoInstance() { 210 VideoDecodeDemoInstance::~VideoDecodeDemoInstance() {
209 for (Decoders::iterator it = video_decoders_.begin(); 211 for (Decoders::iterator it = video_decoders_.begin();
210 it != video_decoders_.end(); ++it) { 212 it != video_decoders_.end(); ++it) {
211 delete it->second; 213 delete it->second;
212 } 214 }
213 video_decoders_.clear(); 215 video_decoders_.clear();
214 delete context_; 216 delete context_;
215 } 217 }
216 218
217 void GLES2DemoInstance::DidChangeView( 219 void VideoDecodeDemoInstance::DidChangeView(
218 const pp::Rect& position, const pp::Rect& clip_ignored) { 220 const pp::Rect& position, const pp::Rect& clip_ignored) {
219 if (position.width() == 0 || position.height() == 0) 221 if (position.width() == 0 || position.height() == 0)
220 return; 222 return;
221 if (plugin_size_.width()) { 223 if (plugin_size_.width()) {
222 assert(position.size() == plugin_size_); 224 assert(position.size() == plugin_size_);
223 return; 225 return;
224 } 226 }
225 plugin_size_ = position.size(); 227 plugin_size_ = position.size();
226 228
227 // Initialize graphics. 229 // Initialize graphics.
228 InitGL(); 230 InitGL();
229 InitializeDecoders(); 231 InitializeDecoders();
230 } 232 }
231 233
232 void GLES2DemoInstance::InitializeDecoders() { 234 void VideoDecodeDemoInstance::InitializeDecoders() {
233 assert(video_decoders_.empty()); 235 assert(video_decoders_.empty());
234 for (int i = 0; i < kNumDecoders; ++i) { 236 for (int i = 0; i < kNumDecoders; ++i) {
235 DecoderClient* client = new DecoderClient( 237 DecoderClient* client = new DecoderClient(
236 this, new pp::VideoDecoder_Dev( 238 this, new pp::VideoDecoder_Dev(
237 this, *context_, PP_VIDEODECODER_H264PROFILE_BASELINE)); 239 this, *context_, PP_VIDEODECODER_H264PROFILE_BASELINE));
238 assert(!client->decoder()->is_null()); 240 assert(!client->decoder()->is_null());
239 assert(video_decoders_.insert(std::make_pair( 241 assert(video_decoders_.insert(std::make_pair(
240 client->decoder()->pp_resource(), client)).second); 242 client->decoder()->pp_resource(), client)).second);
241 client->DecodeNextNALUs(); 243 client->DecodeNextNALUs();
242 } 244 }
243 } 245 }
244 246
245 void GLES2DemoInstance::DecoderClient::DecoderBitstreamDone( 247 void VideoDecodeDemoInstance::DecoderClient::DecoderBitstreamDone(
246 int32_t result, int bitstream_buffer_id) { 248 int32_t result, int bitstream_buffer_id) {
247 assert(bitstream_ids_at_decoder_.erase(bitstream_buffer_id) == 1); 249 assert(bitstream_ids_at_decoder_.erase(bitstream_buffer_id) == 1);
248 BitstreamBufferMap::iterator it = 250 BitstreamBufferMap::iterator it =
249 bitstream_buffers_by_id_.find(bitstream_buffer_id); 251 bitstream_buffers_by_id_.find(bitstream_buffer_id);
250 assert(it != bitstream_buffers_by_id_.end()); 252 assert(it != bitstream_buffers_by_id_.end());
251 delete it->second; 253 delete it->second;
252 bitstream_buffers_by_id_.erase(it); 254 bitstream_buffers_by_id_.erase(it);
253 DecodeNextNALUs(); 255 DecodeNextNALUs();
254 } 256 }
255 257
256 void GLES2DemoInstance::DecoderClient::DecoderFlushDone(int32_t result) { 258 void VideoDecodeDemoInstance::DecoderClient::DecoderFlushDone(int32_t result) {
257 assert(result == PP_OK); 259 assert(result == PP_OK);
258 // Check that each bitstream buffer ID we handed to the decoder got handed 260 // Check that each bitstream buffer ID we handed to the decoder got handed
259 // back to us. 261 // back to us.
260 assert(bitstream_ids_at_decoder_.empty()); 262 assert(bitstream_ids_at_decoder_.empty());
261 delete decoder_; 263 delete decoder_;
262 decoder_ = NULL; 264 decoder_ = NULL;
263 } 265 }
264 266
265 static bool LookingAtNAL(const unsigned char* encoded, size_t pos) { 267 static bool LookingAtNAL(const unsigned char* encoded, size_t pos) {
266 return pos + 3 < kDataLen && 268 return pos + 3 < kDataLen &&
267 encoded[pos] == 0 && encoded[pos + 1] == 0 && 269 encoded[pos] == 0 && encoded[pos + 1] == 0 &&
268 encoded[pos + 2] == 0 && encoded[pos + 3] == 1; 270 encoded[pos + 2] == 0 && encoded[pos + 3] == 1;
269 } 271 }
270 272
271 void GLES2DemoInstance::DecoderClient::GetNextNALUBoundary( 273 void VideoDecodeDemoInstance::DecoderClient::GetNextNALUBoundary(
272 size_t start_pos, size_t* end_pos) { 274 size_t start_pos, size_t* end_pos) {
273 assert(LookingAtNAL(kData, start_pos)); 275 assert(LookingAtNAL(kData, start_pos));
274 *end_pos = start_pos; 276 *end_pos = start_pos;
275 *end_pos += 4; 277 *end_pos += 4;
276 while (*end_pos + 3 < kDataLen && 278 while (*end_pos + 3 < kDataLen &&
277 !LookingAtNAL(kData, *end_pos)) { 279 !LookingAtNAL(kData, *end_pos)) {
278 ++*end_pos; 280 ++*end_pos;
279 } 281 }
280 if (*end_pos + 3 >= kDataLen) { 282 if (*end_pos + 3 >= kDataLen) {
281 *end_pos = kDataLen; 283 *end_pos = kDataLen;
282 return; 284 return;
283 } 285 }
284 } 286 }
285 287
286 void GLES2DemoInstance::DecoderClient::DecodeNextNALUs() { 288 void VideoDecodeDemoInstance::DecoderClient::DecodeNextNALUs() {
287 while (encoded_data_next_pos_to_decode_ <= kDataLen && 289 while (encoded_data_next_pos_to_decode_ <= kDataLen &&
288 bitstream_ids_at_decoder_.size() < kNumConcurrentDecodes) { 290 bitstream_ids_at_decoder_.size() < kNumConcurrentDecodes) {
289 DecodeNextNALU(); 291 DecodeNextNALU();
290 } 292 }
291 } 293 }
292 294
293 void GLES2DemoInstance::DecoderClient::DecodeNextNALU() { 295 void VideoDecodeDemoInstance::DecoderClient::DecodeNextNALU() {
294 if (encoded_data_next_pos_to_decode_ == kDataLen) { 296 if (encoded_data_next_pos_to_decode_ == kDataLen) {
295 ++encoded_data_next_pos_to_decode_; 297 ++encoded_data_next_pos_to_decode_;
296 pp::CompletionCallback cb = callback_factory_.NewCallback( 298 pp::CompletionCallback cb = callback_factory_.NewCallback(
297 &GLES2DemoInstance::DecoderClient::DecoderFlushDone); 299 &VideoDecodeDemoInstance::DecoderClient::DecoderFlushDone);
298 decoder_->Flush(cb); 300 decoder_->Flush(cb);
299 return; 301 return;
300 } 302 }
301 size_t start_pos = encoded_data_next_pos_to_decode_; 303 size_t start_pos = encoded_data_next_pos_to_decode_;
302 size_t end_pos; 304 size_t end_pos;
303 GetNextNALUBoundary(start_pos, &end_pos); 305 GetNextNALUBoundary(start_pos, &end_pos);
304 pp::Buffer_Dev* buffer = new pp::Buffer_Dev(gles2_, end_pos - start_pos); 306 pp::Buffer_Dev* buffer = new pp::Buffer_Dev(gles2_, end_pos - start_pos);
305 PP_VideoBitstreamBuffer_Dev bitstream_buffer; 307 PP_VideoBitstreamBuffer_Dev bitstream_buffer;
306 int id = ++next_bitstream_buffer_id_; 308 int id = ++next_bitstream_buffer_id_;
307 bitstream_buffer.id = id; 309 bitstream_buffer.id = id;
308 bitstream_buffer.size = end_pos - start_pos; 310 bitstream_buffer.size = end_pos - start_pos;
309 bitstream_buffer.data = buffer->pp_resource(); 311 bitstream_buffer.data = buffer->pp_resource();
310 memcpy(buffer->data(), kData + start_pos, end_pos - start_pos); 312 memcpy(buffer->data(), kData + start_pos, end_pos - start_pos);
311 assert(bitstream_buffers_by_id_.insert(std::make_pair(id, buffer)).second); 313 assert(bitstream_buffers_by_id_.insert(std::make_pair(id, buffer)).second);
312 314
313 pp::CompletionCallback cb = 315 pp::CompletionCallback cb =
314 callback_factory_.NewCallback( 316 callback_factory_.NewCallback(
315 &GLES2DemoInstance::DecoderClient::DecoderBitstreamDone, id); 317 &VideoDecodeDemoInstance::DecoderClient::DecoderBitstreamDone, id);
316 assert(bitstream_ids_at_decoder_.insert(id).second); 318 assert(bitstream_ids_at_decoder_.insert(id).second);
317 encoded_data_next_pos_to_decode_ = end_pos; 319 encoded_data_next_pos_to_decode_ = end_pos;
318 decoder_->Decode(bitstream_buffer, cb); 320 decoder_->Decode(bitstream_buffer, cb);
319 } 321 }
320 322
321 void GLES2DemoInstance::ProvidePictureBuffers( 323 void VideoDecodeDemoInstance::ProvidePictureBuffers(
322 PP_Resource decoder, uint32_t req_num_of_bufs, const PP_Size& dimensions) { 324 PP_Resource decoder, uint32_t req_num_of_bufs, const PP_Size& dimensions) {
323 DecoderClient* client = video_decoders_[decoder]; 325 DecoderClient* client = video_decoders_[decoder];
324 assert(client); 326 assert(client);
325 client->ProvidePictureBuffers(req_num_of_bufs, dimensions); 327 client->ProvidePictureBuffers(req_num_of_bufs, dimensions);
326 } 328 }
327 329
328 void GLES2DemoInstance::DecoderClient::ProvidePictureBuffers( 330 void VideoDecodeDemoInstance::DecoderClient::ProvidePictureBuffers(
329 uint32_t req_num_of_bufs, PP_Size dimensions) { 331 uint32_t req_num_of_bufs, PP_Size dimensions) {
330 std::vector<PP_PictureBuffer_Dev> buffers; 332 std::vector<PP_PictureBuffer_Dev> buffers;
331 for (uint32_t i = 0; i < req_num_of_bufs; ++i) { 333 for (uint32_t i = 0; i < req_num_of_bufs; ++i) {
332 PP_PictureBuffer_Dev buffer; 334 PP_PictureBuffer_Dev buffer;
333 buffer.size = dimensions; 335 buffer.size = dimensions;
334 buffer.texture_id = 336 buffer.texture_id =
335 gles2_->CreateTexture(dimensions.width, dimensions.height); 337 gles2_->CreateTexture(dimensions.width, dimensions.height);
336 int id = ++next_picture_buffer_id_; 338 int id = ++next_picture_buffer_id_;
337 buffer.id = id; 339 buffer.id = id;
338 buffers.push_back(buffer); 340 buffers.push_back(buffer);
339 assert(picture_buffers_by_id_.insert(std::make_pair(id, buffer)).second); 341 assert(picture_buffers_by_id_.insert(std::make_pair(id, buffer)).second);
340 } 342 }
341 decoder_->AssignPictureBuffers(buffers); 343 decoder_->AssignPictureBuffers(buffers);
342 } 344 }
343 345
344 const PP_PictureBuffer_Dev& 346 const PP_PictureBuffer_Dev&
345 GLES2DemoInstance::DecoderClient::GetPictureBufferById( 347 VideoDecodeDemoInstance::DecoderClient::GetPictureBufferById(
346 int id) { 348 int id) {
347 PictureBufferMap::iterator it = picture_buffers_by_id_.find(id); 349 PictureBufferMap::iterator it = picture_buffers_by_id_.find(id);
348 assert(it != picture_buffers_by_id_.end()); 350 assert(it != picture_buffers_by_id_.end());
349 return it->second; 351 return it->second;
350 } 352 }
351 353
352 void GLES2DemoInstance::DismissPictureBuffer(PP_Resource decoder, 354 void VideoDecodeDemoInstance::DismissPictureBuffer(PP_Resource decoder,
353 int32_t picture_buffer_id) { 355 int32_t picture_buffer_id) {
354 DecoderClient* client = video_decoders_[decoder]; 356 DecoderClient* client = video_decoders_[decoder];
355 assert(client); 357 assert(client);
356 client->DismissPictureBuffer(picture_buffer_id); 358 client->DismissPictureBuffer(picture_buffer_id);
357 } 359 }
358 360
359 void GLES2DemoInstance::DecoderClient::DismissPictureBuffer( 361 void VideoDecodeDemoInstance::DecoderClient::DismissPictureBuffer(
360 int32_t picture_buffer_id) { 362 int32_t picture_buffer_id) {
361 gles2_->DeleteTexture(GetPictureBufferById(picture_buffer_id).texture_id); 363 gles2_->DeleteTexture(GetPictureBufferById(picture_buffer_id).texture_id);
362 picture_buffers_by_id_.erase(picture_buffer_id); 364 picture_buffers_by_id_.erase(picture_buffer_id);
363 } 365 }
364 366
365 void GLES2DemoInstance::PictureReady(PP_Resource decoder, 367 void VideoDecodeDemoInstance::PictureReady(PP_Resource decoder,
366 const PP_Picture_Dev& picture) { 368 const PP_Picture_Dev& picture) {
367 if (first_frame_delivered_ticks_ == -1) 369 if (first_frame_delivered_ticks_ == -1)
368 assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1); 370 assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1);
369 if (is_painting_) { 371 if (is_painting_) {
370 pictures_pending_paint_.push_back(std::make_pair(decoder, picture)); 372 pictures_pending_paint_.push_back(std::make_pair(decoder, picture));
371 return; 373 return;
372 } 374 }
373 DecoderClient* client = video_decoders_[decoder]; 375 DecoderClient* client = video_decoders_[decoder];
374 assert(client); 376 assert(client);
375 const PP_PictureBuffer_Dev& buffer = 377 const PP_PictureBuffer_Dev& buffer =
376 client->GetPictureBufferById(picture.picture_buffer_id); 378 client->GetPictureBufferById(picture.picture_buffer_id);
377 assert(!is_painting_); 379 assert(!is_painting_);
378 is_painting_ = true; 380 is_painting_ = true;
379 int x = 0; 381 int x = 0;
380 int y = 0; 382 int y = 0;
381 if (client != video_decoders_.begin()->second) { 383 if (client != video_decoders_.begin()->second) {
382 x = plugin_size_.width() / kNumDecoders; 384 x = plugin_size_.width() / kNumDecoders;
383 y = plugin_size_.height() / kNumDecoders; 385 y = plugin_size_.height() / kNumDecoders;
384 } 386 }
385 387
386 gles2_if_->Viewport(context_->pp_resource(), x, y, 388 gles2_if_->Viewport(context_->pp_resource(), x, y,
387 plugin_size_.width() / kNumDecoders, 389 plugin_size_.width() / kNumDecoders,
388 plugin_size_.height() / kNumDecoders); 390 plugin_size_.height() / kNumDecoders);
389 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); 391 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
390 gles2_if_->BindTexture( 392 gles2_if_->BindTexture(
391 context_->pp_resource(), GL_TEXTURE_2D, buffer.texture_id); 393 context_->pp_resource(), GL_TEXTURE_2D, buffer.texture_id);
392 gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4); 394 gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4);
393 pp::CompletionCallback cb = 395 pp::CompletionCallback cb =
394 callback_factory_.NewCallback( 396 callback_factory_.NewCallback(
395 &GLES2DemoInstance::PaintFinished, decoder, buffer.id); 397 &VideoDecodeDemoInstance::PaintFinished, decoder, buffer.id);
396 last_swap_request_ticks_ = core_if_->GetTimeTicks(); 398 last_swap_request_ticks_ = core_if_->GetTimeTicks();
397 assert(context_->SwapBuffers(cb) == PP_OK_COMPLETIONPENDING); 399 assert(context_->SwapBuffers(cb) == PP_OK_COMPLETIONPENDING);
398 } 400 }
399 401
400 void GLES2DemoInstance::NotifyError(PP_Resource decoder, 402 void VideoDecodeDemoInstance::NotifyError(PP_Resource decoder,
401 PP_VideoDecodeError_Dev error) { 403 PP_VideoDecodeError_Dev error) {
402 LogError(this).s() << "Received error: " << error; 404 LogError(this).s() << "Received error: " << error;
403 assert(!"Unexpected error; see stderr for details"); 405 assert(!"Unexpected error; see stderr for details");
404 } 406 }
405 407
406 // This object is the global object representing this plugin library as long 408 // This object is the global object representing this plugin library as long
407 // as it is loaded. 409 // as it is loaded.
408 class GLES2DemoModule : public pp::Module { 410 class VideoDecodeDemoModule : public pp::Module {
409 public: 411 public:
410 GLES2DemoModule() : pp::Module() {} 412 VideoDecodeDemoModule() : pp::Module() {}
411 virtual ~GLES2DemoModule() {} 413 virtual ~VideoDecodeDemoModule() {}
412 414
413 virtual pp::Instance* CreateInstance(PP_Instance instance) { 415 virtual pp::Instance* CreateInstance(PP_Instance instance) {
414 return new GLES2DemoInstance(instance, this); 416 return new VideoDecodeDemoInstance(instance, this);
415 } 417 }
416 }; 418 };
417 419
418 void GLES2DemoInstance::InitGL() { 420 void VideoDecodeDemoInstance::InitGL() {
419 assert(plugin_size_.width() && plugin_size_.height()); 421 assert(plugin_size_.width() && plugin_size_.height());
420 is_painting_ = false; 422 is_painting_ = false;
421 423
422 assert(!context_); 424 assert(!context_);
423 int32_t context_attributes[] = { 425 int32_t context_attributes[] = {
424 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8, 426 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
425 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8, 427 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
426 PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8, 428 PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8,
427 PP_GRAPHICS3DATTRIB_RED_SIZE, 8, 429 PP_GRAPHICS3DATTRIB_RED_SIZE, 8,
428 PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0, 430 PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0,
(...skipping 10 matching lines...) Expand all
439 441
440 // Clear color bit. 442 // Clear color bit.
441 gles2_if_->ClearColor(context_->pp_resource(), 1, 0, 0, 1); 443 gles2_if_->ClearColor(context_->pp_resource(), 1, 0, 0, 1);
442 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); 444 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
443 445
444 assertNoGLError(); 446 assertNoGLError();
445 447
446 CreateGLObjects(); 448 CreateGLObjects();
447 } 449 }
448 450
449 void GLES2DemoInstance::PaintFinished(int32_t result, PP_Resource decoder, 451 void VideoDecodeDemoInstance::PaintFinished(int32_t result, PP_Resource decoder,
450 int picture_buffer_id) { 452 int picture_buffer_id) {
451 assert(result == PP_OK); 453 assert(result == PP_OK);
452 swap_ticks_ += core_if_->GetTimeTicks() - last_swap_request_ticks_; 454 swap_ticks_ += core_if_->GetTimeTicks() - last_swap_request_ticks_;
453 is_painting_ = false; 455 is_painting_ = false;
454 ++num_frames_rendered_; 456 ++num_frames_rendered_;
455 if (num_frames_rendered_ % 50 == 0) { 457 if (num_frames_rendered_ % 50 == 0) {
456 double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_; 458 double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_;
457 double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000; 459 double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000;
458 double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_; 460 double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_;
459 LogError(this).s() << "Rendered frames: " << num_frames_rendered_ 461 LogError(this).s() << "Rendered frames: " << num_frames_rendered_
460 << ", fps: " << fps << ", with average ms/swap of: " 462 << ", fps: " << fps << ", with average ms/swap of: "
461 << ms_per_swap; 463 << ms_per_swap;
462 } 464 }
463 DecoderClient* client = video_decoders_[decoder]; 465 DecoderClient* client = video_decoders_[decoder];
464 if (client && client->decoder()) 466 if (client && client->decoder())
465 client->decoder()->ReusePictureBuffer(picture_buffer_id); 467 client->decoder()->ReusePictureBuffer(picture_buffer_id);
466 if (!pictures_pending_paint_.empty()) { 468 if (!pictures_pending_paint_.empty()) {
467 std::pair<PP_Resource, PP_Picture_Dev> decoder_picture = 469 std::pair<PP_Resource, PP_Picture_Dev> decoder_picture =
468 pictures_pending_paint_.front(); 470 pictures_pending_paint_.front();
469 pictures_pending_paint_.pop_front(); 471 pictures_pending_paint_.pop_front();
470 PictureReady(decoder_picture.first, decoder_picture.second); 472 PictureReady(decoder_picture.first, decoder_picture.second);
471 } 473 }
472 } 474 }
473 475
474 GLuint GLES2DemoInstance::CreateTexture(int32_t width, int32_t height) { 476 GLuint VideoDecodeDemoInstance::CreateTexture(int32_t width, int32_t height) {
475 GLuint texture_id; 477 GLuint texture_id;
476 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); 478 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id);
477 assertNoGLError(); 479 assertNoGLError();
478 // Assign parameters. 480 // Assign parameters.
479 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); 481 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
480 gles2_if_->BindTexture(context_->pp_resource(), GL_TEXTURE_2D, texture_id); 482 gles2_if_->BindTexture(context_->pp_resource(), GL_TEXTURE_2D, texture_id);
481 gles2_if_->TexParameteri( 483 gles2_if_->TexParameteri(
482 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 484 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
483 GL_NEAREST); 485 GL_NEAREST);
484 gles2_if_->TexParameteri( 486 gles2_if_->TexParameteri(
485 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 487 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
486 GL_NEAREST); 488 GL_NEAREST);
487 gles2_if_->TexParameterf( 489 gles2_if_->TexParameterf(
488 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 490 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
489 GL_CLAMP_TO_EDGE); 491 GL_CLAMP_TO_EDGE);
490 gles2_if_->TexParameterf( 492 gles2_if_->TexParameterf(
491 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 493 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
492 GL_CLAMP_TO_EDGE); 494 GL_CLAMP_TO_EDGE);
493 495
494 gles2_if_->TexImage2D( 496 gles2_if_->TexImage2D(
495 context_->pp_resource(), GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, 497 context_->pp_resource(), GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
496 GL_RGBA, GL_UNSIGNED_BYTE, NULL); 498 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
497 assertNoGLError(); 499 assertNoGLError();
498 return texture_id; 500 return texture_id;
499 } 501 }
500 502
501 void GLES2DemoInstance::DeleteTexture(GLuint id) { 503 void VideoDecodeDemoInstance::DeleteTexture(GLuint id) {
502 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &id); 504 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &id);
503 } 505 }
504 506
505 void GLES2DemoInstance::CreateGLObjects() { 507 void VideoDecodeDemoInstance::CreateGLObjects() {
506 // Code and constants for shader. 508 // Code and constants for shader.
507 static const char kVertexShader[] = 509 static const char kVertexShader[] =
508 "varying vec2 v_texCoord; \n" 510 "varying vec2 v_texCoord; \n"
509 "attribute vec4 a_position; \n" 511 "attribute vec4 a_position; \n"
510 "attribute vec2 a_texCoord; \n" 512 "attribute vec2 a_texCoord; \n"
511 "void main() \n" 513 "void main() \n"
512 "{ \n" 514 "{ \n"
513 " v_texCoord = a_texCoord; \n" 515 " v_texCoord = a_texCoord; \n"
514 " gl_Position = a_position; \n" 516 " gl_Position = a_position; \n"
515 "}"; 517 "}";
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 gles2_if_->EnableVertexAttribArray(context_->pp_resource(), pos_location); 560 gles2_if_->EnableVertexAttribArray(context_->pp_resource(), pos_location);
559 gles2_if_->VertexAttribPointer(context_->pp_resource(), pos_location, 2, 561 gles2_if_->VertexAttribPointer(context_->pp_resource(), pos_location, 2,
560 GL_FLOAT, GL_FALSE, 0, 0); 562 GL_FLOAT, GL_FALSE, 0, 0);
561 gles2_if_->EnableVertexAttribArray(context_->pp_resource(), tc_location); 563 gles2_if_->EnableVertexAttribArray(context_->pp_resource(), tc_location);
562 gles2_if_->VertexAttribPointer( 564 gles2_if_->VertexAttribPointer(
563 context_->pp_resource(), tc_location, 2, GL_FLOAT, GL_FALSE, 0, 565 context_->pp_resource(), tc_location, 2, GL_FLOAT, GL_FALSE, 0,
564 static_cast<float*>(0) + 8); // Skip position coordinates. 566 static_cast<float*>(0) + 8); // Skip position coordinates.
565 assertNoGLError(); 567 assertNoGLError();
566 } 568 }
567 569
568 void GLES2DemoInstance::CreateShader( 570 void VideoDecodeDemoInstance::CreateShader(
569 GLuint program, GLenum type, const char* source, int size) { 571 GLuint program, GLenum type, const char* source, int size) {
570 GLuint shader = gles2_if_->CreateShader(context_->pp_resource(), type); 572 GLuint shader = gles2_if_->CreateShader(context_->pp_resource(), type);
571 gles2_if_->ShaderSource(context_->pp_resource(), shader, 1, &source, &size); 573 gles2_if_->ShaderSource(context_->pp_resource(), shader, 1, &source, &size);
572 gles2_if_->CompileShader(context_->pp_resource(), shader); 574 gles2_if_->CompileShader(context_->pp_resource(), shader);
573 gles2_if_->AttachShader(context_->pp_resource(), program, shader); 575 gles2_if_->AttachShader(context_->pp_resource(), program, shader);
574 gles2_if_->DeleteShader(context_->pp_resource(), shader); 576 gles2_if_->DeleteShader(context_->pp_resource(), shader);
575 } 577 }
576 } // anonymous namespace 578 } // anonymous namespace
577 579
578 namespace pp { 580 namespace pp {
579 // Factory function for your specialization of the Module object. 581 // Factory function for your specialization of the Module object.
580 Module* CreateModule() { 582 Module* CreateModule() {
581 return new GLES2DemoModule(); 583 return new VideoDecodeDemoModule();
582 } 584 }
583 } // namespace pp 585 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698