00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00029 #include <string.h>
00030 #include "libavutil/intreadwrite.h"
00031 #include "rtp.h"
00032 #include "rtpdec.h"
00033 #include "rtpdec_formats.h"
00034 
00035 struct PayloadContext {
00036     AVIOContext *pktbuf;
00037     int64_t        timestamp;
00038 };
00039 
00041 static int svq3_parse_packet (AVFormatContext *s, PayloadContext *sv,
00042                               AVStream *st, AVPacket *pkt,
00043                               uint32_t *timestamp,
00044                               const uint8_t *buf, int len, int flags)
00045 {
00046     int config_packet, start_packet, end_packet;
00047 
00048     if (len < 2)
00049         return AVERROR_INVALIDDATA;
00050 
00051     config_packet = buf[0] & 0x40;
00052     start_packet  = buf[0] & 0x20;
00053     end_packet    = buf[0] & 0x10;
00054     buf += 2;     
00055     len -= 2;
00056 
00057     if (config_packet) {
00058 
00059         av_freep(&st->codec->extradata);
00060         st->codec->extradata_size = 0;
00061 
00062         if (len < 2 || !(st->codec->extradata =
00063                          av_malloc(len + 8 + FF_INPUT_BUFFER_PADDING_SIZE)))
00064             return AVERROR_INVALIDDATA;
00065 
00066         st->codec->extradata_size = len + 8;
00067         memcpy(st->codec->extradata, "SEQH", 4);
00068         AV_WB32(st->codec->extradata + 4, len);
00069         memcpy(st->codec->extradata + 8, buf, len);
00070 
00071         
00072 
00073 
00074 
00075 
00076         st->codec->codec_id = CODEC_ID_SVQ3;
00077 
00078         return AVERROR(EAGAIN);
00079     }
00080 
00081     if (start_packet) {
00082         int res;
00083 
00084         if (sv->pktbuf) {
00085             uint8_t *tmp;
00086             avio_close_dyn_buf(sv->pktbuf, &tmp);
00087             av_free(tmp);
00088         }
00089         if ((res = avio_open_dyn_buf(&sv->pktbuf)) < 0)
00090             return res;
00091         sv->timestamp   = *timestamp;
00092     }
00093 
00094     if (!sv->pktbuf)
00095         return AVERROR_INVALIDDATA;
00096 
00097     avio_write(sv->pktbuf, buf, len);
00098 
00099     if (end_packet) {
00100         av_init_packet(pkt);
00101         pkt->stream_index = st->index;
00102         *timestamp        = sv->timestamp;
00103         pkt->size         = avio_close_dyn_buf(sv->pktbuf, &pkt->data);
00104         pkt->destruct     = av_destruct_packet;
00105         sv->pktbuf        = NULL;
00106         return 0;
00107     }
00108 
00109     return AVERROR(EAGAIN);
00110 }
00111 
00112 static PayloadContext *svq3_extradata_new(void)
00113 {
00114     return av_mallocz(sizeof(PayloadContext));
00115 }
00116 
00117 static void svq3_extradata_free(PayloadContext *sv)
00118 {
00119     if (sv->pktbuf) {
00120         uint8_t *buf;
00121         avio_close_dyn_buf(sv->pktbuf, &buf);
00122         av_free(buf);
00123     }
00124     av_free(sv);
00125 }
00126 
00127 RTPDynamicProtocolHandler ff_svq3_dynamic_handler = {
00128     .enc_name         = "X-SV3V-ES",
00129     .codec_type       = AVMEDIA_TYPE_VIDEO,
00130     .codec_id         = CODEC_ID_NONE,      
00131     .alloc            = svq3_extradata_new,
00132     .free             = svq3_extradata_free,
00133     .parse_packet     = svq3_parse_packet,
00134 };