#include "CRtpSender.h" CRtpSender CRtpSender::m_theInstance; static GstElement* m_udpsink_rtp; CRtpSender::CRtpSender(){} CRtpSender::~CRtpSender() { gst_object_unref(GST_OBJECT(m_bin)); g_main_loop_unref(m_mainLoop); } bool CRtpSender::startSender() { m_bin = gst_pipeline_new("mainpipeS"); m_gstrtpbin = gst_element_factory_make("gstrtpbin", "rtpbinS"); m_pads_sender = getPadsSender(m_gstrtpbin); m_vid_sendpipe = createVideoSender(m_gstrtpbin); m_vid_udpsender = createUdpSender(m_gstrtpbin); m_udpsink_rtp = m_vid_udpsender->rtp_sender; g_object_set(m_vid_udpsender->rtp_sender, "host", RHOST, "port", UDP_RTP_PORT_SV, "sync", FALSE, "async", FALSE, "ts-offset", AOFFSET, NULL); g_object_set(m_vid_udpsender->rtcp_sender, "host", RHOST, "port", UDP_RTCP_PORT_SV, "sync", FALSE, "async", FALSE, NULL); g_object_set(m_vid_udpsender->rtcp_receiver, "port", UDP_RTCP_PORT_RV, NULL); gst_bin_add(GST_BIN(m_bin), m_gstrtpbin); GstPad* vidPayloadSrc = gst_element_get_static_pad(m_vid_sendpipe->payloader, "src"); GstPad* rtcpSenderSink = gst_element_get_static_pad(m_vid_udpsender->rtcp_sender, "sink"); GstPad* rtcpReceiverSrc = gst_element_get_static_pad(m_vid_udpsender->rtcp_receiver, "src"); gst_pad_link(vidPayloadSrc, m_pads_sender->send_rtp_sink0); gst_pad_link(m_pads_sender->send_rtcp_src0, rtcpSenderSink); gst_pad_link(rtcpReceiverSrc, m_pads_sender->recv_rtcp_sink0); g_signal_connect (m_gstrtpbin, "pad-added", G_CALLBACK (cb_new_pad), NULL); gst_element_set_state(m_bin, GST_STATE_PLAYING); return true; } bool CRtpSender::stopSender() { gst_element_set_state(m_bin, GST_STATE_NULL); return true; } void CRtpSender::state_changed(const GstBus *const bus, GstMessage *message, void *user_data) { GstObject* src = GST_MESSAGE_SRC(message); GstObject* bin = (GstObject*)m_theInstance.m_bin; if (src == bin) { GstState oldstate, newstate, pending; gst_message_parse_state_changed(message, &oldstate, &newstate, &pending); if(newstate == GST_STATE_PLAYING) g_main_loop_quit(m_theInstance.m_mainLoop); else if(newstate == GST_STATE_PAUSED){ g_main_loop_quit(m_theInstance.m_mainLoop); } } } CRtpSender::VideoSenderPipe_t* CRtpSender::createVideoSender(GstElement* bin) { VideoSenderPipe_t* p = new VideoSenderPipe_t(); p->colorspace = gst_element_factory_make("ffmpegcolorspace", "vsp_cs"); p->encoder = gst_element_factory_make("ffenc_h263p", "vsp_enc"); p->payloader = gst_element_factory_make("rtph263ppay", "vsp_pay"); p->source = gst_element_factory_make("videotestsrc", "vsp_src"); GstCaps* caps = gst_caps_from_string(VIDEO_CAPS); g_object_set(p->caps, "caps", caps, NULL); gst_caps_unref(caps); gst_bin_add(GST_BIN(bin), p->caps); gst_bin_add(GST_BIN(bin), p->colorspace); gst_bin_add(GST_BIN(bin), p->encoder); gst_bin_add(GST_BIN(bin), p->payloader); gst_bin_add(GST_BIN(bin), p->source); gst_element_link(p->source, p->caps); gst_element_link(p->caps, p->colorspace); gst_element_link(p->colorspace, p->encoder); gst_element_link(p->encoder, p->payloader); return p; } CRtpSender::UdpSender_t* CRtpSender::createUdpSender(GstElement* bin) { UdpSender_t* us = new UdpSender_t(); us->rtp_sender = gst_element_factory_make("udpsink", "us_rtp_s"); us->rtcp_sender = gst_element_factory_make("udpsink", "us_rtcp_s"); us->rtcp_receiver = gst_element_factory_make("udpsrc", "us_rtcp_r"); gst_bin_add(GST_BIN(bin), us->rtp_sender); gst_bin_add(GST_BIN(bin), us->rtcp_sender); gst_bin_add(GST_BIN(bin), us->rtcp_receiver); return us; } CRtpSender::PadsSender_t* CRtpSender::getPadsSender(GstElement *rtpbin) { PadsSender_t* ps = new PadsSender_t(); ps->send_rtp_src0 = gst_element_get_request_pad(rtpbin, "send_rtp_src_0"); ps->send_rtp_sink0 = gst_element_get_request_pad(rtpbin, "send_rtp_sink_0"); ps->send_rtcp_src0 = gst_element_get_request_pad(rtpbin, "send_rtcp_src_0"); ps->recv_rtcp_sink0 = gst_element_get_request_pad(rtpbin, "recv_rtcp_sink_0"); return ps; } void CRtpSender::cb_new_pad(GstElement* element, GstPad* pad, gpointer data) { gchar* name; name = gst_pad_get_name(pad); g_print("A new pad %s was created\n", name); g_free(name); GstPad* rtpudpsinkSrc = gst_element_get_static_pad(m_udpsink_rtp, "src"); gst_pad_link(rtpudpsinkSrc, pad); }