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

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

Issue 213313003: Experimental patch for MediaCodec APIs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update. Requires chromium @r273920 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
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>
11 11
12 #include "ppapi/c/pp_errors.h" 12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/c/ppb_console.h" 13 #include "ppapi/c/ppb_console.h"
14 #include "ppapi/c/ppb_opengles2.h" 14 #include "ppapi/c/ppb_opengles2.h"
15 #include "ppapi/cpp/graphics_3d.h" 15 #include "ppapi/cpp/graphics_3d.h"
16 #include "ppapi/cpp/graphics_3d_client.h" 16 #include "ppapi/cpp/graphics_3d_client.h"
17 #include "ppapi/cpp/input_event.h" 17 #include "ppapi/cpp/input_event.h"
18 #include "ppapi/cpp/instance.h" 18 #include "ppapi/cpp/instance.h"
19 #include "ppapi/cpp/module.h" 19 #include "ppapi/cpp/module.h"
20 #include "ppapi/cpp/rect.h" 20 #include "ppapi/cpp/rect.h"
21 #include "ppapi/cpp/var.h" 21 #include "ppapi/cpp/var.h"
22 #include "ppapi/cpp/video_decoder.h" 22 #include "ppapi/cpp/video_decoder.h"
23
24 // One of these should be defined.
25 //#define TEST_H264
26 #define TEST_VP8
23 #include "ppapi/examples/video_decode/testdata.h" 27 #include "ppapi/examples/video_decode/testdata.h"
28
24 #include "ppapi/lib/gl/include/GLES2/gl2.h" 29 #include "ppapi/lib/gl/include/GLES2/gl2.h"
25 #include "ppapi/lib/gl/include/GLES2/gl2ext.h" 30 #include "ppapi/lib/gl/include/GLES2/gl2ext.h"
26 #include "ppapi/utility/completion_callback_factory.h" 31 #include "ppapi/utility/completion_callback_factory.h"
27 32
28 // Use assert as a poor-man's CHECK, even in non-debug mode. 33 // Use assert as a poor-man's CHECK, even in non-debug mode.
29 // Since <assert.h> redefines assert on every inclusion (it doesn't use 34 // Since <assert.h> redefines assert on every inclusion (it doesn't use
30 // include-guards), make sure this is the last file #include'd in this file. 35 // include-guards), make sure this is the last file #include'd in this file.
31 #undef NDEBUG 36 #undef NDEBUG
32 #include <assert.h> 37 #include <assert.h>
33 38
(...skipping 15 matching lines...) Expand all
49 class MyInstance; 54 class MyInstance;
50 55
51 class MyInstance : public pp::Instance, public pp::Graphics3DClient { 56 class MyInstance : public pp::Instance, public pp::Graphics3DClient {
52 public: 57 public:
53 MyInstance(PP_Instance instance, pp::Module* module); 58 MyInstance(PP_Instance instance, pp::Module* module);
54 virtual ~MyInstance(); 59 virtual ~MyInstance();
55 60
56 // pp::Instance implementation. 61 // pp::Instance implementation.
57 virtual void DidChangeView(const pp::Rect& position, 62 virtual void DidChangeView(const pp::Rect& position,
58 const pp::Rect& clip_ignored); 63 const pp::Rect& clip_ignored);
64 virtual bool HandleInputEvent(const pp::InputEvent& event);
59 65
60 // pp::Graphics3DClient implementation. 66 // pp::Graphics3DClient implementation.
61 virtual void Graphics3DContextLost() { 67 virtual void Graphics3DContextLost() {
62 // TODO(vrk/fischman): Properly reset after a lost graphics context. In 68 // TODO(vrk/fischman): Properly reset after a lost graphics context. In
63 // particular need to delete context_ and re-create textures. 69 // particular need to delete context_ and re-create textures.
64 // Probably have to recreate the decoder from scratch, because old textures 70 // Probably have to recreate the decoder from scratch, because old textures
65 // can still be outstanding in the decoder! 71 // can still be outstanding in the decoder!
66 assert(false && "Unexpectedly lost graphics context"); 72 assert(false && "Unexpectedly lost graphics context");
67 } 73 }
68 74
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 pp::VideoDecoder* decoder_; 163 pp::VideoDecoder* decoder_;
158 pp::CompletionCallbackFactory<Decoder> callback_factory_; 164 pp::CompletionCallbackFactory<Decoder> callback_factory_;
159 165
160 size_t encoded_data_next_pos_to_decode_; 166 size_t encoded_data_next_pos_to_decode_;
161 int next_picture_id_; 167 int next_picture_id_;
162 int seek_frame_; 168 int seek_frame_;
163 bool flushing_; 169 bool flushing_;
164 bool resetting_; 170 bool resetting_;
165 }; 171 };
166 172
173 #if defined(TEST_H264)
167 // Returns true if the current position is at the start of a NAL unit. 174 // Returns true if the current position is at the start of a NAL unit.
168 static bool LookingAtNAL(const unsigned char* encoded, size_t pos) { 175 static bool LookingAtNAL(const unsigned char* encoded, size_t pos) {
169 // H264 frames start with 0, 0, 0, 1 in our test data. 176 // H264 frames start with 0, 0, 0, 1 in our test data.
170 return pos + 3 < kDataLen && encoded[pos] == 0 && encoded[pos + 1] == 0 && 177 return pos + 3 < kDataLen && encoded[pos] == 0 && encoded[pos + 1] == 0 &&
171 encoded[pos + 2] == 0 && encoded[pos + 3] == 1; 178 encoded[pos + 2] == 0 && encoded[pos + 3] == 1;
172 } 179 }
180 #endif
173 181
174 // Find the start and end of the next frame. 182 // Find the start and end of the next frame.
175 static void GetNextFrame(size_t* start_pos, size_t* end_pos) { 183 static void GetNextFrame(size_t* start_pos, size_t* end_pos) {
184 #if defined(TEST_H264)
176 assert(LookingAtNAL(kData, *start_pos)); 185 assert(LookingAtNAL(kData, *start_pos));
177 *end_pos = *start_pos; 186 *end_pos = *start_pos;
178 *end_pos += 4; 187 *end_pos += 4;
179 while (*end_pos < kDataLen && !LookingAtNAL(kData, *end_pos)) { 188 while (*end_pos < kDataLen && !LookingAtNAL(kData, *end_pos)) {
180 ++*end_pos; 189 ++*end_pos;
181 } 190 }
191 #elif defined(TEST_VP8)
192 // VP8 is stored in an IVF container.
193 // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF
194 if (*start_pos == 0)
195 *start_pos = 32; // Skip IVF header.
196 uint32_t frame_size = *reinterpret_cast<const uint32_t*>(&kData[*start_pos]);
197 *start_pos += 12; // Skip frame header.
198 *end_pos = *start_pos + frame_size;
199 #endif
182 } 200 }
183 201
184 Decoder::Decoder(MyInstance* instance, 202 Decoder::Decoder(MyInstance* instance,
185 int id, 203 int id,
186 const pp::Graphics3D& graphics_3d) 204 const pp::Graphics3D& graphics_3d)
187 : instance_(instance), 205 : instance_(instance),
188 id_(id), 206 id_(id),
189 decoder_(new pp::VideoDecoder(instance)), 207 decoder_(new pp::VideoDecoder(instance)),
190 callback_factory_(this), 208 callback_factory_(this),
191 encoded_data_next_pos_to_decode_(0), 209 encoded_data_next_pos_to_decode_(0),
192 next_picture_id_(0), 210 next_picture_id_(0),
193 seek_frame_(0), 211 seek_frame_(0),
194 flushing_(false), 212 flushing_(false),
195 resetting_(false) { 213 resetting_(false) {
196 assert(!decoder_->is_null()); 214 assert(!decoder_->is_null());
197 const PP_VideoProfile profile = PP_VIDEOPROFILE_H264MAIN; 215 const PP_VideoProfile profile =
216 #if defined(TEST_H264)
217 PP_VIDEOPROFILE_H264MAIN;
218 #elif defined(TEST_VP8)
219 PP_VIDEOPROFILE_VP8MAIN;
220 #endif
198 decoder_->Initialize(graphics_3d, 221 decoder_->Initialize(graphics_3d,
199 profile, 222 profile,
200 PP_FALSE /* allow_software_fallback */, 223 PP_TRUE /* allow_software_fallback */,
201 callback_factory_.NewCallback(&Decoder::InitializeDone)); 224 callback_factory_.NewCallback(&Decoder::InitializeDone));
202 } 225 }
203 226
204 Decoder::~Decoder() { 227 Decoder::~Decoder() {
205 delete decoder_; 228 delete decoder_;
206 } 229 }
207 230
208 void Decoder::InitializeDone(int32_t result) { 231 void Decoder::InitializeDone(int32_t result) {
209 assert(decoder_); 232 assert(decoder_);
210 assert(result == PP_OK); 233 assert(result == PP_OK);
211 assert(decoding()); 234 assert(decoding());
212 Start(0); 235 Start(0);
213 } 236 }
214 237
215 void Decoder::Start(int frame) { 238 void Decoder::Start(int frame) {
216 assert(decoder_); 239 assert(decoder_);
217 240
218 // Skip to |frame|. 241 // Skip to |frame|.
219 size_t start_pos = 0; 242 size_t start_pos = 0;
220 size_t end_pos = 0; 243 size_t end_pos = 0;
221 for (int i = 0; i < frame; i++) 244 for (int i = 0; i < frame; i++) {
222 GetNextFrame(&start_pos, &end_pos); 245 GetNextFrame(&start_pos, &end_pos);
246 start_pos = end_pos;
247 }
223 encoded_data_next_pos_to_decode_ = end_pos; 248 encoded_data_next_pos_to_decode_ = end_pos;
249 printf("encoded_data_next_pos_to_decode_=%i\n", (int)encoded_data_next_pos_to_ decode_);
224 250
225 // Register callback to get the first picture. We call GetPicture again in 251 // Register callback to get the first picture. We call GetPicture again in
226 // PictureReady to continuously receive pictures as they're decoded. 252 // PictureReady to continuously receive pictures as they're decoded.
227 decoder_->GetPicture( 253 decoder_->GetPicture(
228 callback_factory_.NewCallbackWithOutput(&Decoder::PictureReady)); 254 callback_factory_.NewCallbackWithOutput(&Decoder::PictureReady));
229 255
230 // Start the decode loop. 256 // Start the decode loop.
231 DecodeNextFrame(); 257 DecodeNextFrame();
232 } 258 }
233 259
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 // Break out of the get picture loop on abort. 309 // Break out of the get picture loop on abort.
284 if (result == PP_ERROR_ABORTED) 310 if (result == PP_ERROR_ABORTED)
285 return; 311 return;
286 assert(result == PP_OK); 312 assert(result == PP_OK);
287 decoder_->GetPicture( 313 decoder_->GetPicture(
288 callback_factory_.NewCallbackWithOutput(&Decoder::PictureReady)); 314 callback_factory_.NewCallbackWithOutput(&Decoder::PictureReady));
289 instance_->PaintPicture(this, picture); 315 instance_->PaintPicture(this, picture);
290 } 316 }
291 317
292 void Decoder::FlushDone(int32_t result) { 318 void Decoder::FlushDone(int32_t result) {
319 printf("FlushDone:result=%i\n", result);
293 assert(decoder_); 320 assert(decoder_);
294 assert(result == PP_OK || result == PP_ERROR_ABORTED); 321 assert(result == PP_OK || result == PP_ERROR_ABORTED);
295 flushing_ = false; 322 flushing_ = false;
296 } 323 }
297 324
298 void Decoder::ResetDone(int32_t result) { 325 void Decoder::ResetDone(int32_t result) {
326 printf("ResetDone:result=%i\n", result);
299 assert(decoder_); 327 assert(decoder_);
300 assert(result == PP_OK); 328 assert(result == PP_OK);
301 resetting_ = false; 329 resetting_ = false;
330
331 Start(seek_frame_);
302 } 332 }
303 333
304 MyInstance::MyInstance(PP_Instance instance, pp::Module* module) 334 MyInstance::MyInstance(PP_Instance instance, pp::Module* module)
305 : pp::Instance(instance), 335 : pp::Instance(instance),
306 pp::Graphics3DClient(this), 336 pp::Graphics3DClient(this),
307 is_painting_(false), 337 is_painting_(false),
308 num_frames_rendered_(0), 338 num_frames_rendered_(0),
309 first_frame_delivered_ticks_(-1), 339 first_frame_delivered_ticks_(-1),
310 last_swap_request_ticks_(-1), 340 last_swap_request_ticks_(-1),
311 swap_ticks_(0), 341 swap_ticks_(0),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 assert(position.size() == plugin_size_); 376 assert(position.size() == plugin_size_);
347 return; 377 return;
348 } 378 }
349 plugin_size_ = position.size(); 379 plugin_size_ = position.size();
350 380
351 // Initialize graphics. 381 // Initialize graphics.
352 InitGL(); 382 InitGL();
353 InitializeDecoders(); 383 InitializeDecoders();
354 } 384 }
355 385
386 bool MyInstance::HandleInputEvent(const pp::InputEvent& event) {
387 switch (event.GetType()) {
388 case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
389 pp::MouseInputEvent mouse_event(event);
390 // Reset all decoders and restart video at a point proportional to the
391 // mouse's horiziontal offset from the left edge of the plugin area.
392 if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT) {
393 pp::Point mouse_position = mouse_event.GetPosition();
394 const int num_frames = 300; // TODO figure out real number of frames.
395 int frame =
396 (float)mouse_position.x() / plugin_size_.width() * num_frames;
397 for (size_t i = 0; i < video_decoders_.size(); i++) {
398 video_decoders_[i]->Seek(frame);
399 }
400 printf("Seeking:frame=%i\n", frame);
401 }
402 return true;
403 }
404
405 default:
406 return false;
407 }
408 }
409
356 void MyInstance::InitializeDecoders() { 410 void MyInstance::InitializeDecoders() {
357 assert(video_decoders_.empty()); 411 assert(video_decoders_.empty());
358 // Create two decoders with ids 0 and 1. 412 // Create two decoders with ids 0 and 1.
359 video_decoders_.push_back(new Decoder(this, 0, *context_)); 413 video_decoders_.push_back(new Decoder(this, 0, *context_));
360 video_decoders_.push_back(new Decoder(this, 1, *context_)); 414 video_decoders_.push_back(new Decoder(this, 1, *context_));
361 } 415 }
362 416
363 void MyInstance::PaintPicture(Decoder* decoder, 417 void MyInstance::PaintPicture(Decoder* decoder,
364 const PP_VideoPicture& picture) { 418 const PP_VideoPicture& picture) {
365 if (first_frame_delivered_ticks_ == -1) 419 if (first_frame_delivered_ticks_ == -1)
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 }; 654 };
601 655
602 } // anonymous namespace 656 } // anonymous namespace
603 657
604 namespace pp { 658 namespace pp {
605 // Factory function for your specialization of the Module object. 659 // Factory function for your specialization of the Module object.
606 Module* CreateModule() { 660 Module* CreateModule() {
607 return new MyModule(); 661 return new MyModule();
608 } 662 }
609 } // namespace pp 663 } // namespace pp
OLDNEW
« no previous file with comments | « content/test/ppapi/ppapi_browsertest.cc ('k') | ppapi/examples/video_decode/video_decode_dev.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698