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

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

Issue 333903002: Revert of Revert of Implement software fallback for PPB_VideoDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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 | « gpu/gpu.gyp ('k') | ppapi/ppapi_sources.gypi » ('j') | 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>
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 // VP8 is more likely to work on different versions of Chrome. Undefine this
25 // to decode H264.
26 #define USE_VP8_TESTDATA_INSTEAD_OF_H264
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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 }; 138 };
133 139
134 class Decoder { 140 class Decoder {
135 public: 141 public:
136 Decoder(MyInstance* instance, int id, const pp::Graphics3D& graphics_3d); 142 Decoder(MyInstance* instance, int id, const pp::Graphics3D& graphics_3d);
137 ~Decoder(); 143 ~Decoder();
138 144
139 int id() const { return id_; } 145 int id() const { return id_; }
140 bool decoding() const { return !flushing_ && !resetting_; } 146 bool decoding() const { return !flushing_ && !resetting_; }
141 147
142 void Seek(int frame); 148 void Reset();
143 void RecyclePicture(const PP_VideoPicture& picture); 149 void RecyclePicture(const PP_VideoPicture& picture);
144 150
145 private: 151 private:
146 void InitializeDone(int32_t result); 152 void InitializeDone(int32_t result);
147 void Start(int frame); 153 void Start();
148 void DecodeNextFrame(); 154 void DecodeNextFrame();
149 void DecodeDone(int32_t result); 155 void DecodeDone(int32_t result);
150 void PictureReady(int32_t result, PP_VideoPicture picture); 156 void PictureReady(int32_t result, PP_VideoPicture picture);
151 void FlushDone(int32_t result); 157 void FlushDone(int32_t result);
152 void ResetDone(int32_t result); 158 void ResetDone(int32_t result);
153 159
154 MyInstance* instance_; 160 MyInstance* instance_;
155 int id_; 161 int id_;
156 162
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_;
163 bool flushing_; 168 bool flushing_;
164 bool resetting_; 169 bool resetting_;
165 }; 170 };
166 171
172 #if defined USE_VP8_TESTDATA_INSTEAD_OF_H264
173
174 // VP8 is stored in an IVF container.
175 // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF
176
177 static void GetNextFrame(size_t* start_pos, size_t* end_pos) {
178 size_t current_pos = *start_pos;
179 if (current_pos == 0)
180 current_pos = 32; // Skip stream header.
181 uint32_t frame_size = kData[current_pos] + (kData[current_pos + 1] << 8) +
182 (kData[current_pos + 2] << 16) +
183 (kData[current_pos + 3] << 24);
184 current_pos += 12; // Skip frame header.
185 *start_pos = current_pos;
186 *end_pos = current_pos + frame_size;
187 }
188
189 #else // !USE_VP8_TESTDATA_INSTEAD_OF_H264
190
167 // Returns true if the current position is at the start of a NAL unit. 191 // 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) { 192 static bool LookingAtNAL(const unsigned char* encoded, size_t pos) {
169 // H264 frames start with 0, 0, 0, 1 in our test data. 193 // H264 frames start with 0, 0, 0, 1 in our test data.
170 return pos + 3 < kDataLen && encoded[pos] == 0 && encoded[pos + 1] == 0 && 194 return pos + 3 < kDataLen && encoded[pos] == 0 && encoded[pos + 1] == 0 &&
171 encoded[pos + 2] == 0 && encoded[pos + 3] == 1; 195 encoded[pos + 2] == 0 && encoded[pos + 3] == 1;
172 } 196 }
173 197
174 // Find the start and end of the next frame.
175 static void GetNextFrame(size_t* start_pos, size_t* end_pos) { 198 static void GetNextFrame(size_t* start_pos, size_t* end_pos) {
176 assert(LookingAtNAL(kData, *start_pos)); 199 assert(LookingAtNAL(kData, *start_pos));
177 *end_pos = *start_pos; 200 *end_pos = *start_pos;
178 *end_pos += 4; 201 *end_pos += 4;
179 while (*end_pos < kDataLen && !LookingAtNAL(kData, *end_pos)) { 202 while (*end_pos < kDataLen && !LookingAtNAL(kData, *end_pos)) {
180 ++*end_pos; 203 ++*end_pos;
181 } 204 }
182 } 205 }
183 206
207 #endif // USE_VP8_TESTDATA_INSTEAD_OF_H264
208
184 Decoder::Decoder(MyInstance* instance, 209 Decoder::Decoder(MyInstance* instance,
185 int id, 210 int id,
186 const pp::Graphics3D& graphics_3d) 211 const pp::Graphics3D& graphics_3d)
187 : instance_(instance), 212 : instance_(instance),
188 id_(id), 213 id_(id),
189 decoder_(new pp::VideoDecoder(instance)), 214 decoder_(new pp::VideoDecoder(instance)),
190 callback_factory_(this), 215 callback_factory_(this),
191 encoded_data_next_pos_to_decode_(0), 216 encoded_data_next_pos_to_decode_(0),
192 next_picture_id_(0), 217 next_picture_id_(0),
193 seek_frame_(0),
194 flushing_(false), 218 flushing_(false),
195 resetting_(false) { 219 resetting_(false) {
220 // TODO(bbudge) Remove this for final patch.
221 #if defined USE_VP8_TESTDATA_INSTEAD_OF_H264
222 const PP_VideoProfile kBitstreamProfile = PP_VIDEOPROFILE_VP8MAIN;
223 #else
224 const PP_VideoProfile kBitstreamProfile = PP_VIDEOPROFILE_H264MAIN;
225 #endif
226
196 assert(!decoder_->is_null()); 227 assert(!decoder_->is_null());
197 const PP_VideoProfile profile = PP_VIDEOPROFILE_H264MAIN;
198 decoder_->Initialize(graphics_3d, 228 decoder_->Initialize(graphics_3d,
199 profile, 229 kBitstreamProfile,
200 PP_FALSE /* allow_software_fallback */, 230 PP_TRUE /* allow_software_fallback */,
201 callback_factory_.NewCallback(&Decoder::InitializeDone)); 231 callback_factory_.NewCallback(&Decoder::InitializeDone));
202 } 232 }
203 233
204 Decoder::~Decoder() { 234 Decoder::~Decoder() {
205 delete decoder_; 235 delete decoder_;
206 } 236 }
207 237
208 void Decoder::InitializeDone(int32_t result) { 238 void Decoder::InitializeDone(int32_t result) {
209 assert(decoder_); 239 assert(decoder_);
210 assert(result == PP_OK); 240 assert(result == PP_OK);
211 assert(decoding()); 241 assert(decoding());
212 Start(0); 242 Start();
213 } 243 }
214 244
215 void Decoder::Start(int frame) { 245 void Decoder::Start() {
216 assert(decoder_); 246 assert(decoder_);
217 247
218 // Skip to |frame|. 248 encoded_data_next_pos_to_decode_ = 0;
219 size_t start_pos = 0;
220 size_t end_pos = 0;
221 for (int i = 0; i < frame; i++)
222 GetNextFrame(&start_pos, &end_pos);
223 encoded_data_next_pos_to_decode_ = end_pos;
224 249
225 // Register callback to get the first picture. We call GetPicture again in 250 // Register callback to get the first picture. We call GetPicture again in
226 // PictureReady to continuously receive pictures as they're decoded. 251 // PictureReady to continuously receive pictures as they're decoded.
227 decoder_->GetPicture( 252 decoder_->GetPicture(
228 callback_factory_.NewCallbackWithOutput(&Decoder::PictureReady)); 253 callback_factory_.NewCallbackWithOutput(&Decoder::PictureReady));
229 254
230 // Start the decode loop. 255 // Start the decode loop.
231 DecodeNextFrame(); 256 DecodeNextFrame();
232 } 257 }
233 258
234 void Decoder::Seek(int frame) { 259 void Decoder::Reset() {
235 assert(decoder_); 260 assert(decoder_);
236 seek_frame_ = frame;
237 resetting_ = true; 261 resetting_ = true;
238 decoder_->Reset(callback_factory_.NewCallback(&Decoder::ResetDone)); 262 decoder_->Reset(callback_factory_.NewCallback(&Decoder::ResetDone));
239 } 263 }
240 264
241 void Decoder::RecyclePicture(const PP_VideoPicture& picture) { 265 void Decoder::RecyclePicture(const PP_VideoPicture& picture) {
242 assert(decoder_); 266 assert(decoder_);
243 decoder_->RecyclePicture(picture); 267 decoder_->RecyclePicture(picture);
244 } 268 }
245 269
246 void Decoder::DecodeNextFrame() { 270 void Decoder::DecodeNextFrame() {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 void Decoder::FlushDone(int32_t result) { 316 void Decoder::FlushDone(int32_t result) {
293 assert(decoder_); 317 assert(decoder_);
294 assert(result == PP_OK || result == PP_ERROR_ABORTED); 318 assert(result == PP_OK || result == PP_ERROR_ABORTED);
295 flushing_ = false; 319 flushing_ = false;
296 } 320 }
297 321
298 void Decoder::ResetDone(int32_t result) { 322 void Decoder::ResetDone(int32_t result) {
299 assert(decoder_); 323 assert(decoder_);
300 assert(result == PP_OK); 324 assert(result == PP_OK);
301 resetting_ = false; 325 resetting_ = false;
326
327 Start();
302 } 328 }
303 329
304 MyInstance::MyInstance(PP_Instance instance, pp::Module* module) 330 MyInstance::MyInstance(PP_Instance instance, pp::Module* module)
305 : pp::Instance(instance), 331 : pp::Instance(instance),
306 pp::Graphics3DClient(this), 332 pp::Graphics3DClient(this),
307 is_painting_(false), 333 is_painting_(false),
308 num_frames_rendered_(0), 334 num_frames_rendered_(0),
309 first_frame_delivered_ticks_(-1), 335 first_frame_delivered_ticks_(-1),
310 last_swap_request_ticks_(-1), 336 last_swap_request_ticks_(-1),
311 swap_ticks_(0), 337 swap_ticks_(0),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 assert(position.size() == plugin_size_); 372 assert(position.size() == plugin_size_);
347 return; 373 return;
348 } 374 }
349 plugin_size_ = position.size(); 375 plugin_size_ = position.size();
350 376
351 // Initialize graphics. 377 // Initialize graphics.
352 InitGL(); 378 InitGL();
353 InitializeDecoders(); 379 InitializeDecoders();
354 } 380 }
355 381
382 bool MyInstance::HandleInputEvent(const pp::InputEvent& event) {
383 switch (event.GetType()) {
384 case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
385 pp::MouseInputEvent mouse_event(event);
386 // Reset all decoders on mouse down.
387 if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT) {
388 for (size_t i = 0; i < video_decoders_.size(); i++) {
389 if (video_decoders_[i]->decoding())
390 video_decoders_[i]->Reset();
391 }
392 }
393 return true;
394 }
395
396 default:
397 return false;
398 }
399 }
400
356 void MyInstance::InitializeDecoders() { 401 void MyInstance::InitializeDecoders() {
357 assert(video_decoders_.empty()); 402 assert(video_decoders_.empty());
358 // Create two decoders with ids 0 and 1. 403 // Create two decoders with ids 0 and 1.
359 video_decoders_.push_back(new Decoder(this, 0, *context_)); 404 video_decoders_.push_back(new Decoder(this, 0, *context_));
360 video_decoders_.push_back(new Decoder(this, 1, *context_)); 405 video_decoders_.push_back(new Decoder(this, 1, *context_));
361 } 406 }
362 407
363 void MyInstance::PaintPicture(Decoder* decoder, 408 void MyInstance::PaintPicture(Decoder* decoder,
364 const PP_VideoPicture& picture) { 409 const PP_VideoPicture& picture) {
365 if (first_frame_delivered_ticks_ == -1) 410 if (first_frame_delivered_ticks_ == -1)
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 }; 645 };
601 646
602 } // anonymous namespace 647 } // anonymous namespace
603 648
604 namespace pp { 649 namespace pp {
605 // Factory function for your specialization of the Module object. 650 // Factory function for your specialization of the Module object.
606 Module* CreateModule() { 651 Module* CreateModule() {
607 return new MyModule(); 652 return new MyModule();
608 } 653 }
609 } // namespace pp 654 } // namespace pp
OLDNEW
« no previous file with comments | « gpu/gpu.gyp ('k') | ppapi/ppapi_sources.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698