[gstreamer-bugs] [Bug 570144] [ffdec] decodes unlinked streams
GStreamer (bugzilla.gnome.org)
bugzilla-daemon at bugzilla.gnome.org
Thu Mar 5 01:22:37 PST 2009
If you have any questions why you received this email, please see the text at
the end of this email. Replies to this email are NOT read, please see the text
at the end of this email. You can add comments to this bug at:
http://bugzilla.gnome.org/show_bug.cgi?id=570144
GStreamer | gst-ffmpeg | Ver: git
------- Comment #2 from LRN 2009-03-05 09:23 UTC -------
Here's my code that suffers from unwanted decoding phenomena.
The fix is in GStreamerAutoplugSelectCallback() function - it prevents
autoplugger from constructing video factories. If you comment the check and let
it always return 0, video streams will be decoded (despite the fact that they
are not linked in OnNewStream handler).
What's wrong with it?
Also, what kind of logging would uncover whether or not the video data is
decoded? Debug log (which level?)? Or message bus log would be enough?
class MyApplicationClass : public foobar
{
public:
MyApplicationClass(char *filename);
bool importinit();
int import();
void OnNewStream(GstElement *uridecodebin, GstPad *pad);
int WriteData(GstBuffer *buffer);
...<cut> a bunch of functions
private:
GstElement *mPipeline;
GstBus *mBus;
GstElement *mDec;
GstStaticCaps mStaticCaps;
char *mName;
...<cut> internal stuff
}
MyApplicationClass::MyApplicationClass(char *filename)
: foobar(filename)
{
mName = filename;
mPipeline = mDec = NULL;
memset(&mStaticCaps,0,sizeof(mStaticCaps));
mStaticCaps.string = (
"audio/x-raw-int, "
"signed = (boolean) { TRUE }, "
"width = (int) { 16, 32 }, "
"depth = (int) { 16, 24 }, "
"rate = (int) [ 1, MAX ], "
"channels = (int) [ 1, MAX ], "
"endianness = (int) BYTE_ORDER"
);
}
bool MyApplicationClass::importinit()
{
GstPad *audiopad = NULL;
// Create a pipeline
mPipeline = gst_pipeline_new("pipeline");
// Get it's bus an add a message watch to it
mBus = gst_pipeline_get_bus(GST_PIPELINE(mPipeline));
// Set up source location
gchar *name_utf8 = g_strdup(mName);
gchar *name_with_proto_utf8 = g_strdup_printf("file:///%s",name_utf8);
g_free(name_utf8);
// Create uridecodebin and set up signal handlers
mDec = gst_element_factory_make("uridecodebin", "decoder");
g_signal_connect(mDec, "pad-added", G_CALLBACK(GStreamerNewStreamCallback),
(gpointer)this);
g_signal_connect(mDec, "autoplug-select",
G_CALLBACK(GStreamerAutoplugSelectCallback), (gpointer)this);
g_object_set(G_OBJECT(mDec), "uri", name_with_proto_utf8, NULL);
// Add everythin into the pipeline
gst_bin_add_many(GST_BIN(mPipeline), mDec, NULL);
// Run the pipeline
GstStateChangeReturn statechange = gst_element_set_state(mPipeline,
GST_STATE_PAUSED);
while (true)
{
GstMessage *msg = gst_bus_pop(mBus);
if (msg)
{
//OnBusMessage returns FALSE on GST_MESSAGE_ASYNC_DONE or
GST_MESSAGE_EOS and does message logging.
if (!OnBusMessage(mBus,msg))
break;
}
}
return true; //After some more pondering application will call import()
method
}
gint GStreamerAutoplugSelectCallback(GstElement *element, GstPad *pad, GstCaps
*caps, GstElementFactory *factory, gpointer data)
{
// Check factory class
const gchar *fclass = gst_element_factory_get_klass(factory);
// Skip video decoding
if (g_strrstr(fclass,"Video"))
return 2;
return 0;
}
void GStreamerNewStreamCallback(GstElement *uridecodebin, GstPad *pad, gpointer
data)
{
MyApplicationClass *handle = (MyApplicationClass*)data;
handle->OnNewStream(uridecodebin, pad);
}
void MyApplicationClass::OnNewStream(GstElement *uridecodebin, GstPad *pad)
{
GstCaps *caps;
GstStructure *str;
caps = gst_pad_get_caps(pad);
str = gst_caps_get_structure(caps, 0);
// Check stream type
const gchar *name = gst_structure_get_name(str);
gboolean quit = FALSE;
if (!g_strrstr(name, "audio"))
{
g_string_free(strinfo, TRUE);
quit = TRUE;
}
gst_caps_unref (caps);
if (quit)
return;
// Create unique name
gchar *mAConvName = g_strdup_printf("aconv-%d",mScs->len);
// Create an audioconv
GstElement *mConv = gst_element_factory_make("audioconvert", mAConvName);
// Get it's sink pad
GstPad *convpad = gst_element_get_static_pad(mConv, "sink");
// Add it to the pipeline
gst_bin_add(GST_BIN(mPipeline), mConv);
GstPadLinkReturn ret = gst_pad_link(pad, convpad);
gst_object_unref(convpad);
if (ret)
{
g_print("Failed to link uridecodebin to audioconvert - %d\n",ret);
g_free(mAConvName);
gst_bin_remove(GST_BIN(mPipeline), mConv);
gst_object_unref(mConv);
g_string_free(strinfo, TRUE);
return;
}
gchar *mASinkName = g_strdup_printf("asink-%d",mScs->len);
GstElement *mSink = gst_element_factory_make("appsink", mASinkName);
// Set up sink properties
caps = gst_static_caps_get(&mStaticCaps);
gst_app_sink_set_caps(GST_APP_SINK(mSink), caps);
gst_caps_unref(caps);
gst_base_sink_set_sync(GST_BASE_SINK(mSink), FALSE);
gst_app_sink_set_drop(GST_APP_SINK(mSink), FALSE);
gst_app_sink_set_emit_signals(GST_APP_SINK(mSink), FALSE);
gst_app_sink_set_max_buffers(GST_APP_SINK(mSink), 10);
gst_bin_add(GST_BIN(mPipeline), mSink);
if (!gst_element_link(mConv, mSink))
{
g_free(mAConvName);
gst_bin_remove(GST_BIN(mPipeline), mConv);
gst_object_unref(mConv);
g_free(mASinkName);
gst_bin_remove(GST_BIN(mPipeline), mSink);
gst_object_unref(mSink);
g_string_free(strinfo, TRUE);
}
// Run newly added elements
GstStateChangeReturn statechange;
statechange = gst_element_set_state(mConv, GST_STATE_PAUSED);
statechange = gst_element_set_state(mSink, GST_STATE_PAUSED);
// Next it stores mSink internally, nothing interesting.
...
}
int MyApplicationClass::import()
{
GstStateChangeReturn statechange = gst_element_set_state(mPipeline,
GST_STATE_PLAYING);
gboolean doit = TRUE;
while (doit)
{
doit = FALSE;
GstMessage *msg = gst_bus_pop(mBus);
while (msg != NULL)
{
OnBusMessage(mBus,msg);
msg = gst_bus_pop(mBus);
}
...<cut> for each stream found in source and for which we've made sink and
audioconv (see OnNewStream) do
{
...<cut> get mSink for that stream from internal storage
GstBuffer *incbuf = gst_app_sink_pull_buffer(GST_APP_SINK(mSink));
if (incbuf)
{
doIt = TRUE;
res = WriteData(incbuf);
gst_buffer_unref(incbuf);
}
}
}
}
--
See http://bugzilla.gnome.org/page.cgi?id=email.html for more info about why you received
this email, why you can't respond via email, how to stop receiving
emails (or reduce the number you receive), and how to contact someone
if you are having problems with the system.
You can add comments to this bug at http://bugzilla.gnome.org/show_bug.cgi?id=570144.
More information about the Gstreamer-bugs
mailing list