41
Centricular Ltd Nirbheek Chauhan (nirbheek on IRC) GNOME contributor since 2007 http://nirbheek.in [email protected] [email protected]

An introduction to using GStreamer in your GNOME application

Embed Size (px)

Citation preview

Centricular Ltd

Nirbheek Chauhan(nirbheek on IRC)

GNOME contributor since 2007

http://[email protected]

[email protected]

Centricular Ltd

An introduction to using GStreamerin your GNOME application

Centricular Ltd

What is GStreamer?

Centricular Ltd

GStreamer 1.0

GStreamer 0.10

Centricular Ltd

How does it work?

Centricular Ltd

filter2

sink src

filter1

sink src

bin

sink

sink

source

src

Centricular Ltd

pipeline

mp3 decoder

sink src

audio sink

sink

file source

src

Centricular Ltd

How do you use it?

Centricular Ltd

gst-launch-1.0

Centricular Ltd

$ gst-launch-1.0 \ filesrc location=audio.mp3 ! \ mad ! \ pulsesink

Centricular Ltd

GstElement *pipeline;GstElement *src, *decoder, *sink;

gst_init (&argc, &argv);

src = gst_element_factory_make ("filesrc", NULL);decoder = gst_element_factory_make ("mad", NULL);sink = gst_element_factory_make ("pulsesink", NULL);

g_object_set (src, "location", "audio.mp3", NULL);

pipeline = gst_pipeline_new ();gst_bin_add_many (GST_BIN (pipeline), src, decoder,

sink, NULL);gst_element_link_many (src, decoder, sink, NULL);gst_element_set_state (pipeline, GST_STATE_PLAYING);

do {} while (1); /* Wait forever */

Centricular Ltd

Element States

Centricular Ltd

Element States

NULL READY PAUSED PLAYING→ → →

Centricular Ltd

Element States

PLAYING PAUSED PLAYING→ →

Centricular Ltd

Element States

PLAYING [...] NULL→ →

Centricular Ltd

Video files?

Centricular Ltd

“Sometimes” pads.

Centricular Ltd

pipeline

URI Decoder queue

sink src

audio sink

sinksrc_0

queue

sink src

video sink

sinksrc_1

Centricular Ltd

$ gst-launch-1.0 \ uridecodebin name=d \ uri=file://.../video.mp4 \ d. ! queue ! pulsesink \ d. ! queue ! xvimagesink

Centricular Ltd

GstElement *pipeline, *d;

gst_init (&argc, &argv);

d = gst_element_factory_make ("uridecodebin", NULL);g_object_set (d, "uri", "file://.../video.mp4", NULL);

pipeline = gst_pipeline_new ();

gst_bin_add (GST_BIN (pipeline), d);

g_signal_connect (d, "pad-added", pad_added_cb,pipeline);

gst_element_set_state (pipeline, GST_STATE_PLAYING);

do {} while (1); /* Wait forever */

Centricular Ltd

static voidpad_added_cb (GstElement * d, GstPad * newsrcpad,

GstElement * pipeline){

GstCaps *caps;GstStructure *s;

caps = gst_pad_get_current_caps (newsrcpad);s = gst_caps_get_structure (caps, 0);if (gst_structure_has_name (s, "audio/x-raw"))

pipeline_add_audio_sink (pipeline, newsrcpad); else if (gst_structure_has_name (s, "video/x-raw"))

pipeline_add_video_sink (pipeline, newsrcpad);

gst_caps_unref (caps);/* ignore other types of pads */

}

Centricular Ltd

What the hell are “caps”?!

Centricular Ltd

static voidpad_added_cb (GstElement * d, GstPad * newsrcpad,

GstElement * pipeline){

GstCaps *caps;GstStructure *s;

caps = gst_pad_get_current_caps (newsrcpad);s = gst_caps_get_structure (caps, 0);if (gst_structure_has_name (s, "audio/x-raw"))

pipeline_add_audio_sink (pipeline, newsrcpad); else if (gst_structure_has_name (s, "video/x-raw"))

pipeline_add_video_sink (pipeline, newsrcpad);

gst_caps_unref (caps);/* ignore other types of pads */

}

Centricular Ltd

static voidpipeline_add_audio_sink (GstElement * pipeline,

GstPad * srcpad){

GstElement *q, *sink;GstPad *sinkpad;

q = gst_element_factory_make ("queue", NULL);sink = gst_element_factory_make ("pulsesink", NULL);gst_bin_add_many (GST_BIN (pipeline), q, sink, NULL);

sinkpad = gst_element_get_static_pad (q, "sink");gst_pad_link (srcpad, sinkpad)gst_element_link (q, sink);

gst_element_sync_state_with_parent (q);gst_element_sync_state_with_parent (sink);gst_object_unref (sinkpad);

}

Centricular Ltd

static voidpipeline_add_video_sink (GstElement * pipeline,

GstPad * srcpad){

GstElement *q, *sink;GstPad *sinkpad;

q = gst_element_factory_make ("queue", NULL);sink = gst_element_factory_make ("xvimagesink", NULL);gst_bin_add_many (GST_BIN (pipeline), q, sink, NULL);

sinkpad = gst_element_get_static_pad (q, "sink");gst_pad_link (srcpad, sinkpad)gst_element_link (q, sink);

gst_element_sync_state_with_parent (q);gst_element_sync_state_with_parent (sink);gst_object_unref (sinkpad);

}

Centricular Ltd

Seems like a lot of work for something so common

Centricular Ltd

playbin

Centricular Ltd

$ gst-launch-1.0 playbin uri=file://.../video.mp4

$ gst-launch-1.0 playbin uri=http://.../audio.mp3

Centricular Ltd

GstElement *playbin;

gst_init (&argc, &argv);

playbin = gst_element_factory_make ("playbin", NULL);g_object_set (p, "uri", "file://.../video.mp4", NULL);

gst_element_set_state (playbin, GST_STATE_PLAYING);

do {} while (1); /* Wait forever */

Centricular Ltd

One more thing.

Centricular Ltd

Static Pads & Request Pads

Centricular Ltd

$ gst-launch-1.0 \ qtmux name=m ! filesink location=file.mp4 \ pulsesrc ! queue ! faac ! m. \ v4l2src ! queue ! x264enc ! m.

Centricular Ltd

/* Insert similar code as earlier slides */

srcpad = gst_element_get_static_pad (faac, "src");audio_pad = gst_element_get_request_pad (qtmux,

"audio_%d");gst_pad_link (srcpad, audio_pad);

srcpad = gst_element_get_static_pad (x264enc, "src");video_pad = gst_element_get_request_pad (qtmux,

"video_%d");gst_pad_link (srcpad, video_pad);

gst_element_set_state (pipeline, GST_STATE_PLAYING);

do {} while (1); /* Wait forever */

Centricular Ltd

I lied. There’s a lot more.GStreamer is quite versatile!

Centricular Ltd

Events, Queries, MessagesAction Signals, Pad Probes, Threading

Mainloop integration, Platform-specific quirks...

45 min is only enough for a taste.

Centricular Ltd

The rest is left as an exercise for the reader.

Centricular Ltd

Too much?

Centricular Ltd

$ gst-play-1.0 file://.../video.mp4

Centricular Ltd

$ gst-launch-1.0 playbin uri=file://.../video.mp4

Centricular Ltd

GstElement *playbin;

gst_init (&argc, &argv);

playbin = gst_element_factory_make ("playbin", NULL);g_object_set (p, "uri", "file://.../video.mp4", NULL);

gst_element_set_state (playbin, GST_STATE_PLAYING);

do {} while (1); /* Wait forever */

Centricular Ltd

Questions?