mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
rtph263pay: Allocate Boundry structs on the stack instead of the heap to avoid leaks
Fixes bug #594691.
This commit is contained in:
parent
0a7ef67ad0
commit
411c71da13
1 changed files with 47 additions and 63 deletions
|
@ -389,8 +389,8 @@ static void gst_rtp_h263_pay_get_property (GObject * object, guint prop_id,
|
||||||
static GstFlowReturn gst_rtp_h263_pay_handle_buffer (GstBaseRTPPayload *
|
static GstFlowReturn gst_rtp_h263_pay_handle_buffer (GstBaseRTPPayload *
|
||||||
payload, GstBuffer * buffer);
|
payload, GstBuffer * buffer);
|
||||||
|
|
||||||
static GstRtpH263PayBoundry *gst_rtp_h263_pay_boundry_new (guint8 * start,
|
static void gst_rtp_h263_pay_boundry_init (GstRtpH263PayBoundry * boundry,
|
||||||
guint8 * end, guint8 sbit, guint8 ebit);
|
guint8 * start, guint8 * end, guint8 sbit, guint8 ebit);
|
||||||
static GstRtpH263PayGob *gst_rtp_h263_pay_gob_new (GstRtpH263PayBoundry *
|
static GstRtpH263PayGob *gst_rtp_h263_pay_gob_new (GstRtpH263PayBoundry *
|
||||||
boundry, guint gobn);
|
boundry, guint gobn);
|
||||||
static GstRtpH263PayMB *gst_rtp_h263_pay_mb_new (GstRtpH263PayBoundry * boundry,
|
static GstRtpH263PayMB *gst_rtp_h263_pay_mb_new (GstRtpH263PayBoundry * boundry,
|
||||||
|
@ -400,7 +400,6 @@ static GstRtpH263PayPackage *gst_rtp_h263_pay_package_new (guint8 * start,
|
||||||
guint8 * end, guint length, guint8 sbit, guint8 ebit, GstBuffer * outbuf,
|
guint8 * end, guint length, guint8 sbit, guint8 ebit, GstBuffer * outbuf,
|
||||||
gboolean marker);
|
gboolean marker);
|
||||||
|
|
||||||
static void gst_rtp_h263_pay_boundry_destroy (GstRtpH263PayBoundry * boundry);
|
|
||||||
static void gst_rtp_h263_pay_mb_destroy (GstRtpH263PayMB * mb);
|
static void gst_rtp_h263_pay_mb_destroy (GstRtpH263PayMB * mb);
|
||||||
static void gst_rtp_h263_pay_gob_destroy (GstRtpH263PayGob * gob, guint ind);
|
static void gst_rtp_h263_pay_gob_destroy (GstRtpH263PayGob * gob, guint ind);
|
||||||
static void gst_rtp_h263_pay_context_destroy (GstRtpH263PayContext * context,
|
static void gst_rtp_h263_pay_context_destroy (GstRtpH263PayContext * context,
|
||||||
|
@ -598,27 +597,14 @@ gst_rtp_h263_pay_package_destroy (GstRtpH263PayPackage * pack)
|
||||||
g_free (pack);
|
g_free (pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstRtpH263PayBoundry *
|
static void
|
||||||
gst_rtp_h263_pay_boundry_new (guint8 * start, guint8 * end, guint8 sbit,
|
gst_rtp_h263_pay_boundry_init (GstRtpH263PayBoundry * boundry,
|
||||||
guint8 ebit)
|
guint8 * start, guint8 * end, guint8 sbit, guint8 ebit)
|
||||||
{
|
{
|
||||||
GstRtpH263PayBoundry *boundry;
|
|
||||||
|
|
||||||
boundry = (GstRtpH263PayBoundry *) g_malloc0 (sizeof (GstRtpH263PayBoundry));
|
|
||||||
|
|
||||||
boundry->start = start;
|
boundry->start = start;
|
||||||
boundry->end = end;
|
boundry->end = end;
|
||||||
boundry->sbit = sbit;
|
boundry->sbit = sbit;
|
||||||
boundry->ebit = ebit;
|
boundry->ebit = ebit;
|
||||||
|
|
||||||
return boundry;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_rtp_h263_pay_boundry_destroy (GstRtpH263PayBoundry * boundry)
|
|
||||||
{
|
|
||||||
if (boundry)
|
|
||||||
g_free (boundry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -698,14 +684,13 @@ gst_rtp_h263_pay_splat_header_B (guint8 * header,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstRtpH263PayBoundry *
|
static gboolean
|
||||||
gst_rtp_h263_pay_gobfinder (GstRtpH263Pay * rtph263pay,
|
gst_rtp_h263_pay_gobfinder (GstRtpH263Pay * rtph263pay,
|
||||||
GstRtpH263PayBoundry * boundry)
|
GstRtpH263PayBoundry * boundry)
|
||||||
{
|
{
|
||||||
guint8 *current;
|
guint8 *current;
|
||||||
guint range;
|
guint range;
|
||||||
guint i;
|
guint i;
|
||||||
GstRtpH263PayBoundry *b;
|
|
||||||
|
|
||||||
current = boundry->end + 1;
|
current = boundry->end + 1;
|
||||||
range = (rtph263pay->data - current) + rtph263pay->available_data;
|
range = (rtph263pay->data - current) + rtph263pay->available_data;
|
||||||
|
@ -717,28 +702,26 @@ gst_rtp_h263_pay_gobfinder (GstRtpH263Pay * rtph263pay,
|
||||||
|
|
||||||
/* If we are past the end, stop */
|
/* If we are past the end, stop */
|
||||||
if (current >= rtph263pay->data + rtph263pay->available_data)
|
if (current >= rtph263pay->data + rtph263pay->available_data)
|
||||||
return NULL;
|
return FALSE;
|
||||||
|
|
||||||
for (i = 3; i < range - 3; i++) {
|
for (i = 3; i < range - 3; i++) {
|
||||||
if ((current[i] == 0x0) &&
|
if ((current[i] == 0x0) &&
|
||||||
(current[i + 1] == 0x0) && (current[i + 2] >> 7 == 0x1)) {
|
(current[i + 1] == 0x0) && (current[i + 2] >> 7 == 0x1)) {
|
||||||
GST_LOG ("GOB end found at: %p start: %p len: %d", current + i - 1,
|
GST_LOG ("GOB end found at: %p start: %p len: %d", current + i - 1,
|
||||||
boundry->end + 1, current + i - boundry->end + 2);
|
boundry->end + 1, current + i - boundry->end + 2);
|
||||||
b = gst_rtp_h263_pay_boundry_new (boundry->end + 1, current + i - 1, 0,
|
gst_rtp_h263_pay_boundry_init (boundry, boundry->end + 1,
|
||||||
0);
|
current + i - 1, 0, 0);
|
||||||
gst_rtp_h263_pay_boundry_destroy (boundry);
|
|
||||||
|
|
||||||
return b;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG ("Couldn't find any new GBSC in this frame, range:%u", range);
|
GST_DEBUG ("Couldn't find any new GBSC in this frame, range:%u", range);
|
||||||
|
|
||||||
b = gst_rtp_h263_pay_boundry_new (boundry->end + 1,
|
gst_rtp_h263_pay_boundry_init (boundry, boundry->end + 1,
|
||||||
(guint8 *) (rtph263pay->data + rtph263pay->available_data - 1), 0, 0);
|
(guint8 *) (rtph263pay->data + rtph263pay->available_data - 1), 0, 0);
|
||||||
gst_rtp_h263_pay_boundry_destroy (boundry);
|
|
||||||
|
|
||||||
return b;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstRtpH263PayGob *
|
static GstRtpH263PayGob *
|
||||||
|
@ -981,10 +964,13 @@ gst_rtp_h263_pay_B_mbfinder (GstRtpH263PayContext * context,
|
||||||
guint cbpy_type_index;
|
guint cbpy_type_index;
|
||||||
guint tcoef_type_index;
|
guint tcoef_type_index;
|
||||||
GstRtpH263PayMB *mac;
|
GstRtpH263PayMB *mac;
|
||||||
|
GstRtpH263PayBoundry boundry;
|
||||||
|
|
||||||
|
|
||||||
|
gst_rtp_h263_pay_boundry_init (&boundry, macroblock->end,
|
||||||
|
macroblock->end, 8 - macroblock->ebit, macroblock->ebit);
|
||||||
|
mac = gst_rtp_h263_pay_mb_new (&boundry, mba);
|
||||||
|
|
||||||
mac =
|
|
||||||
gst_rtp_h263_pay_mb_new (gst_rtp_h263_pay_boundry_new (macroblock->end,
|
|
||||||
macroblock->end, 8 - macroblock->ebit, macroblock->ebit), mba);
|
|
||||||
|
|
||||||
if (mac->sbit == 8) {
|
if (mac->sbit == 8) {
|
||||||
mac->start++;
|
mac->start++;
|
||||||
|
@ -1428,7 +1414,7 @@ gst_rtp_h263_pay_mode_B_fragment (GstRtpH263Pay * rtph263pay,
|
||||||
/*---------- MODE B MODE FRAGMENTATION ----------*/
|
/*---------- MODE B MODE FRAGMENTATION ----------*/
|
||||||
GstRtpH263PayMB *mac;
|
GstRtpH263PayMB *mac;
|
||||||
guint max_payload_size;
|
guint max_payload_size;
|
||||||
GstRtpH263PayBoundry *boundry;
|
GstRtpH263PayBoundry boundry;
|
||||||
guint mb;
|
guint mb;
|
||||||
//TODO remove m
|
//TODO remove m
|
||||||
GstRtpH263PayMB *m;
|
GstRtpH263PayMB *m;
|
||||||
|
@ -1439,7 +1425,8 @@ gst_rtp_h263_pay_mode_B_fragment (GstRtpH263Pay * rtph263pay,
|
||||||
max_payload_size =
|
max_payload_size =
|
||||||
context->mtu - GST_RTP_H263_PAYLOAD_HEADER_MODE_B - GST_RTP_HEADER_LEN;
|
context->mtu - GST_RTP_H263_PAYLOAD_HEADER_MODE_B - GST_RTP_HEADER_LEN;
|
||||||
|
|
||||||
boundry = gst_rtp_h263_pay_boundry_new (gob->start, gob->start, gob->sbit, 0);
|
gst_rtp_h263_pay_boundry_init (&boundry, gob->start, gob->start, gob->sbit,
|
||||||
|
0);
|
||||||
|
|
||||||
gob->macroblocks =
|
gob->macroblocks =
|
||||||
(GstRtpH263PayMB **) g_malloc0 (sizeof (GstRtpH263PayMB *) *
|
(GstRtpH263PayMB **) g_malloc0 (sizeof (GstRtpH263PayMB *) *
|
||||||
|
@ -1448,9 +1435,9 @@ gst_rtp_h263_pay_mode_B_fragment (GstRtpH263Pay * rtph263pay,
|
||||||
GST_LOG ("GOB isn't PB frame, applying mode B");
|
GST_LOG ("GOB isn't PB frame, applying mode B");
|
||||||
|
|
||||||
//initializing window
|
//initializing window
|
||||||
context->win_end = boundry->end;
|
context->win_end = boundry.end;
|
||||||
if (gst_rtp_h263_pay_move_window_right (context, 32, boundry->ebit,
|
if (gst_rtp_h263_pay_move_window_right (context, 32, boundry.ebit,
|
||||||
&boundry->end, &gob->end) != 0) {
|
&boundry.end, &gob->end) != 0) {
|
||||||
GST_ERROR
|
GST_ERROR
|
||||||
("The rest of the bits should be 0, exiting, because something bad happend");
|
("The rest of the bits should be 0, exiting, because something bad happend");
|
||||||
gst_adapter_flush (rtph263pay->adapter, rtph263pay->available_data);
|
gst_adapter_flush (rtph263pay->adapter, rtph263pay->available_data);
|
||||||
|
@ -1462,9 +1449,9 @@ gst_rtp_h263_pay_mode_B_fragment (GstRtpH263Pay * rtph263pay,
|
||||||
GST_LOG ("Initial GOB");
|
GST_LOG ("Initial GOB");
|
||||||
shift = 43;
|
shift = 43;
|
||||||
|
|
||||||
boundry->ebit =
|
boundry.ebit =
|
||||||
gst_rtp_h263_pay_move_window_right (context, shift, boundry->ebit,
|
gst_rtp_h263_pay_move_window_right (context, shift, boundry.ebit,
|
||||||
&boundry->end, &gob->end);
|
&boundry.end, &gob->end);
|
||||||
|
|
||||||
//We need PQUANT for mode B packages - so we store it
|
//We need PQUANT for mode B packages - so we store it
|
||||||
gob->quant = context->window >> 27;
|
gob->quant = context->window >> 27;
|
||||||
|
@ -1474,24 +1461,24 @@ gst_rtp_h263_pay_mode_B_fragment (GstRtpH263Pay * rtph263pay,
|
||||||
shift = 6;
|
shift = 6;
|
||||||
if (context->cpm == 1)
|
if (context->cpm == 1)
|
||||||
shift += 2;
|
shift += 2;
|
||||||
boundry->ebit =
|
boundry.ebit =
|
||||||
gst_rtp_h263_pay_move_window_right (context, shift, boundry->ebit,
|
gst_rtp_h263_pay_move_window_right (context, shift, boundry.ebit,
|
||||||
&boundry->end, &gob->end);
|
&boundry.end, &gob->end);
|
||||||
|
|
||||||
GST_DEBUG ("window: 0x%08x", context->window);
|
GST_DEBUG ("window: 0x%08x", context->window);
|
||||||
|
|
||||||
//Shifting the PEI and PSPARE fields
|
//Shifting the PEI and PSPARE fields
|
||||||
while ((context->window & 0x80000000) == 0x80000000) {
|
while ((context->window & 0x80000000) == 0x80000000) {
|
||||||
boundry->ebit =
|
boundry.ebit =
|
||||||
gst_rtp_h263_pay_move_window_right (context, 9,
|
gst_rtp_h263_pay_move_window_right (context, 9,
|
||||||
boundry->ebit, &boundry->end, &gob->end);
|
boundry.ebit, &boundry.end, &gob->end);
|
||||||
GST_LOG ("window: 0x%x", context->window);
|
GST_LOG ("window: 0x%x", context->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
//shift the last PEI field
|
//shift the last PEI field
|
||||||
boundry->ebit =
|
boundry.ebit =
|
||||||
gst_rtp_h263_pay_move_window_right (context, 1, boundry->ebit,
|
gst_rtp_h263_pay_move_window_right (context, 1, boundry.ebit,
|
||||||
&boundry->end, &gob->end);
|
&boundry.end, &gob->end);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//skipping GOBs 24 header bits + 5 GQUANT
|
//skipping GOBs 24 header bits + 5 GQUANT
|
||||||
|
@ -1504,17 +1491,17 @@ gst_rtp_h263_pay_mode_B_fragment (GstRtpH263Pay * rtph263pay,
|
||||||
shift += 2;
|
shift += 2;
|
||||||
|
|
||||||
GST_LOG ("window: 0x%x", context->window);
|
GST_LOG ("window: 0x%x", context->window);
|
||||||
boundry->ebit =
|
boundry.ebit =
|
||||||
gst_rtp_h263_pay_move_window_right (context, shift,
|
gst_rtp_h263_pay_move_window_right (context, shift,
|
||||||
boundry->ebit, &boundry->end, &gob->end);
|
boundry.ebit, &boundry.end, &gob->end);
|
||||||
|
|
||||||
//We need GQUANT for mode B packages - so we store it
|
//We need GQUANT for mode B packages - so we store it
|
||||||
gob->quant = context->window >> 27;
|
gob->quant = context->window >> 27;
|
||||||
|
|
||||||
shift = 5;
|
shift = 5;
|
||||||
boundry->ebit =
|
boundry.ebit =
|
||||||
gst_rtp_h263_pay_move_window_right (context, shift,
|
gst_rtp_h263_pay_move_window_right (context, shift,
|
||||||
boundry->ebit, &boundry->end, &gob->end);
|
boundry.ebit, &boundry.end, &gob->end);
|
||||||
|
|
||||||
GST_LOG ("window: 0x%x", context->window);
|
GST_LOG ("window: 0x%x", context->window);
|
||||||
}
|
}
|
||||||
|
@ -1523,7 +1510,7 @@ gst_rtp_h263_pay_mode_B_fragment (GstRtpH263Pay * rtph263pay,
|
||||||
|
|
||||||
// We are on MB layer
|
// We are on MB layer
|
||||||
|
|
||||||
m = mac = gst_rtp_h263_pay_mb_new (boundry, 0);
|
m = mac = gst_rtp_h263_pay_mb_new (&boundry, 0);
|
||||||
for (mb = 0; mb < format_props[context->piclayer->ptype_srcformat][1]; mb++) {
|
for (mb = 0; mb < format_props[context->piclayer->ptype_srcformat][1]; mb++) {
|
||||||
|
|
||||||
GST_DEBUG ("================ START MB %d =================", mb);
|
GST_DEBUG ("================ START MB %d =================", mb);
|
||||||
|
@ -1562,7 +1549,7 @@ gst_rtp_h263_pay_mode_B_fragment (GstRtpH263Pay * rtph263pay,
|
||||||
|
|
||||||
mb = 0;
|
mb = 0;
|
||||||
first = 0;
|
first = 0;
|
||||||
payload_len = boundry->end - boundry->start + 1;
|
payload_len = boundry.end - boundry.start + 1;
|
||||||
GST_DEBUG ("------------------------- NEW PACKAGE ----------------------");
|
GST_DEBUG ("------------------------- NEW PACKAGE ----------------------");
|
||||||
while (mb < gob->nmacroblocs) {
|
while (mb < gob->nmacroblocs) {
|
||||||
if (payload_len + gob->macroblocks[mb]->length < max_payload_size) {
|
if (payload_len + gob->macroblocks[mb]->length < max_payload_size) {
|
||||||
|
@ -1577,7 +1564,7 @@ gst_rtp_h263_pay_mode_B_fragment (GstRtpH263Pay * rtph263pay,
|
||||||
// first == mb - 1, payload_len);
|
// first == mb - 1, payload_len);
|
||||||
|
|
||||||
if (gst_rtp_h263_pay_B_fragment_push (rtph263pay, context, gob, first,
|
if (gst_rtp_h263_pay_B_fragment_push (rtph263pay, context, gob, first,
|
||||||
mb - 1, boundry)) {
|
mb - 1, &boundry)) {
|
||||||
GST_ERROR ("Oooops, there was an error sending");
|
GST_ERROR ("Oooops, there was an error sending");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1595,7 +1582,7 @@ gst_rtp_h263_pay_mode_B_fragment (GstRtpH263Pay * rtph263pay,
|
||||||
GST_DEBUG ("Remainder first: %d, MB: %d", first, mb);
|
GST_DEBUG ("Remainder first: %d, MB: %d", first, mb);
|
||||||
if (payload_len != 0) {
|
if (payload_len != 0) {
|
||||||
if (gst_rtp_h263_pay_B_fragment_push (rtph263pay, context, gob, first,
|
if (gst_rtp_h263_pay_B_fragment_push (rtph263pay, context, gob, first,
|
||||||
mb - 1, boundry)) {
|
mb - 1, &boundry)) {
|
||||||
GST_ERROR ("Oooops, there was an error sending!");
|
GST_ERROR ("Oooops, there was an error sending!");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1688,7 +1675,7 @@ gst_rtp_h263_pay_flush (GstRtpH263Pay * rtph263pay)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/*---------- FRAGMENTING THE FRAME BECAUSE TOO LARGE TO FIT IN MTU ----------*/
|
/*---------- FRAGMENTING THE FRAME BECAUSE TOO LARGE TO FIT IN MTU ----------*/
|
||||||
GstRtpH263PayBoundry *bound;
|
GstRtpH263PayBoundry bound;
|
||||||
gint first;
|
gint first;
|
||||||
guint payload_len;
|
guint payload_len;
|
||||||
|
|
||||||
|
@ -1697,7 +1684,7 @@ gst_rtp_h263_pay_flush (GstRtpH263Pay * rtph263pay)
|
||||||
* Let's go trough all the data and fragment it untill end is reached
|
* Let's go trough all the data and fragment it untill end is reached
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bound = gst_rtp_h263_pay_boundry_new (NULL, rtph263pay->data - 1, 0, 0);
|
gst_rtp_h263_pay_boundry_init (&bound, NULL, rtph263pay->data - 1, 0, 0);
|
||||||
context->gobs =
|
context->gobs =
|
||||||
(GstRtpH263PayGob **) g_malloc0 (format_props[context->piclayer->
|
(GstRtpH263PayGob **) g_malloc0 (format_props[context->piclayer->
|
||||||
ptype_srcformat][0] * sizeof (GstRtpH263PayGob *));
|
ptype_srcformat][0] * sizeof (GstRtpH263PayGob *));
|
||||||
|
@ -1705,15 +1692,14 @@ gst_rtp_h263_pay_flush (GstRtpH263Pay * rtph263pay)
|
||||||
|
|
||||||
for (i = 0; i < format_props[context->piclayer->ptype_srcformat][0]; i++) {
|
for (i = 0; i < format_props[context->piclayer->ptype_srcformat][0]; i++) {
|
||||||
GST_DEBUG ("Searching for gob %d", i);
|
GST_DEBUG ("Searching for gob %d", i);
|
||||||
bound = gst_rtp_h263_pay_gobfinder (rtph263pay, bound);
|
if (!gst_rtp_h263_pay_gobfinder (rtph263pay, &bound)) {
|
||||||
if (!bound) {
|
|
||||||
GST_WARNING
|
GST_WARNING
|
||||||
("No GOB's were found in data stream! Please enable RTP mode in encoder. Forcing mode A for now.");
|
("No GOB's were found in data stream! Please enable RTP mode in encoder. Forcing mode A for now.");
|
||||||
ret = gst_rtp_h263_send_entire_frame (rtph263pay, context);
|
ret = gst_rtp_h263_send_entire_frame (rtph263pay, context);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->gobs[i] = gst_rtp_h263_pay_gob_new (bound, i);
|
context->gobs[i] = gst_rtp_h263_pay_gob_new (&bound, i);
|
||||||
//FIXME - encoders may generate an EOS gob that has to be processed
|
//FIXME - encoders may generate an EOS gob that has to be processed
|
||||||
GST_DEBUG
|
GST_DEBUG
|
||||||
("Gob values are: gobn: %d, start: %p len: %d ebit: %d sbit: %d", i,
|
("Gob values are: gobn: %d, start: %p len: %d ebit: %d sbit: %d", i,
|
||||||
|
@ -1721,8 +1707,6 @@ gst_rtp_h263_pay_flush (GstRtpH263Pay * rtph263pay)
|
||||||
context->gobs[i]->ebit, context->gobs[i]->sbit);
|
context->gobs[i]->ebit, context->gobs[i]->sbit);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_rtp_h263_pay_boundry_destroy (bound);
|
|
||||||
|
|
||||||
// Make packages smaller than MTU
|
// Make packages smaller than MTU
|
||||||
// A mode
|
// A mode
|
||||||
// - if ( GOB > MTU) -> B mode || C mode
|
// - if ( GOB > MTU) -> B mode || C mode
|
||||||
|
|
Loading…
Reference in a new issue