+2008-02-12 Jan Schmidt <jan.schmidt@sun.com>
+
+ patch by: Wim Taymans <wim.taymans@collabora.co.uk>
+ fixes: #514889
+
+ * gst/rtp/gstrtph264pay.c:
+ * gst/rtp/gstrtpmp4gdepay.c:
+ * gst/rtp/gstrtpmp4gpay.c:
+ * gst/rtp/gstrtpmp4gpay.h:
+ * gst/rtp/gstrtptheorapay.c:
+ * gst/rtp/gstrtpvorbispay.c:
+
+ Fix various leaks shown up in valgrind
+ - free sprops and buffer in error cases in H264 payloader
+ - fix leak in mp4g depayloader when construction the caps
+ - don't leak config string in the mp4g payloader
+ - don't leak buffers and headers in theora and vorbis payloaders
+
+ * tests/check/elements/rtp-payloading.c:
+
+ Fix the RTP data test
+ - Actually send valid amr data to the payloader instead of 20
+ zero-bytes
+ - The mp4g payloader expects codec_data on the caps
+
2008-02-12 Sebastien Moutte <sebastien@moutte.net>
* win32/MANIFEST:
GST_DEBUG ("outcaps udpate: profile=%s, sps=%s, pps=%s\n",
profile, sps, pps);
+ g_free (sprops);
g_free (profile);
g_free (sps);
g_free (pps);
if (idxdata < 5) {
GST_DEBUG_OBJECT (basepayload,
"Returning GST_FLOW_OK without creating RTP packet");
+ gst_buffer_unref (buffer);
return GST_FLOW_OK;
}
GstBuffer *buffer;
buffer = gst_value_get_buffer (&v);
- gst_buffer_ref (buffer);
- g_value_unset (&v);
-
gst_caps_set_simple (srccaps,
"codec_data", GST_TYPE_BUFFER, buffer, NULL);
+ g_value_unset (&v);
} else {
g_warning ("cannot convert config to buffer");
}
static gboolean gst_rtp_mp4g_pay_setcaps (GstBaseRTPPayload * payload,
GstCaps * caps);
+static GstStateChangeReturn gst_rtp_mp4g_pay_change_state (GstElement * element,
+ GstStateChange transition);
static GstFlowReturn gst_rtp_mp4g_pay_handle_buffer (GstBaseRTPPayload *
payload, GstBuffer * buffer);
gobject_class->finalize = gst_rtp_mp4g_pay_finalize;
+ gstelement_class->change_state = gst_rtp_mp4g_pay_change_state;
+
gstbasertppayload_class->set_caps = gst_rtp_mp4g_pay_setcaps;
gstbasertppayload_class->handle_buffer = gst_rtp_mp4g_pay_handle_buffer;
g_free (rtpmp4gpay->params);
rtpmp4gpay->params = NULL;
+ if (rtpmp4gpay->config)
+ gst_buffer_unref (rtpmp4gpay->config);
+ rtpmp4gpay->config = NULL;
+
g_free (rtpmp4gpay->profile);
rtpmp4gpay->profile = NULL;
/* marker only if the packet is complete */
gst_rtp_buffer_set_marker (outbuf, avail <= payload_len);
- GST_BUFFER_TIMESTAMP (outbuf) = rtpmp4gpay->first_ts;
+ GST_BUFFER_TIMESTAMP (outbuf) = rtpmp4gpay->first_timestamp;
+ GST_BUFFER_DURATION (outbuf) = rtpmp4gpay->first_duration;
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpmp4gpay), outbuf);
rtpmp4gpay = GST_RTP_MP4G_PAY (basepayload);
- rtpmp4gpay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
+ rtpmp4gpay->first_timestamp = GST_BUFFER_TIMESTAMP (buffer);
+ rtpmp4gpay->first_duration = GST_BUFFER_DURATION (buffer);
/* we always encode and flush a full AU */
gst_adapter_push (rtpmp4gpay->adapter, buffer);
return ret;
}
+static GstStateChangeReturn
+gst_rtp_mp4g_pay_change_state (GstElement * element, GstStateChange transition)
+{
+ GstRtpMP4GPay *rtpmp4gpay;
+ GstStateChangeReturn ret;
+
+ rtpmp4gpay = GST_RTP_MP4G_PAY (element);
+
+ switch (transition) {
+ default:
+ break;
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ switch (transition) {
+ default:
+ break;
+ }
+ return ret;
+}
+
+
gboolean
gst_rtp_mp4g_pay_plugin_init (GstPlugin * plugin)
{
GstBaseRTPPayload payload;
GstAdapter *adapter;
- GstClockTime first_ts;
+ GstClockTime first_timestamp;
+ GstClockTime first_duration;
GstClockTime duration;
gint rate;
static gboolean gst_rtp_theora_pay_setcaps (GstBaseRTPPayload * basepayload,
GstCaps * caps);
+static GstStateChangeReturn gst_rtp_theora_pay_change_state (GstElement *
+ element, GstStateChange transition);
static GstFlowReturn gst_rtp_theora_pay_handle_buffer (GstBaseRTPPayload * pad,
GstBuffer * buffer);
parent_class = g_type_class_peek_parent (klass);
+ gstelement_class->change_state = gst_rtp_theora_pay_change_state;
+
gstbasertppayload_class->set_caps = gst_rtp_theora_pay_setcaps;
gstbasertppayload_class->handle_buffer = gst_rtp_theora_pay_handle_buffer;
/* needed because of GST_BOILERPLATE */
}
+static void
+gst_rtp_theora_pay_cleanup (GstRtpTheoraPay * rtptheorapay)
+{
+ g_list_foreach (rtptheorapay->headers, (GFunc) gst_mini_object_unref, NULL);
+ g_list_free (rtptheorapay->headers);
+ rtptheorapay->headers = NULL;
+
+ if (rtptheorapay->packet)
+ gst_buffer_unref (rtptheorapay->packet);
+ rtptheorapay->packet = NULL;
+}
+
static gboolean
gst_rtp_theora_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
{
rtptheorapay->payload_duration += duration;
}
}
+ gst_buffer_unref (buffer);
+
done:
return ret;
{
GST_ELEMENT_WARNING (rtptheorapay, STREAM, DECODE,
("Invalid packet size (1 < %d <= 0xffff)", size), (NULL));
+ gst_buffer_unref (buffer);
return GST_FLOW_OK;
}
parse_id_failed:
{
+ gst_buffer_unref (buffer);
return GST_FLOW_ERROR;
}
unknown_header:
{
GST_ELEMENT_WARNING (rtptheorapay, STREAM, DECODE,
(NULL), ("Ignoring unknown header received"));
+ gst_buffer_unref (buffer);
return GST_FLOW_OK;
}
header_error:
{
GST_ELEMENT_WARNING (rtptheorapay, STREAM, DECODE,
(NULL), ("Error initializing header config"));
+ gst_buffer_unref (buffer);
return GST_FLOW_OK;
}
}
+static GstStateChangeReturn
+gst_rtp_theora_pay_change_state (GstElement * element,
+ GstStateChange transition)
+{
+ GstRtpTheoraPay *rtptheorapay;
+ GstStateChangeReturn ret;
+
+ rtptheorapay = GST_RTP_THEORA_PAY (element);
+
+ switch (transition) {
+ default:
+ break;
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ gst_rtp_theora_pay_cleanup (rtptheorapay);
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
gboolean
gst_rtp_theora_pay_plugin_init (GstPlugin * plugin)
{
static gboolean gst_rtp_vorbis_pay_setcaps (GstBaseRTPPayload * basepayload,
GstCaps * caps);
+static GstStateChangeReturn gst_rtp_vorbis_pay_change_state (GstElement *
+ element, GstStateChange transition);
static GstFlowReturn gst_rtp_vorbis_pay_handle_buffer (GstBaseRTPPayload * pad,
GstBuffer * buffer);
parent_class = g_type_class_peek_parent (klass);
+ gstelement_class->change_state = gst_rtp_vorbis_pay_change_state;
+
gstbasertppayload_class->set_caps = gst_rtp_vorbis_pay_setcaps;
gstbasertppayload_class->handle_buffer = gst_rtp_vorbis_pay_handle_buffer;
/* needed because of GST_BOILERPLATE */
}
+static void
+gst_rtp_vorbis_pay_cleanup (GstRtpVorbisPay * rtpvorbispay)
+{
+ g_list_foreach (rtpvorbispay->headers, (GFunc) gst_mini_object_unref, NULL);
+ g_list_free (rtpvorbispay->headers);
+ rtpvorbispay->headers = NULL;
+
+ if (rtpvorbispay->packet)
+ gst_buffer_unref (rtpvorbispay->packet);
+ rtpvorbispay->packet = NULL;
+}
+
static gboolean
gst_rtp_vorbis_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
{
rtpvorbispay->payload_duration += duration;
}
}
+ gst_buffer_unref (buffer);
+
done:
return ret;
{
GST_ELEMENT_WARNING (rtpvorbispay, STREAM, DECODE,
("Invalid packet size (1 < %d <= 0xffff)", size), (NULL));
+ gst_buffer_unref (buffer);
return GST_FLOW_OK;
}
parse_id_failed:
{
+ gst_buffer_unref (buffer);
return GST_FLOW_ERROR;
}
unknown_header:
{
GST_ELEMENT_WARNING (rtpvorbispay, STREAM, DECODE,
(NULL), ("Ignoring unknown header received"));
+ gst_buffer_unref (buffer);
return GST_FLOW_OK;
}
header_error:
{
GST_ELEMENT_WARNING (rtpvorbispay, STREAM, DECODE,
(NULL), ("Error initializing header config"));
+ gst_buffer_unref (buffer);
return GST_FLOW_OK;
}
}
+static GstStateChangeReturn
+gst_rtp_vorbis_pay_change_state (GstElement * element,
+ GstStateChange transition)
+{
+ GstRtpVorbisPay *rtpvorbispay;
+ GstStateChangeReturn ret;
+
+ rtpvorbispay = GST_RTP_VORBIS_PAY (element);
+
+ switch (transition) {
+ default:
+ break;
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ gst_rtp_vorbis_pay_cleanup (rtpvorbispay);
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
gboolean
gst_rtp_vorbis_pay_plugin_init (GstPlugin * plugin)
{
GST_END_TEST;
static char rtp_amr_frame_data[] =
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ { 0x3c, 0x24, 0x03, 0xb3, 0x48, 0x10, 0x68, 0x46, 0x6c, 0xec, 0x03,
+ 0x7a, 0x37, 0x16, 0x41, 0x41, 0xc0, 0x00, 0x0d, 0xcd, 0x12, 0xed,
+ 0xad, 0x80, 0x00, 0x00, 0x11, 0x31, 0x00, 0x00, 0x0d, 0xa0
};
-static int rtp_amr_frame_data_size = 20;
+static int rtp_amr_frame_data_size = 32;
static int rtp_amr_frame_count = 1;
GST_START_TEST (rtp_amr)
GST_START_TEST (rtp_mp4g)
{
rtp_pipeline_test (rtp_mp4g_frame_data, rtp_mp4g_frame_data_size,
- rtp_mp4g_frame_count, "video/mpeg,mpegversion=4", "rtpmp4gpay",
+ rtp_mp4g_frame_count,
+ "video/mpeg,mpegversion=4,codec_data=(buffer)000001b001", "rtpmp4gpay",
"rtpmp4gdepay");
}