GstCaps * caps);
static GstBuffer *gst_rtp_theora_depay_process (GstBaseRTPDepayload * depayload,
GstBuffer * buf);
+static gboolean gst_rtp_theora_depay_packet_lost (GstBaseRTPDepayload *
+ depayload, GstEvent * event);
static void gst_rtp_theora_depay_finalize (GObject * object);
gstbasertpdepayload_class->process = gst_rtp_theora_depay_process;
gstbasertpdepayload_class->set_caps = gst_rtp_theora_depay_setcaps;
+ gstbasertpdepayload_class->packet_lost = gst_rtp_theora_depay_packet_lost;
GST_DEBUG_CATEGORY_INIT (rtptheoradepay_debug, "rtptheoradepay", 0,
"Theora RTP Depayloader");
rtptheoradepay = GST_RTP_THEORA_DEPAY (depayload);
+ rtptheoradepay->needs_keyframe = FALSE;
+
structure = gst_caps_get_structure (caps, 0);
/* read and parse configuration string */
memcpy (GST_BUFFER_DATA (outbuf), payload, length);
}
+ if ((payload[0] & 0xC0) == 0x0)
+ rtptheoradepay->needs_keyframe = FALSE;
+
payload += length;
payload_len -= length;
g_free (to_free);
+ if (rtptheoradepay->needs_keyframe)
+ goto request_keyframe;
+
return NULL;
no_output:
{
GST_ELEMENT_WARNING (rtptheoradepay, STREAM, DECODE,
(NULL), ("Could not switch codebooks"));
- return NULL;
+ goto request_config;
}
packet_short:
{
GST_ELEMENT_WARNING (rtptheoradepay, STREAM, DECODE,
(NULL), ("Packet was too short (%d < 4)", payload_len));
- return NULL;
+ goto request_keyframe;
}
ignore_reserved:
{
{
GST_ELEMENT_WARNING (rtptheoradepay, STREAM, DECODE,
(NULL), ("Packet contains invalid data"));
- return NULL;
+ goto request_keyframe;
}
invalid_configuration:
{
/* fatal, as we otherwise risk carrying on without output */
GST_ELEMENT_ERROR (rtptheoradepay, STREAM, DECODE,
(NULL), ("Packet contains invalid configuration"));
+ goto request_config;
+ }
+request_config:
+ {
+ gst_pad_push_event (GST_BASE_RTP_DEPAYLOAD_SINKPAD (depayload),
+ gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
+ gst_structure_new ("GstForceKeyUnit",
+ "all-headers", G_TYPE_BOOLEAN, TRUE, NULL)));
+ return NULL;
+ }
+request_keyframe:
+ {
+ rtptheoradepay->needs_keyframe = TRUE;
+ gst_pad_push_event (GST_BASE_RTP_DEPAYLOAD_SINKPAD (depayload),
+ gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
+ gst_structure_new ("GstForceKeyUnit", NULL)));
return NULL;
}
}
return gst_element_register (plugin, "rtptheoradepay",
GST_RANK_SECONDARY, GST_TYPE_RTP_THEORA_DEPAY);
}
+
+static gboolean
+gst_rtp_theora_depay_packet_lost (GstBaseRTPDepayload * depayload,
+ GstEvent * event)
+{
+ GstRtpTheoraDepay *rtptheoradepay = GST_RTP_THEORA_DEPAY (depayload);
+ guint seqnum = 0;
+
+ gst_structure_get_uint (event->structure, "seqnum", &seqnum);
+ GST_LOG_OBJECT (depayload, "Requested keyframe because frame with seqnum %u"
+ " is missing", seqnum);
+ rtptheoradepay->needs_keyframe = TRUE;
+
+ gst_pad_push_event (GST_BASE_RTP_DEPAYLOAD_SINKPAD (depayload),
+ gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
+ gst_structure_new ("GstForceKeyUnit", NULL)));
+
+ return TRUE;
+}