changeset 5726:04b39763b51b libavformat

Rename RTP depacketizer files from rtp_* to rtpdec_*
author mstorsjo
date Sun, 28 Feb 2010 11:03:14 +0000
parents 334f223fc455
children 74142991b333
files Makefile rtp_asf.c rtp_asf.h rtp_h264.c rtp_h264.h rtp_vorbis.c rtp_vorbis.h rtpdec.c rtpdec_asf.c rtpdec_asf.h rtpdec_h264.c rtpdec_h264.h rtpdec_vorbis.c rtpdec_vorbis.h rtsp.c
diffstat 15 files changed, 1040 insertions(+), 1040 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Sun Feb 28 03:59:15 2010 +0000
+++ b/Makefile	Sun Feb 28 11:03:14 2010 +0000
@@ -216,10 +216,10 @@
                                             rtp.o         \
                                             rtpdec.o      \
                                             rtpdec_amr.o  \
+                                            rtpdec_asf.o  \
                                             rtpdec_h263.o \
-                                            rtp_asf.o     \
-                                            rtp_h264.o    \
-                                            rtp_vorbis.o
+                                            rtpdec_h264.o \
+                                            rtpdec_vorbis.o
 OBJS-$(CONFIG_SEGAFILM_DEMUXER)          += segafilm.o
 OBJS-$(CONFIG_SHORTEN_DEMUXER)           += raw.o id3v2.o
 OBJS-$(CONFIG_SIFF_DEMUXER)              += siff.o
