Commit 66f1e9dd authored by Jean-Paul Saman's avatar Jean-Paul Saman

Fix several memory leaks and do a bit of coding style cleanup.

parent 3143ebce
...@@ -47,11 +47,10 @@ const unsigned char xor_table[] = { ...@@ -47,11 +47,10 @@ const unsigned char xor_table[] = {
#define MAX(x,y) ((x>y) ? x : y) #define MAX(x,y) ((x>y) ? x : y)
static void hash(char *field, char *param) { static void hash(char *field, char *param)
{
uint32_t a, b, c, d; uint32_t a, b, c, d;
/* fill variables */ /* fill variables */
a = LE_32(field); a = LE_32(field);
b = LE_32(field+4); b = LE_32(field+4);
...@@ -231,7 +230,6 @@ static void call_hash (char *key, char *challenge, int len) { ...@@ -231,7 +230,6 @@ static void call_hash (char *key, char *challenge, int len) {
c = 0; c = 0;
if (a <= len) if (a <= len)
{ {
memcpy(key+b+24, challenge, a); memcpy(key+b+24, challenge, a);
hash(key, key+24); hash(key, key+24);
c = a; c = a;
...@@ -249,8 +247,8 @@ static void call_hash (char *key, char *challenge, int len) { ...@@ -249,8 +247,8 @@ static void call_hash (char *key, char *challenge, int len) {
memcpy(key+b+24, challenge+c, len-c); memcpy(key+b+24, challenge+c, len-c);
} }
static void calc_response (char *result, char *field) { static void calc_response (char *result, char *field)
{
char buf1[128]; char buf1[128];
char buf2[128]; char buf2[128];
int i; int i;
...@@ -259,26 +257,25 @@ static void calc_response (char *result, char *field) { ...@@ -259,26 +257,25 @@ static void calc_response (char *result, char *field) {
*buf1 = 128; *buf1 = 128;
memcpy (buf2, field+16, 8); memcpy (buf2, field+16, 8);
i = ( LE_32((buf2)) >> 3 ) & 0x3f; i = ( LE_32((buf2)) >> 3 ) & 0x3f;
if (i < 56) { if (i < 56)
{
i = 56 - i; i = 56 - i;
} else { } else
{
lprintf("not verified: ! (i < 56)\n"); lprintf("not verified: ! (i < 56)\n");
i = 120 - i; i = 120 - i;
} }
call_hash (field, buf1, i); call_hash (field, buf1, i);
call_hash (field, buf2, 8); call_hash (field, buf2, 8);
memcpy (result, field, 16); memcpy (result, field, 16);
} }
static void calc_response_string (char *result, char *challenge) { static void calc_response_string (char *result, char *challenge)
{
char field[128]; char field[128];
char zres[20]; char zres[20];
int i; int i;
...@@ -307,8 +304,8 @@ static void calc_response_string (char *result, char *challenge) { ...@@ -307,8 +304,8 @@ static void calc_response_string (char *result, char *challenge) {
} }
} }
void real_calc_response_and_checksum (char *response, char *chksum, char *challenge) { void real_calc_response_and_checksum (char *response, char *chksum, char *challenge)
{
int ch_len, table_len, resp_len; int ch_len, table_len, resp_len;
int i; int i;
char *ptr; char *ptr;
...@@ -369,14 +366,12 @@ void real_calc_response_and_checksum (char *response, char *chksum, char *challe ...@@ -369,14 +366,12 @@ void real_calc_response_and_checksum (char *response, char *chksum, char *challe
* takes a MLTI-Chunk and a rule number got from match_asm_rule, * takes a MLTI-Chunk and a rule number got from match_asm_rule,
* returns a pointer to selected data and number of bytes in that. * returns a pointer to selected data and number of bytes in that.
*/ */
static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection, char **out)
static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection, char **out) { {
int numrules, codec, size; int numrules, codec, size;
int i; int i;
/* MLTI chunk should begin with MLTI */ /* MLTI chunk should begin with MLTI */
if ((mlti_chunk[0] != 'M') if ((mlti_chunk[0] != 'M')
||(mlti_chunk[1] != 'L') ||(mlti_chunk[1] != 'L')
||(mlti_chunk[2] != 'T') ||(mlti_chunk[2] != 'T')
...@@ -418,7 +413,6 @@ static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection ...@@ -418,7 +413,6 @@ static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection
size=BE_32(mlti_chunk); size=BE_32(mlti_chunk);
mlti_chunk+=size+4; mlti_chunk+=size+4;
} }
size=BE_32(mlti_chunk); size=BE_32(mlti_chunk);
memcpy(*out, mlti_chunk+4, size); memcpy(*out, mlti_chunk+4, size);
...@@ -429,11 +423,11 @@ static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection ...@@ -429,11 +423,11 @@ static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection
* looking at stream description. * looking at stream description.
*/ */
rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidth) { rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidth)
{
sdpplin_t *desc; sdpplin_t *desc = NULL;
rmff_header_t *header; rmff_header_t *header = NULL;
char *buf; char *buf = NULL;
int len, i; int len, i;
int max_bit_rate=0; int max_bit_rate=0;
int avg_bit_rate=0; int avg_bit_rate=0;
...@@ -441,30 +435,35 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt ...@@ -441,30 +435,35 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt
int avg_packet_size=0; int avg_packet_size=0;
int duration=0; int duration=0;
if( !data ) return NULL;
if (!data) return NULL;
desc=sdpplin_parse(data); desc=sdpplin_parse(data);
if( !desc ) return NULL;
if (!desc) return NULL; buf= (char *)malloc(sizeof(char)*2048);
if( !buf ) goto error;
buf=malloc(2048); header = (rmff_header_t*)malloc(sizeof(rmff_header_t));
header = malloc(sizeof(rmff_header_t)); if( !header ) goto error;
memset(header, 0, sizeof(rmff_header_t));
memset(header, 0, sizeof(rmff_header_t));
header->fileheader=rmff_new_fileheader(4+desc->stream_count); header->fileheader=rmff_new_fileheader(4+desc->stream_count);
header->cont=rmff_new_cont( header->cont=rmff_new_cont(
desc->title, desc->title,
desc->author, desc->author,
desc->copyright, desc->copyright,
desc->abstract); desc->abstract);
header->data=rmff_new_dataheader(0,0); header->data=rmff_new_dataheader(0,0);
header->streams = malloc(sizeof(rmff_mdpr_t*)*(desc->stream_count+1)); if( !header->data ) goto error;
memset(header->streams, 0, sizeof(rmff_mdpr_t*)*(desc->stream_count+1));
lprintf("number of streams: %u\n", desc->stream_count);
for (i=0; i<desc->stream_count; i++) { header->streams = (rmff_mdpr_t*)malloc(sizeof(rmff_mdpr_t*)*(desc->stream_count+1));
if( !header->streams ) goto error;
memset(header->streams, 0, sizeof(rmff_mdpr_t*)*(desc->stream_count+1));
lprintf("number of streams: %u\n", desc->stream_count);
for (i=0; i<desc->stream_count; i++)
{
int j=0; int j=0;
int n; int n;
char b[64]; char b[64];
...@@ -473,18 +472,22 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt ...@@ -473,18 +472,22 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt
lprintf("calling asmrp_match with:\n%s\n%u\n", desc->stream[i]->asm_rule_book, bandwidth); lprintf("calling asmrp_match with:\n%s\n%u\n", desc->stream[i]->asm_rule_book, bandwidth);
n=asmrp_match(desc->stream[i]->asm_rule_book, bandwidth, rulematches); n=asmrp_match(desc->stream[i]->asm_rule_book, bandwidth, rulematches);
for (j=0; j<n; j++) { for (j=0; j<n; j++)
{
lprintf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id); lprintf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id);
sprintf(b,"stream=%u;rule=%u,", desc->stream[i]->stream_id, rulematches[j]); sprintf(b,"stream=%u;rule=%u,", desc->stream[i]->stream_id, rulematches[j]);
strcat(*stream_rules, b); strcat(*stream_rules, b);
} }
if (!desc->stream[i]->mlti_data) { if (!desc->stream[i]->mlti_data)
{
len = 0; len = 0;
if( buf ) free( buf );
buf = NULL; buf = NULL;
} }
else else
len=select_mlti_data(desc->stream[i]->mlti_data, desc->stream[i]->mlti_data_size, rulematches[0], &buf); len=select_mlti_data(desc->stream[i]->mlti_data,
desc->stream[i]->mlti_data_size, rulematches[0], &buf);
header->streams[i]=rmff_new_mdpr( header->streams[i]=rmff_new_mdpr(
desc->stream[i]->stream_id, desc->stream[i]->stream_id,
...@@ -499,6 +502,7 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt ...@@ -499,6 +502,7 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt
desc->stream[i]->mime_type, desc->stream[i]->mime_type,
len, len,
buf); buf);
if( !header->streams[i] ) goto error;
duration=MAX(duration,desc->stream[i]->duration); duration=MAX(duration,desc->stream[i]->duration);
max_bit_rate+=desc->stream[i]->max_bit_rate; max_bit_rate+=desc->stream[i]->max_bit_rate;
...@@ -525,16 +529,35 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt ...@@ -525,16 +529,35 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt
0, 0,
desc->stream_count, desc->stream_count,
desc->flags); desc->flags);
if( !header->prop ) goto error;
rmff_fix_header(header); rmff_fix_header(header);
free(buf);
if( desc )
{
sdpplin_free( desc );
free( desc );
}
if( buf ) free(buf);
return header; return header;
error:
if( desc )
{
sdpplin_free( desc );
free( desc );
}
if( header )
{
rmff_free_header( header );
free( header );
}
if( buf ) free( buf );
return NULL;
} }
int real_get_rdt_chunk_header(rtsp_client_t *rtsp_session, rmff_pheader_t *ph) int real_get_rdt_chunk_header(rtsp_client_t *rtsp_session, rmff_pheader_t *ph)
{ {
int n=1; int n=1;
uint8_t header[8]; uint8_t header[8];
int size; int size;
...@@ -543,7 +566,8 @@ int real_get_rdt_chunk_header(rtsp_client_t *rtsp_session, rmff_pheader_t *ph) ...@@ -543,7 +566,8 @@ int real_get_rdt_chunk_header(rtsp_client_t *rtsp_session, rmff_pheader_t *ph)
uint32_t ts; uint32_t ts;
n=rtsp_read_data(rtsp_session, header, 8); n=rtsp_read_data(rtsp_session, header, 8);
if (n<8) return 0; if (n<8)
return 0;
if (header[0] != 0x24) if (header[0] != 0x24)
{ {
lprintf("rdt chunk not recognized: got 0x%02x\n", header[0]); lprintf("rdt chunk not recognized: got 0x%02x\n", header[0]);
...@@ -563,16 +587,19 @@ int real_get_rdt_chunk_header(rtsp_client_t *rtsp_session, rmff_pheader_t *ph) ...@@ -563,16 +587,19 @@ int real_get_rdt_chunk_header(rtsp_client_t *rtsp_session, rmff_pheader_t *ph)
header[1]=header[6]; header[1]=header[6];
header[2]=header[7]; header[2]=header[7];
n=rtsp_read_data(rtsp_session, header+3, 5); n=rtsp_read_data(rtsp_session, header+3, 5);
if (n<5) return 0; if (n<5)
return 0;
lprintf("ignoring bytes:\n"); lprintf("ignoring bytes:\n");
n=rtsp_read_data(rtsp_session, header+4, 4); n=rtsp_read_data(rtsp_session, header+4, 4);
if (n<4) return 0; if (n<4)
return 0;
flags1=header[4]; flags1=header[4];
size-=9; size-=9;
} }
unknown1=(header[5]<<16)+(header[6]<<8)+(header[7]); unknown1=(header[5]<<16)+(header[6]<<8)+(header[7]);
n=rtsp_read_data(rtsp_session, header, 6); n=rtsp_read_data(rtsp_session, header, 6);
if (n<6) return 0; if (n<6)
return 0;
ts=BE_32(header); ts=BE_32(header);
#if 0 #if 0
...@@ -581,14 +608,12 @@ int real_get_rdt_chunk_header(rtsp_client_t *rtsp_session, rmff_pheader_t *ph) ...@@ -581,14 +608,12 @@ int real_get_rdt_chunk_header(rtsp_client_t *rtsp_session, rmff_pheader_t *ph)
#endif #endif
size+=2; size+=2;
ph->object_version=0; ph->object_version=0;
ph->length=size; ph->length=size;
ph->stream_number=(flags1>>1)&1; ph->stream_number=(flags1>>1)&1;
ph->timestamp=ts; ph->timestamp=ts;
ph->reserved=0; ph->reserved=0;
ph->flags=0; /* TODO: determine keyframe flag and insert here? */ ph->flags=0; /* TODO: determine keyframe flag and insert here? */
return size; return size;
} }
...@@ -603,16 +628,16 @@ int real_get_rdt_chunk(rtsp_client_t *rtsp_session, rmff_pheader_t *ph, ...@@ -603,16 +628,16 @@ int real_get_rdt_chunk(rtsp_client_t *rtsp_session, rmff_pheader_t *ph,
//! maximum size of the rtsp description, must be < INT_MAX //! maximum size of the rtsp description, must be < INT_MAX
#define MAX_DESC_BUF (20 * 1024 * 1024) #define MAX_DESC_BUF (20 * 1024 * 1024)
rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandwidth) { rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandwidth)
{
char *description=NULL; char *description=NULL;
char *session_id=NULL; char *session_id=NULL;
rmff_header_t *h; rmff_header_t *h;
char *challenge1; char *challenge1 = NULL;
char challenge2[64]; char challenge2[64];
char checksum[34]; char checksum[34];
char *subscribe; char *subscribe=NULL;
char *buf=malloc(256); char *buf=(char*)malloc(sizeof(char)*256);
char *mrl=rtsp_get_mrl(rtsp_session); char *mrl=rtsp_get_mrl(rtsp_session);
unsigned int size; unsigned int size;
int status; int status;
...@@ -631,8 +656,8 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw ...@@ -631,8 +656,8 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw
rtsp_schedule_field(rtsp_session, "SupportsMaximumASMBandwidth: 1"); rtsp_schedule_field(rtsp_session, "SupportsMaximumASMBandwidth: 1");
rtsp_schedule_field(rtsp_session, "Language: en-US"); rtsp_schedule_field(rtsp_session, "Language: en-US");
rtsp_schedule_field(rtsp_session, "Require: com.real.retain-entity-for-setup"); rtsp_schedule_field(rtsp_session, "Require: com.real.retain-entity-for-setup");
status=rtsp_request_describe(rtsp_session,NULL);
status=rtsp_request_describe(rtsp_session,NULL);
if ( status<200 || status>299 ) if ( status<200 || status>299 )
{ {
char *alert=rtsp_search_answers(rtsp_session,"Alert"); char *alert=rtsp_search_answers(rtsp_session,"Alert");
...@@ -641,7 +666,9 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw ...@@ -641,7 +666,9 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw
} }
printf( "bou\n"); printf( "bou\n");
rtsp_send_ok(rtsp_session); rtsp_send_ok(rtsp_session);
free(buf); if( challenge1 ) free(challenge1);
if( alert ) free(alert);
if( buf ) free(buf);
return NULL; return NULL;
} }
...@@ -655,8 +682,7 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw ...@@ -655,8 +682,7 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw
if (size > MAX_DESC_BUF) { if (size > MAX_DESC_BUF) {
printf("real: Content-length for description too big (> %uMB)!\n", printf("real: Content-length for description too big (> %uMB)!\n",
MAX_DESC_BUF/(1024*1024) ); MAX_DESC_BUF/(1024*1024) );
free(buf); goto error;
return NULL;
} }
if (!rtsp_search_answers(rtsp_session,"ETag")) if (!rtsp_search_answers(rtsp_session,"ETag"))
...@@ -666,30 +692,30 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw ...@@ -666,30 +692,30 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw
lprintf("Stream description size: %i\n", size); lprintf("Stream description size: %i\n", size);
description = malloc(sizeof(char)*(size+1)); description = (char*)malloc(sizeof(char)*(size+1));
if( !description )
if( rtsp_read_data(rtsp_session, description, size) <= 0) { goto error;
free(buf); if( rtsp_read_data(rtsp_session, description, size) <= 0)
return NULL; goto error;
}
description[size]=0; description[size]=0;
fprintf(stderr,description); fprintf(stderr,description);
/* parse sdp (sdpplin) and create a header and a subscribe string */ /* parse sdp (sdpplin) and create a header and a subscribe string */
subscribe=malloc(256); subscribe = (char *) malloc(sizeof(char)*256);
if( !subscribe )
goto error;
strcpy(subscribe, "Subscribe: "); strcpy(subscribe, "Subscribe: ");
h=real_parse_sdp(description, &subscribe, bandwidth); h=real_parse_sdp(description, &subscribe, bandwidth);
if (!h) { if (!h)
free(subscribe); goto error;
free(buf);
return NULL;
}
rmff_fix_header(h); rmff_fix_header(h);
#if 0 #if 0
fprintf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n", fprintf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n",
h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams); h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams);
#endif #endif
/* setup our streams */ /* setup our streams */
real_calc_response_and_checksum (challenge2, checksum, challenge1); real_calc_response_and_checksum (challenge2, checksum, challenge1);
...@@ -709,7 +735,6 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw ...@@ -709,7 +735,6 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw
buf = realloc(buf, strlen(session_id) + 32); buf = realloc(buf, strlen(session_id) + 32);
sprintf(buf, "If-Match: %s", session_id); sprintf(buf, "If-Match: %s", session_id);
rtsp_schedule_field(rtsp_session, buf); rtsp_schedule_field(rtsp_session, buf);
buf = realloc(buf, strlen(mrl) + 32); buf = realloc(buf, strlen(mrl) + 32);
sprintf(buf, "%s/streamid=1", mrl); sprintf(buf, "%s/streamid=1", mrl);
rtsp_request_setup(rtsp_session,buf); rtsp_request_setup(rtsp_session,buf);
...@@ -722,8 +747,19 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw ...@@ -722,8 +747,19 @@ rmff_header_t *real_setup_and_get_header(rtsp_client_t *rtsp_session, int bandw
rtsp_schedule_field(rtsp_session, "Range: npt=0-"); rtsp_schedule_field(rtsp_session, "Range: npt=0-");
rtsp_request_play(rtsp_session,NULL); rtsp_request_play(rtsp_session,NULL);
free(subscribe); if( challenge1 ) free( challenge1 );
free(buf); if( session_id ) free( session_id );
if( description ) free(description);
if( subscribe ) free(subscribe);
if( buf ) free(buf);
return h; return h;
}
error:
if( h ) rmff_free_header( h );
if( challenge1 ) free( challenge1 );
if( session_id ) free( session_id );
if( description ) free(description);
if( subscribe ) free(subscribe);
if( buf ) free(buf);
return NULL;
}
...@@ -183,9 +183,10 @@ static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) { ...@@ -183,9 +183,10 @@ static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) {
cont->object_id=BE_32(&cont->object_id); cont->object_id=BE_32(&cont->object_id);
} }
static void rmff_dump_dataheader(rmff_data_t *data, char *buffer) { static void rmff_dump_dataheader(rmff_data_t *data, char *buffer)
{
if (!data) return; if (!data) return;
data->object_id=BE_32(&data->object_id); data->object_id=BE_32(&data->object_id);
data->size=BE_32(&data->size); data->size=BE_32(&data->size);
data->object_version=BE_16(&data->object_version); data->object_version=BE_16(&data->object_version);
...@@ -246,11 +247,12 @@ void rmff_dump_pheader(rmff_pheader_t *h, char *data) { ...@@ -246,11 +247,12 @@ void rmff_dump_pheader(rmff_pheader_t *h, char *data) {
data[11]=h->flags; data[11]=h->flags;
} }
rmff_fileheader_t *rmff_new_fileheader(uint32_t num_headers) { rmff_fileheader_t *rmff_new_fileheader(uint32_t num_headers)
{
rmff_fileheader_t *fileheader = malloc(sizeof(rmff_fileheader_t)); rmff_fileheader_t *fileheader = malloc(sizeof(rmff_fileheader_t));
memset(fileheader, 0, sizeof(rmff_fileheader_t)); if( !filehandler ) return NULL;
memset(fileheader, 0, sizeof(rmff_fileheader_t));
fileheader->object_id=RMF_TAG; fileheader->object_id=RMF_TAG;
fileheader->size=18; fileheader->size=18;
fileheader->object_version=0; fileheader->object_version=0;
...@@ -271,15 +273,15 @@ rmff_prop_t *rmff_new_prop ( ...@@ -271,15 +273,15 @@ rmff_prop_t *rmff_new_prop (
uint32_t index_offset, uint32_t index_offset,
uint32_t data_offset, uint32_t data_offset,
uint16_t num_streams, uint16_t num_streams,
uint16_t flags ) { uint16_t flags )
{
rmff_prop_t *prop = malloc(sizeof(rmff_prop_t)); rmff_prop_t *prop = malloc(sizeof(rmff_prop_t));
memset(prop, 0, sizeof(rmff_prop_t)); if( !prop ) return NULL;
memset(prop, 0, sizeof(rmff_prop_t));
prop->object_id=PROP_TAG; prop->object_id=PROP_TAG;
prop->size=50; prop->size=50;
prop->object_version=0; prop->object_version=0;
prop->max_bit_rate=max_bit_rate; prop->max_bit_rate=max_bit_rate;
prop->avg_bit_rate=avg_bit_rate; prop->avg_bit_rate=avg_bit_rate;
prop->max_packet_size=max_packet_size; prop->max_packet_size=max_packet_size;
...@@ -307,14 +309,14 @@ rmff_mdpr_t *rmff_new_mdpr( ...@@ -307,14 +309,14 @@ rmff_mdpr_t *rmff_new_mdpr(
const char *stream_name, const char *stream_name,
const char *mime_type, const char *mime_type,
uint32_t type_specific_len, uint32_t type_specific_len,
const char *type_specific_data ) { const char *type_specific_data )
{
rmff_mdpr_t *mdpr = malloc(sizeof(rmff_mdpr_t)); rmff_mdpr_t *mdpr = malloc(sizeof(rmff_mdpr_t));
memset(mdpr, 0, sizeof(rmff_mdpr_t)); if( !mdpr ) return NULL;
memset(mdpr, 0, sizeof(rmff_mdpr_t));
mdpr->object_id=MDPR_TAG; mdpr->object_id=MDPR_TAG;
mdpr->object_version=0; mdpr->object_version=0;
mdpr->stream_number=stream_number; mdpr->stream_number=stream_number;
mdpr->max_bit_rate=max_bit_rate; mdpr->max_bit_rate=max_bit_rate;
mdpr->avg_bit_rate=avg_bit_rate; mdpr->avg_bit_rate=avg_bit_rate;
...@@ -324,69 +326,79 @@ rmff_mdpr_t *rmff_new_mdpr( ...@@ -324,69 +326,79 @@ rmff_mdpr_t *rmff_new_mdpr(
mdpr->preroll=preroll; mdpr->preroll=preroll;
mdpr->duration=duration; mdpr->duration=duration;
mdpr->stream_name_size=0; mdpr->stream_name_size=0;
if (stream_name) { if (stream_name)
{
mdpr->stream_name=strdup(stream_name); mdpr->stream_name=strdup(stream_name);
mdpr->stream_name_size=strlen(stream_name); mdpr->stream_name_size=strlen(stream_name);
} }
mdpr->mime_type_size=0; mdpr->mime_type_size=0;
if (mime_type) { if (mime_type)
{
mdpr->mime_type=strdup(mime_type); mdpr->mime_type=strdup(mime_type);
mdpr->mime_type_size=strlen(mime_type); mdpr->mime_type_size=strlen(mime_type);
} }
mdpr->type_specific_len=type_specific_len; mdpr->type_specific_len=type_specific_len;
mdpr->type_specific_data = malloc(sizeof(char)*type_specific_len); mdpr->type_specific_data = malloc(sizeof(char)*type_specific_len);
if( !mdpr->type_specific_data )
{
if( mdpr->stream_name ) free( mdpr->stream_name );
free( mdpr );
return NULL;
}
memcpy(mdpr->type_specific_data,type_specific_data,type_specific_len); memcpy(mdpr->type_specific_data,type_specific_data,type_specific_len);
mdpr->mlti_data=NULL; mdpr->mlti_data=NULL;
mdpr->size=mdpr->stream_name_size+mdpr->mime_type_size+mdpr->type_specific_len+46; mdpr->size=mdpr->stream_name_size+mdpr->mime_type_size+mdpr->type_specific_len+46;
return mdpr; return mdpr;
} }
rmff_cont_t *rmff_new_cont(const char *title, const char *author, const char *copyright, const char *comment) { rmff_cont_t *rmff_new_cont(const char *title, const char *author, const char *copyright, const char *comment)
{
rmff_cont_t *cont = malloc(sizeof(rmff_cont_t)); rmff_cont_t *cont = malloc(sizeof(rmff_cont_t));
memset(cont, 0, sizeof(rmff_cont_t)); if( !cont ) return NULL;
memset(cont, 0, sizeof(rmff_cont_t));
cont->object_id=CONT_TAG; cont->object_id=CONT_TAG;
cont->object_version=0; cont->object_version=0;
cont->title=NULL; cont->title=NULL;
cont->author=NULL; cont->author=NULL;
cont->copyright=NULL; cont->copyright=NULL;
cont->comment=NULL; cont->comment=NULL;
cont->title_len=0; cont->title_len=0;
cont->author_len=0; cont->author_len=0;
cont->copyright_len=0; cont->copyright_len=0;
cont->comment_len=0; cont->comment_len=0;
if (title) { if (title)
{
cont->title_len=strlen(title); cont->title_len=strlen(title);
cont->title=strdup(title); cont->title=strdup(title);
} }
if (author) { if (author)
{
cont->author_len=strlen(author); cont->author_len=strlen(author);
cont->author=strdup(author); cont->author=strdup(author);
} }
if (copyright) { if (copyright)
{
cont->copyright_len=strlen(copyright); cont->copyright_len=strlen(copyright);
cont->copyright=strdup(copyright); cont->copyright=strdup(copyright);
} }
if (comment) { if (comment)
{
cont->comment_len=strlen(comment); cont->comment_len=strlen(comment);
cont->comment=strdup(comment); cont->comment=strdup(comment);
} }
cont->size=cont->title_len+cont->author_len+cont->copyright_len+cont->comment_len+18; cont->size=cont->title_len+cont->author_len+cont->copyright_len+cont->comment_len+18;
return cont; return cont;
} }
rmff_data_t *rmff_new_dataheader(uint32_t num_packets, uint32_t next_data_header) { rmff_data_t *rmff_new_dataheader(uint32_t num_packets, uint32_t next_data_header)
{
rmff_data_t *data = malloc(sizeof(rmff_data_t)); rmff_data_t *data = malloc(sizeof(rmff_data_t));
memset(data, 0, sizeof(rmff_data_t)); if( !data ) return NULL;
memset(data, 0, sizeof(rmff_data_t));
data->object_id=DATA_TAG; data->object_id=DATA_TAG;
data->size=18; data->size=18;
data->object_version=0; data->object_version=0;
...@@ -396,11 +408,12 @@ rmff_data_t *rmff_new_dataheader(uint32_t num_packets, uint32_t next_data_header ...@@ -396,11 +408,12 @@ rmff_data_t *rmff_new_dataheader(uint32_t num_packets, uint32_t next_data_header
return data; return data;
} }
void rmff_print_header(rmff_header_t *h) { void rmff_print_header(rmff_header_t *h)
{
rmff_mdpr_t **stream; rmff_mdpr_t **stream;
if(!h) { if(!h)
{
printf("rmff_print_header: NULL given\n"); printf("rmff_print_header: NULL given\n");
return; return;
} }
...@@ -460,21 +473,23 @@ void rmff_print_header(rmff_header_t *h) { ...@@ -460,21 +473,23 @@ void rmff_print_header(rmff_header_t *h) {
} }
} }
void rmff_fix_header(rmff_header_t *h) { void rmff_fix_header(rmff_header_t *h)
{
int num_headers=0; int num_headers=0;
int header_size=0; int header_size=0;
rmff_mdpr_t **streams; rmff_mdpr_t **streams;
int num_streams=0; int num_streams=0;
if (!h) { if (!h)
{
lprintf("rmff_fix_header: fatal: no header given.\n"); lprintf("rmff_fix_header: fatal: no header given.\n");
return; return;
} }
if (!h->streams)
if (!h->streams) { {
lprintf("rmff_fix_header: warning: no MDPR chunks\n"); lprintf("rmff_fix_header: warning: no MDPR chunks\n");
} else }
else
{ {
streams=h->streams; streams=h->streams;
while (*streams) while (*streams)
...@@ -485,35 +500,36 @@ void rmff_fix_header(rmff_header_t *h) { ...@@ -485,35 +500,36 @@ void rmff_fix_header(rmff_header_t *h) {
streams++; streams++;
} }
} }
if (h->prop)
if (h->prop) { {
if (h->prop->size != 50) if (h->prop->size != 50)
{ {
lprintf("rmff_fix_header: correcting prop.size from %i to %i\n", h->prop->size, 50); lprintf("rmff_fix_header: correcting prop.size from %i to %i\n", h->prop->size, 50);
h->prop->size=50; h->prop->size=50;
} }
if (h->prop->num_streams != num_streams) if (h->prop->num_streams != num_streams)
{ {
lprintf("rmff_fix_header: correcting prop.num_streams from %i to %i\n", h->prop->num_streams, num_streams); lprintf("rmff_fix_header: correcting prop.num_streams from %i to %i\n", h->prop->num_streams, num_streams);
h->prop->num_streams=num_streams; h->prop->num_streams=num_streams;
} }
num_headers++; num_headers++;
header_size+=50; header_size+=50;
} else }
lprintf("rmff_fix_header: warning: no PROP chunk.\n"); else lprintf("rmff_fix_header: warning: no PROP chunk.\n");
if (h->cont) { if (h->cont)
{
num_headers++; num_headers++;
header_size+=h->cont->size; header_size+=h->cont->size;
} else }
lprintf("rmff_fix_header: warning: no CONT chunk.\n"); else lprintf("rmff_fix_header: warning: no CONT chunk.\n");
if (!h->data) { if (!h->data)
{
lprintf("rmff_fix_header: no DATA chunk, creating one\n"); lprintf("rmff_fix_header: no DATA chunk, creating one\n");
h->data = malloc(sizeof(rmff_data_t)); h->data = malloc(sizeof(rmff_data_t));
if( h->data )
{
memset(h->data, 0, sizeof(rmff_data_t)); memset(h->data, 0, sizeof(rmff_data_t));
h->data->object_id=DATA_TAG; h->data->object_id=DATA_TAG;
h->data->object_version=0; h->data->object_version=0;
...@@ -521,13 +537,15 @@ void rmff_fix_header(rmff_header_t *h) { ...@@ -521,13 +537,15 @@ void rmff_fix_header(rmff_header_t *h) {
h->data->num_packets=0; h->data->num_packets=0;
h->data->next_data_header=0; h->data->next_data_header=0;
} }
}
num_headers++; num_headers++;
if (!h->fileheader)
if (!h->fileheader) { {
lprintf("rmff_fix_header: no fileheader, creating one"); lprintf("rmff_fix_header: no fileheader, creating one");
h->fileheader = malloc(sizeof(rmff_fileheader_t)); h->fileheader = malloc(sizeof(rmff_fileheader_t));
if( h->fileheader )
{
memset(h->fileheader, 0, sizeof(rmff_fileheader_t)); memset(h->fileheader, 0, sizeof(rmff_fileheader_t));
h->fileheader->object_id=RMF_TAG; h->fileheader->object_id=RMF_TAG;
h->fileheader->size=34; h->fileheader->size=34;
...@@ -535,51 +553,47 @@ void rmff_fix_header(rmff_header_t *h) { ...@@ -535,51 +553,47 @@ void rmff_fix_header(rmff_header_t *h) {
h->fileheader->file_version=0; h->fileheader->file_version=0;
h->fileheader->num_headers=num_headers+1; h->fileheader->num_headers=num_headers+1;
} }
}
header_size+=h->fileheader->size; header_size+=h->fileheader->size;
num_headers++; num_headers++;
if(h->fileheader->num_headers != num_headers) { if(h->fileheader->num_headers != num_headers)
{
lprintf("rmff_fix_header: setting num_headers from %i to %i\n", h->fileheader->num_headers, num_headers); lprintf("rmff_fix_header: setting num_headers from %i to %i\n", h->fileheader->num_headers, num_headers);
h->fileheader->num_headers=num_headers; h->fileheader->num_headers=num_headers;
} }
if(h->prop)
if(h->prop) { {
if (h->prop->data_offset != header_size) { if (h->prop->data_offset != header_size)
{
lprintf("rmff_fix_header: setting prop.data_offset from %i to %i\n", h->prop->data_offset, header_size); lprintf("rmff_fix_header: setting prop.data_offset from %i to %i\n", h->prop->data_offset, header_size);
h->prop->data_offset=header_size; h->prop->data_offset=header_size;
} }
if (h->prop->num_packets == 0) { if (h->prop->num_packets == 0)
{
int p=(int)(h->prop->avg_bit_rate/8.0*(h->prop->duration/1000.0)/h->prop->avg_packet_size); int p=(int)(h->prop->avg_bit_rate/8.0*(h->prop->duration/1000.0)/h->prop->avg_packet_size);
lprintf("rmff_fix_header: assuming prop.num_packets=%i\n", p); lprintf("rmff_fix_header: assuming prop.num_packets=%i\n", p);
h->prop->num_packets=p; h->prop->num_packets=p;
} }
if (h->data->num_packets == 0) { if (h->data->num_packets == 0)
{
lprintf("rmff_fix_header: assuming data.num_packets=%i\n", h->prop->num_packets); lprintf("rmff_fix_header: assuming data.num_packets=%i\n", h->prop->num_packets);
h->data->num_packets=h->prop->num_packets; h->data->num_packets=h->prop->num_packets;
} }
lprintf("rmff_fix_header: assuming data.size=%i\n", h->prop->num_packets*h->prop->avg_packet_size); lprintf("rmff_fix_header: assuming data.size=%i\n", h->prop->num_packets*h->prop->avg_packet_size);
h->data->size=h->prop->num_packets*h->prop->avg_packet_size; h->data->size=h->prop->num_packets*h->prop->avg_packet_size;
} }
} }
int rmff_get_header_size(rmff_header_t *h) { int rmff_get_header_size(rmff_header_t *h)
{
if (!h) return 0; if (!h) return 0;
if (!h->prop) return -1; if (!h->prop) return -1;
return h->prop->data_offset+18; return h->prop->data_offset+18;
} }
void rmff_free_header(rmff_header_t *h) { void rmff_free_header(rmff_header_t *h)
{
if (!h) return; if (!h) return;
if (h->fileheader) free(h->fileheader); if (h->fileheader) free(h->fileheader);
...@@ -597,7 +611,8 @@ void rmff_free_header(rmff_header_t *h) { ...@@ -597,7 +611,8 @@ void rmff_free_header(rmff_header_t *h) {
{ {
rmff_mdpr_t **s=h->streams; rmff_mdpr_t **s=h->streams;
while(*s) { while(*s)
{
free((*s)->stream_name); free((*s)->stream_name);
free((*s)->mime_type); free((*s)->mime_type);
free((*s)->type_specific_data); free((*s)->type_specific_data);
......
...@@ -82,7 +82,6 @@ typedef struct { ...@@ -82,7 +82,6 @@ typedef struct {
uint32_t data_offset; uint32_t data_offset;
uint16_t num_streams; uint16_t num_streams;
uint16_t flags; uint16_t flags;
} rmff_prop_t; } rmff_prop_t;
typedef struct { typedef struct {
......
...@@ -51,16 +51,17 @@ static char *b64_decode(const char *in, char *out, int *size) ...@@ -51,16 +51,17 @@ static char *b64_decode(const char *in, char *out, int *size)
dtable['='] = 0; dtable['='] = 0;
k=0; k=0;
/*CONSTANTCONDITION*/ /*CONSTANTCONDITION*/
for (j=0; j<strlen(in); j+=4) for (j=0; j<strlen(in); j+=4)
{ {
char a[4], b[4]; char a[4], b[4];
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++)
{
int c = in[i+j]; int c = in[i+j];
if (dtable[c] & 0x80) { if (dtable[c] & 0x80)
{
printf("Illegal character '%c' in input.\n", c); printf("Illegal character '%c' in input.\n", c);
exit(1); exit(1);
} }
...@@ -72,7 +73,8 @@ static char *b64_decode(const char *in, char *out, int *size) ...@@ -72,7 +73,8 @@ static char *b64_decode(const char *in, char *out, int *size)
out[k++] = (b[1] << 4) | (b[2] >> 2); out[k++] = (b[1] << 4) | (b[2] >> 2);
out[k++] = (b[2] << 6) | b[3]; out[k++] = (b[2] << 6) | b[3];
i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3); i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3);
if (i < 3) { if (i < 3)
{
out[k]=0; out[k]=0;
*size=k; *size=k;
return out; return out;
...@@ -83,14 +85,14 @@ static char *b64_decode(const char *in, char *out, int *size) ...@@ -83,14 +85,14 @@ static char *b64_decode(const char *in, char *out, int *size)
return out; return out;
} }
static char *nl(char *data) { static char *nl(char *data)
{
char *nlptr = (data) ? strchr(data,'\n') : NULL; char *nlptr = (data) ? strchr(data,'\n') : NULL;
return (nlptr) ? nlptr + 1 : NULL; return (nlptr) ? nlptr + 1 : NULL;
} }
static int filter(const char *in, const char *filter, char **out) { static int filter(const char *in, const char *filter, char **out)
{
int flen=strlen(filter); int flen=strlen(filter);
int len; int len;
...@@ -98,7 +100,6 @@ static int filter(const char *in, const char *filter, char **out) { ...@@ -98,7 +100,6 @@ static int filter(const char *in, const char *filter, char **out) {
return 0; return 0;
len = (strchr(in,'\n')) ? strchr(in,'\n')-in : strlen(in); len = (strchr(in,'\n')) ? strchr(in,'\n')-in : strlen(in);
if (!strncmp(in,filter,flen)) if (!strncmp(in,filter,flen))
{ {
if(in[flen]=='"') flen++; if(in[flen]=='"') flen++;
...@@ -106,91 +107,96 @@ static int filter(const char *in, const char *filter, char **out) { ...@@ -106,91 +107,96 @@ static int filter(const char *in, const char *filter, char **out) {
if(in[len-1]=='"') len--; if(in[len-1]=='"') len--;
memcpy(*out, in+flen, len-flen+1); memcpy(*out, in+flen, len-flen+1);
(*out)[len-flen]=0; (*out)[len-flen]=0;
return len-flen; return len-flen;
} }
return 0; return 0;
} }
static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
static sdpplin_stream_t *sdpplin_parse_stream(char **data)
{
sdpplin_stream_t *desc = malloc(sizeof(sdpplin_stream_t)); sdpplin_stream_t *desc = malloc(sizeof(sdpplin_stream_t));
char *buf=malloc(32000); char *buf = malloc(32000);
char *decoded=malloc(32000); char *decoded = malloc(32000);
int handled; int handled;
if( !desc ) goto error;
memset(desc, 0, sizeof(sdpplin_stream_t)); memset(desc, 0, sizeof(sdpplin_stream_t));
if (filter(*data, "m=", &buf)) { if (filter(*data, "m=", &buf))
{
desc->id = strdup(buf); desc->id = strdup(buf);
} else }
else
{ {
lprintf("sdpplin: no m= found.\n"); lprintf("sdpplin: no m= found.\n");
free(desc); if( decoded ) free(decoded);
free(buf); if( desc ) free( desc );
if( buf ) free( buf );
return NULL; return NULL;
} }
*data=nl(*data); *data=nl(*data);
while (*data && **data && *data[0]!='m') { while (*data && **data && *data[0]!='m')
{
handled=0; handled=0;
if(filter(*data,"a=control:streamid=",&buf)) { if(filter(*data,"a=control:streamid=",&buf))
{
desc->stream_id=atoi(buf); desc->stream_id=atoi(buf);
handled=1; handled=1;
*data=nl(*data); *data=nl(*data);
} }
if(filter(*data,"a=MaxBitRate:integer;",&buf))
if(filter(*data,"a=MaxBitRate:integer;",&buf)) { {
desc->max_bit_rate=atoi(buf); desc->max_bit_rate=atoi(buf);
if (!desc->avg_bit_rate) if (!desc->avg_bit_rate)
desc->avg_bit_rate=desc->max_bit_rate; desc->avg_bit_rate=desc->max_bit_rate;
handled=1; handled=1;
*data=nl(*data); *data=nl(*data);
} }
if(filter(*data,"a=MaxPacketSize:integer;",&buf))
if(filter(*data,"a=MaxPacketSize:integer;",&buf)) { {
desc->max_packet_size=atoi(buf); desc->max_packet_size=atoi(buf);
if (!desc->avg_packet_size) if (!desc->avg_packet_size)
desc->avg_packet_size=desc->max_packet_size; desc->avg_packet_size=desc->max_packet_size;
handled=1; handled=1;
*data=nl(*data); *data=nl(*data);
} }
if(filter(*data,"a=StartTime:integer;",&buf))
if(filter(*data,"a=StartTime:integer;",&buf)) { {
desc->start_time=atoi(buf); desc->start_time=atoi(buf);
handled=1; handled=1;
*data=nl(*data); *data=nl(*data);
} }
if(filter(*data,"a=Preroll:integer;",&buf))
if(filter(*data,"a=Preroll:integer;",&buf)) { {
desc->preroll=atoi(buf); desc->preroll=atoi(buf);
handled=1; handled=1;
*data=nl(*data); *data=nl(*data);
} }
if(filter(*data,"a=length:npt=",&buf))
if(filter(*data,"a=length:npt=",&buf)) { {
desc->duration=(uint32_t)(atof(buf)*1000); desc->duration=(uint32_t)(atof(buf)*1000);
handled=1; handled=1;
*data=nl(*data); *data=nl(*data);
} }
if(filter(*data,"a=StreamName:string;",&buf))
if(filter(*data,"a=StreamName:string;",&buf)) { {
desc->stream_name=strdup(buf); desc->stream_name=strdup(buf);
desc->stream_name_size=strlen(desc->stream_name); desc->stream_name_size=strlen(desc->stream_name);
handled=1; handled=1;
*data=nl(*data); *data=nl(*data);
} }
if(filter(*data,"a=mimetype:string;",&buf))
if(filter(*data,"a=mimetype:string;",&buf)) { {
desc->mime_type=strdup(buf); desc->mime_type=strdup(buf);
desc->mime_type_size=strlen(desc->mime_type); desc->mime_type_size=strlen(desc->mime_type);
handled=1; handled=1;
*data=nl(*data); *data=nl(*data);
} }
if(filter(*data,"a=OpaqueData:buffer;",&buf))
if(filter(*data,"a=OpaqueData:buffer;",&buf)) { {
decoded = b64_decode(buf, decoded, &(desc->mlti_data_size)); decoded = b64_decode(buf, decoded, &(desc->mlti_data_size));
desc->mlti_data = malloc(sizeof(char)*desc->mlti_data_size); desc->mlti_data = malloc(sizeof(char)*desc->mlti_data_size);
memcpy(desc->mlti_data, decoded, desc->mlti_data_size); memcpy(desc->mlti_data, decoded, desc->mlti_data_size);
...@@ -198,14 +204,15 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) { ...@@ -198,14 +204,15 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
*data=nl(*data); *data=nl(*data);
lprintf("mlti_data_size: %i\n", desc->mlti_data_size); lprintf("mlti_data_size: %i\n", desc->mlti_data_size);
} }
if(filter(*data,"a=ASMRuleBook:string;",&buf))
if(filter(*data,"a=ASMRuleBook:string;",&buf)) { {
desc->asm_rule_book=strdup(buf); desc->asm_rule_book=strdup(buf);
handled=1; handled=1;
*data=nl(*data); *data=nl(*data);
} }
if(!handled) { if(!handled)
{
#ifdef LOG #ifdef LOG
int len=strchr(*data,'\n')-(*data); int len=strchr(*data,'\n')-(*data);
memcpy(buf, *data, len+1); memcpy(buf, *data, len+1);
...@@ -215,15 +222,13 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) { ...@@ -215,15 +222,13 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
*data=nl(*data); *data=nl(*data);
} }
} }
if( buf ) free(buf);
free(buf); if( decoded )free(decoded);
free(decoded);
return desc; return desc;
} }
sdpplin_t *sdpplin_parse(char *data) { sdpplin_t *sdpplin_parse(char *data)
{
sdpplin_t *desc = malloc(sizeof(sdpplin_t)); sdpplin_t *desc = malloc(sizeof(sdpplin_t));
sdpplin_stream_t *stream; sdpplin_stream_t *stream;
char *buf=malloc(3200); char *buf=malloc(3200);
...@@ -231,61 +236,75 @@ sdpplin_t *sdpplin_parse(char *data) { ...@@ -231,61 +236,75 @@ sdpplin_t *sdpplin_parse(char *data) {
int handled; int handled;
int len; int len;
if( !desc ) return NULL;
if( !buf )
{
free( desc );
return NULL;
}
if( !decoded )
{
free( buf );
free( desc );
return NULL;
}
memset(desc, 0, sizeof(sdpplin_t)); memset(desc, 0, sizeof(sdpplin_t));
while (data && *data) { while (data && *data)
{
handled=0; handled=0;
if (filter(data, "m=", &buf)) { if (filter(data, "m=", &buf))
{
stream=sdpplin_parse_stream(&data); stream=sdpplin_parse_stream(&data);
lprintf("got data for stream id %u\n", stream->stream_id); lprintf("got data for stream id %u\n", stream->stream_id);
desc->stream[stream->stream_id]=stream; desc->stream[stream->stream_id]=stream;
continue; continue;
} }
if(filter(data,"a=Title:buffer;",&buf))
if(filter(data,"a=Title:buffer;",&buf)) { {
decoded=b64_decode(buf, decoded, &len); decoded=b64_decode(buf, decoded, &len);
desc->title=strdup(decoded); desc->title=strdup(decoded);
handled=1; handled=1;
data=nl(data); data=nl(data);
} }
if(filter(data,"a=Author:buffer;",&buf))
if(filter(data,"a=Author:buffer;",&buf)) { {
decoded=b64_decode(buf, decoded, &len); decoded=b64_decode(buf, decoded, &len);
desc->author=strdup(decoded); desc->author=strdup(decoded);
handled=1; handled=1;
data=nl(data); data=nl(data);
} }
if(filter(data,"a=Copyright:buffer;",&buf))
if(filter(data,"a=Copyright:buffer;",&buf)) { {
decoded=b64_decode(buf, decoded, &len); decoded=b64_decode(buf, decoded, &len);
desc->copyright=strdup(decoded); desc->copyright=strdup(decoded);
handled=1; handled=1;
data=nl(data); data=nl(data);
} }
if(filter(data,"a=Abstract:buffer;",&buf))
if(filter(data,"a=Abstract:buffer;",&buf)) { {
decoded=b64_decode(buf, decoded, &len); decoded=b64_decode(buf, decoded, &len);
desc->abstract=strdup(decoded); desc->abstract=strdup(decoded);
handled=1; handled=1;
data=nl(data); data=nl(data);
} }
if(filter(data,"a=StreamCount:integer;",&buf))
if(filter(data,"a=StreamCount:integer;",&buf)) { {
desc->stream_count=atoi(buf); desc->stream_count=atoi(buf);
desc->stream = malloc(sizeof(sdpplin_stream_t*)*desc->stream_count); desc->stream = malloc(sizeof(sdpplin_stream_t*)*desc->stream_count);
handled=1; handled=1;
data=nl(data); data=nl(data);
} }
if(filter(data,"a=Flags:integer;",&buf))
if(filter(data,"a=Flags:integer;",&buf)) { {
desc->flags=atoi(buf); desc->flags=atoi(buf);
handled=1; handled=1;
data=nl(data); data=nl(data);
} }
if(!handled) { if(!handled)
{
#ifdef LOG #ifdef LOG
int len=strchr(data,'\n')-data; int len=strchr(data,'\n')-data;
memcpy(buf, data, len+1); memcpy(buf, data, len+1);
...@@ -296,15 +315,13 @@ sdpplin_t *sdpplin_parse(char *data) { ...@@ -296,15 +315,13 @@ sdpplin_t *sdpplin_parse(char *data) {
} }
} }
free(buf);
free(decoded); free(decoded);
free(buf);
return desc; return desc;
} }
void sdpplin_free(sdpplin_t *description) { void sdpplin_free(sdpplin_t *description)
{
/* TODO: free strings */ /* TODO: free strings */
free(description); free(description);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment