Hi, <div><br></div><div>I've built a small pipeline..</div><div><br></div><div> - queue2 ! filesrc (file1.avi)</div><div>
v4l2src ! {caps filter } ! ffmpegcolorspace ! jpegenc ! avimux ! tee ! -| <br clear="all">
<div> - queue2 ! filesrc (file2.avi)</div><div><br></div><div><br></div><div>Works great! I get identical copies of my web cam recorded to two files.</div>
<div><br></div><div><br></div><div><br>But, what I really need is to replace "tee" with "output selector"</div><div><br></div><div>Like this</div><div><div> - queue2 ! filesrc (file1.avi)</div>
<div><br></div><div>v4l2src ! {caps filter } ! ffmpegcolorspace ! jpegenc ! avimux ! output-selector ! -|</div><div> <br clear="all"><div> - queue2 ! filesrc (file2.avi)</div>
<div><br></div></div></div><div>I also added </div><div><br></div><div><div>GstPad* pad = gst_element_get_pad( selector, "sink" );</div></div><div>g_object_set(G_OBJECT(selector), "active-pad", pad, NULL);</div>
<div><br></div><div><br></div><div>However when I change to the output-selector I get no errors and no output at all to the two files.</div><div><br></div><div><br></div><div>Anyone know what I'm missing? Can anyone suggest a good source for sample code demonstrating how to wire up an output-selector element?</div>
<div><br></div><div>complete code below... it is directly derivative if the hello world app.</div><div><br></div><div>Thanks,</div><div><br></div><div><br></div><div>Garth Tissington</div><div><br></div><div><br></div><div>
Complete code </div><div><br></div><div><br></div><div>=========================</div><div><br></div><div><div>#include <gst/gst.h></div><div>#include <glib.h></div><div>#include <gstreamer-0.10/gst/gstelementfactory.h></div>
<div><br></div><div>static gboolean</div><div>bus_call(GstBus *bus,</div><div> GstMessage *msg,</div><div> gpointer data) {</div><div> GMainLoop *loop = (GMainLoop *) data;</div><div><br></div><div> switch (GST_MESSAGE_TYPE(msg)) {</div>
<div><br></div><div> case GST_MESSAGE_EOS:</div><div> g_print("End of stream\n");</div><div> g_main_loop_quit(loop);</div><div> break;</div><div><br></div><div> case GST_MESSAGE_ERROR:</div>
<div> {</div><div> gchar *debug;</div><div> GError *error;</div><div><br></div><div> gst_message_parse_error(msg, &error, &debug);</div><div> g_free(debug);</div>
<div><br></div><div> g_printerr("Error: %s\n", error->message);</div><div> g_error_free(error);</div><div><br></div><div> g_main_loop_quit(loop);</div><div> break;</div>
<div> }</div><div> default:</div><div> break;</div><div> }</div><div><br></div><div> return TRUE;</div><div>}</div><div><br></div><div>static void</div><div>on_pad_added(GstElement *element,</div>
<div> GstPad *pad,</div><div> gpointer data) {</div><div> GstPad *sinkpad;</div><div> GstElement *decoder = (GstElement *) data;</div><div><br></div><div> /* We can now link this pad with the vorbis-decoder sink pad */</div>
<div> g_print("Dynamic pad created, linking demuxer/decoder\n");</div><div><br></div><div> sinkpad = gst_element_get_static_pad(decoder, "sink");</div><div><br></div><div> gst_pad_link(pad, sinkpad);</div>
<div><br></div><div> gst_object_unref(sinkpad);</div><div>}</div><div><br></div><div>GstElement* CreateDvrBin() {</div><div> GstElement *pipeline, *source, *colorspace, *muxer, *encoder, *selector, *sink1, *sink2, *q1, *q2 ;</div>
<div><br></div><div> source = gst_element_factory_make("v4l2src", "source");</div><div> muxer = gst_element_factory_make("avimux", "muxer");</div><div> encoder = gst_element_factory_make("jpegenc", "encoder");</div>
<div> colorspace = gst_element_factory_make("ffmpegcolorspace", "colorspace");</div><div> q1 = gst_element_factory_make("queue2", "q1");</div><div> q2 = gst_element_factory_make("queue2", "q2");</div>
<div> sink1 = gst_element_factory_make("filesink", "sink1");</div><div> sink2 = gst_element_factory_make("filesink", "sink2");</div><div> selector = gst_element_factory_make("output-selector", "selector");</div>
<div><br></div><div> if (!pipeline || !source || !colorspace || !encoder || !muxer || !sink1 || !sink2 || !selector || !q1 || !q2 ) {</div><div> g_printerr("One element could not be created. Exiting.\n");</div>
<div> return NULL;</div><div> }</div><div><br></div><div> /* Set up the pipeline */</div><div> pipeline = gst_pipeline_new("DVR");</div><div><br></div><div> g_object_set(G_OBJECT(sink1), "location", "/home/garth/a1.avi", NULL);</div>
<div> g_object_set(G_OBJECT(sink2), "location", "/home/garth/a2.avi", NULL);</div><div><br></div><div><br></div><div> /* we add all elements into the pipeline */</div><div> /* file-source | ogg-demuxer | vorbis-decoder | converter | alsa-output */</div>
<div> GstCaps *caps;</div><div><br></div><div> caps = gst_caps_new_simple("video/x-raw-yuv",</div><div> // "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),</div>
<div> "width", G_TYPE_INT, 800,</div><div> "height", G_TYPE_INT, 600,</div><div> "framerate", GST_TYPE_FRACTION, 30, 1,</div><div> NULL);</div><div>
<br></div><div> gst_bin_add_many(GST_BIN(pipeline),</div><div> source, colorspace, encoder, muxer, selector, q1, q2, sink1, sink2, NULL);</div><div><br></div><div><br></div><div> gst_element_link_filtered(source, colorspace, caps);</div>
<div> gst_element_link(colorspace, encoder);</div><div> gst_element_link(encoder, muxer);</div><div><br></div><div><br></div><div> gst_element_link(muxer, selector);</div><div><br></div><div><br></div><div> GstPad* pad1 = gst_element_get_request_pad(selector, "src%d");</div>
<div> gchar *padName1 = gst_pad_get_name(pad1);</div><div> g_print("Pad 1: %s\n", padName1);</div><div> GstPad* pad2 = gst_element_get_request_pad(selector, "src%d");</div><div> gchar *padName2 = gst_pad_get_name(pad2);</div>
<div> g_print("Pad 2: %s\n", padName2);</div><div><br></div><div><br></div><div> gst_element_link_pads(selector, padName1, q1, "sink");</div><div> gst_element_link_pads(selector, padName2, q2, "sink");</div>
<div><br></div><div> gst_element_link(q1, sink1);</div><div> gst_element_link(q2, sink2);</div><div><br></div><div><br></div><div><br></div><div> return pipeline;</div><div><br></div><div>}</div><div><br></div><div>
//gboolean</div><div>//timeout_cb(gpointer data) {</div><div>// g_print("Tick\n");</div><div>//</div><div>//}</div><div><br></div><div>int</div><div>main(int argc,</div><div> char *argv[]) {</div><div>
<br></div><div> // gint m_timer =</div><div> // g_timeout_add(2000, timeout_cb, NULL);</div><div><br></div><div><br></div><div> GMainLoop *loop;</div><div> GstBus *bus;</div><div><br></div><div> GstElement *pipeline;</div>
<div><br></div><div> /* Initialization */</div><div> gst_init(&argc, &argv);</div><div><br></div><div> loop = g_main_loop_new(NULL, FALSE);</div><div><br></div><div> /* Create gstreamer elements */</div>
<div><br></div><div><br></div><div><br></div><div> pipeline = CreateDvrBin();</div><div><br></div><div><br></div><div> /* we add a message handler */</div><div> // bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));</div>
<div> // gst_bus_add_watch (bus, bus_call, loop);</div><div> // gst_object_unref (bus);</div><div><br></div><div><br></div><div><br></div><div> //g_signal_connect (demuxer, "pad-added", G_CALLBACK (on_pad_added), decoder);</div>
<div><br></div><div> /* note that the demuxer will be linked to the decoder dynamically.</div><div> The reason is that Ogg may contain various streams (for example</div><div> audio and video). The source pad(s) will be created at run time,</div>
<div> by the demuxer when it detects the amount and nature of streams.</div><div> Therefore we connect a callback function which will be executed</div><div> when the "pad-added" is emitted.*/</div>
<div><br></div><div> /* Set the pipeline to "playing" state*/</div><div> g_print("Now playing: %s\n", argv[1]);</div><div> gst_element_set_state(pipeline, GST_STATE_PLAYING);</div><div><br></div>
<div><br></div><div> /* Iterate */</div><div> g_print("Running...\n");</div><div> g_main_loop_run(loop);</div><div><br></div><div><br></div><div> /* Out of the main loop, clean up nicely */</div><div>
g_print("Returned, stopping playback\n");</div><div> gst_element_set_state(pipeline, GST_STATE_NULL);</div><div><br></div><div> g_print("Deleting pipeline\n");</div><div> gst_object_unref(GST_OBJECT(pipeline));</div>
<div><br></div><div> return 0;</div><div>}</div><div><br></div></div><div><br></div>
</div>