Original commit message from CVS:
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
This commit is contained in:
Wim Taymans 2008-02-12 23:38:19 +00:00 committed by Jan Schmidt
parent 4bb12df007
commit 4a7cbe8489
8 changed files with 167 additions and 10 deletions

View file

@ -1,3 +1,28 @@
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:

View file

@ -383,6 +383,7 @@ gst_rtp_h264_pay_parse_sps_pps (GstBaseRTPPayload * basepayload,
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);
@ -431,6 +432,7 @@ gst_rtp_h264_pay_handle_buffer (GstBaseRTPPayload * basepayload,
if (idxdata < 5) {
GST_DEBUG_OBJECT (basepayload,
"Returning GST_FLOW_OK without creating RTP packet");
gst_buffer_unref (buffer);
return GST_FLOW_OK;
}

View file

@ -223,11 +223,9 @@ gst_rtp_mp4g_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
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");
}

View file

@ -85,6 +85,8 @@ static void gst_rtp_mp4g_pay_finalize (GObject * object);
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);
@ -143,6 +145,8 @@ gst_rtp_mp4g_pay_class_init (GstRtpMP4GPayClass * klass)
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;
@ -171,6 +175,10 @@ gst_rtp_mp4g_pay_finalize (GObject * object)
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;
@ -504,7 +512,8 @@ gst_rtp_mp4g_pay_flush (GstRtpMP4GPay * rtpmp4gpay)
/* 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);
@ -528,7 +537,8 @@ gst_rtp_mp4g_pay_handle_buffer (GstBaseRTPPayload * basepayload,
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);
@ -537,6 +547,29 @@ gst_rtp_mp4g_pay_handle_buffer (GstBaseRTPPayload * basepayload,
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)
{

View file

@ -45,7 +45,8 @@ struct _GstRtpMP4GPay
GstBaseRTPPayload payload;
GstAdapter *adapter;
GstClockTime first_ts;
GstClockTime first_timestamp;
GstClockTime first_duration;
GstClockTime duration;
gint rate;

View file

@ -79,6 +79,8 @@ GST_BOILERPLATE (GstRtpTheoraPay, gst_rtp_theora_pay, GstBaseRTPPayload,
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);
@ -108,6 +110,8 @@ gst_rtp_theora_pay_class_init (GstRtpTheoraPayClass * klass)
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;
@ -122,6 +126,18 @@ gst_rtp_theora_pay_init (GstRtpTheoraPay * rtptheorapay,
/* 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)
{
@ -624,6 +640,8 @@ gst_rtp_theora_pay_handle_buffer (GstBaseRTPPayload * basepayload,
rtptheorapay->payload_duration += duration;
}
}
gst_buffer_unref (buffer);
done:
return ret;
@ -632,26 +650,56 @@ wrong_size:
{
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)
{

View file

@ -75,6 +75,8 @@ GST_BOILERPLATE (GstRtpVorbisPay, gst_rtp_vorbis_pay, GstBaseRTPPayload,
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);
@ -104,6 +106,8 @@ gst_rtp_vorbis_pay_class_init (GstRtpVorbisPayClass * klass)
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;
@ -118,6 +122,18 @@ gst_rtp_vorbis_pay_init (GstRtpVorbisPay * rtpvorbispay,
/* 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)
{
@ -623,6 +639,8 @@ gst_rtp_vorbis_pay_handle_buffer (GstBaseRTPPayload * basepayload,
rtpvorbispay->payload_duration += duration;
}
}
gst_buffer_unref (buffer);
done:
return ret;
@ -631,26 +649,56 @@ wrong_size:
{
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)
{

View file

@ -323,10 +323,11 @@ GST_START_TEST (rtp_gsm)
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)
@ -481,7 +482,8 @@ static int rtp_mp4g_frame_count = 1;
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");
}