pad-added does not get fired for decodebin
Describe your issue
I am using gstreamer to decode a packet at a time using appsrc, decodebin, videoconvert and appsink to pull out the decoded frames which will be rendered later in the application.
I have created caps from the source file, however pad-added signal of decodebin is never fired, so decodebin is never linked to videoconvert.
I have noticed that my callback function is called when video is set to video/x-raw, which is obviously the wrong caps for the file below. I am using decodebin as the code needs to work on different formats.
I can see in the log that h264parse, vaapidecodebin are created. However since decodebin never gets linked due to pad-added not firing, my data has no where to go!
Expected Behavior
Testfile: jellyfish-3-mbps-hd-h264.mkv Caps used:
video/x-h264, level=(string)4, profile=(string)high,
codec_data=(buffer)01640028ffe1002e67640028ac2ca401e0089f97ff0001000152020202800001f48000753070100016e36000089545f8c7076858b44801000568eb735250,
stream-format=(string)avc, alignment=(string)au, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1,
framerate=(fraction)30000/1001, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8,
colorimetry=(string)bt709, parsed=(boolean)true
GStreamer should fire my call back function once decodebin has source pad.
Code Source
data.pipeline = gst_pipeline_new("pipeline");
data.app_source = gst_element_factory_make("appsrc", "video_source");
m_bus = gst_pipeline_get_bus(GST_PIPELINE (data.pipeline));
gst_bus_add_watch(m_bus, (GstBusFunc)CBBusMessage, this);
// fake test caps (real from the file)
GstCaps *test = gst_caps_from_string("video/x-h264, level=(string)4, profile=(string)high, codec_data=(buffer)01640028ffe1002e67640028ac2ca401e0089f97ff0001000152020202800001f48000753070100016e36000089545f8c7076858b44801000568eb735250, stream-format=(string)avc, alignment=(string)au, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30000/1001, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, colorimetry=(string)bt709, parsed=(boolean)true");
g_object_set(G_OBJECT(data.app_source),
"caps", test,
"stream-type", 0, // stream-type is stream or seekable for push mode
"format", GST_FORMAT_TIME, // GST_FORMAT_TIME for timestamped buffers
"is-live", true,
nullptr);
data.decoder = gst_element_factory_make("decodebin", "mydecoder");
g_signal_connect (data.decoder, "pad-added", G_CALLBACK (CBNewPadAdded), this);
data.queue = gst_element_factory_make("queue", "queue");
data.video_convert = gst_element_factory_make("videoconvert", "video_convert");
data.app_sink = gst_element_factory_make ("appsink", "app_sink");
g_object_set(data.app_sink, "emit-signals", true, nullptr);
g_signal_connect (data.app_sink, "new-sample", G_CALLBACK (CBNewSample), this);
gst_bin_add_many (GST_BIN (data.pipeline), data.app_source, data.decoder, data.queue,
data.video_convert, data.app_sink, nullptr);
if(!gst_element_link_many (data.app_source, data.decoder, nullptr)) {
return false;
}
if(!gst_element_link_many (data.video_convert, data.app_sink, nullptr)) {
return false;
}
ret = gst_element_set_state(data.pipeline, GST_STATE_PLAYING);
main_loop = g_main_loop_new(nullptr, false);
Snip: my call back function:
GstFlowReturn CDVDVideoCodecGStreamerWrapper::CBNewPadAdded(GstElement *object, GstPad *pad, gpointer user_data) {
// link pads
}
I tried launching it using gst_parse_launch:
pipeline appsrc name=video_src ! video/x-h264, width=(int)1920, height=(int)1080, framerate=(fraction)30000/1001, alignment=(string)au, stream-format=(string)avc, codec_data=(buffer)01640028ffe1002e67640028ac2ca401e0089f97ff0001000152020202800001f48000753070100016e36000089545f8c7076858b44801000568eb735250fdf8f800 ! decodebin name=decoder ! videoconvert name=video_convert ! appsink name=app_sink
Same issue, decodebin has no peers.
Observed Behavior
CBNewPadAdded call back function is never called. decodebin has no peer messages in terminal output.
See: https://pastebin.com/U4THdqbj
I have noticed that CBNewPadAdded is fired when I use wrong caps like video/x-raw. I have tried other solutions like using filtercap bin, I have also tried setting g_object_set(data.decoder, "sink-caps", data.input_caps, nullptr); instead of caps on the appsrc.
Setup
- Ubuntu 22.10 x86/64 Linux
- Laptop
- GStreamer 1.20.3