summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.co.uk>2010-01-08 22:13:59 -0500
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2010-05-10 15:07:09 +0200
commit34d0d591422f8d1c2285ecfd3e7ba9edf3acd892 (patch)
treef9c8e63f76564a85bb9eeda3eb1b9f3318baf742
parent90311e522f04b8501c3a0a6547a893d573161777 (diff)
rtph264pay: Re-send SPS/PPS when requested
https://bugzilla.gnome.org/show_bug.cgi?id=606689
-rw-r--r--gst/rtp/gstrtph264pay.c57
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)