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

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

Issue 337683002: 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
27 #include "ppapi/examples/video_decode/testdata.h" 23 #include "ppapi/examples/video_decode/testdata.h"
28
29 #include "ppapi/lib/gl/include/GLES2/gl2.h" 24 #include "ppapi/lib/gl/include/GLES2/gl2.h"
30 #include "ppapi/lib/gl/include/GLES2/gl2ext.h" 25 #include "ppapi/lib/gl/include/GLES2/gl2ext.h"
31 #include "ppapi/utility/completion_callback_factory.h" 26 #include "ppapi/utility/completion_callback_factory.h"
32 27
33 // Use assert as a poor-man's CHECK, even in non-debug mode. 28 // Use assert as a poor-man's CHECK, even in non-debug mode.
34 // Since <assert.h> redefines assert on every inclusion (it doesn't use 29 // Since <assert.h> redefines assert on every inclusion (it doesn't use
35 // include-guards), make sure this is the last file #include'd in this file. 30 // include-guards), make sure this is the last file #include'd in this file.
36 #undef NDEBUG 31 #undef NDEBUG
37 #include <assert.h> 32 #include <assert.h>
38 33
(...skipping 15 matching lines...) Expand all
54 class MyInstance; 49 class MyInstance;
55 50
56 class MyInstance : public pp::Instance, public pp::Graphics3DClient { 51 class MyInstance : public pp::Instance, public pp::Graphics3DClient {
57 public: 52 public:
58 MyInstance(PP_Instance instance, pp::Module* module); 53 MyInstance(PP_Instance instance, pp::Module* module);
59 virtual ~MyInstance(); 54 virtual ~MyInstance();
60 55
61 // pp::Instance implementation. 56 // pp::Instance implementation.
62 virtual void DidChangeView(const pp::Rect& position, 57 virtual void DidChangeView(const pp::Rect& position,
63 const pp::Rect& clip_ignored); 58 const pp::Rect& clip_ignored);
64 virtual bool HandleInputEvent(const pp::InputEvent& event);
65 59
66 // pp::Graphics3DClient implementation. 60 // pp::Graphics3DClient implementation.
67 virtual void Graphics3DContextLost() { 61 virtual void Graphics3DContextLost() {
68 // TODO(vrk/fischman): Properly reset after a lost graphics context. In 62 // TODO(vrk/fischman): Properly reset after a lost graphics context. In
69 // particular need to delete context_ and re-create textures. 63 // particular need to delete context_ and re-create textures.
70 // Probably have to recreate the decoder from scratch, because old textures 64 // Probably have to recreate the decoder from scratch, because old textures
71 // can still be outstanding in the decoder! 65 // can still be outstanding in the decoder!
72 assert(false && "Unexpectedly lost graphics context"); 66 assert(false && "Unexpectedly lost graphics context");
73 } 67 }
74 68
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 }; 132 };
139 133
140 class Decoder { 134 class Decoder {
141 public: 135 public:
142 Decoder(MyInstance* instance, int id, const pp::Graphics3D& graphics_3d); 136 Decoder(MyInstance* instance, int id, const pp::Graphics3D& graphics_3d);
143 ~Decoder(); 137 ~Decoder();
144 138
145 int id() const { return id_; } 139 int id() const { return id_; }
146 bool decoding() const { return !flushing_ && !resetting_; } 140 bool decoding() const { return !flushing_ && !resetting_; }
147 141
148 void Reset(); 142 void Seek(int frame);
149 void RecyclePicture(const PP_VideoPicture& picture); 143 void RecyclePicture(const PP_VideoPicture& picture);
150 144
151 private: 145 private:
152 void InitializeDone(int32_t result); 146 void InitializeDone(int32_t result);
153 void Start(); 147 void Start(int frame);
154 void DecodeNextFrame(); 148 void DecodeNextFrame();
155 void DecodeDone(int32_t result); 149 void DecodeDone(int32_t result);
156 void PictureReady(int32_t result, PP_VideoPicture picture); 150 void PictureReady(int32_t result, PP_VideoPicture picture);
157 void FlushDone(int32_t result); 151 void FlushDone(int32_t result);
158 void ResetDone(int32_t result); 152 void ResetDone(int32_t result);
159 153
160 MyInstance* instance_; 154 MyInstance* instance_;
161 int id_; 155 int id_;
162 156
163 pp::VideoDecoder* decoder_; 157 pp::VideoDecoder* decoder_;
164 pp::CompletionCallbackFactory<Decoder> callback_factory_; 158 pp::CompletionCallbackFactory<Decoder> callback_factory_;
165 159
166 size_t encoded_data_next_pos_to_decode_; 160 size_t encoded_data_next_pos_to_decode_;
167 int next_picture_id_; 161 int next_picture_id_;
162 int seek_frame_;
168 bool flushing_; 163 bool flushing_;
169 bool resetting_; 164 bool resetting_;
170 }; 165 };
171 166
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
191 // Returns true if the current position is at the start of a NAL unit. 167 // Returns true if the current position is at the start of a NAL unit.
192 static bool LookingAtNAL(const unsigned char* encoded, size_t pos) { 168 static bool LookingAtNAL(const unsigned char* encoded, size_t pos) {
193 // H264 frames start with 0, 0, 0, 1 in our test data. 169 // H264 frames start with 0, 0, 0, 1 in our test data.
194 return pos + 3 < kDataLen && encoded[pos] == 0 && encoded[pos + 1] == 0 && 170 return pos + 3 < kDataLen && encoded[pos] == 0 && encoded[pos + 1] == 0 &&
195 encoded[pos + 2] == 0 && encoded[pos + 3] == 1; 171 encoded[pos + 2] == 0 && encoded[pos + 3] == 1;
196 } 172 }
197 173
174 // Find the start and end of the next frame.
198 static void GetNextFrame(size_t* start_pos, size_t* end_pos) { 175 static void GetNextFrame(size_t* start_pos, size_t* end_pos) {
199 assert(LookingAtNAL(kData, *start_pos)); 176 assert(LookingAtNAL(kData, *start_pos));
200 *end_pos = *start_pos; 177 *end_pos = *start_pos;
201 *end_pos += 4; 178 *end_pos += 4;
202 while (*end_pos < kDataLen && !LookingAtNAL(kData, *end_pos)) { 179 while (*end_pos < kDataLen && !LookingAtNAL(kData, *end_pos)) {
203 ++*end_pos; 180 ++*end_pos;
204 } 181 }
205 } 182 }
206 183
207 #endif // USE_VP8_TESTDATA_INSTEAD_OF_H264
208
209 Decoder::Decoder(MyInstance* instance, 184 Decoder::Decoder(MyInstance* instance,
210 int id, 185 int id,
211 const pp::Graphics3D& graphics_3d) 186 const pp::Graphics3D& graphics_3d)
212 : instance_(instance), 187 : instance_(instance),
213 id_(id), 188 id_(id),
214 decoder_(new pp::VideoDecoder(instance)), 189 decoder_(new pp::VideoDecoder(instance)),
215 callback_factory_(this), 190 callback_factory_(this),
216 encoded_data_next_pos_to_decode_(0), 191 encoded_data_next_pos_to_decode_(0),
217 next_picture_id_(0), 192 next_picture_id_(0),
193 seek_frame_(0),
218 flushing_(false), 194 flushing_(false),
219 resetting_(false) { 195 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
227 assert(!decoder_->is_null()); 196 assert(!decoder_->is_null());
197 const PP_VideoProfile profile = PP_VIDEOPROFILE_H264MAIN;
228 decoder_->Initialize(graphics_3d, 198 decoder_->Initialize(graphics_3d,
229 kBitstreamProfile, 199 profile,
230 PP_TRUE /* allow_software_fallback */, 200 PP_FALSE /* allow_software_fallback */,
231 callback_factory_.NewCallback(&Decoder::InitializeDone)); 201 callback_factory_.NewCallback(&Decoder::InitializeDone));
232 } 202 }
233 203
234 Decoder::~Decoder() { 204 Decoder::~Decoder() {
235 delete decoder_; 205 delete decoder_;
236 } 206 }
237 207
238 void Decoder::InitializeDone(int32_t result) { 208 void Decoder::InitializeDone(int32_t result) {
239 assert(decoder_); 209 assert(decoder_);
240 assert(result == PP_OK); 210 assert(result == PP_OK);
241 assert(decoding()); 211 assert(decoding());
242 Start(); 212 Start(0);
243 } 213 }
244 214
245 void Decoder::Start() { 215 void Decoder::Start(int frame) {
246 assert(decoder_); 216 assert(decoder_);
247 217
248 encoded_data_next_pos_to_decode_ = 0; 218 // Skip to |frame|.
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;
249 224
250 // Register callback to get the first picture. We call GetPicture again in 225 // Register callback to get the first picture. We call GetPicture again in
251 // PictureReady to continuously receive pictures as they're decoded. 226 // PictureReady to continuously receive pictures as they're decoded.
252 decoder_->GetPicture( 227 decoder_->GetPicture(
253 callback_factory_.NewCallbackWithOutput(&Decoder::PictureReady)); 228 callback_factory_.NewCallbackWithOutput(&Decoder::PictureReady));
254 229
255 // Start the decode loop. 230 // Start the decode loop.
256 DecodeNextFrame(); 231 DecodeNextFrame();
257 } 232 }
258 233
259 void Decoder::Reset() { 234 void Decoder::Seek(int frame) {
260 assert(decoder_); 235 assert(decoder_);
236 seek_frame_ = frame;
261 resetting_ = true; 237 resetting_ = true;
262 decoder_->Reset(callback_factory_.NewCallback(&Decoder::ResetDone)); 238 decoder_->Reset(callback_factory_.NewCallback(&Decoder::ResetDone));
263 } 239 }
264 240
265 void Decoder::RecyclePicture(const PP_VideoPicture& picture) { 241 void Decoder::RecyclePicture(const PP_VideoPicture& picture) {
266 assert(decoder_); 242 assert(decoder_);
267 decoder_->RecyclePicture(picture); 243 decoder_->RecyclePicture(picture);
268 } 244 }
269 245
270 void Decoder::DecodeNextFrame() { 246 void Decoder::DecodeNextFrame() {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 void Decoder::FlushDone(int32_t result) { 292 void Decoder::FlushDone(int32_t result) {
317 assert(decoder_); 293 assert(decoder_);
318 assert(result == PP_OK || result == PP_ERROR_ABORTED); 294 assert(result == PP_OK || result == PP_ERROR_ABORTED);
319 flushing_ = false; 295 flushing_ = false;
320 } 296 }
321 297
322 void Decoder::ResetDone(int32_t result) { 298 void Decoder::ResetDone(int32_t result) {
323 assert(decoder_); 299 assert(decoder_);
324 assert(result == PP_OK); 300 assert(result == PP_OK);
325 resetting_ = false; 301 resetting_ = false;
326
327 Start();
328 } 302 }
329 303
330 MyInstance::MyInstance(PP_Instance instance, pp::Module* module) 304 MyInstance::MyInstance(PP_Instance instance, pp::Module* module)
331 : pp::Instance(instance), 305 : pp::Instance(instance),
332 pp::Graphics3DClient(this), 306 pp::Graphics3DClient(this),
333 is_painting_(false), 307 is_painting_(false),
334 num_frames_rendered_(0), 308 num_frames_rendered_(0),
335 first_frame_delivered_ticks_(-1), 309 first_frame_delivered_ticks_(-1),
336 last_swap_request_ticks_(-1), 310 last_swap_request_ticks_(-1),
337 swap_ticks_(0), 311 swap_ticks_(0),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 assert(position.size() == plugin_size_); 346 assert(position.size() == plugin_size_);
373 return; 347 return;
374 } 348 }
375 plugin_size_ = position.size(); 349 plugin_size_ = position.size();
376 350
377 // Initialize graphics. 351 // Initialize graphics.
378 InitGL(); 352 InitGL();
379 InitializeDecoders(); 353 InitializeDecoders();
380 } 354 }
381 355
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
401 void MyInstance::InitializeDecoders() { 356 void MyInstance::InitializeDecoders() {
402 assert(video_decoders_.empty()); 357 assert(video_decoders_.empty());
403 // Create two decoders with ids 0 and 1. 358 // Create two decoders with ids 0 and 1.
404 video_decoders_.push_back(new Decoder(this, 0, *context_)); 359 video_decoders_.push_back(new Decoder(this, 0, *context_));
405 video_decoders_.push_back(new Decoder(this, 1, *context_)); 360 video_decoders_.push_back(new Decoder(this, 1, *context_));
406 } 361 }
407 362
408 void MyInstance::PaintPicture(Decoder* decoder, 363 void MyInstance::PaintPicture(Decoder* decoder,
409 const PP_VideoPicture& picture) { 364 const PP_VideoPicture& picture) {
410 if (first_frame_delivered_ticks_ == -1) 365 if (first_frame_delivered_ticks_ == -1)
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 }; 600 };
646 601
647 } // anonymous namespace 602 } // anonymous namespace
648 603
649 namespace pp { 604 namespace pp {
650 // Factory function for your specialization of the Module object. 605 // Factory function for your specialization of the Module object.
651 Module* CreateModule() { 606 Module* CreateModule() {
652 return new MyModule(); 607 return new MyModule();
653 } 608 }
654 } // namespace pp 609 } // 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