rtp_payload_type.c

Go to the documentation of this file.
00001 /* * 
00002  * This file is part of libnemesi
00003  *
00004  * Copyright (C) 2007 by LScube team <team@streaming.polito.it>
00005  * See AUTHORS for more details
00006  * 
00007  * libnemesi is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * libnemesi is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with libnemesi; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  *  
00021  * */
00022 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 
00031 #include "utils.h"
00032 #include "comm.h"
00033 #include "rtp.h"
00034 #include "parsers/rtpparsers.h"
00035 #include "rtpptdefs.h"
00036 
00037 // definitions of known payload types specified in RFC 3551
00038 
00039 /* pt  0 */ static rtp_audio pcmu =
00040 { "PCMU", AU, 8000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00041 
00042 #if 0
00043     /* we do not define reserved, unassigned or dynamic pt,
00044      * just initialize this position to NULL in rtpptdefs array */
00045                                                 /* pt  1 */ static rtp_audio res_au =
00046 { "res", AU, RTP_PT_ATTRS_INITIALIZER, NULL, 0 };
00047 
00048                                                 // pt 1,2,19
00049 #endif
00050 /* pt  2 = res_au (reserved audio) */
00051 /* pt  3 */ static rtp_audio gsm =
00052 { "GSM", AU, 8000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00053 /* pt  4 */ static rtp_audio g723 =
00054 { "G723", AU, 8000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00055 /* pt  5 */ static rtp_audio dvi4_8000 =
00056 { "DVI4", AU, 8000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00057 /* pt  6 */ static rtp_audio dvi4_16000 =
00058 { "DVI4", AU, 16000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00059 /* pt  7 */ static rtp_audio lpc =
00060 { "LPC", AU, 8000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00061 /* pt  8 */ static rtp_audio pcma =
00062 { "PCMA", AU, 8000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00063 /* pt  9 */ static rtp_audio g722 =
00064 { "G722", AU, 8000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00065 /* pt 10 */ static rtp_audio l16_2 =
00066 { "L16", AU, 44100, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 2 };
00067 /* pt 11 */ static rtp_audio l16_1 =
00068 { "L16", AU, 44100, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00069 /* pt 12 */ static rtp_audio qcelp =
00070 { "QCELP", AU, 8000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00071 /* pt 13 */ static rtp_audio cn =
00072 { "CN", AU, 8000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00073 /* pt 14 */ static rtp_audio mpa =
00074 { "MPA", AU, 90000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 0 };
00075 /* pt 15 */ static rtp_audio g728 =
00076 { "G728", AU, 8000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00077 /* pt 16 */ static rtp_audio dvi4_11025 =
00078 { "DVI4", AU, 11025, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00079 /* pt 17 */ static rtp_audio dvi4_22050 =
00080 { "DVI4", AU, 22050, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00081 /* pt 18 */ static rtp_audio g729 =
00082 { "G729", AU, 8000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00083 
00084 /* pt 19 = res_au (reserved audio) */
00085 #if 0
00086     /* we do not define reserved, unassigned or dynamic pt,
00087      * just initialize this position to NULL in rtpptdefs array */
00088                                                 /* pt 20-23 */ static rtp_audio unas_a =
00089 { "unas", AU, RTP_PT_ATTRS_INITIALIZER, NULL, 0 };
00090 
00091                                                 // (unassigned audio)
00092                                                 /* pt 24 */ static rtp_video unas_v =
00093 { "unas", VI, RTP_PT_ATTRS_INITIALIZER, NULL };
00094 
00095                                                 // pt 24, 27, 29, 30
00096 #endif
00097 /* pt 25 */ static rtp_video celb =
00098 { "CelB", VI, 90000, 0, RTP_PT_ATTRS_INITIALIZER, NULL };
00099 /* pt 26 */ static rtp_video jpeg =
00100 { "JPEG", VI, 90000, 0, RTP_PT_ATTRS_INITIALIZER, NULL };
00101 
00102 /* pt 27 = unas_v (unassigned video) */
00103 /* pt 28 */ static rtp_video nv =
00104 { "nv", VI, 90000, 0, RTP_PT_ATTRS_INITIALIZER, NULL };
00105 
00106 /* pt 29 = unas_v (unassigned video) */
00107 /* pt 30 = unas_v (unassigned video) */
00108 /* pt 31 */ static rtp_video h261 =
00109 { "H261", VI, 90000, 0, RTP_PT_ATTRS_INITIALIZER, NULL };
00110 /* pt 32 */ static rtp_video mpv =
00111 { "MPV", VI, 90000, 0, RTP_PT_ATTRS_INITIALIZER, NULL };
00112 /* pt 33 */ static rtp_audio_video mp2t =
00113 { "MP2T", AV, 90000, 0, RTP_PT_ATTRS_INITIALIZER, NULL, 0 };
00114 /* pt 34 */ static rtp_video h263 =
00115 { "H263", VI, 90000, 0, RTP_PT_ATTRS_INITIALIZER, NULL };
00116 
00117 #if 0
00118     /* we do not define reserved, unassigned or dynamic pt,
00119      * just initialize this position to NULL in rtpptdefs array */
00120 /* pt 35-71 */ static rtp_pt unas =
00121 { "unas", NA, RTP_PT_ATTRS_INITIALIZER, NULL };
00122 /* pt 72-76 */ static rtp_pt res =
00123 { "res", NA, RTP_PT_ATTRS_INITIALIZER, NULL };
00124 
00125 /* pt 77-95 = unas (unassigned) */
00126 /* pt 96-127 */ static rtp_pt dyn =
00127 { "dyn", NA, RTP_PT_ATTRS_INITIALIZER, NULL };
00128 #endif
00129 
00130 #if 0                // we don't use them yet.
00131 // other dynamically defined payload types
00132 /* dyn */ static rtp_audio g726_40 =
00133 { "G726-40", AU, 800RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00134 /* dyn */ static rtp_audio g726_32 =
00135 { "G726-32", AU, 800RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00136 /* dyn */ static rtp_audio g726_24 =
00137 { "G726-24", AU, 800RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00138 /* dyn */ static rtp_audio g726_16 =
00139 { "G726-16", AU, 800RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00140 /* dyn */ static rtp_audio g729d =
00141 { "G729D", AU, 800RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00142 /* dyn */ static rtp_audio g729e =
00143 { "G729E", AU, 800RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00144 /* dyn */ static rtp_audio gsm_efr =
00145 { "GSM-EFR", AU, 800RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00146 /* dyn */ static rtp_audio l8 =
00147 { "L8", AU, RTP_PT_ATTRS_INITIALIZER, NULL, 0 };
00148 /* dyn */ static rtp_audio red =
00149 { "RED", AU, RTP_PT_ATTRS_INITIALIZER, NULL, 0 };
00150 /* dyn */ static rtp_audio vdvi =
00151 { "VDVI", AU, RTP_PT_ATTRS_INITIALIZER, NULL, 1 };
00152 /* dyn */ static rtp_video h263_1998 =
00153 { "H263-1998", VI, 9000RTP_PT_ATTRS_INITIALIZER, NULL };
00154 #endif
00155 
00156 static rtp_pt *rtp_pt_defs[128] = {
00157     /*   0 */ RTP_PT(&pcmu), /*   1 */ NULL /* res AU */ ,    /*   2 */
00158     NULL /* res AU */ , /*   3 */ RTP_PT(&gsm),
00159     /*   4 */ RTP_PT(&g723), /*   5 */ RTP_PT(&dvi4_8000),    /*   6 */
00160     RTP_PT(&dvi4_16000), /*   7 */ RTP_PT(&lpc),
00161     /*   8 */ RTP_PT(&pcma), /*   9 */ RTP_PT(&g722),    /*  10 */
00162     RTP_PT(&l16_2), /*  11 */ RTP_PT(&l16_1),
00163     /*  12 */ RTP_PT(&qcelp), /*  13 */ RTP_PT(&cn),    /*  14 */
00164     RTP_PT(&mpa),
00165     /*  15 */ RTP_PT(&g728),
00166     /*  16 */ RTP_PT(&dvi4_11025), /*  17 */ RTP_PT(&dvi4_22050), /*  18 */ RTP_PT(&g729),    /*  19 */
00167     NULL /* res AU */ ,
00168     /*  20 */ NULL /* unas AU */ , /*  21 */ NULL /* unas AU */ , /*  22 */ NULL /* unas AU */ ,    /*  23 */
00169     NULL /* unas AU */ ,
00170     /*  24 */ NULL /* unas VI */ , /*  25 */ RTP_PT(&celb),    /*  26 */
00171     RTP_PT(&jpeg), /*  27 */ NULL /* unas VI */ ,
00172     /*  28 */ RTP_PT(&nv), /*  29 */ NULL /* unas VI */ ,    /*  30 */
00173     NULL /* unas VI */ , /*  31 */ RTP_PT(&h261),
00174     /*  32 */ RTP_PT(&mpv), /*  33 */ RTP_PT(&mp2t),    /*  34 */
00175     RTP_PT(&h263), /*  35 */ NULL /* unas */ ,
00176     /*  36 */ NULL /* unas */ , /*  37 */ NULL /* unas */ ,    /*  38 */
00177     NULL /* unas */ , /*  39 */ NULL /* unas */ ,
00178     /*  40 */ NULL /* unas */ , /*  41 */ NULL /* unas */ ,    /*  42 */
00179     NULL /* unas */ , /*  43 */ NULL /* unas */ ,
00180     /*  44 */ NULL /* unas */ , /*  45 */ NULL /* unas */ ,    /*  46 */
00181     NULL /* unas */ , /*  47 */ NULL /* unas */ ,
00182     /*  48 */ NULL /* unas */ , /*  49 */ NULL /* unas */ ,    /*  50 */
00183     NULL /* unas */ , /*  51 */ NULL /* unas */ ,
00184     /*  52 */ NULL /* unas */ , /*  53 */ NULL /* unas */ ,    /*  54 */
00185     NULL /* unas */ , /*  55 */ NULL /* unas */ ,
00186     /*  56 */ NULL /* unas */ , /*  57 */ NULL /* unas */ ,    /*  58 */
00187     NULL /* unas */ , /*  59 */ NULL /* unas */ ,
00188     /*  60 */ NULL /* unas */ , /*  61 */ NULL /* unas */ ,    /*  62 */
00189     NULL /* unas */ , /*  63 */ NULL /* unas */ ,
00190     /*  64 */ NULL /* unas */ , /*  65 */ NULL /* unas */ ,    /*  66 */
00191     NULL /* unas */ , /*  67 */ NULL /* unas */ ,
00192     /*  68 */ NULL /* unas */ , /*  69 */ NULL /* unas */ ,    /*  70 */
00193     NULL /* unas */ , /*  71 */ NULL /* unas */ ,
00194     /*  72 */ NULL /* res */ , /*  73 */ NULL /* res */ ,    /*  74 */
00195     NULL /* res */ , /*  75 */ NULL /* res */ ,
00196     /*  76 */ NULL /* res */ , /*  77 */ NULL /* unas */ ,    /*  78 */
00197     NULL /* unas */ , /*  79 */ NULL /* unas */ ,
00198     /*  80 */ NULL /* unas */ , /*  81 */ NULL /* unas */ ,    /*  82 */
00199     NULL /* unas */ , /*  83 */ NULL /* unas */ ,
00200     /*  84 */ NULL /* unas */ , /*  85 */ NULL /* unas */ ,    /*  86 */
00201     NULL /* unas */ , /*  87 */ NULL /* unas */ ,
00202     /*  88 */ NULL /* unas */ , /*  89 */ NULL /* unas */ ,    /*  90 */
00203     NULL /* unas */ , /*  91 */ NULL /* unas */ ,
00204     /*  92 */ NULL /* unas */ , /*  93 */ NULL /* unas */ ,    /*  94 */
00205     NULL /* unas */ , /*  95 */ NULL /* unas */ ,
00206     /*  96 */ NULL /* dyn */ , /*  97 */ NULL /* dyn */ ,    /*  98 */
00207     NULL /* dyn */ , /*  99 */ NULL /* dyn */ ,
00208     /* 100 */ NULL /* dyn */ , /* 101 */ NULL /* dyn */ ,    /* 102 */
00209     NULL /* dyn */ , /* 103 */ NULL /* dyn */ ,
00210     /* 104 */ NULL /* dyn */ , /* 105 */ NULL /* dyn */ ,    /* 106 */
00211     NULL /* dyn */ , /* 107 */ NULL /* dyn */ ,
00212     /* 108 */ NULL /* dyn */ , /* 109 */ NULL /* dyn */ ,    /* 110 */
00213     NULL /* dyn */ , /* 111 */ NULL /* dyn */ ,
00214     /* 112 */ NULL /* dyn */ , /* 113 */ NULL /* dyn */ ,    /* 114 */
00215     NULL /* dyn */ , /* 115 */ NULL /* dyn */ ,
00216     /* 116 */ NULL /* dyn */ , /* 117 */ NULL /* dyn */ ,    /* 118 */
00217     NULL /* dyn */ , /* 119 */ NULL /* dyn */ ,
00218     /* 120 */ NULL /* dyn */ , /* 121 */ NULL /* dyn */ ,    /* 122 */
00219     NULL /* dyn */ , /* 123 */ NULL /* dyn */ ,
00220     /* 124 */ NULL /* dyn */ , /* 125 */ NULL /* dyn */ ,    /* 126 */
00221     NULL /* dyn */ , /* 127 */ NULL /* dyn */ ,
00222 };
00223 
00227 void rtpptdefs_new(rtp_pt * new_defs[])
00228 {
00229     memcpy(new_defs, rtp_pt_defs, sizeof(rtp_pt_defs));
00230 }
00231 
00237 rtp_pt *rtp_pt_new(rtp_media_type mtype)
00238 {
00239     rtp_pt *new;
00240     size_t struct_size;
00241 
00242     switch (mtype) {
00243     case AU:
00244         struct_size = sizeof(rtp_audio);
00245         break;
00246     case VI:
00247         struct_size = sizeof(rtp_video);
00248         break;
00249     case AV:
00250         struct_size = sizeof(rtp_audio_video);
00251         break;
00252     case NA:
00253         struct_size = sizeof(rtp_pt);
00254         break;
00255     default:
00256         return NULL;
00257         break;
00258     }
00259 
00260     if (!(new = calloc(1, struct_size)))
00261         return NULL;
00262 
00263     new->type = mtype;
00264     return new;
00265 }
00266 
00276 int rtp_dynpt_set(rtp_pt * defs[], rtp_pt * pt, uint8_t value)
00277 {
00278     if (value < 96) {
00279         nms_printf(NMSML_ERR,
00280                "You tried to set a non-dynamic payload type (%u)\n",
00281                value);
00282         return RTP_ERROR;
00283     }
00284 
00285     free(defs[value]);
00286     defs[value] = pt;
00287 
00288     return RTP_OK;
00289 }
00290 
00301 int rtp_dynpt_encname(rtp_pt * defs[], uint8_t value, char *enc_name)
00302 {
00303     if (value < 96) {
00304         nms_printf(NMSML_ERR,
00305                "You tried to set encoding name for non-dynamic payload type (%u)\n",
00306                value);
00307         return RTP_ERROR;
00308     }
00309 
00310     if (!defs[value]) {
00311         nms_printf(NMSML_ERR,
00312                "No dynamic payload type initialized for pt %u\n",
00313                value);
00314         return RTP_ERROR;
00315     }
00316 
00317     strncpy(defs[value]->name, enc_name, sizeof(defs[value]->name));
00318     defs[value]->name[sizeof(defs[value]->name)-1] = '\0';    // safety end-of-string
00319 
00320     return RTP_OK;
00321 }
00322 
00323 #if 0
00324 // rtp_pt_attrs specific functions
00325 void rtp_pt_attrs_init(rtp_pt_attrs * attrs)
00326 {
00327     attrs->data = NULL;
00328     attrs->size = attrs->allocated = 0;
00329 }
00330 #endif
00331 
00343 int rtp_pt_attr_add(rtp_pt * defs[], uint8_t value, char *attr)
00344 {
00345     rtp_pt_attrs *attrs;
00346 
00347     if (value > 127)
00348         return RTP_ERROR;
00349 
00350     attrs = &defs[value]->attrs;
00351 
00352     if (attrs->allocated == attrs->size) {    // we must realloc
00353         int minsize = min(attrs->allocated + 1, RTP_ATTRS_ARRAY_DEF_SIZE);
00354         if (! (attrs->data = realloc(attrs->data, minsize * sizeof(char*))))
00355             return -1;
00356         attrs->allocated = minsize;
00357     }
00358     if (!(attrs->data[attrs->size] = strdup(attr)))
00359         return -1;
00360 
00361     attrs->size++;
00362 
00363     return RTP_OK;
00364 }
00365 
00376 rtp_pt * rtp_get_pt_info(rtp_session * rtp_sess, unsigned pt)
00377 {
00378     return rtp_sess->ptdefs[pt];
00379 }
00380 
00392 int rtp_dynpt_reg(rtp_session * rtp_sess, unsigned pt, char *mime)
00393 {
00394     if (rtp_dynpt_encname(rtp_sess->ptdefs, pt, mime))
00395         return RTP_ERROR;
00396 
00397     if (rtp_parser_reg(rtp_sess, pt, mime))
00398         return RTP_ERROR;
00399 
00400     nms_printf(NMSML_DBG2, "registered %s mime for %d payload type\n",
00401            mime, pt);
00402 
00403     return RTP_OK;
00404 }
00405 
00417 int rtp_announce_pt(rtp_session * rtp_sess, unsigned pt,
00418             rtp_media_type media_type)
00419 {
00420     rtp_pt *rtppt;
00421     rtp_fmts_list *fmt, **prev_fmt;
00422 
00423     if (pt > 127) {
00424         nms_printf(NMSML_ERR, "rtp payload type not valid (%u)\n", pt);
00425         return RTP_ERROR;
00426     } else if (pt >= 96) {
00427         if (!(rtppt = rtp_pt_new(media_type)))
00428             return RTP_ERROR;
00429         rtp_dynpt_set(rtp_sess->ptdefs, rtppt, pt);
00430     }
00431 
00432     if (!(fmt = malloc(sizeof(rtp_fmts_list)))) {
00433         nms_printf(NMSML_FATAL,
00434                "Could not alloc memory for rtp_fmts_list\n");
00435         return RTP_ERRALLOC;
00436     }
00437     fmt->pt = pt;
00438     fmt->rtppt = rtp_sess->ptdefs[pt];
00439     fmt->next = NULL;
00440     for (prev_fmt = &rtp_sess->announced_fmts; *prev_fmt;
00441          prev_fmt = &(*prev_fmt)->next);
00442     *prev_fmt = fmt;
00443     prev_fmt = &fmt->next;
00444 
00445     return RTP_OK;
00446 }

Generated on Tue Feb 3 03:10:02 2009 for libnemesi by  doxygen 1.5.4