1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
/*
* main.cc
*
* Created on: Aug 14, 2013
* Author: m.kolny
*
* based on sample described here: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-dynamic-pipelines.html
*/
#include <gstreamermm.h>
#include <glibmm/main.h>
#include <iostream>
#include <vector>
using namespace Gst;
using Glib::RefPtr;
RefPtr<Pad> blockpad;
RefPtr<Element> conv_before,
conv_after,
curr_effect;
RefPtr<Pipeline> pipeline;
std::vector<Glib::ustring> effects = {"identity", "exclusion",
"navigationtest", "agingtv", "videoflip", "vertigotv",
"gaussianblur", "shagadelictv", "edgetv"};
int curr_position = 0;
RefPtr<Glib::MainLoop> main_loop;
PadProbeReturn event_probe_cb (const RefPtr<Pad>& pad, const PadProbeInfo& info)
{
RefPtr<Event> event = info.get_event();
if (event->get_event_type()!= EVENT_EOS)
return PAD_PROBE_OK;
pad->remove_probe(info.get_id());
curr_effect->set_state(STATE_NULL);
pipeline->remove(curr_effect);
curr_effect = ElementFactory::create_element(effects[curr_position++ % effects.size()]);
pipeline->add(curr_effect);
conv_before->link(curr_effect)->link(conv_after);
curr_effect->set_state(STATE_PLAYING);
return PAD_PROBE_DROP;
}
PadProbeReturn pad_probe_cb(const RefPtr<Pad>& pad, const PadProbeInfo& info)
{
pad->remove_probe(info.get_id());
RefPtr<Pad> srcpad = curr_effect->get_static_pad("src");
srcpad->add_probe(PAD_PROBE_TYPE_BLOCK | PAD_PROBE_TYPE_EVENT_DOWNSTREAM, sigc::ptr_fun(event_probe_cb));
RefPtr<Pad> sinkpad = curr_effect->get_static_pad("sink");
sinkpad->send_event(EventEos::create());
return PAD_PROBE_OK;
}
bool on_bus_message(const Glib::RefPtr<Gst::Bus>&,
const Glib::RefPtr<Gst::Message>& message)
{
switch (message->get_message_type())
{
case MESSAGE_ERROR:
std::cerr << "Error." << std::endl;
main_loop->quit();
return false;
default:
break;
}
return true;
}
bool on_timeout()
{
blockpad->add_probe(PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, sigc::ptr_fun(&pad_probe_cb));
return true;
}
int main(int argc, char** argv)
{
init(argc, argv);
main_loop = Glib::MainLoop::create();
pipeline = Pipeline::create("effects-pipeline");
RefPtr<Element> src = ElementFactory::create_element("videotestsrc"),
sink = ElementFactory::create_element("xvimagesink");
conv_before = ElementFactory::create_element("videoconvert");
curr_effect = ElementFactory::create_element(effects[curr_position++]);
conv_after = ElementFactory::create_element("videoconvert");
blockpad = src->get_static_pad("src");
src->property("is-live", true);
pipeline->add(src)->add(conv_before)->add(curr_effect)->add(conv_after)->add(sink);
src->link(conv_before)->link(curr_effect)->link(conv_after)->link(sink);
RefPtr<Bus> bus = pipeline->get_bus();
bus->add_watch(sigc::ptr_fun(on_bus_message));
pipeline->set_state(STATE_PLAYING);
Glib::signal_timeout().connect(sigc::ptr_fun(&on_timeout), 1000);
main_loop->run();
pipeline->set_state(STATE_NULL);
return 0;
}
|