[gst-devel] setting packet time on playbin
Alfred E. Heggestad
aeh at db.org
Thu Oct 25 20:05:53 CEST 2007
René Stadler wrote:
> Alfred E. Heggestad schrieb:
<snip>
>>
>> while it is possible to detect this in run-time using
>> gst_structure_get_int(s, "width", &width); on the Buffer's CAPS
>> structure,
>> and decode accordingly, I would rather prefer to *always* get the format
>> of the GstBuffer in 16-bit signed int. Do you know if this is possible,
>> and how this can be achieved when setting up the pipeline, playbin etc?
>>
>>
>> thanks again for your help :)
>>
>>
>>
>> /alfred
>
> This is usually done with a combination of an audioconvert,
> audioresample and a capsfilter element. Before your sink, you need to
> have these three elements in a row. Capsfilter has a property named
> "caps", set this to the fixed caps you want as output. This forces
> upstream to deliver data in this format, the audioconvert and
> audioresample elements will handle all conversions that are needed.
>
> Since you are using playbin, there is no need to need for audioconvert
> and audioresample since playbin adds these before the audio sink
> already. So for playbin usage, create a bin which you set as audio-sink
> later. Inside the bin, put a capsfilter linked to your fakesink. Add a
> ghost pad named "sink" to the bin which proxies the sink pad of the
> capsfilter. This makes the bin look like a regular audio sink which
> supports a single format to the outside world.
>
René, many thanks for your help. Your suggestion is indeed what I am looking
for, and after some hard thinking I managed to set it up. The hard work is now
done inside the gstreamer playbin, including resampling etc, and the audio
samples are delivered to my callback handler in 16-bit signed format.
For the reference (and for other people doing similar stuff) I am posting
my working code below:
/alfred
static void set_caps(struct gst *g)
{
GstCaps *caps;
/* Set the capabilities we want */
caps = gst_caps_new_simple("audio/x-raw-int",
"rate", G_TYPE_INT, g->cfg.srate,
"channels", G_TYPE_INT, 1,
"width", G_TYPE_INT, 16,
"signed", G_TYPE_BOOLEAN, true,
NULL);
g_object_set(G_OBJECT(g->capsfilt), "caps", caps, NULL);
}
static int gst_setup(struct gst *g)
{
GstBus *bus;
GstPad *pad;
gst_init(0, NULL);
g->loop = g_main_loop_new(NULL, FALSE);
g->pipeline = gst_pipeline_new("pipeline");
if (!g->pipeline) {
DEBUG_WARNING("failed to create pipeline element\n");
return ENOMEM;
}
/********************* Player BIN **************************/
g->source = gst_element_factory_make("playbin", "source");
if (!g->source) {
DEBUG_WARNING("failed to create playbin source element\n");
return ENOMEM;
}
/********************* My BIN **************************/
g->bin = gst_bin_new("mybin");
g->capsfilt = gst_element_factory_make("capsfilter", NULL);
if (!g->capsfilt) {
DEBUG_WARNING("failed to create capsfilter element\n");
return ENOMEM;
}
set_caps(g);
g->sink = gst_element_factory_make("fakesink", "sink");
if (!g->sink) {
DEBUG_WARNING("failed to create sink element\n");
return ENOMEM;
}
gst_bin_add_many(GST_BIN(g->bin), g->capsfilt, g->sink, NULL);
gst_element_link_many(g->capsfilt, g->sink, NULL);
/* add ghostpad */
pad = gst_element_get_pad(g->capsfilt, "sink");
gst_element_add_pad(g->bin, gst_ghost_pad_new("sink", pad));
gst_object_unref(GST_OBJECT(pad));
/* put all elements in a bin */
gst_bin_add_many(GST_BIN(g->pipeline), g->source, NULL);
/* Override audio-sink handoff handler */
g_object_set(G_OBJECT(g->sink), "signal-handoffs", TRUE, NULL);
g_signal_connect(g->sink, "handoff", G_CALLBACK(handoff_handler), g);
g_object_set(G_OBJECT(g->source), "audio-sink", g->bin, NULL);
/********************* Misc **************************/
/* Bus watch */
bus = gst_pipeline_get_bus(GST_PIPELINE(g->pipeline));
gst_bus_add_watch(bus, bus_watch_handler, g);
gst_object_unref(bus);
/* Set URI */
g_object_set(G_OBJECT(g->source), "uri", g->uri, NULL);
return 0;
}
More information about the gstreamer-devel
mailing list