Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support/test new method to EOS pipeline on stop #1247

Merged
merged 1 commit into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 97 additions & 2 deletions src/DslNodetr.h
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,101 @@ namespace DSL
// call the parent class to complete the link-to-sink
return Nodetr::LinkToSink(pMuxer);
}

/**
* @brief Sets the state of the Src to NULL and then sends flush-start,
* flush-stop, EOS events to the muxers Sink Pad connected to this GstNoder.
* @return true if able to successfully EOS the Sink Pad
*/
virtual bool NullSrcEosSinkMuxer()
{
LOG_FUNC();

if (!IsLinkedToSink())
{
return false;
}

GstState currState, nextState;
GstStateChangeReturn result = gst_element_get_state(GetGstElement(),
&currState, &nextState, 1);

if (currState < GST_STATE_PLAYING)
{
LOG_ERROR("GstNodetr '" << GetName()
<< "' is not in a PLAYING state");
return false;
}

// Get a reference to this GstNodetr's source pad
GstPad* pStaticSrcPad = gst_element_get_static_pad(GetGstElement(), "src");
if (!pStaticSrcPad)
{
LOG_ERROR("Failed to get static source pad for GstNodetr '"
<< GetName() << "'");
return false;
}

// Get a reference to the Muxer's sink pad that is connected
// to this GstNodetr's source pad
GstPad* pRequestedSinkPad = gst_pad_get_peer(pStaticSrcPad);
if (!pRequestedSinkPad)
{
LOG_ERROR("Failed to get requested sink pad peer for GstNodetr '"
<< GetName() << "'");
return false;
}

GstStateChangeReturn changeResult = gst_element_set_state(
GetGstElement(), GST_STATE_NULL);

switch (changeResult)
{
case GST_STATE_CHANGE_FAILURE:
LOG_ERROR("GstNodetr '" << GetName()
<< "' failed to set state to NULL");
return false;

case GST_STATE_CHANGE_ASYNC:
LOG_INFO("GstNodetr '" << GetName()
<< "' changing state to NULL async");

// block on get state until change completes.
if (gst_element_get_state(GetGstElement(),
NULL, NULL, GST_CLOCK_TIME_NONE) == GST_STATE_CHANGE_FAILURE)
{
LOG_ERROR("GstNodetr '" << GetName()
<< "' failed to set state to NULL");
return false;
}
// drop through on success - DO NOT BREAK

case GST_STATE_CHANGE_SUCCESS:
LOG_INFO("GstNodetr '" << GetName()
<< "' changed state to NULL successfully");

// Send flush-start and flush-stop events downstream to the muxer
// followed by an end-of-stream for this GstNodetr's stream
gst_pad_send_event(pRequestedSinkPad,
gst_event_new_flush_start());
gst_pad_send_event(pRequestedSinkPad,
gst_event_new_flush_stop(TRUE));
gst_pad_send_event(pRequestedSinkPad,
gst_event_new_eos());

break;
default:
LOG_ERROR("Unknown state change for Bintr '" << GetName() << "'");
return false;
}

// unreference both the static source pad and requested sink
gst_object_unref(pStaticSrcPad);
gst_object_unref(pRequestedSinkPad);

// Call the parent class to complete the unlink from sink
return true;
}

/**
* @brief unlinks this Nodetr from a previously linked Muxer Sink Pad
Expand Down Expand Up @@ -773,7 +868,7 @@ namespace DSL
gst_object_unref(pRequestedSinkPad);

// Call the parent class to complete the unlink from sink
return Nodetr::UnlinkFromSink();
return Nodetr::UnlinkFromSink();
}

/**
Expand Down Expand Up @@ -947,7 +1042,7 @@ namespace DSL
bool SendEos()
{
LOG_FUNC();

return gst_element_send_event(GetGstElement(), gst_event_new_eos());
}

Expand Down
9 changes: 8 additions & 1 deletion src/DslPipelineBintr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,8 +516,15 @@ namespace DSL
{
m_eosFlag = true;

// Send an EOS event to the Pipline bin.
// IMPORTANT! There are two methods to send the EOS event.
// The best method is still under investigation. Only call one.

// 1. Send the event to the Pipeline bin
SendEos();

// 2. Send the event to each Streammuxer sink pads connected
// to a Source component.
// m_pPipelineSourcesBintr->EosAll();

// once the EOS event has been received on all sink pads of all
// elements, an EOS message will be posted on the bus. We need to
Expand Down
7 changes: 4 additions & 3 deletions src/DslPipelineSourcesBintr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,9 +405,10 @@ namespace DSL
// Send EOS message to each source object.
for (auto const& imap: m_pChildSources)
{
LOG_INFO("Sending EOS message to Source " << imap.second->GetName());
gst_element_send_event(imap.second->GetGstElement(),
gst_event_new_eos());
LOG_INFO("Sending EOS for Source " << imap.second->GetName());
imap.second->NullSrcEosSinkMuxer();
// gst_element_send_event(imap.second->GetGstElement(),
// gst_event_new_eos());
}
}

Expand Down
1 change: 0 additions & 1 deletion src/DslSourceBintr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3520,7 +3520,6 @@ namespace DSL
}
m_pDepay->UnlinkFromSink();
m_pParser->UnlinkFromSink();
m_pDecoder->UnlinkFromSink();
UnlinkCommon();
}
m_isLinked = false;
Expand Down