00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "rtpparser.h"
00024 #include "rtp_utils.h"
00025 #include <math.h>
00026
00035 typedef struct aac_elem_s {
00036 uint8_t *data;
00037 long len;
00038 struct aac_elem_s *next;
00039 } aac_elem;
00040
00045 typedef struct {
00046 uint8_t *data;
00047 long len;
00048 long data_size;
00049 unsigned long timestamp;
00050 uint8_t *conf;
00051 long conf_len;
00052 int size_len;
00053 int index_len;
00054 int delta_len;
00055 aac_elem *head;
00056 } rtp_aac;
00057
00058
00059
00060 static const rtpparser_info aac_served = {
00061 -1,
00062 {"MPEG4-GENERIC", NULL}
00063 };
00064
00065 static int aac_init_parser(rtp_session * rtp_sess, unsigned pt)
00066 {
00067 rtp_aac *priv = calloc(1, sizeof(rtp_aac));
00068 rtp_pt_attrs *attrs = &rtp_sess->ptdefs[pt]->attrs;
00069 char value[1024];
00070 uint8_t buffer[1024];
00071 int i, v_len, len, err = RTP_ERRALLOC;
00072
00073 if (!priv)
00074 return RTP_ERRALLOC;
00075
00076 for (i=0; i < attrs->size; i++){
00077 if ((v_len = nms_get_attr_value(attrs->data[i], "config", value,
00078 sizeof(value)))) {
00079 if (!(v_len % 2) && v_len > 0) {
00080 if ((len = nms_hex_decode(buffer, value, sizeof(buffer))) < 0)
00081 goto err_alloc;
00082 if (!(priv->conf = realloc(priv->conf, priv->conf_len + len)))
00083 goto err_alloc;
00084 memcpy(priv->conf + priv->conf_len, buffer, len);
00085 priv->conf_len += len;
00086 }
00087 }
00088 if ((v_len = nms_get_attr_value(attrs->data[i], "mode", value,
00089 sizeof(value)))) {
00090 if (strcmp(value,"AAC-hbr")) {
00091 nms_printf(NMSML_ERR, "Mode %s not supported\n",
00092 value);
00093 err = RTP_PARSE_ERROR;
00094 goto err_alloc;
00095 }
00096 }
00097 if ((v_len = nms_get_attr_value(attrs->data[i], "sizeLength",
00098 value, sizeof(value)))) {
00099 if ((priv->size_len = strtol(value, NULL, 0)) != 13) {
00100 nms_printf(NMSML_ERR, "Size Length %d not supported\n",
00101 priv->size_len);
00102 err = RTP_PARSE_ERROR;
00103 goto err_alloc;
00104 }
00105 }
00106 if ((v_len = nms_get_attr_value(attrs->data[i], "indexLength",
00107 value, sizeof(value)))) {
00108 if ((priv->index_len = strtol(value, NULL, 0)) != 3) {
00109 nms_printf(NMSML_ERR, "Index Length %d not supported\n",
00110 priv->index_len);
00111 err = RTP_PARSE_ERROR;
00112 goto err_alloc;
00113 }
00114 }
00115 if ((v_len = nms_get_attr_value(attrs->data[i], "indexDeltaLength",
00116 value, sizeof(value)))) {
00117 if ((priv->delta_len = strtol(value, NULL, 0)) != 3) {
00118 nms_printf(NMSML_ERR, "Index Delta Length %d not supported\n",
00119 priv->index_len);
00120 err = RTP_PARSE_ERROR;
00121 goto err_alloc;
00122 }
00123 }
00124 }
00125
00126 rtp_sess->ptdefs[pt]->priv = priv;
00127
00128 return 0;
00129
00130 err_alloc:
00131 if (priv->data)
00132 free(priv->data);
00133 free(priv);
00134 return err;
00135 }
00136
00137 static int aac_uninit_parser(rtp_ssrc * ssrc, unsigned pt)
00138 {
00139 aac_elem *tmp;
00140 rtp_aac *priv = ssrc->rtp_sess->ptdefs[pt]->priv;
00141
00142 if (priv) {
00143 if (priv->data)
00144 free(priv->data);
00145 if (priv->conf)
00146 free(priv->conf);
00147 while (priv->head) {
00148 tmp = priv->head;
00149 priv->head = priv->head->next;
00150 if (tmp->data)
00151 free(tmp->data);
00152 free(tmp);
00153 }
00154 free(priv);
00155 }
00156
00157 ssrc->rtp_sess->ptdefs[pt]->priv = NULL;
00158
00159 return 0;
00160 }
00161
00167 static int aac_parse(rtp_ssrc * ssrc, rtp_frame * fr, rtp_buff * config)
00168 {
00169 rtp_pkt *pkt;
00170 uint8_t *buf, *payload;
00171 aac_elem *cur = NULL;
00172 rtp_aac *priv = ssrc->rtp_sess->ptdefs[fr->pt]->priv;
00173 size_t len;
00174 int i, buf_index;
00175 int header_len, header_len_bytes, headers_num, frame_len, frame_index;
00176
00177 int err = RTP_FILL_OK;
00178
00179 if (!(pkt = rtp_get_pkt(ssrc, &len)))
00180 return RTP_BUFF_EMPTY;
00181
00182 payload = buf = RTP_PKT_DATA(pkt);
00183 len = RTP_PAYLOAD_SIZE(pkt, len);
00184
00185 if (priv->len && (RTP_PKT_TS(pkt) != priv->timestamp)) {
00186
00187 fr->data = priv->data;
00188 fr->len = priv->len;
00189 priv->len = 0;
00190 return RTP_FILL_OK;
00191 }
00192
00193 if (!priv->head) {
00194 header_len = (buf[0] << 8) | buf[1];
00195 header_len_bytes = (header_len + 7) / 8;
00196 headers_num = header_len / 16;
00197
00198 payload += 2;
00199 buf_index = 2 + header_len_bytes;
00200
00201 for (i = 0; i < headers_num; i++) {
00202 frame_len = ((payload[0] << 8) | payload[1]) >> 3;
00203 frame_index = payload[1] & 0x7;
00204 payload += 2;
00205
00206 if (!cur) {
00207 cur = priv->head = calloc(1, sizeof(aac_elem));
00208 } else {
00209 cur->next = calloc(1, sizeof(aac_elem));
00210 cur = cur->next;
00211 }
00212
00213 if (!cur)
00214 return RTP_ERRALLOC;
00215
00216 cur->data = malloc(frame_len);
00217
00218 if (!cur->data)
00219 return RTP_ERRALLOC;
00220
00221 memcpy(cur->data, buf + buf_index, frame_len);
00222
00223 cur->len = frame_len;
00224 buf_index += frame_len;
00225 }
00226 }
00227
00228 if (priv->data_size < priv->len + priv->head->len) {
00229 if (!(priv->data = realloc(priv->data, len + priv->len))) {
00230 return RTP_ERRALLOC;
00231 }
00232 priv->data_size = priv->len + priv->head->len;
00233 }
00234
00235 if (priv->head) {
00236 memcpy(priv->data + priv->len, priv->head->data, priv->head->len);
00237 priv->len += priv->head->len;
00238 cur = priv->head;
00239 priv->head = priv->head->next;
00240 if (cur->data)
00241 free(cur->data);
00242 free(cur);
00243 }
00244
00245 if (!RTP_PKT_MARK(pkt)) {
00246 priv->timestamp = RTP_PKT_TS(pkt);
00247 err = EAGAIN;
00248 } else {
00249 fr->data = priv->data;
00250 fr->len = priv->len;
00251 priv->len = 0;
00252 }
00253
00254 if (priv->conf_len) {
00255 config->data = priv->conf;
00256 config->len = priv->conf_len;
00257 }
00258
00259 if (!priv->head) {
00260 rtp_rm_pkt(ssrc);
00261 }
00262
00263 return err;
00264 }
00265
00266 RTP_PARSER_FULL(aac);