File: main.cc

package info (click to toggle)
gstreamermm-1.0 1.10.0%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 12,508 kB
  • sloc: xml: 68,148; cpp: 6,109; sh: 4,187; makefile: 243; perl: 236
file content (113 lines) | stat: -rw-r--r-- 3,007 bytes parent folder | download | duplicates (5)
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;
}