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
00037 typedef struct {
00038 uint8_t *data;
00039 long len;
00040 long data_size;
00041 unsigned long timestamp;
00042 uint8_t *conf;
00043 long conf_len;
00044 int configured;
00045 } rtp_h264;
00046
00047 static const rtpparser_info h264_served = {
00048 -1,
00049 {"H264", NULL}
00050 };
00051
00052 static int h264_init_parser(rtp_session * rtp_sess, unsigned pt)
00053 {
00054 rtp_h264 *priv = calloc(1, sizeof(rtp_h264));
00055 rtp_pt_attrs *attrs = &rtp_sess->ptdefs[pt]->attrs;
00056 char value[1024];
00057 int i;
00058 int len;
00059
00060 if (!priv) return RTP_ERRALLOC;
00061
00062 for (i=0; i < attrs->size; i++) {
00063
00064 if ((len = nms_get_attr_value(attrs->data[i], "profile-level-id",
00065 value, sizeof(value)))) {
00066 if (len==6){ }
00067 }
00068 if ((len = nms_get_attr_value(attrs->data[i], "packetization-mode",
00069 value, sizeof(value)))) {
00070
00071 if (len != 1 || atoi(value) >= 2) {
00072 nms_printf(NMSML_ERR,
00073 "Unsupported H.264 packetization mode %s\n", value);
00074 return RTP_PARSE_ERROR;
00075 }
00076 }
00077 if ((len = nms_get_attr_value(attrs->data[i], "sprop-parameter-sets",
00078 value, sizeof(value)))) {
00079
00080 uint8_t start_seq[4] = {0, 0, 0, 1};
00081 char *v = value;
00082 priv->conf_len = 0;
00083 priv->conf = NULL;
00084 while (*v) {
00085 char base64packet[1024];
00086 uint8_t decoded_packet[1024];
00087 unsigned packet_size;
00088 char *dst = base64packet;
00089
00090 while (*v && *v != ','
00091 && (dst - base64packet) < sizeof(base64packet) - 1) {
00092 *dst++ = *v++;
00093 }
00094 *dst++ = '\0';
00095
00096 if (*v == ',')
00097 v++;
00098
00099 packet_size = nms_base64_decode(decoded_packet,
00100 base64packet,
00101 sizeof(decoded_packet));
00102 if (packet_size) {
00103 uint8_t *dest = calloc(1, packet_size +
00104 sizeof(start_seq) +
00105 priv->conf_len);
00106 if(dest) {
00107 if(priv->conf_len) {
00108 memcpy(dest, priv->conf, priv->conf_len);
00109 free(priv->conf);
00110 }
00111
00112 memcpy(dest+priv->conf_len, start_seq,
00113 sizeof(start_seq));
00114 memcpy(dest + priv->conf_len + sizeof(start_seq),
00115 decoded_packet, packet_size);
00116
00117 priv->conf = dest;
00118 priv->conf_len += sizeof(start_seq) + packet_size;
00119 } else {
00120 goto err_alloc;
00121 }
00122 }
00123 }
00124 }
00125 }
00126
00127 rtp_sess->ptdefs[pt]->priv = priv;
00128
00129 return 0;
00130
00131 err_alloc:
00132 free(priv);
00133 return RTP_ERRALLOC;
00134 }
00135
00136 static int h264_uninit_parser(rtp_ssrc * ssrc, unsigned pt)
00137 {
00138 rtp_h264 *priv = ssrc->rtp_sess->ptdefs[pt]->priv;
00139
00140 if (priv && priv->data)
00141 free(priv->data);
00142 if (priv && priv->conf)
00143 free(priv->conf);
00144 if (priv)
00145 free(priv);
00146
00147 ssrc->rtp_sess->ptdefs[pt]->priv = NULL;
00148
00149 return 0;
00150 }
00151
00157 static int h264_parse(rtp_ssrc * ssrc, rtp_frame * fr, rtp_buff * config)
00158 {
00159 rtp_pkt *pkt;
00160 size_t len;
00161 rtp_h264 *priv = ssrc->rtp_sess->ptdefs[fr->pt]->priv;
00162 uint8_t *buf;
00163 uint8_t type;
00164 uint8_t start_seq[4] = {0, 0, 0, 1};
00165 int err = RTP_FILL_OK;
00166
00167 if (!(pkt = rtp_get_pkt(ssrc, &len)))
00168 return RTP_BUFF_EMPTY;
00169
00170 buf = RTP_PKT_DATA(pkt);
00171 len = RTP_PAYLOAD_SIZE(pkt, len);
00172 type = (buf[0] & 0x1f);
00173
00174
00175
00176 if (!priv->configured && priv->conf_len) {
00177 if(nms_alloc_data(&priv->data, &priv->data_size, priv->conf_len)) {
00178 return RTP_ERRALLOC;
00179 }
00180 nms_append_incr(priv->data, &priv->len, priv->conf, priv->conf_len);
00181 priv->configured = 1;
00182 }
00183
00184 if (priv->conf_len) {
00185 config->data = priv->conf;
00186 config->len = priv->conf_len;
00187 }
00188
00189 if (type >= 1 && type <= 23) type = 1;
00190
00191 switch (type) {
00192 case 0:
00193 err = RTP_PKT_UNKNOWN;
00194 break;
00195 case 1:
00196 if(nms_alloc_data(&priv->data, &priv->data_size,
00197 len + sizeof(start_seq) + priv->len)) {
00198 return RTP_ERRALLOC;
00199 }
00200 nms_append_incr(priv->data, &priv->len, start_seq, sizeof(start_seq));
00201 nms_append_incr(priv->data, &priv->len, buf, len);
00202 fr->data = priv->data;
00203 fr->len = priv->len;
00204 priv->len = 0;
00205 break;
00206 case 24:
00207 #if 0
00208 {
00209 size_t frame_len;
00210 buf += priv->index + 1;
00211 frame_len = nms_consume_BE2(&buf);
00212 if (!frame_len) {
00213 nms_printf (NMSML_WARN,"Empty frame\n");
00214 err = RTP_PARSE_ERROR;
00215 break;
00216 }
00217
00218 nms_printf(NMSML_WARN, "NAL: %d", *buf & 0x1f);
00219
00220 if (frame_len + priv->index < len) {
00221 nms_printf (NMSML_WARN,"Packet size %d\n",frame_len);
00222
00223 priv->data = fr->data = realloc(priv->data,
00224 sizeof(start_seq)
00225 + frame_len);
00226 memcpy(fr->data, &start_seq, sizeof(start_seq));
00227 memcpy(fr->data + sizeof(start_seq), buf, frame_len);
00228 fr->len = sizeof(start_seq) + frame_len;
00229 priv->index += 2 + frame_len;
00230 if ( priv->index + 1 < len) return err;
00231 else priv->index = 0;
00232 } else {
00233 nms_printf (NMSML_ERR,"STAP-A corrupted\n");
00234 err = RTP_PARSE_ERROR;
00235 }
00236 }
00237 break;
00238 #else
00239
00240 buf++;
00241 len--;
00242
00243 {
00244 int pass = 0;
00245 int total_length = 0;
00246
00247 for(pass= 0; pass<2; pass++) {
00248 uint8_t *src = buf;
00249 int src_len = len;
00250 do {
00251 uint16_t nal_size = nms_consume_BE2(&src);
00252 src_len -= 2;
00253
00254 if (nal_size <= src_len) {
00255 if(pass==0) {
00256 total_length += sizeof(start_seq) + nal_size;
00257 } else {
00258 nms_append_incr(priv->data, &priv->len, start_seq,
00259 sizeof(start_seq));
00260 nms_append_incr(priv->data, &priv->len, src,
00261 nal_size);
00262 }
00263 } else {
00264 nms_printf(NMSML_ERR,
00265 "nal size exceeds length: %d %d\n",
00266 nal_size, src_len);
00267 }
00268
00269 src += nal_size;
00270 src_len -= nal_size;
00271
00272 if (src_len < 0)
00273 nms_printf(NMSML_ERR,
00274 "Consumed more bytes than we got! (%d)\n",
00275 src_len);
00276 } while (src_len > 2);
00277
00278 if(pass==0) {
00279 if(nms_alloc_data(&priv->data, &priv->data_size,
00280 total_length + priv->len)) {
00281 return RTP_ERRALLOC;
00282 }
00283 }
00284 }
00285 }
00286 fr->data = priv->data;
00287 fr->len = priv->len;
00288 priv->len = 0;
00289 break;
00290 #endif
00291
00292 case 25:
00293 err = RTP_PKT_UNKNOWN;
00294 nms_printf (NMSML_WARN,"STAP-B\n");
00295 break;
00296 case 26:
00297 err = RTP_PKT_UNKNOWN;
00298 nms_printf (NMSML_WARN,"MTAP-16\n");
00299 break;
00300 case 27:
00301 nms_printf (NMSML_WARN,"MTAP-24\n");
00302 err = RTP_PKT_UNKNOWN;
00303 break;
00304
00305 case 28:
00306 {
00307 uint8_t fu_indicator = nms_consume_1(&buf);
00308 uint8_t fu_header = nms_consume_1(&buf);
00309 uint8_t start_bit = (fu_header & 0x80) >> 7;
00310 uint8_t end_bit = (fu_header & 0x40) >> 6;
00311 uint8_t nal_type = (fu_header & 0x1f);
00312 uint8_t reconstructed_nal;
00313
00314 len -= 2;
00315
00316
00317
00318
00319 reconstructed_nal = fu_indicator & 0xe0;
00320 reconstructed_nal |= nal_type;
00321
00322 if(start_bit && !priv->len) {
00323 if(nms_alloc_data(&priv->data, &priv->data_size,
00324 len + 1 + sizeof(start_seq) + priv->len)) {
00325 return RTP_ERRALLOC;
00326 }
00327
00328 nms_append_incr(priv->data, &priv->len, start_seq,
00329 sizeof(start_seq));
00330 nms_append_incr(priv->data, &priv->len, &reconstructed_nal, 1);
00331 nms_append_incr(priv->data, &priv->len, buf, len);
00332 } else {
00333 if (priv->timestamp != RTP_PKT_TS(pkt)) {
00334 fr->len = priv->len = 0;
00335 rtp_rm_pkt(ssrc);
00336 return RTP_PKT_UNKNOWN;
00337 }
00338 if(nms_alloc_data(&priv->data, &priv->data_size,
00339 len + priv->len)) {
00340 return RTP_ERRALLOC;
00341 }
00342 nms_append_incr(priv->data, &priv->len, buf, len);
00343 }
00344
00345 priv->timestamp = RTP_PKT_TS(pkt);
00346 if (!end_bit) {
00347 err = EAGAIN;
00348 } else {
00349 fr->data = priv->data;
00350 fr->len = priv->len;
00351 priv->len = 0;
00352 }
00353 }
00354 break;
00355 case 30:
00356 case 31:
00357 default:
00358 err = RTP_PKT_UNKNOWN;
00359 break;
00360 }
00361
00362 rtp_rm_pkt(ssrc);
00363
00364 return err;
00365 }
00366
00367 RTP_PARSER_FULL(h264);