probes on a queue element pads after tee elements

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

probes on a queue element pads after tee elements

alcosar
Hello,
I have an application that has to send audio stream to 2 different addresses, but not at the same time. So only one channel can be active at a time.
I thought that I can use tee element to split 2 streams before sending them to udpsink. I would register 2 callbacks on 2 queue pads and will drop buffers on one of them. Here is my pipeline and code:
constexpr char kSenderPipeline[] =
    "filesrc location=temple_of_love-sisters_of_mercy.wav ! "
    "wavparse ! "
    "audioresample ! "
    "audio/x-raw,format=S16LE ! "
    "opusenc bandwidth=narrowband bitrate=16000 ! "
    "rtpopuspay ! "
    "tee name=t "
    "t. ! "
    "queue name=q0 ! "
    "udpsink name=usink0 "
    "t. !"
    "queue name=q1 ! "
    "udpsink name=usink1";

void AudioSender::Initialize(GSocket *gsocket) {
  // Build the pipeline.
  GstElement *pipebin =  CHECK_NOTNULL(gst_parse_launch(pipeline_string(), nullptr));
  set_pipebin(pipebin);
  GstElement *udpsink = CHECK_NOTNULL(gst_bin_get_by_name(GST_BIN(pipebin), "usink0"));
  g_object_set(udpsink, "host", ip_address_.c_str(), "port", kPort, nullptr);
  GstElement *queue =  CHECK_NOTNULL(gst_bin_get_by_name(GST_BIN(pipebin), "q0"));
  GstPad *pad = CHECK_NOTNULL(gst_element_get_static_pad(queue, "src"));
  gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER,
                    reinterpret_cast<GstPadProbeCallback>(Queue0_cb),
                    this, nullptr);
  udpsink = CHECK_NOTNULL(gst_bin_get_by_name(GST_BIN(pipebin), "usink1"));
  g_object_set(udpsink, "host", ip_address_lte_.c_str(), "port", kPort, nullptr);
  g_object_set(udpsink, "socket", gsocket, nullptr);
  queue = CHECK_NOTNULL(gst_bin_get_by_name(GST_BIN(pipebin), "q1"));
  pad = CHECK_NOTNULL(gst_element_get_static_pad(queue, "src"));
  gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER,
                    reinterpret_cast<GstPadProbeCallback>(Queue1_cb),
                    this, nullptr);
  gst_object_unref(udpsink);
  gst_object_unref(queue);
  gst_object_unref(pad);
  // start playing
  CHECK_NE(GST_STATE_CHANGE_FAILURE,  gst_element_set_state(pipebin_, GST_STATE_PLAYING));
}

GstPadProbeReturn AudioSender::Queue0_cb(
    GstPad * /*pad*/, GstPadProbeInfo * /*info*/,
    AudioSender *const audio_sender) {
  if (audio_sender->state() == State::kInactive ||
      audio_sender->mode_ == CommunicationMode::kLte) {
    return GST_PAD_PROBE_DROP;
  }
  return GST_PAD_PROBE_OK;
}

GstPadProbeReturn AudioSender::Queue1_cb(
    GstPad * /*pad*/, GstPadProbeInfo * /*info*/,
    AudioSender *const audio_sender) {
  if (audio_sender->state() == State::kInactive ||
      audio_sender->mode_ == CommunicationMode::kHost) {
    return GST_PAD_PROBE_DROP;
  }
  return GST_PAD_PROBE_OK;
}

Queue1_cb is called only once and GST_DEBUG says that it changed state to PAUSED.
I tested pipeline with gst-launch and it seems does what I want. gstreamer-1.0
How do I make all callbacks to be called?

Thanks!
Reply | Threaded
Open this post in threaded view
|

Re: probes on a queue element pads after tee elements

Nicolas Dufresne-5


Le 14 juin 2017 4:13 AM, "alcosar" <[hidden email]> a écrit :
Hello,
I have an application that has to send audio stream to 2 different
addresses, but not at the same time. So only one channel can be active at a
time.
I thought that I can use tee element to split 2 streams before sending them
to udpsink. I would register 2 callbacks on 2 queue pads and will drop

