AW: AW: record H264 stream use multifilesink

Thornton, Keith keith.thornton at zeiss.com
Mon Nov 20 12:59:34 UTC 2017


Hi,
I'm not sure it will help you but here is an example. There is some cleaning up to do after the EOS has been received which isn't included. 
I call the disconnect function with the first element in the branch which I wish to disconnect (In my case the queue after a tee), The last element in the branch (in my case usually the filesink embedded in the splitmuxsink)and the tee pad to which the branch of the pipeline is connected (might be e.g. my recording branch)



    typedef struct
    {
        GstElement* branchFirstElement;
        GstElement* branchLastElement;
        BaseConnector* pConnector;
        GstPad* pTeePad;
        gboolean removing;
		gulong probeId;
    }GstBranchDescriptor;


    static GstPadProbeReturn event_probe_cb(GstPad* lastPadInPipeline, GstPadProbeInfo* info, gpointer userData)
    {
        GstBranchDescriptor* branchDescriptor = static_cast<GstBranchDescriptor*>(userData);
        BaseConnector* pConnector = branchDescriptor->pConnector;

        if (GST_EVENT_TYPE(GST_PAD_PROBE_INFO_DATA(info)) != GST_EVENT_EOS)
        {
            return GST_PAD_PROBE_PASS;
        }

        MULTIMEDIA_INFO << _T(" eos received by ") << lastPadInPipeline->object.parent->name;
        pConnector->setEosReceived();
        gst_pad_remove_probe(lastPadInPipeline, GST_PAD_PROBE_INFO_ID(info));

		m_unlinkMutex.lock();
		m_unlinkDone = true;
		m_unlinkCondition.wakeAll();
		pConnector->m_unlinkMutex.unlock();

		return GST_PAD_PROBE_PASS;
    }

    static GstPadProbeReturn base_connector_cb_blocked(GstPad* teeSrcPad, GstPadProbeInfo* info, gpointer userData)
    {
        Q_UNUSED(info);
        Q_UNUSED(teeSrcPad);
		GstBranchDescriptor* branchDescriptor = static_cast<GstBranchDescriptor*>(userData);
        GstPad* firstElementSinkPad = gst_element_get_static_pad(branchDescriptor->branchFirstElement, "sink");
		if (firstElementSinkPad == nullptr) {
			ERROR << _T("gst_element_get_static_pad(branchDescriptor->branchFirstElement, sink); failed");
			throw GstreamerException(GstreamerException::EVENT_FLOW_ERROR);
		}

		GstPad* lastPadInPipeline = nullptr;
        lastPadInPipeline = gst_element_get_static_pad(branchDescriptor->branchLastElement, "sink");
		if (lastPadInPipeline == nullptr) {
			ERROR << _T("gst_element_get_static_pad(branchDescriptor->branchLastElement, sink); failed");
			gst_object_unref(firstElementSinkPad);
			throw GstreamerException(GstreamerException::EVENT_FLOW_ERROR);
		}

        DEBUG << _T("setting probe in ") << lastPadInPipeline->object.name << _T(" of ") << lastPadInPipeline->object.parent->name;
		gst_pad_unlink(branchDescriptor->pTeePad, firstElementSinkPad);
		gst_pad_remove_probe(branchDescriptor->pTeePad, branchDescriptor->probeId);

		gst_pad_add_probe(lastPadInPipeline, GstPadProbeType(GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM), event_probe_cb, userData, NULL);
		if (!gst_pad_send_event(firstElementSinkPad, gst_event_new_eos()))
        {
			gst_object_unref(firstElementSinkPad);
			MULTIMEDIA_ERROR << _T("failed to send eos from ") << firstElementSinkPad->object.name << _T(" of ") << firstElementSinkPad->object.parent->name;
			throw GstreamerException(GstreamerException::EVENT_FLOW_ERROR);
		}
        INFO << _T("sent EOS from ") << firstElementSinkPad->object.name << _T(" of ") << firstElementSinkPad->object.parent->name;

        gst_object_unref(firstElementSinkPad);
        gst_object_unref(lastPadInPipeline);
        return GST_PAD_PROBE_OK;
    }


    bool BaseConnector::disconnect(GstElement* firstElement, GstElement* lastElement, GstPad* connectorPad)
    {
        if (connectorPad == nullptr || firstElement == nullptr || lastElement == nullptr){
			ERROR << _T("an error occured while disconnecting the pipeline");
            throw GstreamerException(GstreamerException::EVENT_FLOW_ERROR);
        }

		if (m_activeConnectionCounter == 0) {
			WARN << _T("received disconnect request for pipeline with no active connections");
			return true;
		}
		INFO << m_namePrefix.data() << _T(" disconnecting branch nr. ") << m_activeConnectionCounter;
		INFO << firstElement->object.name << _T(",  ") << lastElement->object.name << _T(",  ") << connectorPad->object.name << _T(",  ") << connectorPad->object.parent->name;
		disconnectLock();
		if (m_activeConnectionCounter == 1)  // This is the last connection send EOS along the whole pipeline
		{
			sendEOSDownPipeline();
		}
		else
		{
			GstBranchDescriptor* branchDescriptor = new GstBranchDescriptor;
			branchDescriptor->branchFirstElement = firstElement;
			branchDescriptor->branchLastElement = lastElement;
			branchDescriptor->pConnector = this;
			branchDescriptor->pTeePad = connectorPad;
			branchDescriptor->removing = false;

			m_eosReceived = false;
			m_unlinkDone = false;
			int unlinkDoneCount = INITIAL_UNLINK_DONE_COUNT;
			branchDescriptor->probeId = gst_pad_add_probe(connectorPad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, static_cast<GstPadProbeCallback>(base_connector_cb_blocked), static_cast<gpointer>(branchDescriptor), NULL);


			// wait for cb_pad_probe() call
			{
				m_unlinkMutex.lock();
				while (!m_unlinkDone && unlinkDoneCount) {
					m_unlinkCondition.wait(&m_unlinkMutex, 1000);
					if (m_unlinkDone) {
						break;
					}
					else {
						unlinkDoneCount--;
						if (unlinkDoneCount == 0) {
							ERROR << _T(" Failed to send EOS down pipeline");
							m_unlinkMutex.unlock();
							throw GstreamerException(GstreamerException::EVENT_FLOW_ERROR);
						}
						if (logLimiter.doLog()) {
							WARN << _T("m_unlinkDone == false");
						}
					}
				}
				m_unlinkDone = false;
				m_unlinkMutex.unlock();
				INFO << "unlink done";
			}

			if (!m_eosReceived)
			{
				ERROR << _T(" Failed to dismantle pipeline containing ") << lastElement->object.name;
				throw GstreamerException(GstreamerException::EVENT_FLOW_ERROR);
			}





-----Ursprüngliche Nachricht-----
Von: gstreamer-devel [mailto:gstreamer-devel-bounces at lists.freedesktop.org] Im Auftrag von Michelle Guo
Gesendet: Montag, 20. November 2017 13:01
An: gstreamer-devel at lists.freedesktop.org
Betreff: Re: AW: record H264 stream use multifilesink

Hi Thornton, 

Thank you for your reply. 
I don't know how to send EOS event, is the EOS event sent by the pipeline, or by the element ? 
When the splitmuxsink receive EOS event, how to write mov block to the end of the file ?
Whether I need probe in my pipeline?
Could you give me some example?

regsrds;
Michelle





--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
gstreamer-devel at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel


More information about the gstreamer-devel mailing list