diff options
author | Olivier CrĂȘte <olivier.crete@collabora.co.uk> | 2010-01-08 22:13:59 -0500 |
---|---|---|
committer | Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk> | 2010-05-10 15:07:09 +0200 |
commit | 34d0d591422f8d1c2285ecfd3e7ba9edf3acd892 (patch) | |
tree | f9c8e63f76564a85bb9eeda3eb1b9f3318baf742 | |
parent | 90311e522f04b8501c3a0a6547a893d573161777 (diff) |
rtph264pay: Re-send SPS/PPS when requested
https://bugzilla.gnome.org/show_bug.cgi?id=606689
-rw-r--r-- | gst/rtp/gstrtph264pay.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/gst/rtp/gstrtph264pay.c b/gst/rtp/gstrtph264pay.c index 4bae67abc..64eac0db0 100644 --- a/gst/rtp/gstrtph264pay.c +++ b/gst/rtp/gstrtph264pay.c @@ -112,6 +112,9 @@ static gboolean gst_rtp_h264_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps); static GstFlowReturn gst_rtp_h264_pay_handle_buffer (GstBaseRTPPayload * pad, GstBuffer * buffer); +static gboolean gst_rtp_h264_pay_handle_event (GstPad * pad, GstEvent * event); +static GstStateChangeReturn gst_basertppayload_change_state (GstElement * + element, GstStateChange transition); GST_BOILERPLATE (GstRtpH264Pay, gst_rtp_h264_pay, GstBaseRTPPayload, GST_TYPE_BASE_RTP_PAYLOAD); @@ -136,9 +139,11 @@ static void gst_rtp_h264_pay_class_init (GstRtpH264PayClass * klass) { GObjectClass *gobject_class; + GstElementClass *gstelement_class; GstBaseRTPPayloadClass *gstbasertppayload_class; gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass; gobject_class->set_property = gst_rtp_h264_pay_set_property; @@ -183,8 +188,12 @@ gst_rtp_h264_pay_class_init (GstRtpH264PayClass * klass) gobject_class->finalize = gst_rtp_h264_pay_finalize; + gstelement_class->change_state = + GST_DEBUG_FUNCPTR (gst_basertppayload_change_state); + gstbasertppayload_class->set_caps = gst_rtp_h264_pay_setcaps; gstbasertppayload_class->handle_buffer = gst_rtp_h264_pay_handle_buffer; + gstbasertppayload_class->handle_event = gst_rtp_h264_pay_handle_event; GST_DEBUG_CATEGORY_INIT (rtph264pay_debug, "rtph264pay", 0, "H264 RTP Payloader"); @@ -668,9 +677,10 @@ gst_rtp_h264_pay_payload_nal (GstBaseRTPPayload * basepayload, guint8 * data, } } - if (send_spspps) { + if (send_spspps || rtph264pay->send_spspps) { /* we need to send SPS/PPS now first. FIXME, don't use the timestamp for * checking when we need to send SPS/PPS but convert to running_time first. */ + rtph264pay->send_spspps = FALSE; ret = gst_rtp_h264_pay_send_sps_pps (basepayload, rtph264pay, timestamp); if (ret != GST_FLOW_OK) return ret; @@ -1012,6 +1022,51 @@ caps_rejected: return GST_FLOW_NOT_NEGOTIATED; } +static gboolean +gst_rtp_h264_pay_handle_event (GstPad * pad, GstEvent * event) +{ + const GstStructure *s; + GstRtpH264Pay *rtph264pay = + GST_RTP_H264_PAY (gst_pad_get_parent_element (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CUSTOM_DOWNSTREAM: + s = gst_event_get_structure (event); + if (gst_structure_has_name (s, "GstForceKeyUnit")) { + gboolean resend_codec_data; + + if (gst_structure_get_boolean (s, "all-headers", + &resend_codec_data) && resend_codec_data) + rtph264pay->send_spspps = TRUE; + } + break; + default: + break; + } + + return FALSE; +} + +static GstStateChangeReturn +gst_basertppayload_change_state (GstElement * element, + GstStateChange transition) +{ + GstStateChangeReturn ret; + GstRtpH264Pay *rtph264pay = GST_RTP_H264_PAY (element); + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_PAUSED: + rtph264pay->send_spspps = FALSE; + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + return ret; +} + static void gst_rtp_h264_pay_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) |