Yes, but you'll probably need to set your udpsink to async=1 to get your pipeline into playing state.

buffers on one of them. Here is my pipeline and code:
constexpr char kSenderPipeline[] =
    "filesrc location=temple_of_love-sisters_of_mercy.wav ! "
    "wavparse ! "
    "audioresample ! "
    "audio/x-raw,format=S16LE ! "
    "opusenc bandwidth=narrowband bitrate=16000 ! "
    "rtpopuspay ! "
    "tee name=t "
    "t. ! "
    "queue name=q0 ! "
    "udpsink name=usink0 "
    "t. !"
    "queue name=q1 ! "
    "udpsink name=usink1";

void AudioSender::Initialize(GSocket *gsocket) {
  // Build the pipeline.
  GstElement *pipebin =  CHECK_NOTNULL(gst_parse_launch(pipeline_string(),
nullptr));
  set_pipebin(pipebin);
  GstElement *udpsink = CHECK_NOTNULL(gst_bin_get_by_name(GST_BIN(pipebin),
"usink0"));
  g_object_set(udpsink, "host", ip_address_.c_str(), "port", kPort,
nullptr);
  GstElement *queue =  CHECK_NOTNULL(gst_bin_get_by_name(GST_BIN(pipebin),
"q0"));
  GstPad *pad = CHECK_NOTNULL(gst_element_get_static_pad(queue, "src"));
  gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER,
                    reinterpret_cast<GstPadProbeCallback>(Queue0_cb),
                    this, nullptr);
  udpsink = CHECK_NOTNULL(gst_bin_get_by_name(GST_BIN(pipebin), "usink1"));
  g_object_set(udpsink, "host", ip_address_lte_.c_str(), "port", kPort,
nullptr);
  g_object_set(udpsink, "socket", gsocket, nullptr);
  queue = CHECK_NOTNULL(gst_bin_get_by_name(GST_BIN(pipebin), "q1"));
  pad = CHECK_NOTNULL(gst_element_get_static_pad(queue, "src"));
  gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER,
                    reinterpret_cast<GstPadProbeCallback>(Queue1_cb),
                    this, nullptr);
  gst_object_unref(udpsink);
  gst_object_unref(queue);
  gst_object_unref(pad);
  // start playing
  CHECK_NE(GST_STATE_CHANGE_FAILURE,  gst_element_set_state(pipebin_,
GST_STATE_PLAYING));
}

GstPadProbeReturn AudioSender::Queue0_cb(
    GstPad * /*pad*/, GstPadProbeInfo * /*info*/,
    AudioSender *const audio_sender) {
  if (audio_sender->state() == State::kInactive ||
      audio_sender->mode_ == CommunicationMode::kLte) {
    return GST_PAD_PROBE_DROP;
  }
  return GST_PAD_PROBE_OK;
}

GstPadProbeReturn AudioSender::Queue1_cb(
    GstPad * /*pad*/, GstPadProbeInfo * /*info*/,
    AudioSender *const audio_sender) {
  if (audio_sender->state() == State::kInactive ||
      audio_sender->mode_ == CommunicationMode::kHost) {
    return GST_PAD_PROBE_DROP;
  }
  return GST_PAD_PROBE_OK;
}

Queue1_cb is called only once and GST_DEBUG says that it changed state to
PAUSED.
I tested pipeline with gst-launch and it seems does what I want.
gstreamer-1.0
How do I make all callbacks to be called?

Thanks!




--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/probes-on-a-queue-element-pads-after-tee-elements-tp4683366.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel


_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: probes on a queue element pads after tee elements

alcosar
Thank you for the reply Nicolas!
"gst-inspect-1.0 udpsink" says that async default value is 1.
 async               : Go asynchronously to PAUSED
                        flags: readable, writable
                        Boolean. Default: true
I changed it to async=0 it is working now!
Thank you!