Chromium Code Reviews| Index: ppapi/examples/video_decode/video_decode.cc |
| diff --git a/ppapi/examples/video_decode/video_decode.cc b/ppapi/examples/video_decode/video_decode.cc |
| index de9bb8df2c0c417ecb1c1a45cf5a4e2a58ec10e0..f379d0497db704bcc5eb79e906884b7c377dc379 100644 |
| --- a/ppapi/examples/video_decode/video_decode.cc |
| +++ b/ppapi/examples/video_decode/video_decode.cc |
| @@ -20,7 +20,12 @@ |
| #include "ppapi/cpp/rect.h" |
| #include "ppapi/cpp/var.h" |
| #include "ppapi/cpp/video_decoder.h" |
| + |
| +// One of these should be defined. |
| +//#define TEST_H264 |
| +#define TEST_VP8 |
|
Ami GONE FROM CHROMIUM
2014/06/05 00:06:24
If you made these USE_VP8_TESTDATA_INSTEAD_OF_H264
bbudge
2014/06/06 02:03:45
I like it. Done.
|
| #include "ppapi/examples/video_decode/testdata.h" |
| + |
| #include "ppapi/lib/gl/include/GLES2/gl2.h" |
| #include "ppapi/lib/gl/include/GLES2/gl2ext.h" |
| #include "ppapi/utility/completion_callback_factory.h" |
| @@ -56,6 +61,7 @@ class MyInstance : public pp::Instance, public pp::Graphics3DClient { |
| // pp::Instance implementation. |
| virtual void DidChangeView(const pp::Rect& position, |
| const pp::Rect& clip_ignored); |
| + virtual bool HandleInputEvent(const pp::InputEvent& event); |
| // pp::Graphics3DClient implementation. |
| virtual void Graphics3DContextLost() { |
| @@ -139,12 +145,12 @@ class Decoder { |
| int id() const { return id_; } |
| bool decoding() const { return !flushing_ && !resetting_; } |
| - void Seek(int frame); |
| + void Reset(); |
| void RecyclePicture(const PP_VideoPicture& picture); |
| private: |
| void InitializeDone(int32_t result); |
| - void Start(int frame); |
| + void Start(); |
| void DecodeNextFrame(); |
| void DecodeDone(int32_t result); |
| void PictureReady(int32_t result, PP_VideoPicture picture); |
| @@ -159,11 +165,12 @@ class Decoder { |
| size_t encoded_data_next_pos_to_decode_; |
| int next_picture_id_; |
| - int seek_frame_; |
| bool flushing_; |
| bool resetting_; |
| }; |
| +#if defined(TEST_H264) |
| + |
| // Returns true if the current position is at the start of a NAL unit. |
| static bool LookingAtNAL(const unsigned char* encoded, size_t pos) { |
| // H264 frames start with 0, 0, 0, 1 in our test data. |
| @@ -171,7 +178,6 @@ static bool LookingAtNAL(const unsigned char* encoded, size_t pos) { |
| encoded[pos + 2] == 0 && encoded[pos + 3] == 1; |
| } |
| -// Find the start and end of the next frame. |
| static void GetNextFrame(size_t* start_pos, size_t* end_pos) { |
| assert(LookingAtNAL(kData, *start_pos)); |
| *end_pos = *start_pos; |
| @@ -181,6 +187,23 @@ static void GetNextFrame(size_t* start_pos, size_t* end_pos) { |
| } |
| } |
| +#elif defined(TEST_VP8) // VP8 |
| + |
| +// VP8 is stored in an IVF container. |
| +// Helpful description: http://wiki.multimedia.cx/index.php?title=IVF |
| + |
| +static void GetNextFrame(size_t* start_pos, size_t* end_pos) { |
| + size_t current_pos = *start_pos; |
| + if (current_pos == 0) |
| + current_pos = 32; // Skip stream header. |
| + uint32_t frame_size = *reinterpret_cast<const uint32_t*>(&kData[current_pos]); |
|
Ami GONE FROM CHROMIUM
2014/06/05 00:06:24
This is a type-punning violation; please see base/
bbudge
2014/06/06 02:03:45
Done.
|
| + current_pos += 12; // Skip frame header. |
| + *start_pos = current_pos; |
| + *end_pos = current_pos + frame_size; |
| +} |
| + |
| +#endif |
|
Ami GONE FROM CHROMIUM
2014/06/05 00:06:24
#else
#error Oops!
unless you take my suggestion
bbudge
2014/06/06 02:03:45
Done.
|
| + |
| Decoder::Decoder(MyInstance* instance, |
| int id, |
| const pp::Graphics3D& graphics_3d) |
| @@ -190,14 +213,18 @@ Decoder::Decoder(MyInstance* instance, |
| callback_factory_(this), |
| encoded_data_next_pos_to_decode_(0), |
| next_picture_id_(0), |
| - seek_frame_(0), |
| flushing_(false), |
| resetting_(false) { |
| assert(!decoder_->is_null()); |
| - const PP_VideoProfile profile = PP_VIDEOPROFILE_H264MAIN; |
| + const PP_VideoProfile profile = |
| +#if defined(TEST_H264) |
| + PP_VIDEOPROFILE_H264MAIN; |
|
Ami GONE FROM CHROMIUM
2014/06/05 00:06:24
This should probably be part of the header file al
bbudge
2014/06/06 02:03:46
Done.
|
| +#elif defined(TEST_VP8) |
| + PP_VIDEOPROFILE_VP8MAIN; |
| +#endif |
| decoder_->Initialize(graphics_3d, |
| profile, |
| - PP_FALSE /* allow_software_fallback */, |
| + PP_TRUE /* allow_software_fallback */, |
| callback_factory_.NewCallback(&Decoder::InitializeDone)); |
| } |
| @@ -209,18 +236,13 @@ void Decoder::InitializeDone(int32_t result) { |
| assert(decoder_); |
| assert(result == PP_OK); |
| assert(decoding()); |
| - Start(0); |
| + Start(); |
| } |
| -void Decoder::Start(int frame) { |
| +void Decoder::Start() { |
| assert(decoder_); |
| - // Skip to |frame|. |
| - size_t start_pos = 0; |
| - size_t end_pos = 0; |
| - for (int i = 0; i < frame; i++) |
| - GetNextFrame(&start_pos, &end_pos); |
| - encoded_data_next_pos_to_decode_ = end_pos; |
| + encoded_data_next_pos_to_decode_ = 0; |
| // Register callback to get the first picture. We call GetPicture again in |
| // PictureReady to continuously receive pictures as they're decoded. |
| @@ -231,9 +253,8 @@ void Decoder::Start(int frame) { |
| DecodeNextFrame(); |
| } |
| -void Decoder::Seek(int frame) { |
| +void Decoder::Reset() { |
| assert(decoder_); |
| - seek_frame_ = frame; |
| resetting_ = true; |
| decoder_->Reset(callback_factory_.NewCallback(&Decoder::ResetDone)); |
| } |
| @@ -299,6 +320,8 @@ void Decoder::ResetDone(int32_t result) { |
| assert(decoder_); |
| assert(result == PP_OK); |
| resetting_ = false; |
| + |
| + Start(); |
| } |
| MyInstance::MyInstance(PP_Instance instance, pp::Module* module) |
| @@ -353,6 +376,23 @@ void MyInstance::DidChangeView(const pp::Rect& position, |
| InitializeDecoders(); |
| } |
| +bool MyInstance::HandleInputEvent(const pp::InputEvent& event) { |
| + switch (event.GetType()) { |
| + case PP_INPUTEVENT_TYPE_MOUSEDOWN: { |
| + pp::MouseInputEvent mouse_event(event); |
| + // Reset all decoders on mouse down. |
| + if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT) { |
| + for (size_t i = 0; i < video_decoders_.size(); i++) |
| + video_decoders_[i]->Reset(); |
|
Ami GONE FROM CHROMIUM
2014/06/05 00:06:24
I'm surprised you don't end up having to pause/can
bbudge
2014/06/06 02:03:46
The example won't call Decode after Reset, since a
|
| + } |
| + return true; |
| + } |
| + |
| + default: |
| + return false; |
| + } |
| +} |
| + |
| void MyInstance::InitializeDecoders() { |
| assert(video_decoders_.empty()); |
| // Create two decoders with ids 0 and 1. |