--- a/rtp_asf.c	Sun Feb 28 03:59:15 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,281 +0,0 @@
-/*
- * Microsoft RTP/ASF support.
- * Copyright (c) 2008 Ronald S. Bultje
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file libavformat/rtp_asf.c
- * @brief Microsoft RTP/ASF support
- * @author Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- */
-
-#include <libavutil/base64.h>
-#include <libavutil/avstring.h>
-#include <libavutil/intreadwrite.h>
-#include "rtp.h"
-#include "rtp_asf.h"
-#include "rtsp.h"
-#include "asf.h"
-
-/**
- * From MSDN 2.2.1.4, we learn that ASF data packets over RTP should not
- * contain any padding. Unfortunately, the header min/max_pktsize are not
- * updated (thus making min_pktsize invalid). Here, we "fix" these faulty
- * min_pktsize values in the ASF file header.
- * @return 0 on success, <0 on failure (currently -1).
- */
-static int rtp_asf_fix_header(uint8_t *buf, int len)
-{
-    uint8_t *p = buf, *end = buf + len;
-
-    if (len < sizeof(ff_asf_guid) * 2 + 22 ||
-        memcmp(p, ff_asf_header, sizeof(ff_asf_guid))) {
-        return -1;
-    }
-    p += sizeof(ff_asf_guid) + 14;
-    do {
-        uint64_t chunksize = AV_RL64(p + sizeof(ff_asf_guid));
-        if (memcmp(p, ff_asf_file_header, sizeof(ff_asf_guid))) {
-            if (chunksize > end - p)
-                return -1;
-            p += chunksize;
-            continue;
-        }
-
-        /* skip most of the file header, to min_pktsize */
-        p += 6 * 8 + 3 * 4 + sizeof(ff_asf_guid) * 2;
-        if (p + 8 <= end && AV_RL32(p) == AV_RL32(p + 4)) {
-            /* and set that to zero */
-            AV_WL32(p, 0);
-            return 0;
-        }
-        break;
-    } while (end - p >= sizeof(ff_asf_guid) + 8);
-
-    return -1;
-}
-
-/**
- * The following code is basically a buffered ByteIOContext,
- * with the added benefit of returning -EAGAIN (instead of 0)
- * on packet boundaries, such that the ASF demuxer can return
- * safely and resume business at the next packet.
- */
-static int packetizer_read(void *opaque, uint8_t *buf, int buf_size)
-{
-    return AVERROR(EAGAIN);
-}
-
-static void init_packetizer(ByteIOContext *pb, uint8_t *buf, int len)
-{
-    init_put_byte(pb, buf, len, 0, NULL, packetizer_read, NULL, NULL);
-
-    /* this "fills" the buffer with its current content */
-    pb->pos     = len;
-    pb->buf_end = buf + len;
-}
-
-void ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p)
-{
-    if (av_strstart(p, "pgmpu:data:application/vnd.ms.wms-hdr.asfv1;base64,", &p)) {
-        ByteIOContext pb;
-        RTSPState *rt = s->priv_data;
-        int len = strlen(p) * 6 / 8;
-        char *buf = av_mallocz(len);
-        av_base64_decode(buf, p, len);
-
-        if (rtp_asf_fix_header(buf, len) < 0)
-            av_log(s, AV_LOG_ERROR,
-                   "Failed to fix invalid RTSP-MS/ASF min_pktsize\n");
-        init_packetizer(&pb, buf, len);
-        if (rt->asf_ctx) {
-            av_close_input_stream(rt->asf_ctx);
-            rt->asf_ctx = NULL;
-        }
-        av_open_input_stream(&rt->asf_ctx, &pb, "", &asf_demuxer, NULL);
-        rt->asf_pb_pos = url_ftell(&pb);
-        av_free(buf);
-        rt->asf_ctx->pb = NULL;
-    }
-}
-
-static int asfrtp_parse_sdp_line(AVFormatContext *s, int stream_index,
-                                 PayloadContext *asf, const char *line)
-{
-    if (av_strstart(line, "stream:", &line)) {
-        RTSPState *rt = s->priv_data;
-
-        s->streams[stream_index]->id = strtol(line, NULL, 10);
-
-        if (rt->asf_ctx) {
-            int i;
-
-            for (i = 0; i < rt->asf_ctx->nb_streams; i++) {
-                if (s->streams[stream_index]->id == rt->asf_ctx->streams[i]->id) {
-                    *s->streams[stream_index]->codec =
-                        *rt->asf_ctx->streams[i]->codec;
-                    rt->asf_ctx->streams[i]->codec->extradata_size = 0;
-                    rt->asf_ctx->streams[i]->codec->extradata = NULL;
-                    av_set_pts_info(s->streams[stream_index], 32, 1, 1000);
-                }
-           }
-        }
-    }
-
-    return 0;
-}
-
-struct PayloadContext {
-    ByteIOContext *pktbuf, pb;
-    char *buf;
-};
-
-/**
- * @return 0 when a packet was written into /p pkt, and no more data is left;
- *         1 when a packet was written into /p pkt, and more packets might be left;
- *        <0 when not enough data was provided to return a full packet, or on error.
- */
-static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,
-                               AVStream *st, AVPacket *pkt,
-                               uint32_t *timestamp,
-                               const uint8_t *buf, int len, int flags)
-{
-    ByteIOContext *pb = &asf->pb;
-    int res, mflags, len_off;
-    RTSPState *rt = s->priv_data;
-
-    if (!rt->asf_ctx)
-        return -1;
-
-    if (len > 0) {
-        int off, out_len;
-
-        if (len < 4)
-            return -1;
-
-        init_put_byte(pb, buf, len, 0, NULL, NULL, NULL, NULL);
-        mflags = get_byte(pb);
-        if (mflags & 0x80)
-            flags |= RTP_FLAG_KEY;
-        len_off = get_be24(pb);
-        if (mflags & 0x20)   /**< relative timestamp */
-            url_fskip(pb, 4);
-        if (mflags & 0x10)   /**< has duration */
-            url_fskip(pb, 4);
-        if (mflags & 0x8)    /**< has location ID */
-            url_fskip(pb, 4);
-        off = url_ftell(pb);
-
-        av_freep(&asf->buf);
-        if (!(mflags & 0x40)) {
-            /**
-             * If 0x40 is not set, the len_off field specifies an offset of this
-             * packet's payload data in the complete (reassembled) ASF packet.
-             * This is used to spread one ASF packet over multiple RTP packets.
-             */
-            if (asf->pktbuf && len_off != url_ftell(asf->pktbuf)) {
-                uint8_t *p;
-                url_close_dyn_buf(asf->pktbuf, &p);
-                asf->pktbuf = NULL;
-                av_free(p);
-            }
-            if (!len_off && !asf->pktbuf &&
-                (res = url_open_dyn_buf(&asf->pktbuf)) < 0)
-                return res;
-            if (!asf->pktbuf)
-                return AVERROR(EIO);
-
-            put_buffer(asf->pktbuf, buf + off, len - off);
-            if (!(flags & RTP_FLAG_MARKER))
-                return -1;
-            out_len     = url_close_dyn_buf(asf->pktbuf, &asf->buf);
-            asf->pktbuf = NULL;
-        } else {
-            /**
-             * If 0x40 is set, the len_off field specifies the length of the
-             * next ASF packet that can be read from this payload data alone.
-             * This is commonly the same as the payload size, but could be
-             * less in case of packet splitting (i.e. multiple ASF packets in
-             * one RTP packet).
-             */
-            if (len_off != len) {
-                av_log_missing_feature(s,
-                    "RTSP-MS packet splitting", 1);
-                return -1;
-            }
-            asf->buf = av_malloc(len - off);
-            out_len  = len - off;
-            memcpy(asf->buf, buf + off, len - off);
-        }
-
-        init_packetizer(pb, asf->buf, out_len);
-        pb->pos += rt->asf_pb_pos;
-        pb->eof_reached = 0;
-        rt->asf_ctx->pb = pb;
-    }
-
-    for (;;) {
-        int i;
-
-        res = av_read_packet(rt->asf_ctx, pkt);
-        rt->asf_pb_pos = url_ftell(pb);
-        if (res != 0)
-            break;
-        for (i = 0; i < s->nb_streams; i++) {
-            if (s->streams[i]->id == rt->asf_ctx->streams[pkt->stream_index]->id) {
-                pkt->stream_index = i;
-                return 1; // FIXME: return 0 if last packet
-            }
-        }
-        av_free_packet(pkt);
-    }
-
-    return res == 1 ? -1 : res;
-}
-
-static PayloadContext *asfrtp_new_context(void)
-{
-    return av_mallocz(sizeof(PayloadContext));
-}
-
-static void asfrtp_free_context(PayloadContext *asf)
-{
-    if (asf->pktbuf) {
-        uint8_t *p = NULL;
-        url_close_dyn_buf(asf->pktbuf, &p);
-        asf->pktbuf = NULL;
-        av_free(p);
-    }
-    av_freep(&asf->buf);
-    av_free(asf);
-}
-
-#define RTP_ASF_HANDLER(n, s, t) \
-RTPDynamicProtocolHandler ff_ms_rtp_ ## n ## _handler = { \
-    .enc_name         = s, \
-    .codec_type       = t, \
-    .codec_id         = CODEC_ID_NONE, \
-    .parse_sdp_a_line = asfrtp_parse_sdp_line, \
-    .open             = asfrtp_new_context, \
-    .close            = asfrtp_free_context, \
-    .parse_packet     = asfrtp_parse_packet,   \
-};
-
-RTP_ASF_HANDLER(asf_pfv, "x-asf-pf",  CODEC_TYPE_VIDEO);
-RTP_ASF_HANDLER(asf_pfa, "x-asf-pf",  CODEC_TYPE_AUDIO);
--- a/rtp_asf.h	Sun Feb 28 03:59:15 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Microsoft RTP/ASF support.
- * Copyright (c) 2008 Ronald S. Bultje
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVFORMAT_RTP_ASF_H
-#define AVFORMAT_RTP_ASF_H
-
-#include "avformat.h"
-#include "rtpdec.h"
-
-/**
- * Parse a Windows Media Server-specific SDP line
- *
- * @param s RTSP demux context
- * @param line the SDP line to be parsed
- */
-void ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p);
-
-/**
- * Handlers for the x-asf-pf payloads (the payload ID for RTP/ASF).
- * Defined and implemented in rtp_asf.c, registered in rtpdec.c.
- */
-extern RTPDynamicProtocolHandler ff_ms_rtp_asf_pfv_handler,
-                                 ff_ms_rtp_asf_pfa_handler;
-
-#endif /* AVFORMAT_RTP_ASF_H */
--- a/rtp_h264.c	Sun Feb 28 03:59:15 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,416 +0,0 @@
-/*
- * RTP H264 Protocol (RFC3984)
- * Copyright (c) 2006 Ryan Martell
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
-* @file libavformat/rtp_h264.c
- * @brief H.264 / RTP Code (RFC3984)
- * @author Ryan Martell <rdm4@martellventures.com>
- *
- * @note Notes:
- * Notes:
- * This currently supports packetization mode:
- * Single Nal Unit Mode (0), or
- * Non-Interleaved Mode (1).  It currently does not support
- * Interleaved Mode (2). (This requires implementing STAP-B, MTAP16, MTAP24, FU-B packet types)
- *
- * @note TODO:
- * 1) RTCP sender reports for udp streams are required..
- *
- */
-
-#include "libavutil/base64.h"
-#include "libavutil/avstring.h"
-#include "libavcodec/get_bits.h"
-#include "avformat.h"
-#include "mpegts.h"
-
-#include <unistd.h>
-#include "network.h"
-#include <assert.h>
-
-#include "rtpdec.h"
-#include "rtp_h264.h"
-
-/**
-    RTP/H264 specific private data.
-*/
-struct PayloadContext {
-    unsigned long cookie;       ///< sanity check, to make sure we get the pointer we're expecting.
-
-    //sdp setup parameters
-    uint8_t profile_idc;        ///< from the sdp setup parameters.
-    uint8_t profile_iop;        ///< from the sdp setup parameters.
-    uint8_t level_idc;          ///< from the sdp setup parameters.
-    int packetization_mode;     ///< from the sdp setup parameters.
-#ifdef DEBUG
-    int packet_types_received[32];
-#endif
-};
-
-#define MAGIC_COOKIE (0xdeadbeef)       ///< Cookie for the extradata; to verify we are what we think we are, and that we haven't been freed.
-#define DEAD_COOKIE (0xdeaddead)        ///< Cookie for the extradata; once it is freed.
-
-/* ---------------- private code */
-static void sdp_parse_fmtp_config_h264(AVStream * stream,
-                                       PayloadContext * h264_data,
-                                       char *attr, char *value)
-{
-    AVCodecContext *codec = stream->codec;
-    assert(codec->codec_id == CODEC_ID_H264);
-    assert(h264_data != NULL);
-
-    if (!strcmp(attr, "packetization-mode")) {
-        av_log(codec, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value));
-        h264_data->packetization_mode = atoi(value);
-        /*
-           Packetization Mode:
-           0 or not present: Single NAL mode (Only nals from 1-23 are allowed)
-           1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed.
-           2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), and 29 (FU-B) are allowed.
-         */
-        if (h264_data->packetization_mode > 1)
-            av_log(codec, AV_LOG_ERROR,
-                   "Interleaved RTP mode is not supported yet.");
-    } else if (!strcmp(attr, "profile-level-id")) {
-        if (strlen(value) == 6) {
-            char buffer[3];
-            // 6 characters=3 bytes, in hex.
-            uint8_t profile_idc;
-            uint8_t profile_iop;
-            uint8_t level_idc;
-
-            buffer[0] = value[0]; buffer[1] = value[1]; buffer[2] = '\0';
-            profile_idc = strtol(buffer, NULL, 16);
-            buffer[0] = value[2]; buffer[1] = value[3];
-            profile_iop = strtol(buffer, NULL, 16);
-            buffer[0] = value[4]; buffer[1] = value[5];
-            level_idc = strtol(buffer, NULL, 16);
-
-            // set the parameters...
-            av_log(codec, AV_LOG_DEBUG,
-                   "RTP Profile IDC: %x Profile IOP: %x Level: %x\n",
-                   profile_idc, profile_iop, level_idc);
-            h264_data->profile_idc = profile_idc;
-            h264_data->profile_iop = profile_iop;
-            h264_data->level_idc = level_idc;
-        }
-    } else  if (!strcmp(attr, "sprop-parameter-sets")) {
-        uint8_t start_sequence[]= { 0, 0, 1 };
-        codec->extradata_size= 0;
-        codec->extradata= NULL;
-
-        while (*value) {
-            char base64packet[1024];
-            uint8_t decoded_packet[1024];
-            uint32_t packet_size;
-            char *dst = base64packet;
-
-            while (*value && *value != ','
-                   && (dst - base64packet) < sizeof(base64packet) - 1) {
-                *dst++ = *value++;
-            }
-            *dst++ = '\0';
-
-            if (*value == ',')
-                value++;
-
-            packet_size= av_base64_decode(decoded_packet, base64packet, sizeof(decoded_packet));
-            if (packet_size) {
-                uint8_t *dest= av_malloc(packet_size+sizeof(start_sequence)+codec->extradata_size);
-                if(dest)
-                {
-                    if(codec->extradata_size)
-                    {
-                        // av_realloc?
-                        memcpy(dest, codec->extradata, codec->extradata_size);
-                        av_free(codec->extradata);
-                    }
-
-                    memcpy(dest+codec->extradata_size, start_sequence, sizeof(start_sequence));
-                    memcpy(dest+codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size);
-
-                    codec->extradata= dest;
-                    codec->extradata_size+= sizeof(start_sequence)+packet_size;
-                } else {
-                    av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!");
-                }
-            }
-        }
-        av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!", codec->extradata, codec->extradata_size);
-    }
-}
-
-// return 0 on packet, no more left, 1 on packet, 1 on partial packet...
-static int h264_handle_packet(AVFormatContext *ctx,
-                              PayloadContext *data,
-                              AVStream *st,
-                              AVPacket * pkt,
-                              uint32_t * timestamp,
-                              const uint8_t * buf,
-                              int len, int flags)
-{
-    uint8_t nal = buf[0];
-    uint8_t type = (nal & 0x1f);
-    int result= 0;
-    uint8_t start_sequence[]= {0, 0, 1};
-
-#ifdef DEBUG
-    assert(data);
-    assert(data->cookie == MAGIC_COOKIE);
-#endif
-    assert(buf);
-
-    if (type >= 1 && type <= 23)
-        type = 1;              // simplify the case. (these are all the nal types used internally by the h264 codec)
-    switch (type) {
-    case 0:                    // undefined;
-        result= -1;
-        break;
-
-    case 1:
-        av_new_packet(pkt, len+sizeof(start_sequence));
-        memcpy(pkt->data, start_sequence, sizeof(start_sequence));
-        memcpy(pkt->data+sizeof(start_sequence), buf, len);
-#ifdef DEBUG
-        data->packet_types_received[nal & 0x1f]++;
-#endif
-        break;
-
-    case 24:                   // STAP-A (one packet, multiple nals)
-        // consume the STAP-A NAL
-        buf++;
-        len--;
-        // first we are going to figure out the total size....
-        {
-            int pass= 0;
-            int total_length= 0;
-            uint8_t *dst= NULL;
-
-            for(pass= 0; pass<2; pass++) {
-                const uint8_t *src= buf;
-                int src_len= len;
-
-                do {
-                    uint16_t nal_size = AV_RB16(src); // this going to be a problem if unaligned (can it be?)
-
-                    // consume the length of the aggregate...
-                    src += 2;
-                    src_len -= 2;
-
-                    if (nal_size <= src_len) {
-                        if(pass==0) {
-                            // counting...
-                            total_length+= sizeof(start_sequence)+nal_size;
-                        } else {
-                            // copying
-                            assert(dst);
-                            memcpy(dst, start_sequence, sizeof(start_sequence));
-                            dst+= sizeof(start_sequence);
-                            memcpy(dst, src, nal_size);
-#ifdef DEBUG
-                            data->packet_types_received[*src & 0x1f]++;
-#endif
-                            dst+= nal_size;
-                        }
-                    } else {
-                        av_log(ctx, AV_LOG_ERROR,
-                               "nal size exceeds length: %d %d\n", nal_size, src_len);
-                    }
-
-                    // eat what we handled...
-                    src += nal_size;
-                    src_len -= nal_size;
-
-                    if (src_len < 0)
-                        av_log(ctx, AV_LOG_ERROR,
-                               "Consumed more bytes than we got! (%d)\n", src_len);
-                } while (src_len > 2);      // because there could be rtp padding..
-
-                if(pass==0) {
-                    // now we know the total size of the packet (with the start sequences added)
-                    av_new_packet(pkt, total_length);
-                    dst= pkt->data;
-                } else {
-                    assert(dst-pkt->data==total_length);
-                }
-            }
-        }
-        break;
-
-    case 25:                   // STAP-B
-    case 26:                   // MTAP-16
-    case 27:                   // MTAP-24
-    case 29:                   // FU-B
-        av_log(ctx, AV_LOG_ERROR,
-               "Unhandled type (%d) (See RFC for implementation details\n",
-               type);
-        result= -1;
-        break;
-
-    case 28:                   // FU-A (fragmented nal)
-        buf++;
-        len--;                  // skip the fu_indicator
-        {
-            // these are the same as above, we just redo them here for clarity...
-            uint8_t fu_indicator = nal;
-            uint8_t fu_header = *buf;   // read the fu_header.
-            uint8_t start_bit = fu_header >> 7;
-//            uint8_t end_bit = (fu_header & 0x40) >> 6;
-            uint8_t nal_type = (fu_header & 0x1f);
-            uint8_t reconstructed_nal;
-
-            // reconstruct this packet's true nal; only the data follows..
-            reconstructed_nal = fu_indicator & (0xe0);  // the original nal forbidden bit and NRI are stored in this packet's nal;
-            reconstructed_nal |= nal_type;
-
-            // skip the fu_header...
-            buf++;
-            len--;
-
-#ifdef DEBUG
-            if (start_bit)
-                data->packet_types_received[nal_type]++;
-#endif
-            if(start_bit) {
-                // copy in the start sequence, and the reconstructed nal....
-                av_new_packet(pkt, sizeof(start_sequence)+sizeof(nal)+len);
-                memcpy(pkt->data, start_sequence, sizeof(start_sequence));
-                pkt->data[sizeof(start_sequence)]= reconstructed_nal;
-                memcpy(pkt->data+sizeof(start_sequence)+sizeof(nal), buf, len);
-            } else {
-                av_new_packet(pkt, len);
-                memcpy(pkt->data, buf, len);
-            }
-        }
-        break;
-
-    case 30:                   // undefined
-    case 31:                   // undefined
-    default:
-        av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)", type);
-        result= -1;
-        break;
-    }
-
-    pkt->stream_index = st->index;
-
-    return result;
-}
-
-/* ---------------- public code */
-static PayloadContext *h264_new_context(void)
-{
-    PayloadContext *data =
-        av_mallocz(sizeof(PayloadContext) +
-                   FF_INPUT_BUFFER_PADDING_SIZE);
-
-    if (data) {
-        data->cookie = MAGIC_COOKIE;
-    }
-
-    return data;
-}
-
-static void h264_free_context(PayloadContext *data)
-{
-#ifdef DEBUG
-    int ii;
-
-    for (ii = 0; ii < 32; ii++) {
-        if (data->packet_types_received[ii])
-            av_log(NULL, AV_LOG_DEBUG, "Received %d packets of type %d\n",
-                   data->packet_types_received[ii], ii);
-    }
-#endif
-
-    assert(data);
-    assert(data->cookie == MAGIC_COOKIE);
-
-    // avoid stale pointers (assert)
-    data->cookie = DEAD_COOKIE;
-
-    // and clear out this...
-    av_free(data);
-}
-
-static int parse_h264_sdp_line(AVFormatContext *s, int st_index,
-                               PayloadContext *h264_data, const char *line)
-{
-    AVStream *stream = s->streams[st_index];
-    AVCodecContext *codec = stream->codec;
-    const char *p = line;
-
-    assert(h264_data->cookie == MAGIC_COOKIE);
-
-    if (av_strstart(p, "framesize:", &p)) {
-        char buf1[50];
-        char *dst = buf1;
-
-        // remove the protocol identifier..
-        while (*p && *p == ' ') p++; // strip spaces.
-        while (*p && *p != ' ') p++; // eat protocol identifier
-        while (*p && *p == ' ') p++; // strip trailing spaces.
-        while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) {
-            *dst++ = *p++;
-        }
-        *dst = '\0';
-
-        // a='framesize:96 320-240'
-        // set our parameters..
-        codec->width = atoi(buf1);
-        codec->height = atoi(p + 1); // skip the -
-        codec->pix_fmt = PIX_FMT_YUV420P;
-    } else if (av_strstart(p, "fmtp:", &p)) {
-        char attr[256];
-        char value[4096];
-
-        // remove the protocol identifier..
-        while (*p && *p == ' ') p++; // strip spaces.
-        while (*p && *p != ' ') p++; // eat protocol identifier
-        while (*p && *p == ' ') p++; // strip trailing spaces.
-
-        /* loop on each attribute */
-        while (ff_rtsp_next_attr_and_value
-               (&p, attr, sizeof(attr), value, sizeof(value))) {
-            /* grab the codec extra_data from the config parameter of the fmtp line */
-            sdp_parse_fmtp_config_h264(stream, h264_data, attr, value);
-        }
-    } else if (av_strstart(p, "cliprect:", &p)) {
-        // could use this if we wanted.
-    }
-
-    av_set_pts_info(stream, 33, 1, 90000);      // 33 should be right, because the pts is 64 bit? (done elsewhere; this is a one time thing)
-
-    return 0;                   // keep processing it the normal way...
-}
-
-/**
-This is the structure for expanding on the dynamic rtp protocols (makes everything static. yay!)
-*/
-RTPDynamicProtocolHandler ff_h264_dynamic_handler = {
-    .enc_name         = "H264",
-    .codec_type       = CODEC_TYPE_VIDEO,
-    .codec_id         = CODEC_ID_H264,
-    .parse_sdp_a_line = parse_h264_sdp_line,
-    .open             = h264_new_context,
-    .close            = h264_free_context,
-    .parse_packet     = h264_handle_packet
-};
--- a/rtp_h264.h	Sun Feb 28 03:59:15 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * RTP H264 Protocol (RFC3984)
- * Copyright (c) 2006 Ryan Martell
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVFORMAT_RTP_H264_H
-#define AVFORMAT_RTP_H264_H
-
-#include "rtpdec.h"
-
-extern RTPDynamicProtocolHandler ff_h264_dynamic_handler;
-
-#endif /* AVFORMAT_RTP_H264_H */
--- a/rtp_vorbis.c	Sun Feb 28 03:59:15 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-/*
- * RTP Vorbis Protocol (RFC5215)
- * Copyright (c) 2009 Colin McQuillan
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file libavformat/rtp_vorbis.c
- * @brief Vorbis / RTP Code (RFC 5215)
- * @author Colin McQuillan <m.niloc@gmail.com>
- */
-
-#include "libavutil/base64.h"
-#include "libavutil/avstring.h"
-#include "libavcodec/bytestream.h"
-
-#include <assert.h>
-
-#include "rtpdec.h"
-#include "rtp_vorbis.h"
-
-/**
- * RTP/Vorbis specific private data.
- */
-struct PayloadContext {
-    unsigned ident;             ///< 24-bit stream configuration identifier
-};
-
-/**
- * Length encoding described in RFC5215 section 3.1.1.
- */
-static int get_base128(const uint8_t ** buf, const uint8_t * buf_end)
-{
-    int n = 0;
-    for (; *buf < buf_end; ++*buf) {
-        n <<= 7;
-        n += **buf & 0x7f;
-        if (!(**buf & 0x80)) {
-            ++*buf;
-            return n;
-        }
-    }
-    return 0;
-}
-
-/**
- * Out-of-band headers, described in RFC 5251 section 3.2.1
- */
-static unsigned int
-parse_packed_headers(const uint8_t * packed_headers,
-                     const uint8_t * packed_headers_end,
-                     AVCodecContext * codec, PayloadContext * vorbis_data)
-{
-    unsigned num_packed, num_headers, length, length1, length2;
-    uint8_t *ptr;
-
-    num_packed         = bytestream_get_be32(&packed_headers);
-    vorbis_data->ident = bytestream_get_be24(&packed_headers);
-    length             = bytestream_get_be16(&packed_headers);
-    num_headers        = get_base128(&packed_headers, packed_headers_end);
-    length1            = get_base128(&packed_headers, packed_headers_end);
-    length2            = get_base128(&packed_headers, packed_headers_end);
-
-    if (num_packed != 1 || num_headers > 3) {
-        av_log(codec, AV_LOG_ERROR,
-               "Unimplemented number of headers: %d packed headers, %d headers\n",
-               num_packed, num_headers);
-        return AVERROR_PATCHWELCOME;
-    }
-
-    if (packed_headers_end - packed_headers != length ||
-        length1 > length || length2 > length - length1) {
-        av_log(codec, AV_LOG_ERROR,
-               "Bad packed header lengths (%d,%d,%d,%d)\n", length1,
-               length2, packed_headers_end - packed_headers, length);
-        return AVERROR_INVALIDDATA;
-    }
-
-    ptr = codec->extradata = av_mallocz(length + length / 255 + 64);
-    if (!ptr) {
-        av_log(codec, AV_LOG_ERROR, "Out of memory");
-        return AVERROR_NOMEM;
-    }
-    *ptr++ = 2;
-    ptr += av_xiphlacing(ptr, length1);
-    ptr += av_xiphlacing(ptr, length2);
-    memcpy(ptr, packed_headers, length);
-    ptr += length;
-    codec->extradata_size = ptr - codec->extradata;
-
-    return 0;
-}
-
-int
-ff_vorbis_parse_fmtp_config(AVCodecContext * codec,
-                            void *vorbis_data, char *attr, char *value)
-{
-    int result = 0;
-    assert(codec->codec_id == CODEC_ID_VORBIS);
-    assert(vorbis_data);
-
-    // The configuration value is a base64 encoded packed header
-    if (!strcmp(attr, "configuration")) {
-        uint8_t *decoded_packet = NULL;
-        int packet_size;
-        size_t decoded_alloc = strlen(value) / 4 * 3 + 4;
-
-        if (decoded_alloc <= INT_MAX) {
-            decoded_packet = av_malloc(decoded_alloc);
-            if (decoded_packet) {
-                packet_size =
-                    av_base64_decode(decoded_packet, value, decoded_alloc);
-
-                result = parse_packed_headers
-                    (decoded_packet, decoded_packet + packet_size, codec,
-                     vorbis_data);
-            } else {
-                av_log(codec, AV_LOG_ERROR,
-                       "Out of memory while decoding SDP configuration.\n");
-                result = AVERROR_NOMEM;
-            }
-        } else {
-            av_log(codec, AV_LOG_ERROR, "Packet too large\n");
-            result = AVERROR_INVALIDDATA;
-        }
-        av_free(decoded_packet);
-    }
-    return result;
-}
-
-static PayloadContext *vorbis_new_context(void)
-{
-    return av_mallocz(sizeof(PayloadContext));
-}
-
-static void vorbis_free_context(PayloadContext * data)
-{
-    av_free(data);
-}
-
-/**
- * Handle payload as described in RFC 5215 section 2.2
- */
-static int
-vorbis_handle_packet(AVFormatContext * ctx,
-                     PayloadContext * data,
-                     AVStream * st,
-                     AVPacket * pkt,
-                     uint32_t * timestamp,
-                     const uint8_t * buf, int len, int flags)
-{
-    int ident, fragmented, vdt, num_pkts, pkt_len;
-
-    if (len < 6) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid %d byte packet\n", len);
-        return AVERROR_INVALIDDATA;
-    }
-
-    ident = AV_RB24(buf);
-    fragmented = buf[3] >> 6;
-    vdt = (buf[3] >> 4) & 3;
-    num_pkts = buf[3] & 7;
-    pkt_len = AV_RB16(buf + 4);
-
-    if (pkt_len > len - 6) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Invalid packet length %d in %d byte packet\n", pkt_len,
-               len);
-        return AVERROR_INVALIDDATA;
-    }
-
-    if (ident != data->ident) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Unimplemented Vorbis SDP configuration change detected\n");
-        return AVERROR_PATCHWELCOME;
-    }
-
-    if (fragmented != 0 || vdt != 0 || num_pkts != 1) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Unimplemented RTP Vorbis packet settings (%d,%d,%d)\n",
-               fragmented, vdt, num_pkts);
-        return AVERROR_PATCHWELCOME;
-    }
-
-    if (av_new_packet(pkt, pkt_len)) {
-        av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
-        return AVERROR_NOMEM;
-    }
-
-    memcpy(pkt->data, buf + 6, pkt_len);
-    pkt->stream_index = st->index;
-    return 0;
-}
-
-RTPDynamicProtocolHandler ff_vorbis_dynamic_handler = {
-    .enc_name         = "vorbis",
-    .codec_type       = CODEC_TYPE_AUDIO,
-    .codec_id         = CODEC_ID_VORBIS,
-    .parse_sdp_a_line = NULL,
-    .open             = vorbis_new_context,
-    .close            = vorbis_free_context,
-    .parse_packet     = vorbis_handle_packet
-};
--- a/rtp_vorbis.h	Sun Feb 28 03:59:15 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * RTP Vorbis Protocol (RFC 5215)
- * Copyright (c) 2009 Colin McQuillan
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVFORMAT_RTP_VORBIS_H
-#define AVFORMAT_RTP_VORBIS_H
-
-#include "libavcodec/avcodec.h"
-#include "rtpdec.h"
-
-/**
- * Handle a Vorbis-specific FMTP parameter
- *
- * @param codec The context of the codec
- * @param ctx Private Vorbis RTP context
- * @param attr Format-specific parameter name
- * @param value Format-specific paremeter value
- */
-int
-ff_vorbis_parse_fmtp_config(AVCodecContext * codec,
-                            void *ctx, char *attr, char *value);
-
-/**
- * Vorbis RTP callbacks.
- */
-extern RTPDynamicProtocolHandler ff_vorbis_dynamic_handler;
-
-#endif /* AVFORMAT_RTP_VORBIS_H */
--- a/rtpdec.c	Sun Feb 28 03:59:15 2010 +0000
+++ b/rtpdec.c	Sun Feb 28 11:03:14 2010 +0000
@@ -30,11 +30,11 @@
 #include "network.h"
 
 #include "rtpdec.h"
