rtp_m4v.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 
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                 /*hex string*/
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         //incomplete packet without final fragment
00126         priv->len = 0;
00127         return RTP_PKT_UNKNOWN;
00128     }
00129 
00130     // In order to produce a compliant bitstream, a 'VOL Header' should prefix
00131     // the data stream.
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);

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