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_m4v;
00046
00047 static const rtpparser_info m4v_served = {
00048 -1,
00049 {"MP4V-ES", NULL}
00050 };
00051
00052 static int m4v_init_parser(rtp_session * rtp_sess, unsigned pt)
00053 {
00054 rtp_m4v *priv = calloc(1, sizeof(rtp_m4v));
00055 rtp_pt_attrs *attrs = &rtp_sess->ptdefs[pt]->attrs;
00056 char value[1024];
00057 uint8_t buffer[1024];
00058 int i, v_len, len;
00059
00060 if (!priv)
00061 return RTP_ERRALLOC;
00062
00063 for (i=0; i < attrs->size; i++) {
00064 if ((v_len = nms_get_attr_value(attrs->data[i], "config", value, sizeof(value)))) {
00065 if (!(v_len % 2) && v_len > 0) {
00066
00067 *(value + v_len) = '\0';
00068 if ((len = nms_hex_decode(buffer, value, sizeof(buffer))) < 0)
00069 goto err_alloc;
00070 if (!(priv->conf = realloc(priv->conf, priv->conf_len + len)))
00071 goto err_alloc;
00072 memcpy(priv->conf + priv->conf_len, buffer, len);
00073 priv->conf_len += len;
00074 }
00075 }
00076 }
00077
00078 rtp_sess->ptdefs[pt]->priv = priv;
00079
00080 return 0;
00081
00082 err_alloc:
00083 if (priv->data)
00084 free(priv->data);
00085 free(priv);
00086 return RTP_ERRALLOC;
00087 }
00088
00089 static int m4v_uninit_parser(rtp_ssrc * ssrc, unsigned pt)
00090 {
00091 rtp_m4v *priv = ssrc->rtp_sess->ptdefs[pt]->priv;
00092
00093 if (priv && priv->data)
00094 free(priv->data);
00095 if (priv && priv->conf)
00096 free(priv->conf);
00097 if (priv)
00098 free(priv);
00099
00100 ssrc->rtp_sess->ptdefs[pt]->priv = NULL;
00101
00102 return 0;
00103 }
00104
00109 static int m4v_parse(rtp_ssrc * ssrc, rtp_frame * fr, rtp_buff * config)
00110 {
00111 rtp_pkt *pkt;
00112 uint8_t *buf;
00113 rtp_m4v *priv = ssrc->rtp_sess->ptdefs[fr->pt]->priv;
00114 size_t len;
00115
00116 int err = RTP_FILL_OK;
00117
00118 if (!(pkt = rtp_get_pkt(ssrc, &len)))
00119 return RTP_BUFF_EMPTY;
00120
00121 buf = RTP_PKT_DATA(pkt);
00122 len = RTP_PAYLOAD_SIZE(pkt, len);
00123
00124 if (priv->len && (RTP_PKT_TS(pkt) != priv->timestamp)) {
00125
00126 priv->len = 0;
00127 return RTP_PKT_UNKNOWN;
00128 }
00129
00130
00131
00132 if (!priv->configured && !priv->len && priv->conf_len) {
00133 if (!(priv->data = realloc(priv->data, priv->conf_len))) {
00134 return RTP_ERRALLOC;
00135 }
00136 priv->data_size = len;
00137 memcpy(priv->data, priv->conf, priv->conf_len);
00138 priv->len = priv->conf_len;
00139 priv->configured = 1;
00140 }
00141
00142 if (priv->data_size < len + priv->len) {
00143 if (!(priv->data = realloc(priv->data, len + priv->len))) {
00144 return RTP_ERRALLOC;
00145 }
00146 priv->data_size = len + priv->len;
00147 }
00148
00149 memcpy(priv->data + priv->len, buf, len);
00150
00151 priv->len += len;
00152
00153 if (!RTP_PKT_MARK(pkt)) {
00154 priv->timestamp = RTP_PKT_TS(pkt);
00155 err = EAGAIN;
00156 } else {
00157 fr->data = priv->data;
00158 fr->len = priv->len;
00159 priv->len = 0;
00160 }
00161
00162 if (priv->conf_len) {
00163 config->data = priv->conf;
00164 config->len = priv->conf_len;
00165 }
00166
00167 rtp_rm_pkt(ssrc);
00168 return err;
00169 }
00170
00171 RTP_PARSER_FULL(m4v);