14 #ifndef NVDS3D_GST_NVDS3D_PIPELINE_CONTEXT_H
15 #define NVDS3D_GST_NVDS3D_PIPELINE_CONTEXT_H
31 namespace ds3d {
namespace gst {
42 GstPad* peer = gst_pad_get_peer(pad);
45 "send EOS downstream [elem:%s] skipped; not linked\n",
46 GST_ELEMENT_NAME(GST_ELEMENT(gst_pad_get_parent(pad))));
50 "sending EOS downstream [elem:%s->%s]\n", GST_ELEMENT_NAME(GST_ELEMENT(gst_pad_get_parent(pad))),
51 GST_ELEMENT_NAME(GST_ELEMENT(gst_pad_get_parent(peer))));
52 if (gst_pad_send_event(peer, gst_event_new_eos()) == FALSE) {
54 "send EOS downstream [elem:%s->%s] failed\n", GST_ELEMENT_NAME(GST_ELEMENT(gst_pad_get_parent(pad))),
55 GST_ELEMENT_NAME(GST_ELEMENT(gst_pad_get_parent(peer))));
57 gst_object_unref(peer);
97 runMainLoop(std::move(loopQuitCb)),
"failed to run main loop on the pipeline");
107 std::unique_lock<std::mutex> lock(
mutex());
108 if (!
_StatusCond.wait_for(lock, std::chrono::seconds(3), [
this]() {
109 return _mainStopped || _eosReceived;
111 LOG_DEBUG(
"waiting for EOS timed out, force to stop");
124 gst_bus_remove_watch(
bus());
135 std::unique_lock<std::mutex> locker(
mutex());
139 if (!g_main_loop_is_running(
mainLoop())) {
144 GstState state = GST_STATE_NULL;
145 GstState pending = GST_STATE_NULL;
146 GstStateChangeReturn ret = gst_element_get_state(
147 GST_ELEMENT(
pipeline()), &state, &pending,
148 (timeout ? timeout * 1000000 : GST_CLOCK_TIME_NONE));
152 while (ret == GST_STATE_CHANGE_FAILURE && times++ < 3) {
153 ret = gst_element_get_state(GST_ELEMENT(
pipeline()), &state, &pending, 0);
155 if (ret == GST_STATE_CHANGE_FAILURE) {
158 if (state == GST_STATE_PLAYING || pending == GST_STATE_PLAYING) {
166 std::unique_lock<std::mutex> locker(
mutex());
175 std::unique_lock<std::mutex> locker(
mutex());
177 if (
_StatusCond.wait_for(locker, std::chrono::milliseconds(3000)) ==
178 std::cv_status::timeout) {
179 LOG_DEBUG(
"waiting loop timed out, force loop to stop");
195 std::unique_lock<std::mutex> locker(
mutex());
209 LOG_WARNING(
"set pipeline state to GST_STATE_NULL failed");
211 GstState end = GST_STATE_NULL;
213 if (!
isGood(c) || end != GST_STATE_NULL) {
214 LOG_WARNING(
"waiting for pipeline state to null failed, force to quit");
218 c =
setState(each.get(), GST_STATE_NULL);
226 std::function<bool()>* f = (std::function<bool()>*)(user_data);
233 std::unique_lock<std::mutex> locker(
mutex());
236 "failed to run main loop due to loop might not set or thread already running.");
239 auto loopThread = std::make_unique<std::thread>([
this, quitCb = std::move(loopQuitCb)]() {
242 std::unique_lock<std::mutex> locker(
mutex());
249 std::atomic_bool loopStarted{
false};
250 std::function<bool()> loopCheck = [&loopStarted,
this]() ->
bool {
251 std::unique_lock<std::mutex> locker(
mutex());
260 if (!
_StatusCond.wait_for(locker, std::chrono::milliseconds(20000), [
this, &loopStarted]() {
261 return loopStarted || _mainStopped;
272 LOG_ERROR(
"Run main loop stopped too fast, please check.");
285 GstIterator* itr =
nullptr;
289 for (itr = gst_bin_iterate_sources(GST_BIN(
pipeline())); gst_iterator_next(itr, &data) == GST_ITERATOR_OK;) {
290 GstElement* elem = GST_ELEMENT_CAST(g_value_get_object(&data));
291 LOG_DEBUG(
"sending EOS downstream from src element %s\n", GST_ELEMENT_NAME(elem));
295 g_value_reset(&data);
297 g_value_unset(&data);
298 gst_iterator_free(itr);
309 virtual bool busCall(GstMessage* msg)
312 switch (GST_MESSAGE_TYPE(msg)) {
313 case GST_MESSAGE_EOS:
316 std::unique_lock<std::mutex> locker(
mutex());
324 case GST_MESSAGE_ERROR: {
325 gchar* debug =
nullptr;
326 GError* error =
nullptr;
327 gst_message_parse_error(msg, &error, &debug);
329 "ERROR from element %s: %s, details: %s", GST_OBJECT_NAME(msg->src), error->message,
330 (debug ? debug :
""));
337 case GST_MESSAGE_STATE_CHANGED: {
338 GstState oldState, newState, pendingState;
340 gst_message_parse_state_changed(msg, &oldState, &newState, &pendingState);
342 "Element %s changed state from %s to %s, pending: %s.", GST_OBJECT_NAME(msg->src),
343 gst_element_state_get_name(oldState), gst_element_state_get_name(newState),
344 gst_element_state_get_name(pendingState));
363 GstStateChangeReturn ret = gst_element_set_state(ele, state);
365 ret != GST_STATE_CHANGE_FAILURE,
ErrCode::kGst,
"element set state: %d failed", state);
372 GstElement* ele, GstState* state, GstState* pending =
nullptr,
size_t timeout = 0)
375 GstStateChangeReturn ret = gst_element_get_state(
376 ele, state, pending, (timeout ? timeout * 1000000 : GST_CLOCK_TIME_NONE));
378 case GST_STATE_CHANGE_FAILURE:
380 case GST_STATE_CHANGE_SUCCESS:
381 case GST_STATE_CHANGE_NO_PREROLL:
389 static gboolean
sBusCall(GstBus*
bus, GstMessage* msg, gpointer data)
393 return ctx->busCall(msg);
415 #endif // NVDS3D_GST_NVDS3D_PIPELINE_CONTEXT_H