M4Err SDP_Write(SDPInfo *sdp, char **out_str_buf) { char *buf; SDP_FMTP *fmtp; char temp[50]; SDPMedia *media; SDPBandwidth *bw; u32 buf_size, pos, i, j, k; SDP_RTPMap *map; SDPConnection *conn; M4Err e; SDPTiming *timing; X_Attribute *att; e = SDP_CheckInfo(sdp); if (e) return e; buf = malloc(SDP_WRITE_STEPALLOC); buf_size = SDP_WRITE_STEPALLOC; pos = 0; //v SDP_WRITE_ALLOC_STR("v=", 0); SDP_WRITE_ALLOC_INT(sdp->Version, 0, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); //o SDP_WRITE_ALLOC_STR("o=", 0); SDP_WRITE_ALLOC_STR(sdp->o_username, 1); SDP_WRITE_ALLOC_STR(sdp->o_session_id, 1); SDP_WRITE_ALLOC_STR(sdp->o_version, 1); SDP_WRITE_ALLOC_STR(sdp->o_net_type, 1); SDP_WRITE_ALLOC_STR(sdp->o_add_type, 1); SDP_WRITE_ALLOC_STR(sdp->o_address, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); //s TEST_SDP_WRITE_SINGLE("s=", sdp->s_session_name, 0); //i TEST_SDP_WRITE_SINGLE("i=", sdp->i_description, 0); //u TEST_SDP_WRITE_SINGLE("u=", sdp->u_uri, 0); //e TEST_SDP_WRITE_SINGLE("e=", sdp->e_email, 0); //p TEST_SDP_WRITE_SINGLE("p=", sdp->p_phone, 0); //c SDP_WRITE_CONN(sdp->c_connection); //b for (i=0; i<ChainGetCount(sdp->b_bandwidth); i++) { bw = ChainGetEntry(sdp->b_bandwidth, i); SDP_WRITE_ALLOC_STR("b=", 0); SDP_WRITE_ALLOC_STR(bw->name, 0); SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_INT(bw->value, 0, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); } //t+r+z for (i=0; i<ChainGetCount(sdp->Timing); i++) { timing = ChainGetEntry(sdp->Timing, i); if (timing->NbRepeatOffsets > SDP_MAX_TIMEOFFSET) timing->NbRepeatOffsets = SDP_MAX_TIMEOFFSET; if (timing->NbZoneOffsets > SDP_MAX_TIMEOFFSET) timing->NbZoneOffsets = SDP_MAX_TIMEOFFSET; //t SDP_WRITE_ALLOC_STR("t=", 0); SDP_WRITE_ALLOC_INT(timing->StartTime, 1, 0); SDP_WRITE_ALLOC_INT(timing->StopTime, 0, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); if (timing->NbRepeatOffsets) { SDP_WRITE_ALLOC_STR("r=", 0); SDP_WRITE_ALLOC_INT(timing->RepeatInterval, 1, 0); SDP_WRITE_ALLOC_INT(timing->ActiveDuration, 0, 0); for (j=0; j<timing->NbRepeatOffsets; j++) { SDP_WRITE_ALLOC_STR(" ", 0); SDP_WRITE_ALLOC_INT(timing->OffsetFromStart[j], 0, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); } if (timing->NbZoneOffsets) { SDP_WRITE_ALLOC_STR("z=", 0); for (j=0; j<timing->NbZoneOffsets; j++) { SDP_WRITE_ALLOC_INT(timing->AdjustmentTime[j], 1, 0); if (j+1 == timing->NbRepeatOffsets) { SDP_WRITE_ALLOC_INT(timing->AdjustmentOffset[j], 0, 1); } else { SDP_WRITE_ALLOC_INT(timing->AdjustmentOffset[j], 1, 1); } } SDP_WRITE_ALLOC_STR("\r\n", 0); } } //k if (sdp->k_method) { SDP_WRITE_ALLOC_STR("k=", 0); SDP_WRITE_ALLOC_STR(sdp->k_method, 0); if (sdp->k_key) { SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_STR(sdp->k_key, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); } //a=cat TEST_SDP_WRITE_SINGLE("a=cat", sdp->a_cat, 1); //a=keywds TEST_SDP_WRITE_SINGLE("a=keywds", sdp->a_keywds, 1); //a=tool TEST_SDP_WRITE_SINGLE("a=tool", sdp->a_tool, 1); //a=SendRecv switch (sdp->a_SendRecieve) { case 1: TEST_SDP_WRITE_SINGLE("a=", "recvonly", 0); break; case 2: TEST_SDP_WRITE_SINGLE("a=", "sendonly", 0); break; case 3: TEST_SDP_WRITE_SINGLE("a=", "sendrecv", 0); break; default: break; } //a=type TEST_SDP_WRITE_SINGLE("a=type", sdp->a_type, 1); //a=charset TEST_SDP_WRITE_SINGLE("a=charset", sdp->a_charset, 1); //a=sdplang TEST_SDP_WRITE_SINGLE("a=sdplang", sdp->a_sdplang, 1); //a=lang TEST_SDP_WRITE_SINGLE("a=lang", sdp->a_lang, 1); //the rest for (i=0; i<ChainGetCount(sdp->Attributes); i++) { att = ChainGetEntry(sdp->Attributes, i); SDP_WRITE_ALLOC_STR("a=", 0); SDP_WRITE_ALLOC_STR(att->Name, 0); if (att->Value) { SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_STR(att->Value, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); } //now write media specific for (i=0; i<ChainGetCount(sdp->media_desc); i++) { media = ChainGetEntry(sdp->media_desc, i); //m= SDP_WRITE_ALLOC_STR("m=", 0); switch (media->Type) { case 1: SDP_WRITE_ALLOC_STR("video", 1); break; case 2: SDP_WRITE_ALLOC_STR("audio", 1); break; case 3: SDP_WRITE_ALLOC_STR("data", 1); break; case 4: SDP_WRITE_ALLOC_STR("control", 1); break; default: SDP_WRITE_ALLOC_STR("application", 1); break; } SDP_WRITE_ALLOC_INT(media->PortNumber, 0, 0); if (media->NumPorts >= 2) { SDP_WRITE_ALLOC_STR("/", 0); SDP_WRITE_ALLOC_INT(media->NumPorts, 1, 0); } else { SDP_WRITE_ALLOC_STR(" ", 0); } SDP_WRITE_ALLOC_STR(media->Profile, 1); SDP_WRITE_ALLOC_STR(media->fmt_list, 0); for (j=0;j<ChainGetCount(media->RTPMaps); j++) { map = ChainGetEntry(media->RTPMaps, j); SDP_WRITE_ALLOC_STR(" ", 0); SDP_WRITE_ALLOC_INT(map->PayloadType, 0, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); //c= for (j=0; j<ChainGetCount(media->Connections); j++) { conn = ChainGetEntry(media->Connections, j); SDP_WRITE_CONN(conn); } //k= if (media->k_method) { SDP_WRITE_ALLOC_STR("k=", 0); SDP_WRITE_ALLOC_STR(media->k_method, 0); if (media->k_key) { SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_STR(media->k_key, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); } //b for (j=0; j<ChainGetCount(media->Bandwidths); j++) { bw = ChainGetEntry(media->Bandwidths, j); SDP_WRITE_ALLOC_STR("b=", 0); SDP_WRITE_ALLOC_STR(bw->name, 0); SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_INT(bw->value, 0, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); } //a=rtpmap for (j=0; j<ChainGetCount(media->RTPMaps); j++) { map = ChainGetEntry(media->RTPMaps, j); SDP_WRITE_ALLOC_STR("a=rtpmap", 0); SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_INT(map->PayloadType, 1, 0); SDP_WRITE_ALLOC_STR(map->payload_name, 0); SDP_WRITE_ALLOC_STR("/", 0); SDP_WRITE_ALLOC_INT(map->ClockRate, 0, 0); if (map->AudioChannels > 1) { SDP_WRITE_ALLOC_STR("/", 0); SDP_WRITE_ALLOC_INT(map->AudioChannels, 0, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); } //a=fmtp for (j=0; j<ChainGetCount(media->FMTP); j++) { fmtp = ChainGetEntry(media->FMTP, j); SDP_WRITE_ALLOC_STR("a=fmtp:", 0); SDP_WRITE_ALLOC_INT(fmtp->PayloadType, 1 , 0); for (k=0; k<ChainGetCount(fmtp->Attributes); k++) { if (k) SDP_WRITE_ALLOC_STR(";", 0); att = ChainGetEntry(fmtp->Attributes, k); SDP_WRITE_ALLOC_STR(att->Name, 0); if (att->Value) { SDP_WRITE_ALLOC_STR("=", 0); SDP_WRITE_ALLOC_STR(att->Value, 0); } } SDP_WRITE_ALLOC_STR("\r\n", 0); } //a=ptime if (media->PacketTime) { SDP_WRITE_ALLOC_STR("a=ptime:", 0); SDP_WRITE_ALLOC_INT(media->PacketTime, 0, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); } //a=FrameRate if (media->Type == 1 && media->FrameRate) { SDP_WRITE_ALLOC_STR("a=framerate:", 0); SDP_WRITE_ALLOC_FLOAT(media->FrameRate, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); } //a=SendRecv switch (media->SendRecieve) { case 1: TEST_SDP_WRITE_SINGLE("a=", "recvonly", 0); break; case 2: TEST_SDP_WRITE_SINGLE("a=", "sendonly", 0); break; case 3: TEST_SDP_WRITE_SINGLE("a=", "sendrecv", 0); break; default: break; } //a=orient TEST_SDP_WRITE_SINGLE("a=orient", media->orientation, 1); //a=sdplang TEST_SDP_WRITE_SINGLE("a=sdplang", media->sdplang, 1); //a=lang TEST_SDP_WRITE_SINGLE("a=lang", media->lang, 1); //a=quality if (media->Quality >= 0) { SDP_WRITE_ALLOC_STR("a=quality:", 0); SDP_WRITE_ALLOC_INT(media->Quality, 0, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); } //the rest for (j=0; j<ChainGetCount(media->Attributes); j++) { att = ChainGetEntry(media->Attributes, j); SDP_WRITE_ALLOC_STR("a=", 0); SDP_WRITE_ALLOC_STR(att->Name, 0); if (att->Value) { SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_STR(att->Value, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); } } //finally realloc //finall NULL char pos += 1; buf = realloc(buf, pos); *out_str_buf = buf; return M4OK; }
GF_EXPORT GF_Err gf_sdp_info_write(GF_SDPInfo *sdp, char **out_str_buf) { char *buf; GF_SDP_FMTP *fmtp; char temp[50]; GF_SDPMedia *media; GF_SDPBandwidth *bw; u32 buf_size, pos, i, j, k; GF_RTPMap *map; GF_SDPConnection *conn; GF_Err e; GF_SDPTiming *timing; GF_X_Attribute *att; e = gf_sdp_info_check(sdp); if (e) return e; buf = (char *)gf_malloc(SDP_WRITE_STEPALLOC); buf_size = SDP_WRITE_STEPALLOC; pos = 0; //v SDP_WRITE_ALLOC_STR("v=", 0); SDP_WRITE_ALLOC_INT(sdp->Version, 0, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); //o SDP_WRITE_ALLOC_STR("o=", 0); SDP_WRITE_ALLOC_STR(sdp->o_username, 1); SDP_WRITE_ALLOC_STR(sdp->o_session_id, 1); SDP_WRITE_ALLOC_STR(sdp->o_version, 1); SDP_WRITE_ALLOC_STR(sdp->o_net_type, 1); SDP_WRITE_ALLOC_STR(sdp->o_add_type, 1); SDP_WRITE_ALLOC_STR(sdp->o_address, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); //s TEST_SDP_WRITE_SINGLE("s=", sdp->s_session_name, 0); //i TEST_SDP_WRITE_SINGLE("i=", sdp->i_description, 0); //u TEST_SDP_WRITE_SINGLE("u=", sdp->u_uri, 0); //e TEST_SDP_WRITE_SINGLE("e=", sdp->e_email, 0); //p TEST_SDP_WRITE_SINGLE("p=", sdp->p_phone, 0); //c SDP_WRITE_CONN(sdp->c_connection); //b i=0; while ((bw = (GF_SDPBandwidth*)gf_list_enum(sdp->b_bandwidth, &i))) { SDP_WRITE_ALLOC_STR("b=", 0); SDP_WRITE_ALLOC_STR(bw->name, 0); SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_INT(bw->value, 0, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); } //t+r+z i=0; while ((timing = (GF_SDPTiming*)gf_list_enum(sdp->Timing, &i))) { if (timing->NbRepeatOffsets > GF_SDP_MAX_TIMEOFFSET) timing->NbRepeatOffsets = GF_SDP_MAX_TIMEOFFSET; if (timing->NbZoneOffsets > GF_SDP_MAX_TIMEOFFSET) timing->NbZoneOffsets = GF_SDP_MAX_TIMEOFFSET; //t SDP_WRITE_ALLOC_STR("t=", 0); SDP_WRITE_ALLOC_INT(timing->StartTime, 1, 0); SDP_WRITE_ALLOC_INT(timing->StopTime, 0, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); if (timing->NbRepeatOffsets) { SDP_WRITE_ALLOC_STR("r=", 0); SDP_WRITE_ALLOC_INT(timing->RepeatInterval, 1, 0); SDP_WRITE_ALLOC_INT(timing->ActiveDuration, 0, 0); for (j=0; j<timing->NbRepeatOffsets; j++) { SDP_WRITE_ALLOC_STR(" ", 0); SDP_WRITE_ALLOC_INT(timing->OffsetFromStart[j], 0, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); } if (timing->NbZoneOffsets) { SDP_WRITE_ALLOC_STR("z=", 0); for (j=0; j<timing->NbZoneOffsets; j++) { SDP_WRITE_ALLOC_INT(timing->AdjustmentTime[j], 1, 0); if (j+1 == timing->NbRepeatOffsets) { SDP_WRITE_ALLOC_INT(timing->AdjustmentOffset[j], 0, 1); } else { SDP_WRITE_ALLOC_INT(timing->AdjustmentOffset[j], 1, 1); } } SDP_WRITE_ALLOC_STR("\r\n", 0); } } //k if (sdp->k_method) { SDP_WRITE_ALLOC_STR("k=", 0); SDP_WRITE_ALLOC_STR(sdp->k_method, 0); if (sdp->k_key) { SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_STR(sdp->k_key, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); } //a=cat TEST_SDP_WRITE_SINGLE("a=cat", sdp->a_cat, 1); //a=keywds TEST_SDP_WRITE_SINGLE("a=keywds", sdp->a_keywds, 1); //a=tool TEST_SDP_WRITE_SINGLE("a=tool", sdp->a_tool, 1); //a=SendRecv switch (sdp->a_SendReceive) { case 1: TEST_SDP_WRITE_SINGLE("a=", "recvonly", 0); break; case 2: TEST_SDP_WRITE_SINGLE("a=", "sendonly", 0); break; case 3: TEST_SDP_WRITE_SINGLE("a=", "sendrecv", 0); break; default: break; } //a=type TEST_SDP_WRITE_SINGLE("a=type", sdp->a_type, 1); //a=charset TEST_SDP_WRITE_SINGLE("a=charset", sdp->a_charset, 1); //a=sdplang TEST_SDP_WRITE_SINGLE("a=sdplang", sdp->a_sdplang, 1); //a=lang TEST_SDP_WRITE_SINGLE("a=lang", sdp->a_lang, 1); //the rest i=0; while ((att = (GF_X_Attribute*)gf_list_enum(sdp->Attributes, &i))) { SDP_WRITE_ALLOC_STR("a=", 0); SDP_WRITE_ALLOC_STR(att->Name, 0); if (att->Value) { SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_STR(att->Value, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); } //now write media specific i=0; while ((media = (GF_SDPMedia*)gf_list_enum(sdp->media_desc, &i))) { //m= SDP_WRITE_ALLOC_STR("m=", 0); switch (media->Type) { case 1: SDP_WRITE_ALLOC_STR("video", 1); break; case 2: SDP_WRITE_ALLOC_STR("audio", 1); break; case 3: SDP_WRITE_ALLOC_STR("data", 1); break; case 4: SDP_WRITE_ALLOC_STR("control", 1); break; default: SDP_WRITE_ALLOC_STR("application", 1); break; } SDP_WRITE_ALLOC_INT(media->PortNumber, 0, 0); if (media->NumPorts >= 2) { SDP_WRITE_ALLOC_STR("/", 0); SDP_WRITE_ALLOC_INT(media->NumPorts, 1, 0); } else { SDP_WRITE_ALLOC_STR(" ", 0); } SDP_WRITE_ALLOC_STR(media->Profile, 1); SDP_WRITE_ALLOC_STR(media->fmt_list, 0); j=0; while ((map = (GF_RTPMap*)gf_list_enum(media->RTPMaps, &j))) { SDP_WRITE_ALLOC_STR(" ", 0); SDP_WRITE_ALLOC_INT(map->PayloadType, 0, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); //c= j=0; while ((conn = (GF_SDPConnection*)gf_list_enum(media->Connections, &j))) { SDP_WRITE_CONN(conn); } //k= if (media->k_method) { SDP_WRITE_ALLOC_STR("k=", 0); SDP_WRITE_ALLOC_STR(media->k_method, 0); if (media->k_key) { SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_STR(media->k_key, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); } //b j=0; while ((bw = (GF_SDPBandwidth*)gf_list_enum(media->Bandwidths, &j))) { SDP_WRITE_ALLOC_STR("b=", 0); SDP_WRITE_ALLOC_STR(bw->name, 0); SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_INT(bw->value, 0, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); } //a=rtpmap j=0; while ((map = (GF_RTPMap*)gf_list_enum(media->RTPMaps, &j))) { SDP_WRITE_ALLOC_STR("a=rtpmap", 0); SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_INT(map->PayloadType, 1, 0); SDP_WRITE_ALLOC_STR(map->payload_name, 0); SDP_WRITE_ALLOC_STR("/", 0); SDP_WRITE_ALLOC_INT(map->ClockRate, 0, 0); if (map->AudioChannels > 1) { SDP_WRITE_ALLOC_STR("/", 0); SDP_WRITE_ALLOC_INT(map->AudioChannels, 0, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); } //a=fmtp j=0; while ((fmtp = (GF_SDP_FMTP*)gf_list_enum(media->FMTP, &j))) { SDP_WRITE_ALLOC_STR("a=fmtp:", 0); SDP_WRITE_ALLOC_INT(fmtp->PayloadType, 1 , 0); k=0; while ((att = (GF_X_Attribute*)gf_list_enum(fmtp->Attributes, &k)) ) { if (k>1) SDP_WRITE_ALLOC_STR(";", 0); SDP_WRITE_ALLOC_STR(att->Name, 0); if (att->Value) { SDP_WRITE_ALLOC_STR("=", 0); SDP_WRITE_ALLOC_STR(att->Value, 0); } } SDP_WRITE_ALLOC_STR("\r\n", 0); } //a=ptime if (media->PacketTime) { SDP_WRITE_ALLOC_STR("a=ptime:", 0); SDP_WRITE_ALLOC_INT(media->PacketTime, 0, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); } //a=FrameRate if (media->Type == 1 && media->FrameRate) { SDP_WRITE_ALLOC_STR("a=framerate:", 0); SDP_WRITE_ALLOC_FLOAT(media->FrameRate, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); } //a=SendRecv switch (media->SendReceive) { case 1: TEST_SDP_WRITE_SINGLE("a=", "recvonly", 0); break; case 2: TEST_SDP_WRITE_SINGLE("a=", "sendonly", 0); break; case 3: TEST_SDP_WRITE_SINGLE("a=", "sendrecv", 0); break; default: break; } //a=orient TEST_SDP_WRITE_SINGLE("a=orient", media->orientation, 1); //a=sdplang TEST_SDP_WRITE_SINGLE("a=sdplang", media->sdplang, 1); //a=lang TEST_SDP_WRITE_SINGLE("a=lang", media->lang, 1); //a=quality if (media->Quality >= 0) { SDP_WRITE_ALLOC_STR("a=quality:", 0); SDP_WRITE_ALLOC_INT(media->Quality, 0, 0); SDP_WRITE_ALLOC_STR("\r\n", 0); } //the rest j=0; while ((att = (GF_X_Attribute*)gf_list_enum(media->Attributes, &j))) { SDP_WRITE_ALLOC_STR("a=", 0); SDP_WRITE_ALLOC_STR(att->Name, 0); if (att->Value) { SDP_WRITE_ALLOC_STR(":", 0); SDP_WRITE_ALLOC_STR(att->Value, 0); } SDP_WRITE_ALLOC_STR("\r\n", 0); } } //finally gf_realloc //finall NULL char pos += 1; buf = (char *)gf_realloc(buf, pos); *out_str_buf = buf; return GF_OK; }