splitmuxsink could not config another muxer
Describe your issue
Why the splitmuxsink change the default muxer by g_object_set not effect? Also if I set muxer-factory it could be crash and exit.
First situation
GstElement *matroskamux;
matroskamux = gst_element_factory_make("matroskamux", NULL);
gst_bin_add(splitmuxsin,matroskamux);
g_object_set(splitmuxsink, "muxer", matroskamux,NULL);
- The above code can not effect, it always use the default muxer
mp4mux
.
Second situation
g_object_set(splitmuxsink,async-finalize", TRUE, "muxer-factory", "matroskamux",NULL);
The will be occur the following error when it start the second segment.
** Message: 14:29:56.817: get message: splitmuxsink-fragment-opened, location=(string)/tmp/output/mkv/segment-00000.mkv, running-time=(guint64)2730312695, sink=(GstElement)"\(GstFileSink\)\ sink";
location: /tmp/output/mkv/segment-00000.mkv
Pipeline state changed from PAUSED to PLAYING:
(v4l2-record:1445531): GStreamer-CRITICAL **: 14:30:16.976: Element type GstMatroskaMux does not have a pad template video_%u (0x55cac6dc9b80)
(v4l2-record:1445531): GStreamer-CRITICAL **: 14:30:16.976: gst_pad_link_full: assertion 'GST_IS_PAD (sinkpad)' failed
(v4l2-record:1445531): GStreamer-CRITICAL **: 14:30:16.976: gst_element_release_request_pad: assertion 'GST_IS_PAD (pad)' failed
(v4l2-record:1445531): GStreamer-CRITICAL **: 14:30:16.976: gst_object_unref: assertion 'object != NULL' failed
(v4l2-record:1445531): GStreamer-CRITICAL **: 14:30:16.976: Element type GstMatroskaMux does not have a pad template audio_%u (0x55cac6dc9af0)
(v4l2-record:1445531): GStreamer-CRITICAL **: 14:30:16.976: gst_pad_link_full: assertion 'GST_IS_PAD (sinkpad)' failed
(v4l2-record:1445531): GStreamer-CRITICAL **: 14:30:16.976: gst_element_release_request_pad: assertion 'GST_IS_PAD (pad)' failed
(v4l2-record:1445531): GStreamer-CRITICAL **: 14:30:16.976: gst_object_unref: assertion 'object != NULL' failed
(v4l2-record:1445531): GStreamer-CRITICAL **: 14:30:16.977: gst_pad_send_event: assertion 'GST_IS_PAD (pad)' failed
(v4l2-record:1445531): GStreamer-CRITICAL **: 14:30:16.977: gst_object_unref: assertion 'object != NULL' failed
(v4l2-record:1445531): GStreamer-CRITICAL **: 14:30:16.977: gst_pad_send_event: assertion 'GST_IS_PAD (pad)' failed
(v4l2-record:1445531): GStreamer-CRITICAL **: 14:30:16.977: gst_object_unref: assertion 'object != NULL' failed
ERROR: from element /GstPipeline:pipeline/GstSplitMuxSink:splitmuxsink0: Could not create the new muxer/sink
Additional debug info:
../subprojects/gst-plugins-good/gst/multifile/gstsplitmuxsink.c(1947): relink_context (): /GstPipeline:pipeline/GstSplitMuxSink:splitmuxsink0
- So, I'm try to some code to replace the default as below. Have some
GStreamer-CRITICAL
but not crash exit, also it's still working onsegment-00000.mkv
, not have following by new file generate.
if (new_state == GST_STATE_READY) {
// Fixed me. Why the splitmuxsink change the default muxer by g_object_set not effect.
// I just find these complex approach to replace the default muxer but also can not remove it from memory.
GstElement *splitmuxsink = gst_bin_get_by_name(GST_BIN(pipeline), "splitmuxsink0");
GstElement *muxer = gst_bin_get_by_name(GST_BIN(splitmuxsink), "muxer");
GstElement *sink = gst_bin_get_by_name(GST_BIN(splitmuxsink), "sink");
GstPad *old_src_vpad, *old_src_apad, *old_sink_fpad;
if (muxer) {
GstPad *old_src_pad = muxer->srcpads->data;
old_sink_fpad = gst_pad_get_peer(old_src_pad);
gst_pad_unlink(old_src_pad, old_sink_fpad);
gst_object_unref(old_src_pad);
// gst_element_link(matroskamux, sink);
// gchar *name;
GList *iter = muxer->sinkpads;
// name = gst_pad_get_name(iter->data);
old_src_vpad = gst_pad_get_peer(iter->data);
gst_pad_unlink(old_src_vpad, iter->data);
gst_object_unref(iter->data);
// unlink audio 0
old_src_apad = gst_pad_get_peer(iter->next->data);
gst_pad_unlink(old_src_apad, iter->next->data);
gst_object_unref(iter->next->data);
gst_object_unref(old_src_vpad);
gst_element_set_locked_state(muxer, TRUE);
gst_element_set_state(muxer, GST_STATE_NULL);
gst_bin_remove(GST_BIN(splitmuxsink), muxer);
gst_element_set_locked_state(muxer, FALSE);
}
GstElement *matroskamux;
matroskamux = gst_element_factory_make("matroskamux", "muxer");
gst_bin_add(GST_BIN(splitmuxsink), matroskamux);
gst_element_sync_state_with_parent(matroskamux);
gst_println("muxer parent addr: %x, file sink parent: %x, mkv parent: %x\n",
gst_object_get_parent(muxer), gst_object_get_parent(sink), gst_object_get_parent(matroskamux));
// link to old file sink pad.
// GstPad *mkv_src_pad = gst_element_get_static_pad(matroskamux, "src");
// if (gst_pad_link(mkv_src_pad, old_sink_fpad) != GST_PAD_LINK_OK) {
// gst_println("---> mkv src sink link to file sink failed.\n");
// }
if (!gst_element_link(matroskamux, sink)) {
gst_println(" what problem?\n");
}
// link to old src pad.
GstPad *mkv_vpad = gst_element_request_pad_simple(matroskamux, "video_%u");
if (gst_pad_link(old_src_vpad, mkv_vpad) != GST_PAD_LINK_OK) {
g_error("Tee split new video pad could not be linked.\n");
// return -1;
}
gst_object_unref(mkv_vpad);
mkv_vpad = gst_element_request_pad_simple(matroskamux, "audio_%u");
if (gst_pad_link(old_src_apad, mkv_vpad) != GST_PAD_LINK_OK) {
g_error("Tee split new video pad could not be linked.\n");
// return -1;
}
gst_object_unref(mkv_vpad);
}