Add an exponential backoff to rechecking the app list doodle.
[chromium-blink-merge.git] / ppapi / examples / video_effects / video_effects.cc
blob101ba9c5021edea24e75872b5f33aca75f432a80
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <string.h>
6 #include <iterator>
7 #include <sstream>
8 #include <string>
9 #include <vector>
11 #include "ppapi/c/pp_errors.h"
12 #include "ppapi/cpp/instance.h"
13 #include "ppapi/cpp/message_loop.h"
14 #include "ppapi/cpp/module.h"
15 #include "ppapi/cpp/private/video_destination_private.h"
16 #include "ppapi/cpp/private/video_frame_private.h"
17 #include "ppapi/cpp/private/video_source_private.h"
18 #include "ppapi/cpp/var.h"
19 #include "ppapi/utility/completion_callback_factory.h"
21 // When compiling natively on Windows, PostMessage can be #define-d to
22 // something else.
23 #ifdef PostMessage
24 #undef PostMessage
25 #endif
27 namespace {
29 // Helper functions
30 std::vector<std::string> SplitStringBySpace(const std::string& str) {
31 std::istringstream buf(str);
32 std::istream_iterator<std::string> begin(buf), end;
33 std::vector<std::string> tokens(begin, end);
34 return tokens;
37 // This object is the global object representing this plugin library as long
38 // as it is loaded.
39 class VEDemoModule : public pp::Module {
40 public:
41 VEDemoModule() : pp::Module() {}
42 virtual ~VEDemoModule() {}
44 virtual pp::Instance* CreateInstance(PP_Instance instance);
47 class VEDemoInstance : public pp::Instance {
48 public:
49 VEDemoInstance(PP_Instance instance, pp::Module* module);
50 virtual ~VEDemoInstance();
52 // pp::Instance implementation (see PPP_Instance).
53 virtual void HandleMessage(const pp::Var& message_data);
55 private:
56 void DestinationOpenDone(int32_t result, const std::string& src_url);
57 void SourceOpenDone(int32_t result);
58 void GetFrameDone(int32_t result, pp::VideoFrame_Private video_frame);
59 void KickoffEffect(int32_t result);
60 pp::VideoSource_Private video_source_;
61 pp::VideoDestination_Private video_destination_;
62 bool effect_on_;
63 pp::CompletionCallbackFactory<VEDemoInstance> factory_;
64 pp::MessageLoop message_loop_;
67 VEDemoInstance::VEDemoInstance(PP_Instance instance, pp::Module* module)
68 : pp::Instance(instance),
69 video_source_(this),
70 video_destination_(this),
71 effect_on_(false),
72 message_loop_(pp::MessageLoop::GetCurrent()) {
73 factory_.Initialize(this);
76 VEDemoInstance::~VEDemoInstance() {
77 video_source_.Close();
78 video_destination_.Close();
81 void VEDemoInstance::HandleMessage(const pp::Var& message_data) {
82 if (message_data.is_string()) {
83 std::vector<std::string> messages;
84 messages = SplitStringBySpace(message_data.AsString());
85 if (messages.empty()) {
86 PostMessage(pp::Var("Ignored empty message."));
87 return;
89 if (messages[0] == "registerStream") {
90 if (messages.size() < 3) {
91 PostMessage(pp::Var("Got 'registerStream' with incorrect parameters."));
92 return;
94 // Open destination stream for write.
95 video_destination_.Open(
96 messages[2],
97 factory_.NewCallback(&VEDemoInstance::DestinationOpenDone,
98 messages[1]));
99 } else if (messages[0] == "effectOn") {
100 effect_on_ = true;
101 PostMessage(pp::Var("Effect ON."));
102 } else if (messages[0] == "effectOff") {
103 effect_on_ = false;
104 PostMessage(pp::Var("Effect OFF."));
109 void VEDemoInstance::DestinationOpenDone(int32_t result,
110 const std::string& src_url) {
111 if (result != PP_OK) {
112 PostMessage(pp::Var("Failed to open destination stream."));
113 return;
115 // Open source stream for read.
116 video_source_.Open(src_url,
117 factory_.NewCallback(&VEDemoInstance::SourceOpenDone));
120 void VEDemoInstance::SourceOpenDone(int32_t result) {
121 if (result != PP_OK) {
122 PostMessage(pp::Var("Failed to open source stream."));
123 return;
125 // Done with the stream register.
126 PostMessage(pp::Var("DoneRegistering"));
128 // Kick off the processing loop.
129 message_loop_.PostWork(factory_.NewCallback(&VEDemoInstance::KickoffEffect));
132 void VEDemoInstance::GetFrameDone(int32_t result,
133 pp::VideoFrame_Private video_frame) {
134 if (result != PP_OK) {
135 PostMessage(pp::Var("Failed to get frame."));
136 return;
139 // Apply the effect to the received frame.
140 if (effect_on_) {
141 pp::ImageData image_data = video_frame.image_data();
142 pp::Size size = image_data.size();
143 std::vector<uint8_t> tmp_row(image_data.stride());
144 uint8_t* image = static_cast<uint8_t*>(image_data.data());
145 for (int i = 0; i < size.height() / 2; ++i) {
146 uint8_t* top = image + i * image_data.stride();
147 uint8_t* bottom = image + (size.height() - 1 - i) * image_data.stride();
148 memcpy(&tmp_row[0], top, image_data.stride());
149 memcpy(top, bottom, image_data.stride());
150 memcpy(bottom, &tmp_row[0], image_data.stride());
154 // Put frame back to destination stream
155 video_destination_.PutFrame(video_frame);
157 // Trigger for the next frame.
158 message_loop_.PostWork(factory_.NewCallback(&VEDemoInstance::KickoffEffect));
161 void VEDemoInstance::KickoffEffect(int32_t /* result */) {
162 // Get the frame from the source stream.
163 video_source_.GetFrame(
164 factory_.NewCallbackWithOutput<pp::VideoFrame_Private>(
165 &VEDemoInstance::GetFrameDone));
168 pp::Instance* VEDemoModule::CreateInstance(PP_Instance instance) {
169 return new VEDemoInstance(instance, this);
172 } // anonymous namespace
174 namespace pp {
175 // Factory function for your specialization of the Module object.
176 Module* CreateModule() {
177 return new VEDemoModule();
179 } // namespace pp