-#include "rtp_asf.h"
-#include "rtp_h264.h"
-#include "rtp_vorbis.h"
 #include "rtpdec_amr.h"
+#include "rtpdec_asf.h"
 #include "rtpdec_h263.h"
+#include "rtpdec_h264.h"
+#include "rtpdec_vorbis.h"
 
 //#define DEBUG
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtpdec_asf.c	Sun Feb 28 11:03:14 2010 +0000
@@ -0,0 +1,281 @@
+/*
+ * Microsoft RTP/ASF support.
+ * Copyright (c) 2008 Ronald S. Bultje
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file libavformat/rtpdec_asf.c
+ * @brief Microsoft RTP/ASF support
+ * @author Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ */
+
+#include <libavutil/base64.h>
+#include <libavutil/avstring.h>
+#include <libavutil/intreadwrite.h>
+#include "rtp.h"
+#include "rtpdec_asf.h"
+#include "rtsp.h"
+#include "asf.h"
+
+/**
+ * From MSDN 2.2.1.4, we learn that ASF data packets over RTP should not
+ * contain any padding. Unfortunately, the header min/max_pktsize are not
+ * updated (thus making min_pktsize invalid). Here, we "fix" these faulty
+ * min_pktsize values in the ASF file header.
+ * @return 0 on success, <0 on failure (currently -1).
+ */
+static int rtp_asf_fix_header(uint8_t *buf, int len)
+{
+    uint8_t *p = buf, *end = buf + len;
+
+    if (len < sizeof(ff_asf_guid) * 2 + 22 ||
+        memcmp(p, ff_asf_header, sizeof(ff_asf_guid))) {
+        return -1;
+    }
+    p += sizeof(ff_asf_guid) + 14;
+    do {
+        uint64_t chunksize = AV_RL64(p + sizeof(ff_asf_guid));
+        if (memcmp(p, ff_asf_file_header, sizeof(ff_asf_guid))) {
+            if (chunksize > end - p)
+                return -1;
+            p += chunksize;
+            continue;
+        }
+
+        /* skip most of the file header, to min_pktsize */
+        p += 6 * 8 + 3 * 4 + sizeof(ff_asf_guid) * 2;
+        if (p + 8 <= end && AV_RL32(p) == AV_RL32(p + 4)) {
+            /* and set that to zero */
+            AV_WL32(p, 0);
+            return 0;
+        }
+        break;
+    } while (end - p >= sizeof(ff_asf_guid) + 8);
+
+    return -1;
+}
+
+/**
+ * The following code is basically a buffered ByteIOContext,
+ * with the added benefit of returning -EAGAIN (instead of 0)
+ * on packet boundaries, such that the ASF demuxer can return
+ * safely and resume business at the next packet.
+ */
+static int packetizer_read(void *opaque, uint8_t *buf, int buf_size)
+{
+    return AVERROR(EAGAIN);
+}
+
+static void init_packetizer(ByteIOContext *pb, uint8_t *buf, int len)
+{
+    init_put_byte(pb, buf, len, 0, NULL, packetizer_read, NULL, NULL);
+
+    /* this "fills" the buffer with its current content */
+    pb->pos     = len;
+    pb->buf_end = buf + len;
+}
+
+void ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p)
+{
+    if (av_strstart(p, "pgmpu:data:application/vnd.ms.wms-hdr.asfv1;base64,", &p)) {
+        ByteIOContext pb;
+        RTSPState *rt = s->priv_data;
+        int len = strlen(p) * 6 / 8;
+        char *buf = av_mallocz(len);
+        av_base64_decode(buf, p, len);
+
+        if (rtp_asf_fix_header(buf, len) < 0)
+            av_log(s, AV_LOG_ERROR,
+                   "Failed to fix invalid RTSP-MS/ASF min_pktsize\n");
+        init_packetizer(&pb, buf, len);
+        if (rt->asf_ctx) {
+            av_close_input_stream(rt->asf_ctx);
+            rt->asf_ctx = NULL;
+        }
+        av_open_input_stream(&rt->asf_ctx, &pb, "", &asf_demuxer, NULL);
+        rt->asf_pb_pos = url_ftell(&pb);
+        av_free(buf);
+        rt->asf_ctx->pb = NULL;
+    }
+}
+
+static int asfrtp_parse_sdp_line(AVFormatContext *s, int stream_index,
+                                 PayloadContext *asf, const char *line)
+{
+    if (av_strstart(line, "stream:", &line)) {
+        RTSPState *rt = s->priv_data;
+
+        s->streams[stream_index]->id = strtol(line, NULL, 10);
+
+        if (rt->asf_ctx) {
+            int i;
+
+            for (i = 0; i < rt->asf_ctx->nb_streams; i++) {
+                if (s->streams[stream_index]->id == rt->asf_ctx->streams[i]->id) {
+                    *s->streams[stream_index]->codec =
+                        *rt->asf_ctx->streams[i]->codec;
+                    rt->asf_ctx->streams[i]->codec->extradata_size = 0;
+                    rt->asf_ctx->streams[i]->codec->extradata = NULL;
+                    av_set_pts_info(s->streams[stream_index], 32, 1, 1000);
+                }
+           }
+        }
+    }
+
+    return 0;
+}
+
+struct PayloadContext {
+    ByteIOContext *pktbuf, pb;
+    char *buf;
+};
+
+/**
+ * @return 0 when a packet was written into /p pkt, and no more data is left;
+ *         1 when a packet was written into /p pkt, and more packets might be left;
+ *        <0 when not enough data was provided to return a full packet, or on error.
+ */
+static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,
+                               AVStream *st, AVPacket *pkt,
+                               uint32_t *timestamp,
+                               const uint8_t *buf, int len, int flags)
+{
+    ByteIOContext *pb = &asf->pb;
+    int res, mflags, len_off;
+    RTSPState *rt = s->priv_data;
+
+    if (!rt->asf_ctx)
+        return -1;
+
+    if (len > 0) {
+        int off, out_len;
+
+        if (len < 4)
+            return -1;
+
+        init_put_byte(pb, buf, len, 0, NULL, NULL, NULL, NULL);
+        mflags = get_byte(pb);
+        if (mflags & 0x80)
+            flags |= RTP_FLAG_KEY;
+        len_off = get_be24(pb);
+        if (mflags & 0x20)   /**< relative timestamp */
+            url_fskip(pb, 4);
+        if (mflags & 0x10)   /**< has duration */
+            url_fskip(pb, 4);
+        if (mflags & 0x8)    /**< has location ID */
+            url_fskip(pb, 4);
+        off = url_ftell(pb);
+
+        av_freep(&asf->buf);
+        if (!(mflags & 0x40)) {
+            /**
+             * If 0x40 is not set, the len_off field specifies an offset of this
+             * packet's payload data in the complete (reassembled) ASF packet.
+             * This is used to spread one ASF packet over multiple RTP packets.
+             */
+            if (asf->pktbuf && len_off != url_ftell(asf->pktbuf)) {
+                uint8_t *p;
+                url_close_dyn_buf(asf->pktbuf, &p);
+                asf->pktbuf = NULL;
+                av_free(p);
+            }
+            if (!len_off && !asf->pktbuf &&
+                (res = url_open_dyn_buf(&asf->pktbuf)) < 0)
+                return res;
+            if (!asf->pktbuf)
+                return AVERROR(EIO);
+
+            put_buffer(asf->pktbuf, buf + off, len - off);
+            if (!(flags & RTP_FLAG_MARKER))
+                return -1;
+            out_len     = url_close_dyn_buf(asf->pktbuf, &asf->buf);
+            asf->pktbuf = NULL;
+        } else {
+            /**
+             * If 0x40 is set, the len_off field specifies the length of the
+             * next ASF packet that can be read from this payload data alone.
+             * This is commonly the same as the payload size, but could be
+             * less in case of packet splitting (i.e. multiple ASF packets in
+             * one RTP packet).
+             */
+            if (len_off != len) {
+                av_log_missing_feature(s,
+                    "RTSP-MS packet splitting", 1);
+                return -1;
+            }
+            asf->buf = av_malloc(len - off);
+            out_len  = len - off;
+            memcpy(asf->buf, buf + off, len - off);
+        }
+
+        init_packetizer(pb, asf->buf, out_len);
+        pb->pos += rt->asf_pb_pos;
+        pb->eof_reached = 0;
+        rt->asf_ctx->pb = pb;
+    }
+
+    for (;;) {
+        int i;
+
+        res = av_read_packet(rt->asf_ctx, pkt);
+        rt->asf_pb_pos = url_ftell(pb);
+        if (res != 0)
+            break;
+        for (i = 0; i < s->nb_streams; i++) {
+            if (s->streams[i]->id == rt->asf_ctx->streams[pkt->stream_index]->id) {
+                pkt->stream_index = i;
+                return 1; // FIXME: return 0 if last packet
+            }
+        }
+        av_free_packet(pkt);
+    }
+
+    return res == 1 ? -1 : res;
+}
+
+static PayloadContext *asfrtp_new_context(void)
+{
+    return av_mallocz(sizeof(PayloadContext));
+}
+
+static void asfrtp_free_context(PayloadContext *asf)
+{
+    if (asf->pktbuf) {
+        uint8_t *p = NULL;
+        url_close_dyn_buf(asf->pktbuf, &p);
+        asf->pktbuf = NULL;
+        av_free(p);
+    }
+    av_freep(&asf->buf);
+    av_free(asf);
+}
+
+#define RTP_ASF_HANDLER(n, s, t) \
+RTPDynamicProtocolHandler ff_ms_rtp_ ## n ## _handler = { \
+    .enc_name         = s, \
+    .codec_type       = t, \
+    .codec_id         = CODEC_ID_NONE, \
+    .parse_sdp_a_line = asfrtp_parse_sdp_line, \
+    .open             = asfrtp_new_context, \
+    .close            = asfrtp_free_context, \
+    .parse_packet     = asfrtp_parse_packet,   \
+};
+
+RTP_ASF_HANDLER(asf_pfv, "x-asf-pf",  CODEC_TYPE_VIDEO);
+RTP_ASF_HANDLER(asf_pfa, "x-asf-pf",  CODEC_TYPE_AUDIO);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtpdec_asf.h	Sun Feb 28 11:03:14 2010 +0000
@@ -0,0 +1,43 @@
+/*
+ * Microsoft RTP/ASF support.
+ * Copyright (c) 2008 Ronald S. Bultje
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFORMAT_RTPDEC_ASF_H
+#define AVFORMAT_RTPDEC_ASF_H
+
+#include "avformat.h"
+#include "rtpdec.h"
+
+/**
+ * Parse a Windows Media Server-specific SDP line
+ *
+ * @param s RTSP demux context
+ * @param line the SDP line to be parsed
+ */
+void ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p);
+
+/**
+ * Handlers for the x-asf-pf payloads (the payload ID for RTP/ASF).
+ * Defined and implemented in rtp_asf.c, registered in rtpdec.c.
+ */
+extern RTPDynamicProtocolHandler ff_ms_rtp_asf_pfv_handler,
+                                 ff_ms_rtp_asf_pfa_handler;
+
+#endif /* AVFORMAT_RTPDEC_ASF_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtpdec_h264.c	Sun Feb 28 11:03:14 2010 +0000
@@ -0,0 +1,416 @@
+/*
+ * RTP H264 Protocol (RFC3984)
+ * Copyright (c) 2006 Ryan Martell
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+* @file libavformat/rtpdec_h264.c
+ * @brief H.264 / RTP Code (RFC3984)
+ * @author Ryan Martell <rdm4@martellventures.com>
+ *
+ * @note Notes:
+ * Notes:
+ * This currently supports packetization mode:
+ * Single Nal Unit Mode (0), or
+ * Non-Interleaved Mode (1).  It currently does not support
+ * Interleaved Mode (2). (This requires implementing STAP-B, MTAP16, MTAP24, FU-B packet types)
+ *
+ * @note TODO:
+ * 1) RTCP sender reports for udp streams are required..
+ *
+ */
+
+#include "libavutil/base64.h"
+#include "libavutil/avstring.h"
+#include "libavcodec/get_bits.h"
+#include "avformat.h"
+#include "mpegts.h"
+
+#include <unistd.h>
+#include "network.h"
+#include <assert.h>
+
+#include "rtpdec.h"
+#include "rtpdec_h264.h"
+
+/**
+    RTP/H264 specific private data.
+*/
+struct PayloadContext {
+    unsigned long cookie;       ///< sanity check, to make sure we get the pointer we're expecting.
+
+    //sdp setup parameters
+    uint8_t profile_idc;        ///< from the sdp setup parameters.
+    uint8_t profile_iop;        ///< from the sdp setup parameters.
+    uint8_t level_idc;          ///< from the sdp setup parameters.
+    int packetization_mode;     ///< from the sdp setup parameters.
+#ifdef DEBUG
+    int packet_types_received[32];
+#endif
+};
+
+#define MAGIC_COOKIE (0xdeadbeef)       ///< Cookie for the extradata; to verify we are what we think we are, and that we haven't been freed.
+#define DEAD_COOKIE (0xdeaddead)        ///< Cookie for the extradata; once it is freed.
+
+/* ---------------- private code */
+static void sdp_parse_fmtp_config_h264(AVStream * stream,
+                                       PayloadContext * h264_data,
+                                       char *attr, char *value)
+{
+    AVCodecContext *codec = stream->codec;
+    assert(codec->codec_id == CODEC_ID_H264);
+    assert(h264_data != NULL);
+
+    if (!strcmp(attr, "packetization-mode")) {
+        av_log(codec, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value));
+        h264_data->packetization_mode = atoi(value);
+        /*
+           Packetization Mode:
+           0 or not present: Single NAL mode (Only nals from 1-23 are allowed)
+           1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed.
+           2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), and 29 (FU-B) are allowed.
+         */
+        if (h264_data->packetization_mode > 1)
+            av_log(codec, AV_LOG_ERROR,
+                   "Interleaved RTP mode is not supported yet.");
+    } else if (!strcmp(attr, "profile-level-id")) {
+        if (strlen(value) == 6) {
+            char buffer[3];
+            // 6 characters=3 bytes, in hex.
+            uint8_t profile_idc;
+            uint8_t profile_iop;
+            uint8_t level_idc;
+
+            buffer[0] = value[0]; buffer[1] = value[1]; buffer[2] = '\0';
+            profile_idc = strtol(buffer, NULL, 16);
+            buffer[0] = value[2]; buffer[1] = value[3];
+            profile_iop = strtol(buffer, NULL, 16);
+            buffer[0] = value[4]; buffer[1] = value[5];
+            level_idc = strtol(buffer, NULL, 16);
+
+            // set the parameters...
+            av_log(codec, AV_LOG_DEBUG,
+                   "RTP Profile IDC: %x Profile IOP: %x Level: %x\n",
+                   profile_idc, profile_iop, level_idc);
+            h264_data->profile_idc = profile_idc;
+            h264_data->profile_iop = profile_iop;
+            h264_data->level_idc = level_idc;
+        }
+    } else  if (!strcmp(attr, "sprop-parameter-sets")) {
+        uint8_t start_sequence[]= { 0, 0, 1 };
+        codec->extradata_size= 0;
+        codec->extradata= NULL;
+
+        while (*value) {
+            char base64packet[1024];
+            uint8_t decoded_packet[1024];
+            uint32_t packet_size;
+            char *dst = base64packet;
+
+            while (*value && *value != ','
+                   && (dst - base64packet) < sizeof(base64packet) - 1) {
+                *dst++ = *value++;
+            }
+            *dst++ = '\0';
+
+            if (*value == ',')
+                value++;
+
+            packet_size= av_base64_decode(decoded_packet, base64packet, sizeof(decoded_packet));
+            if (packet_size) {
+                uint8_t *dest= av_malloc(packet_size+sizeof(start_sequence)+codec->extradata_size);
+                if(dest)
+                {
+                    if(codec->extradata_size)
+                    {
+                        // av_realloc?
+                        memcpy(dest, codec->extradata, codec->extradata_size);
+                        av_free(codec->extradata);
+                    }
+
+                    memcpy(dest+codec->extradata_size, start_sequence, sizeof(start_sequence));
+                    memcpy(dest+codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size);
+
+                    codec->extradata= dest;
+                    codec->extradata_size+= sizeof(start_sequence)+packet_size;
+                } else {
+                    av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!");
+                }
+            }
+        }
+        av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!", codec->extradata, codec->extradata_size);
+    }
+}
+
+// return 0 on packet, no more left, 1 on packet, 1 on partial packet...
+static int h264_handle_packet(AVFormatContext *ctx,
+                              PayloadContext *data,
+                              AVStream *st,
+                              AVPacket * pkt,
+                              uint32_t * timestamp,
+                              const uint8_t * buf,
+                              int len, int flags)
+{
+    uint8_t nal = buf[0];
+    uint8_t type = (nal & 0x1f);
+    int result= 0;
+    uint8_t start_sequence[]= {0, 0, 1};
+
+#ifdef DEBUG
+    assert(data);
+    assert(data->cookie == MAGIC_COOKIE);
+#endif
+    assert(buf);
+
+    if (type >= 1 && type <= 23)
+        type = 1;              // simplify the case. (these are all the nal types used internally by the h264 codec)
+    switch (type) {
+    case 0:                    // undefined;
+        result= -1;
+        break;
+
+    case 1:
+        av_new_packet(pkt, len+sizeof(start_sequence));
+        memcpy(pkt->data, start_sequence, sizeof(start_sequence));
+        memcpy(pkt->data+sizeof(start_sequence), buf, len);
+#ifdef DEBUG
+        data->packet_types_received[nal & 0x1f]++;
+#endif
+        break;
+
+    case 24:                   // STAP-A (one packet, multiple nals)
+        // consume the STAP-A NAL
+        buf++;
+        len--;
+        // first we are going to figure out the total size....
+        {
+            int pass= 0;
+            int total_length= 0;
+            uint8_t *dst= NULL;
+
+            for(pass= 0; pass<2; pass++) {
+                const uint8_t *src= buf;
+                int src_len= len;
+
+                do {
+                    uint16_t nal_size = AV_RB16(src); // this going to be a problem if unaligned (can it be?)
+
+                    // consume the length of the aggregate...
+                    src += 2;
+                    src_len -= 2;
+
+                    if (nal_size <= src_len) {
+                        if(pass==0) {
+                            // counting...
+                            total_length+= sizeof(start_sequence)+nal_size;
+                        } else {
+                            // copying
+                            assert(dst);
+                            memcpy(dst, start_sequence, sizeof(start_sequence));
+                            dst+= sizeof(start_sequence);
+                            memcpy(dst, src, nal_size);
+#ifdef DEBUG
+                            data->packet_types_received[*src & 0x1f]++;
+#endif
+                            dst+= nal_size;
+                        }
+                    } else {
+                        av_log(ctx, AV_LOG_ERROR,
+                               "nal size exceeds length: %d %d\n", nal_size, src_len);
+                    }
+
+                    // eat what we handled...
+                    src += nal_size;
+                    src_len -= nal_size;
+
+                    if (src_len < 0)
+                        av_log(ctx, AV_LOG_ERROR,
+                               "Consumed more bytes than we got! (%d)\n", src_len);
+                } while (src_len > 2);      // because there could be rtp padding..
+
+                if(pass==0) {
+                    // now we know the total size of the packet (with the start sequences added)
+                    av_new_packet(pkt, total_length);
+                    dst= pkt->data;
+                } else {
+                    assert(dst-pkt->data==total_length);
+                }
+            }
+        }
+        break;
+
+    case 25:                   // STAP-B
+    case 26:                   // MTAP-16
+    case 27:                   // MTAP-24
+    case 29:                   // FU-B
+        av_log(ctx, AV_LOG_ERROR,
+               "Unhandled type (%d) (See RFC for implementation details\n",
+               type);
+        result= -1;
+        break;
+
+    case 28:                   // FU-A (fragmented nal)
+        buf++;
+        len--;                  // skip the fu_indicator
+        {
+            // these are the same as above, we just redo them here for clarity...
+            uint8_t fu_indicator = nal;
+            uint8_t fu_header = *buf;   // read the fu_header.
+            uint8_t start_bit = fu_header >> 7;
+//            uint8_t end_bit = (fu_header & 0x40) >> 6;
+            uint8_t nal_type = (fu_header & 0x1f);
+            uint8_t reconstructed_nal;
+
+            // reconstruct this packet's true nal; only the data follows..
+            reconstructed_nal = fu_indicator & (0xe0);  // the original nal forbidden bit and NRI are stored in this packet's nal;
+            reconstructed_nal |= nal_type;
+
+            // skip the fu_header...
+            buf++;
+            len--;
+
+#ifdef DEBUG
+            if (start_bit)
+                data->packet_types_received[nal_type]++;
+#endif
+            if(start_bit) {
+                // copy in the start sequence, and the reconstructed nal....
+                av_new_packet(pkt, sizeof(start_sequence)+sizeof(nal)+len);
+                memcpy(pkt->data, start_sequence, sizeof(start_sequence));
+                pkt->data[sizeof(start_sequence)]= reconstructed_nal;
+                memcpy(pkt->data+sizeof(start_sequence)+sizeof(nal), buf, len);
+            } else {
+                av_new_packet(pkt, len);
+                memcpy(pkt->data, buf, len);
+            }
+        }
+        break;
+
+    case 30:                   // undefined
+    case 31:                   // undefined
+    default:
+        av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)", type);
+        result= -1;
+        break;
+    }
+
+    pkt->stream_index = st->index;
+
+    return result;
+}
+
+/* ---------------- public code */
+static PayloadContext *h264_new_context(void)
+{
+    PayloadContext *data =
+        av_mallocz(sizeof(PayloadContext) +
+                   FF_INPUT_BUFFER_PADDING_SIZE);
+
+    if (data) {
+        data->cookie = MAGIC_COOKIE;
+    }
+
+    return data;
+}
+
+static void h264_free_context(PayloadContext *data)
+{
+#ifdef DEBUG
+    int ii;
+
+    for (ii = 0; ii < 32; ii++) {
+        if (data->packet_types_received[ii])
+            av_log(NULL, AV_LOG_DEBUG, "Received %d packets of type %d\n",
+                   data->packet_types_received[ii], ii);
+    }
+#endif
+
+    assert(data);
+    assert(data->cookie == MAGIC_COOKIE);
+
+    // avoid stale pointers (assert)
+    data->cookie = DEAD_COOKIE;
+
+    // and clear out this...
+    av_free(data);
+}
+
+static int parse_h264_sdp_line(AVFormatContext *s, int st_index,
+                               PayloadContext *h264_data, const char *line)
+{
+    AVStream *stream = s->streams[st_index];
+    AVCodecContext *codec = stream->codec;
+    const char *p = line;
+
+    assert(h264_data->cookie == MAGIC_COOKIE);
+
+    if (av_strstart(p, "framesize:", &p)) {
+        char buf1[50];
+        char *dst = buf1;
+
+        // remove the protocol identifier..
+        while (*p && *p == ' ') p++; // strip spaces.
+        while (*p && *p != ' ') p++; // eat protocol identifier
+        while (*p && *p == ' ') p++; // strip trailing spaces.
+        while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) {
+            *dst++ = *p++;
+        }
+        *dst = '\0';
+
+        // a='framesize:96 320-240'
+        // set our parameters..
+        codec->width = atoi(buf1);
+        codec->height = atoi(p + 1); // skip the -
+        codec->pix_fmt = PIX_FMT_YUV420P;
+    } else if (av_strstart(p, "fmtp:", &p)) {
+        char attr[256];
+        char value[4096];
+
+        // remove the protocol identifier..
+        while (*p && *p == ' ') p++; // strip spaces.
+        while (*p && *p != ' ') p++; // eat protocol identifier
+        while (*p && *p == ' ') p++; // strip trailing spaces.
+
+        /* loop on each attribute */
+        while (ff_rtsp_next_attr_and_value
+               (&p, attr, sizeof(attr), value, sizeof(value))) {
+            /* grab the codec extra_data from the config parameter of the fmtp line */
+            sdp_parse_fmtp_config_h264(stream, h264_data, attr, value);
+        }
+    } else if (av_strstart(p, "cliprect:", &p)) {
+        // could use this if we wanted.
+    }
+
+    av_set_pts_info(stream, 33, 1, 90000);      // 33 should be right, because the pts is 64 bit? (done elsewhere; this is a one time thing)
+
+    return 0;                   // keep processing it the normal way...
+}
+
+/**
+This is the structure for expanding on the dynamic rtp protocols (makes everything static. yay!)
+*/
+RTPDynamicProtocolHandler ff_h264_dynamic_handler = {
+    .enc_name         = "H264",
+    .codec_type       = CODEC_TYPE_VIDEO,
+    .codec_id         = CODEC_ID_H264,
+    .parse_sdp_a_line = parse_h264_sdp_line,
+    .open             = h264_new_context,
+    .close            = h264_free_context,
+    .parse_packet     = h264_handle_packet
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtpdec_h264.h	Sun Feb 28 11:03:14 2010 +0000
@@ -0,0 +1,29 @@
+/*
+ * RTP H264 Protocol (RFC3984)
+ * Copyright (c) 2006 Ryan Martell
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFORMAT_RTPDEC_H264_H
+#define AVFORMAT_RTPDEC_H264_H
+
+#include "rtpdec.h"
+
+extern RTPDynamicProtocolHandler ff_h264_dynamic_handler;
+
+#endif /* AVFORMAT_RTPDEC_H264_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtpdec_vorbis.c	Sun Feb 28 11:03:14 2010 +0000
@@ -0,0 +1,218 @@
+/*
+ * RTP Vorbis Protocol (RFC5215)
+ * Copyright (c) 2009 Colin McQuillan
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file libavformat/rtpdec_vorbis.c
+ * @brief Vorbis / RTP Code (RFC 5215)
+ * @author Colin McQuillan <m.niloc@gmail.com>
+ */
+
+#include "libavutil/base64.h"
+#include "libavutil/avstring.h"
+#include "libavcodec/bytestream.h"
+
+#include <assert.h>
+
+#include "rtpdec.h"
+#include "rtpdec_vorbis.h"
+
+/**
+ * RTP/Vorbis specific private data.
+ */
+struct PayloadContext {
+    unsigned ident;             ///< 24-bit stream configuration identifier
+};
+
+/**
+ * Length encoding described in RFC5215 section 3.1.1.
+ */
+static int get_base128(const uint8_t ** buf, const uint8_t * buf_end)
+{
+    int n = 0;
+    for (; *buf < buf_end; ++*buf) {
+        n <<= 7;
+        n += **buf & 0x7f;
+        if (!(**buf & 0x80)) {
+            ++*buf;
+            return n;
+        }
+    }
+    return 0;
+}
+
+/**
+ * Out-of-band headers, described in RFC 5251 section 3.2.1
+ */
+static unsigned int
+parse_packed_headers(const uint8_t * packed_headers,
+                     const uint8_t * packed_headers_end,
+                     AVCodecContext * codec, PayloadContext * vorbis_data)
+{
+    unsigned num_packed, num_headers, length, length1, length2;
+    uint8_t *ptr;
+
+    num_packed         = bytestream_get_be32(&packed_headers);
+    vorbis_data->ident = bytestream_get_be24(&packed_headers);
+    length             = bytestream_get_be16(&packed_headers);
+    num_headers        = get_base128(&packed_headers, packed_headers_end);
+    length1            = get_base128(&packed_headers, packed_headers_end);
+    length2            = get_base128(&packed_headers, packed_headers_end);
+
+    if (num_packed != 1 || num_headers > 3) {
+        av_log(codec, AV_LOG_ERROR,
+               "Unimplemented number of headers: %d packed headers, %d headers\n",
+               num_packed, num_headers);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    if (packed_headers_end - packed_headers != length ||
+        length1 > length || length2 > length - length1) {
+        av_log(codec, AV_LOG_ERROR,
+               "Bad packed header lengths (%d,%d,%d,%d)\n", length1,
+               length2, packed_headers_end - packed_headers, length);
+        return AVERROR_INVALIDDATA;
+    }
+
+    ptr = codec->extradata = av_mallocz(length + length / 255 + 64);
+    if (!ptr) {
+        av_log(codec, AV_LOG_ERROR, "Out of memory");
+        return AVERROR_NOMEM;
+    }
+    *ptr++ = 2;
+    ptr += av_xiphlacing(ptr, length1);
+    ptr += av_xiphlacing(ptr, length2);
+    memcpy(ptr, packed_headers, length);
+    ptr += length;
+    codec->extradata_size = ptr - codec->extradata;
+
+    return 0;
+}
+
+int
+ff_vorbis_parse_fmtp_config(AVCodecContext * codec,
+                            void *vorbis_data, char *attr, char *value)
+{
+    int result = 0;
+    assert(codec->codec_id == CODEC_ID_VORBIS);
+    assert(vorbis_data);
+
+    // The configuration value is a base64 encoded packed header
+    if (!strcmp(attr, "configuration")) {
+        uint8_t *decoded_packet = NULL;
+        int packet_size;
+        size_t decoded_alloc = strlen(value) / 4 * 3 + 4;
+
+        if (decoded_alloc <= INT_MAX) {
+            decoded_packet = av_malloc(decoded_alloc);
+            if (decoded_packet) {
+                packet_size =
+                    av_base64_decode(decoded_packet, value, decoded_alloc);
+
+                result = parse_packed_headers
+                    (decoded_packet, decoded_packet + packet_size, codec,
+                     vorbis_data);
+            } else {
+                av_log(codec, AV_LOG_ERROR,
+                       "Out of memory while decoding SDP configuration.\n");
+                result = AVERROR_NOMEM;
+            }
+        } else {
+            av_log(codec, AV_LOG_ERROR, "Packet too large\n");
+            result = AVERROR_INVALIDDATA;
+        }
+        av_free(decoded_packet);
+    }
+    return result;
+}
+
+static PayloadContext *vorbis_new_context(void)
+{
+    return av_mallocz(sizeof(PayloadContext));
+}
+
+static void vorbis_free_context(PayloadContext * data)
+{
+    av_free(data);
+}
+
+/**
+ * Handle payload as described in RFC 5215 section 2.2
+ */
+static int
+vorbis_handle_packet(AVFormatContext * ctx,
+                     PayloadContext * data,
+                     AVStream * st,
+                     AVPacket * pkt,
+                     uint32_t * timestamp,
+                     const uint8_t * buf, int len, int flags)
+{
+    int ident, fragmented, vdt, num_pkts, pkt_len;
+
+    if (len < 6) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid %d byte packet\n", len);
+        return AVERROR_INVALIDDATA;
+    }
+
+    ident = AV_RB24(buf);
+    fragmented = buf[3] >> 6;
+    vdt = (buf[3] >> 4) & 3;
+    num_pkts = buf[3] & 7;
+    pkt_len = AV_RB16(buf + 4);
+
+    if (pkt_len > len - 6) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Invalid packet length %d in %d byte packet\n", pkt_len,
+               len);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (ident != data->ident) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Unimplemented Vorbis SDP configuration change detected\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    if (fragmented != 0 || vdt != 0 || num_pkts != 1) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Unimplemented RTP Vorbis packet settings (%d,%d,%d)\n",
+               fragmented, vdt, num_pkts);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    if (av_new_packet(pkt, pkt_len)) {
+        av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
+        return AVERROR_NOMEM;
+    }
+
+    memcpy(pkt->data, buf + 6, pkt_len);
+    pkt->stream_index = st->index;
+    return 0;
+}
+
+RTPDynamicProtocolHandler ff_vorbis_dynamic_handler = {
+    .enc_name         = "vorbis",
+    .codec_type       = CODEC_TYPE_AUDIO,
+    .codec_id         = CODEC_ID_VORBIS,
+    .parse_sdp_a_line = NULL,
+    .open             = vorbis_new_context,
+    .close            = vorbis_free_context,
+    .parse_packet     = vorbis_handle_packet
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtpdec_vorbis.h	Sun Feb 28 11:03:14 2010 +0000
@@ -0,0 +1,45 @@
+/*
+ * RTP Vorbis Protocol (RFC 5215)
+ * Copyright (c) 2009 Colin McQuillan
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFORMAT_RTPDEC_VORBIS_H
+#define AVFORMAT_RTPDEC_VORBIS_H
+
+#include "libavcodec/avcodec.h"
+#include "rtpdec.h"
+
+/**
+ * Handle a Vorbis-specific FMTP parameter
+ *
+ * @param codec The context of the codec
+ * @param ctx Private Vorbis RTP context
+ * @param attr Format-specific parameter name
+ * @param value Format-specific paremeter value
+ */
+int
+ff_vorbis_parse_fmtp_config(AVCodecContext * codec,
+                            void *ctx, char *attr, char *value);
+
+/**
+ * Vorbis RTP callbacks.
+ */
+extern RTPDynamicProtocolHandler ff_vorbis_dynamic_handler;
+
+#endif /* AVFORMAT_RTPDEC_VORBIS_H */
--- a/rtsp.c	Sun Feb 28 03:59:15 2010 +0000
+++ b/rtsp.c	Sun Feb 28 11:03:14 2010 +0000
@@ -37,8 +37,8 @@
 
 #include "rtpdec.h"
 #include "rdt.h"
-#include "rtp_asf.h"
-#include "rtp_vorbis.h"
+#include "rtpdec_asf.h"
+#include "rtpdec_vorbis.h"
 
 //#define DEBUG
 //#define DEBUG_RTP_TCP