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

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

Issue 340163002: Pepper: Add latency calculation to ppapi/examples/video_decode. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 6 years, 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2014 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 <stdio.h> 5 #include <stdio.h>
6 #include <string.h> 6 #include <string.h>
7 7
8 #include <iostream> 8 #include <iostream>
9 #include <queue> 9 #include <queue>
10 #include <sstream> 10 #include <sstream>
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 Decoder(MyInstance* instance, int id, const pp::Graphics3D& graphics_3d); 152 Decoder(MyInstance* instance, int id, const pp::Graphics3D& graphics_3d);
153 ~Decoder(); 153 ~Decoder();
154 154
155 int id() const { return id_; } 155 int id() const { return id_; }
156 bool flushing() const { return flushing_; } 156 bool flushing() const { return flushing_; }
157 bool resetting() const { return resetting_; } 157 bool resetting() const { return resetting_; }
158 158
159 void Reset(); 159 void Reset();
160 void RecyclePicture(const PP_VideoPicture& picture); 160 void RecyclePicture(const PP_VideoPicture& picture);
161 161
162 PP_TimeTicks GetAverageLatency() {
163 return num_pictures_ ? total_latency_ / num_pictures_ : 0;
164 }
165
162 private: 166 private:
163 void InitializeDone(int32_t result); 167 void InitializeDone(int32_t result);
164 void Start(); 168 void Start();
165 void DecodeNextFrame(); 169 void DecodeNextFrame();
166 void DecodeDone(int32_t result); 170 void DecodeDone(int32_t result);
167 void PictureReady(int32_t result, PP_VideoPicture picture); 171 void PictureReady(int32_t result, PP_VideoPicture picture);
168 void FlushDone(int32_t result); 172 void FlushDone(int32_t result);
169 void ResetDone(int32_t result); 173 void ResetDone(int32_t result);
170 174
171 MyInstance* instance_; 175 MyInstance* instance_;
172 int id_; 176 int id_;
173 177
174 pp::VideoDecoder* decoder_; 178 pp::VideoDecoder* decoder_;
175 pp::CompletionCallbackFactory<Decoder> callback_factory_; 179 pp::CompletionCallbackFactory<Decoder> callback_factory_;
176 180
177 size_t encoded_data_next_pos_to_decode_; 181 size_t encoded_data_next_pos_to_decode_;
178 int next_picture_id_; 182 int next_picture_id_;
179 bool flushing_; 183 bool flushing_;
180 bool resetting_; 184 bool resetting_;
185
186 const PPB_Core* core_if_;
187 static const int kMaxDecodeDelay = 128;
188 PP_TimeTicks decode_time_[kMaxDecodeDelay];
189 PP_TimeTicks total_latency_;
190 int num_pictures_;
181 }; 191 };
182 192
183 #if defined USE_VP8_TESTDATA_INSTEAD_OF_H264 193 #if defined USE_VP8_TESTDATA_INSTEAD_OF_H264
184 194
185 // VP8 is stored in an IVF container. 195 // VP8 is stored in an IVF container.
186 // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF 196 // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF
187 197
188 static void GetNextFrame(size_t* start_pos, size_t* end_pos) { 198 static void GetNextFrame(size_t* start_pos, size_t* end_pos) {
189 size_t current_pos = *start_pos; 199 size_t current_pos = *start_pos;
190 if (current_pos == 0) 200 if (current_pos == 0)
(...skipping 29 matching lines...) Expand all
220 Decoder::Decoder(MyInstance* instance, 230 Decoder::Decoder(MyInstance* instance,
221 int id, 231 int id,
222 const pp::Graphics3D& graphics_3d) 232 const pp::Graphics3D& graphics_3d)
223 : instance_(instance), 233 : instance_(instance),
224 id_(id), 234 id_(id),
225 decoder_(new pp::VideoDecoder(instance)), 235 decoder_(new pp::VideoDecoder(instance)),
226 callback_factory_(this), 236 callback_factory_(this),
227 encoded_data_next_pos_to_decode_(0), 237 encoded_data_next_pos_to_decode_(0),
228 next_picture_id_(0), 238 next_picture_id_(0),
229 flushing_(false), 239 flushing_(false),
230 resetting_(false) { 240 resetting_(false),
241 total_latency_(0.0),
242 num_pictures_(0) {
243 core_if_ = static_cast<const PPB_Core*>(
244 pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
245
231 #if defined USE_VP8_TESTDATA_INSTEAD_OF_H264 246 #if defined USE_VP8_TESTDATA_INSTEAD_OF_H264
232 const PP_VideoProfile kBitstreamProfile = PP_VIDEOPROFILE_VP8MAIN; 247 const PP_VideoProfile kBitstreamProfile = PP_VIDEOPROFILE_VP8MAIN;
233 #else 248 #else
234 const PP_VideoProfile kBitstreamProfile = PP_VIDEOPROFILE_H264MAIN; 249 const PP_VideoProfile kBitstreamProfile = PP_VIDEOPROFILE_H264MAIN;
235 #endif 250 #endif
236 251
237 assert(!decoder_->is_null()); 252 assert(!decoder_->is_null());
238 decoder_->Initialize(graphics_3d, 253 decoder_->Initialize(graphics_3d,
239 kBitstreamProfile, 254 kBitstreamProfile,
240 PP_TRUE /* allow_software_fallback */, 255 PP_TRUE /* allow_software_fallback */,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 } 303 }
289 304
290 // Find the start of the next frame. 305 // Find the start of the next frame.
291 size_t start_pos = encoded_data_next_pos_to_decode_; 306 size_t start_pos = encoded_data_next_pos_to_decode_;
292 size_t end_pos; 307 size_t end_pos;
293 GetNextFrame(&start_pos, &end_pos); 308 GetNextFrame(&start_pos, &end_pos);
294 encoded_data_next_pos_to_decode_ = end_pos; 309 encoded_data_next_pos_to_decode_ = end_pos;
295 // Decode the frame. On completion, DecodeDone will call DecodeNextFrame 310 // Decode the frame. On completion, DecodeDone will call DecodeNextFrame
296 // to implement a decode loop. 311 // to implement a decode loop.
297 uint32_t size = static_cast<uint32_t>(end_pos - start_pos); 312 uint32_t size = static_cast<uint32_t>(end_pos - start_pos);
313 decode_time_[next_picture_id_ % kMaxDecodeDelay] = core_if_->GetTimeTicks();
298 decoder_->Decode(next_picture_id_++, 314 decoder_->Decode(next_picture_id_++,
299 size, 315 size,
300 kData + start_pos, 316 kData + start_pos,
301 callback_factory_.NewCallback(&Decoder::DecodeDone)); 317 callback_factory_.NewCallback(&Decoder::DecodeDone));
302 } 318 }
303 } 319 }
304 320
305 void Decoder::DecodeDone(int32_t result) { 321 void Decoder::DecodeDone(int32_t result) {
306 assert(decoder_); 322 assert(decoder_);
307 // Break out of the decode loop on abort. 323 // Break out of the decode loop on abort.
308 if (result == PP_ERROR_ABORTED) 324 if (result == PP_ERROR_ABORTED)
309 return; 325 return;
310 assert(result == PP_OK); 326 assert(result == PP_OK);
311 if (!flushing_ && !resetting_) 327 if (!flushing_ && !resetting_)
312 DecodeNextFrame(); 328 DecodeNextFrame();
313 } 329 }
314 330
315 void Decoder::PictureReady(int32_t result, PP_VideoPicture picture) { 331 void Decoder::PictureReady(int32_t result, PP_VideoPicture picture) {
316 assert(decoder_); 332 assert(decoder_);
317 // Break out of the get picture loop on abort. 333 // Break out of the get picture loop on abort.
318 if (result == PP_ERROR_ABORTED) 334 if (result == PP_ERROR_ABORTED)
319 return; 335 return;
320 assert(result == PP_OK); 336 assert(result == PP_OK);
337
338 num_pictures_++;
339 PP_TimeTicks latency = core_if_->GetTimeTicks() -
340 decode_time_[picture.decode_id % kMaxDecodeDelay];
341 total_latency_ += latency;
342
321 decoder_->GetPicture( 343 decoder_->GetPicture(
322 callback_factory_.NewCallbackWithOutput(&Decoder::PictureReady)); 344 callback_factory_.NewCallbackWithOutput(&Decoder::PictureReady));
323 instance_->PaintPicture(this, picture); 345 instance_->PaintPicture(this, picture);
324 } 346 }
325 347
326 void Decoder::FlushDone(int32_t result) { 348 void Decoder::FlushDone(int32_t result) {
327 assert(decoder_); 349 assert(decoder_);
328 assert(result == PP_OK || result == PP_ERROR_ABORTED); 350 assert(result == PP_OK || result == PP_ERROR_ABORTED);
329 assert(flushing_); 351 assert(flushing_);
330 flushing_ = false; 352 flushing_ = false;
(...skipping 11 matching lines...) Expand all
342 MyInstance::MyInstance(PP_Instance instance, pp::Module* module) 364 MyInstance::MyInstance(PP_Instance instance, pp::Module* module)
343 : pp::Instance(instance), 365 : pp::Instance(instance),
344 pp::Graphics3DClient(this), 366 pp::Graphics3DClient(this),
345 is_painting_(false), 367 is_painting_(false),
346 num_frames_rendered_(0), 368 num_frames_rendered_(0),
347 first_frame_delivered_ticks_(-1), 369 first_frame_delivered_ticks_(-1),
348 last_swap_request_ticks_(-1), 370 last_swap_request_ticks_(-1),
349 swap_ticks_(0), 371 swap_ticks_(0),
350 callback_factory_(this), 372 callback_factory_(this),
351 context_(NULL) { 373 context_(NULL) {
352 assert((console_if_ = static_cast<const PPB_Console*>( 374 console_if_ = static_cast<const PPB_Console*>(
353 module->GetBrowserInterface(PPB_CONSOLE_INTERFACE)))); 375 pp::Module::Get()->GetBrowserInterface(PPB_CONSOLE_INTERFACE));
354 assert((core_if_ = static_cast<const PPB_Core*>( 376 core_if_ = static_cast<const PPB_Core*>(
355 module->GetBrowserInterface(PPB_CORE_INTERFACE)))); 377 pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
356 assert((gles2_if_ = static_cast<const PPB_OpenGLES2*>( 378 gles2_if_ = static_cast<const PPB_OpenGLES2*>(
357 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)))); 379 pp::Module::Get()->GetBrowserInterface(PPB_OPENGLES2_INTERFACE));
380
358 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE); 381 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
359 } 382 }
360 383
361 MyInstance::~MyInstance() { 384 MyInstance::~MyInstance() {
362 if (!context_) 385 if (!context_)
363 return; 386 return;
364 387
365 PP_Resource graphics_3d = context_->pp_resource(); 388 PP_Resource graphics_3d = context_->pp_resource();
366 if (shader_2d_.program) 389 if (shader_2d_.program)
367 gles2_if_->DeleteProgram(graphics_3d, shader_2d_.program); 390 gles2_if_->DeleteProgram(graphics_3d, shader_2d_.program);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 503
481 void MyInstance::PaintFinished(int32_t result) { 504 void MyInstance::PaintFinished(int32_t result) {
482 assert(result == PP_OK); 505 assert(result == PP_OK);
483 swap_ticks_ += core_if_->GetTimeTicks() - last_swap_request_ticks_; 506 swap_ticks_ += core_if_->GetTimeTicks() - last_swap_request_ticks_;
484 is_painting_ = false; 507 is_painting_ = false;
485 ++num_frames_rendered_; 508 ++num_frames_rendered_;
486 if (num_frames_rendered_ % 50 == 0) { 509 if (num_frames_rendered_ % 50 == 0) {
487 double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_; 510 double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_;
488 double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000; 511 double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000;
489 double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_; 512 double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_;
513 double secs_average_latency = 0;
514 for (DecoderList::iterator it = video_decoders_.begin();
515 it != video_decoders_.end();
516 ++it)
517 secs_average_latency += (*it)->GetAverageLatency();
518 secs_average_latency /= video_decoders_.size();
519 double ms_average_latency = 1000 * secs_average_latency;
490 LogError(this).s() << "Rendered frames: " << num_frames_rendered_ 520 LogError(this).s() << "Rendered frames: " << num_frames_rendered_
491 << ", fps: " << fps 521 << ", fps: " << fps
492 << ", with average ms/swap of: " << ms_per_swap; 522 << ", with average ms/swap of: " << ms_per_swap
523 << ", with average latency (ms) of: "
524 << ms_average_latency;
493 } 525 }
494 526
495 // If the decoders were reset, this will be empty. 527 // If the decoders were reset, this will be empty.
496 if (pending_pictures_.empty()) 528 if (pending_pictures_.empty())
497 return; 529 return;
498 530
499 const PendingPicture& next = pending_pictures_.front(); 531 const PendingPicture& next = pending_pictures_.front();
500 Decoder* decoder = next.decoder; 532 Decoder* decoder = next.decoder;
501 const PP_VideoPicture& picture = next.picture; 533 const PP_VideoPicture& picture = next.picture;
502 decoder->RecyclePicture(picture); 534 decoder->RecyclePicture(picture);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 567
536 assertNoGLError(); 568 assertNoGLError();
537 569
538 CreateGLObjects(); 570 CreateGLObjects();
539 } 571 }
540 572
541 void MyInstance::CreateGLObjects() { 573 void MyInstance::CreateGLObjects() {
542 // Assign vertex positions and texture coordinates to buffers for use in 574 // Assign vertex positions and texture coordinates to buffers for use in
543 // shader program. 575 // shader program.
544 static const float kVertices[] = { 576 static const float kVertices[] = {
545 -1, 1, -1, -1, 1, 1, 1, -1, // Position coordinates. 577 -1, -1, -1, 1, 1, -1, 1, 1, // Position coordinates.
546 0, 1, 0, 0, 1, 1, 1, 0, // Texture coordinates. 578 0, 1, 0, 0, 1, 1, 1, 0, // Texture coordinates.
547 }; 579 };
548 580
549 GLuint buffer; 581 GLuint buffer;
550 gles2_if_->GenBuffers(context_->pp_resource(), 1, &buffer); 582 gles2_if_->GenBuffers(context_->pp_resource(), 1, &buffer);
551 gles2_if_->BindBuffer(context_->pp_resource(), GL_ARRAY_BUFFER, buffer); 583 gles2_if_->BindBuffer(context_->pp_resource(), GL_ARRAY_BUFFER, buffer);
552 584
553 gles2_if_->BufferData(context_->pp_resource(), 585 gles2_if_->BufferData(context_->pp_resource(),
554 GL_ARRAY_BUFFER, 586 GL_ARRAY_BUFFER,
555 sizeof(kVertices), 587 sizeof(kVertices),
556 kVertices, 588 kVertices,
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 }; 704 };
673 705
674 } // anonymous namespace 706 } // anonymous namespace
675 707
676 namespace pp { 708 namespace pp {
677 // Factory function for your specialization of the Module object. 709 // Factory function for your specialization of the Module object.
678 Module* CreateModule() { 710 Module* CreateModule() {
679 return new MyModule(); 711 return new MyModule();
680 } 712 }
681 } // namespace pp 713 } // namespace pp
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698