Browse code

Rename RTP depacketizer files from rtp_* to rtpdec_*

Originally committed as revision 22109 to svn://svn.ffmpeg.org/ffmpeg/trunk

Martin Storsjö authored on 2010/02/28 20:03:14
Showing 15 changed files
... ...
@@ -216,10 +216,10 @@ OBJS-$(CONFIG_SDP_DEMUXER)               += rtsp.o        \
216 216
                                             rtp.o         \
217 217
                                             rtpdec.o      \
218 218
                                             rtpdec_amr.o  \
219
+                                            rtpdec_asf.o  \
219 220
                                             rtpdec_h263.o \
220
-                                            rtp_asf.o     \
221
-                                            rtp_h264.o    \
222
-                                            rtp_vorbis.o
221
+                                            rtpdec_h264.o \
222
+                                            rtpdec_vorbis.o
223 223
 OBJS-$(CONFIG_SEGAFILM_DEMUXER)          += segafilm.o
224 224
 OBJS-$(CONFIG_SHORTEN_DEMUXER)           += raw.o id3v2.o
225 225
 OBJS-$(CONFIG_SIFF_DEMUXER)              += siff.o
226 226
deleted file mode 100644
... ...
@@ -1,281 +0,0 @@
1
-/*
2
- * Microsoft RTP/ASF support.
3
- * Copyright (c) 2008 Ronald S. Bultje
4
- *
5
- * This file is part of FFmpeg.
6
- *
7
- * FFmpeg is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU Lesser General Public
9
- * License as published by the Free Software Foundation; either
10
- * version 2.1 of the License, or (at your option) any later version.
11
- *
12
- * FFmpeg is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
- * Lesser General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU Lesser General Public
18
- * License along with FFmpeg; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
- */
21
-
22
-/**
23
- * @file libavformat/rtp_asf.c
24
- * @brief Microsoft RTP/ASF support
25
- * @author Ronald S. Bultje <rbultje@ronald.bitfreak.net>
26
- */
27
-
28
-#include <libavutil/base64.h>
29
-#include <libavutil/avstring.h>
30
-#include <libavutil/intreadwrite.h>
31
-#include "rtp.h"
32
-#include "rtp_asf.h"
33
-#include "rtsp.h"
34
-#include "asf.h"
35
-
36
-/**
37
- * From MSDN 2.2.1.4, we learn that ASF data packets over RTP should not
38
- * contain any padding. Unfortunately, the header min/max_pktsize are not
39
- * updated (thus making min_pktsize invalid). Here, we "fix" these faulty
40
- * min_pktsize values in the ASF file header.
41
- * @return 0 on success, <0 on failure (currently -1).
42
- */
43
-static int rtp_asf_fix_header(uint8_t *buf, int len)
44
-{
45
-    uint8_t *p = buf, *end = buf + len;
46
-
47
-    if (len < sizeof(ff_asf_guid) * 2 + 22 ||
48
-        memcmp(p, ff_asf_header, sizeof(ff_asf_guid))) {
49
-        return -1;
50
-    }
51
-    p += sizeof(ff_asf_guid) + 14;
52
-    do {
53
-        uint64_t chunksize = AV_RL64(p + sizeof(ff_asf_guid));
54
-        if (memcmp(p, ff_asf_file_header, sizeof(ff_asf_guid))) {
55
-            if (chunksize > end - p)
56
-                return -1;
57
-            p += chunksize;
58
-            continue;
59
-        }
60
-
61
-        /* skip most of the file header, to min_pktsize */
62
-        p += 6 * 8 + 3 * 4 + sizeof(ff_asf_guid) * 2;
63
-        if (p + 8 <= end && AV_RL32(p) == AV_RL32(p + 4)) {
64
-            /* and set that to zero */
65
-            AV_WL32(p, 0);
66
-            return 0;
67
-        }
68
-        break;
69
-    } while (end - p >= sizeof(ff_asf_guid) + 8);
70
-
71
-    return -1;
72
-}
73
-
74
-/**
75
- * The following code is basically a buffered ByteIOContext,
76
- * with the added benefit of returning -EAGAIN (instead of 0)
77
- * on packet boundaries, such that the ASF demuxer can return
78
- * safely and resume business at the next packet.
79
- */
80
-static int packetizer_read(void *opaque, uint8_t *buf, int buf_size)
81
-{
82
-    return AVERROR(EAGAIN);
83
-}
84
-
85
-static void init_packetizer(ByteIOContext *pb, uint8_t *buf, int len)
86
-{
87
-    init_put_byte(pb, buf, len, 0, NULL, packetizer_read, NULL, NULL);
88
-
89
-    /* this "fills" the buffer with its current content */
90
-    pb->pos     = len;
91
-    pb->buf_end = buf + len;
92
-}
93
-
94
-void ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p)
95
-{
96
-    if (av_strstart(p, "pgmpu:data:application/vnd.ms.wms-hdr.asfv1;base64,", &p)) {
97
-        ByteIOContext pb;
98
-        RTSPState *rt = s->priv_data;
99
-        int len = strlen(p) * 6 / 8;
100
-        char *buf = av_mallocz(len);
101
-        av_base64_decode(buf, p, len);
102
-
103
-        if (rtp_asf_fix_header(buf, len) < 0)
104
-            av_log(s, AV_LOG_ERROR,
105
-                   "Failed to fix invalid RTSP-MS/ASF min_pktsize\n");
106
-        init_packetizer(&pb, buf, len);
107
-        if (rt->asf_ctx) {
108
-            av_close_input_stream(rt->asf_ctx);
109
-            rt->asf_ctx = NULL;
110
-        }
111
-        av_open_input_stream(&rt->asf_ctx, &pb, "", &asf_demuxer, NULL);
112
-        rt->asf_pb_pos = url_ftell(&pb);
113
-        av_free(buf);
114
-        rt->asf_ctx->pb = NULL;
115
-    }
116
-}
117
-
118
-static int asfrtp_parse_sdp_line(AVFormatContext *s, int stream_index,
119
-                                 PayloadContext *asf, const char *line)
120
-{
121
-    if (av_strstart(line, "stream:", &line)) {
122
-        RTSPState *rt = s->priv_data;
123
-
124
-        s->streams[stream_index]->id = strtol(line, NULL, 10);
125
-
126
-        if (rt->asf_ctx) {
127
-            int i;
128
-
129
-            for (i = 0; i < rt->asf_ctx->nb_streams; i++) {
130
-                if (s->streams[stream_index]->id == rt->asf_ctx->streams[i]->id) {
131
-                    *s->streams[stream_index]->codec =
132
-                        *rt->asf_ctx->streams[i]->codec;
133
-                    rt->asf_ctx->streams[i]->codec->extradata_size = 0;
134
-                    rt->asf_ctx->streams[i]->codec->extradata = NULL;
135
-                    av_set_pts_info(s->streams[stream_index], 32, 1, 1000);
136
-                }
137
-           }
138
-        }
139
-    }
140
-
141
-    return 0;
142
-}
143
-
144
-struct PayloadContext {
145
-    ByteIOContext *pktbuf, pb;
146
-    char *buf;
147
-};
148
-
149
-/**
150
- * @return 0 when a packet was written into /p pkt, and no more data is left;
151
- *         1 when a packet was written into /p pkt, and more packets might be left;
152
- *        <0 when not enough data was provided to return a full packet, or on error.
153
- */
154
-static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,
155
-                               AVStream *st, AVPacket *pkt,
156
-                               uint32_t *timestamp,
157
-                               const uint8_t *buf, int len, int flags)
158
-{
159
-    ByteIOContext *pb = &asf->pb;
160
-    int res, mflags, len_off;
161
-    RTSPState *rt = s->priv_data;
162
-
163
-    if (!rt->asf_ctx)
164
-        return -1;
165
-
166
-    if (len > 0) {
167
-        int off, out_len;
168
-
169
-        if (len < 4)
170
-            return -1;
171
-
172
-        init_put_byte(pb, buf, len, 0, NULL, NULL, NULL, NULL);
173
-        mflags = get_byte(pb);
174
-        if (mflags & 0x80)
175
-            flags |= RTP_FLAG_KEY;
176
-        len_off = get_be24(pb);
177
-        if (mflags & 0x20)   /**< relative timestamp */
178
-            url_fskip(pb, 4);
179
-        if (mflags & 0x10)   /**< has duration */
180
-            url_fskip(pb, 4);
181
-        if (mflags & 0x8)    /**< has location ID */
182
-            url_fskip(pb, 4);
183
-        off = url_ftell(pb);
184
-
185
-        av_freep(&asf->buf);
186
-        if (!(mflags & 0x40)) {
187
-            /**
188
-             * If 0x40 is not set, the len_off field specifies an offset of this
189
-             * packet's payload data in the complete (reassembled) ASF packet.
190
-             * This is used to spread one ASF packet over multiple RTP packets.
191
-             */
192
-            if (asf->pktbuf && len_off != url_ftell(asf->pktbuf)) {
193
-                uint8_t *p;
194
-                url_close_dyn_buf(asf->pktbuf, &p);
195
-                asf->pktbuf = NULL;
196
-                av_free(p);
197
-            }
198
-            if (!len_off && !asf->pktbuf &&
199
-                (res = url_open_dyn_buf(&asf->pktbuf)) < 0)
200
-                return res;
201
-            if (!asf->pktbuf)
202
-                return AVERROR(EIO);
203
-
204
-            put_buffer(asf->pktbuf, buf + off, len - off);
205
-            if (!(flags & RTP_FLAG_MARKER))
206
-                return -1;
207
-            out_len     = url_close_dyn_buf(asf->pktbuf, &asf->buf);
208
-            asf->pktbuf = NULL;
209
-        } else {
210
-            /**
211
-             * If 0x40 is set, the len_off field specifies the length of the
212
-             * next ASF packet that can be read from this payload data alone.
213
-             * This is commonly the same as the payload size, but could be
214
-             * less in case of packet splitting (i.e. multiple ASF packets in
215
-             * one RTP packet).
216
-             */
217
-            if (len_off != len) {
218
-                av_log_missing_feature(s,
219
-                    "RTSP-MS packet splitting", 1);
220
-                return -1;
221
-            }
222
-            asf->buf = av_malloc(len - off);
223
-            out_len  = len - off;
224
-            memcpy(asf->buf, buf + off, len - off);
225
-        }
226
-
227
-        init_packetizer(pb, asf->buf, out_len);
228
-        pb->pos += rt->asf_pb_pos;
229
-        pb->eof_reached = 0;
230
-        rt->asf_ctx->pb = pb;
231
-    }
232
-
233
-    for (;;) {
234
-        int i;
235
-
236
-        res = av_read_packet(rt->asf_ctx, pkt);
237
-        rt->asf_pb_pos = url_ftell(pb);
238
-        if (res != 0)
239
-            break;
240
-        for (i = 0; i < s->nb_streams; i++) {
241
-            if (s->streams[i]->id == rt->asf_ctx->streams[pkt->stream_index]->id) {
242
-                pkt->stream_index = i;
243
-                return 1; // FIXME: return 0 if last packet
244
-            }
245
-        }
246
-        av_free_packet(pkt);
247
-    }
248
-
249
-    return res == 1 ? -1 : res;
250
-}
251
-
252
-static PayloadContext *asfrtp_new_context(void)
253
-{
254
-    return av_mallocz(sizeof(PayloadContext));
255
-}
256
-
257
-static void asfrtp_free_context(PayloadContext *asf)
258
-{
259
-    if (asf->pktbuf) {
260
-        uint8_t *p = NULL;
261
-        url_close_dyn_buf(asf->pktbuf, &p);
262
-        asf->pktbuf = NULL;
263
-        av_free(p);
264
-    }
265
-    av_freep(&asf->buf);
266
-    av_free(asf);
267
-}
268
-
269
-#define RTP_ASF_HANDLER(n, s, t) \
270
-RTPDynamicProtocolHandler ff_ms_rtp_ ## n ## _handler = { \
271
-    .enc_name         = s, \
272
-    .codec_type       = t, \
273
-    .codec_id         = CODEC_ID_NONE, \
274
-    .parse_sdp_a_line = asfrtp_parse_sdp_line, \
275
-    .open             = asfrtp_new_context, \
276
-    .close            = asfrtp_free_context, \
277
-    .parse_packet     = asfrtp_parse_packet,   \
278
-};
279
-
280
-RTP_ASF_HANDLER(asf_pfv, "x-asf-pf",  CODEC_TYPE_VIDEO);
281
-RTP_ASF_HANDLER(asf_pfa, "x-asf-pf",  CODEC_TYPE_AUDIO);
282 1
deleted file mode 100644
... ...
@@ -1,43 +0,0 @@
1
-/*
2
- * Microsoft RTP/ASF support.
3
- * Copyright (c) 2008 Ronald S. Bultje
4
- *
5
- * This file is part of FFmpeg.
6
- *
7
- * FFmpeg is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU Lesser General Public
9
- * License as published by the Free Software Foundation; either
10
- * version 2.1 of the License, or (at your option) any later version.
11
- *
12
- * FFmpeg is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
- * Lesser General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU Lesser General Public
18
- * License along with FFmpeg; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
- */
21
-
22
-#ifndef AVFORMAT_RTP_ASF_H
23
-#define AVFORMAT_RTP_ASF_H
24
-
25
-#include "avformat.h"
26
-#include "rtpdec.h"
27
-
28
-/**
29
- * Parse a Windows Media Server-specific SDP line
30
- *
31
- * @param s RTSP demux context
32
- * @param line the SDP line to be parsed
33
- */
34
-void ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p);
35
-
36
-/**
37
- * Handlers for the x-asf-pf payloads (the payload ID for RTP/ASF).
38
- * Defined and implemented in rtp_asf.c, registered in rtpdec.c.
39
- */
40
-extern RTPDynamicProtocolHandler ff_ms_rtp_asf_pfv_handler,
41
-                                 ff_ms_rtp_asf_pfa_handler;
42
-
43
-#endif /* AVFORMAT_RTP_ASF_H */
44 1
deleted file mode 100644
... ...
@@ -1,416 +0,0 @@
1
-/*
2
- * RTP H264 Protocol (RFC3984)
3
- * Copyright (c) 2006 Ryan Martell
4
- *
5
- * This file is part of FFmpeg.
6
- *
7
- * FFmpeg is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU Lesser General Public
9
- * License as published by the Free Software Foundation; either
10
- * version 2.1 of the License, or (at your option) any later version.
11
- *
12
- * FFmpeg is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
- * Lesser General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU Lesser General Public
18
- * License along with FFmpeg; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
- */
21
-
22
-/**
23
-* @file libavformat/rtp_h264.c
24
- * @brief H.264 / RTP Code (RFC3984)
25
- * @author Ryan Martell <rdm4@martellventures.com>
26
- *
27
- * @note Notes:
28
- * Notes:
29
- * This currently supports packetization mode:
30
- * Single Nal Unit Mode (0), or
31
- * Non-Interleaved Mode (1).  It currently does not support
32
- * Interleaved Mode (2). (This requires implementing STAP-B, MTAP16, MTAP24, FU-B packet types)
33
- *
34
- * @note TODO:
35
- * 1) RTCP sender reports for udp streams are required..
36
- *
37
- */
38
-
39
-#include "libavutil/base64.h"
40
-#include "libavutil/avstring.h"
41
-#include "libavcodec/get_bits.h"
42
-#include "avformat.h"
43
-#include "mpegts.h"
44
-
45
-#include <unistd.h>
46
-#include "network.h"
47
-#include <assert.h>
48
-
49
-#include "rtpdec.h"
50
-#include "rtp_h264.h"
51
-
52
-/**
53
-    RTP/H264 specific private data.
54
-*/
55
-struct PayloadContext {
56
-    unsigned long cookie;       ///< sanity check, to make sure we get the pointer we're expecting.
57
-
58
-    //sdp setup parameters
59
-    uint8_t profile_idc;        ///< from the sdp setup parameters.
60
-    uint8_t profile_iop;        ///< from the sdp setup parameters.
61
-    uint8_t level_idc;          ///< from the sdp setup parameters.
62
-    int packetization_mode;     ///< from the sdp setup parameters.
63
-#ifdef DEBUG
64
-    int packet_types_received[32];
65
-#endif
66
-};
67
-
68
-#define MAGIC_COOKIE (0xdeadbeef)       ///< Cookie for the extradata; to verify we are what we think we are, and that we haven't been freed.
69
-#define DEAD_COOKIE (0xdeaddead)        ///< Cookie for the extradata; once it is freed.
70
-
71
-/* ---------------- private code */
72
-static void sdp_parse_fmtp_config_h264(AVStream * stream,
73
-                                       PayloadContext * h264_data,
74
-                                       char *attr, char *value)
75
-{
76
-    AVCodecContext *codec = stream->codec;
77
-    assert(codec->codec_id == CODEC_ID_H264);
78
-    assert(h264_data != NULL);
79
-
80
-    if (!strcmp(attr, "packetization-mode")) {
81
-        av_log(codec, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value));
82
-        h264_data->packetization_mode = atoi(value);
83
-        /*
84
-           Packetization Mode:
85
-           0 or not present: Single NAL mode (Only nals from 1-23 are allowed)
86
-           1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed.
87
-           2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), and 29 (FU-B) are allowed.
88
-         */
89
-        if (h264_data->packetization_mode > 1)
90
-            av_log(codec, AV_LOG_ERROR,
91
-                   "Interleaved RTP mode is not supported yet.");
92
-    } else if (!strcmp(attr, "profile-level-id")) {
93
-        if (strlen(value) == 6) {
94
-            char buffer[3];
95
-            // 6 characters=3 bytes, in hex.
96
-            uint8_t profile_idc;
97
-            uint8_t profile_iop;
98
-            uint8_t level_idc;
99
-
100
-            buffer[0] = value[0]; buffer[1] = value[1]; buffer[2] = '\0';
101
-            profile_idc = strtol(buffer, NULL, 16);
102
-            buffer[0] = value[2]; buffer[1] = value[3];
103
-            profile_iop = strtol(buffer, NULL, 16);
104
-            buffer[0] = value[4]; buffer[1] = value[5];
105
-            level_idc = strtol(buffer, NULL, 16);
106
-
107
-            // set the parameters...
108
-            av_log(codec, AV_LOG_DEBUG,
109
-                   "RTP Profile IDC: %x Profile IOP: %x Level: %x\n",
110
-                   profile_idc, profile_iop, level_idc);
111
-            h264_data->profile_idc = profile_idc;
112
-            h264_data->profile_iop = profile_iop;
113
-            h264_data->level_idc = level_idc;
114
-        }
115
-    } else  if (!strcmp(attr, "sprop-parameter-sets")) {
116
-        uint8_t start_sequence[]= { 0, 0, 1 };
117
-        codec->extradata_size= 0;
118
-        codec->extradata= NULL;
119
-
120
-        while (*value) {
121
-            char base64packet[1024];
122
-            uint8_t decoded_packet[1024];
123
-            uint32_t packet_size;
124
-            char *dst = base64packet;
125
-
126
-            while (*value && *value != ','
127
-                   && (dst - base64packet) < sizeof(base64packet) - 1) {
128
-                *dst++ = *value++;
129
-            }
130
-            *dst++ = '\0';
131
-
132
-            if (*value == ',')
133
-                value++;
134
-
135
-            packet_size= av_base64_decode(decoded_packet, base64packet, sizeof(decoded_packet));
136
-            if (packet_size) {
137
-                uint8_t *dest= av_malloc(packet_size+sizeof(start_sequence)+codec->extradata_size);
138
-                if(dest)
139
-                {
140
-                    if(codec->extradata_size)
141
-                    {
142
-                        // av_realloc?
143
-                        memcpy(dest, codec->extradata, codec->extradata_size);
144
-                        av_free(codec->extradata);
145
-                    }
146
-
147
-                    memcpy(dest+codec->extradata_size, start_sequence, sizeof(start_sequence));
148
-                    memcpy(dest+codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size);
149
-
150
-                    codec->extradata= dest;
151
-                    codec->extradata_size+= sizeof(start_sequence)+packet_size;
152
-                } else {
153
-                    av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!");
154
-                }
155
-            }
156
-        }
157
-        av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!", codec->extradata, codec->extradata_size);
158
-    }
159
-}
160
-
161
-// return 0 on packet, no more left, 1 on packet, 1 on partial packet...
162
-static int h264_handle_packet(AVFormatContext *ctx,
163
-                              PayloadContext *data,
164
-                              AVStream *st,
165
-                              AVPacket * pkt,
166
-                              uint32_t * timestamp,
167
-                              const uint8_t * buf,
168
-                              int len, int flags)
169
-{
170
-    uint8_t nal = buf[0];
171
-    uint8_t type = (nal & 0x1f);
172
-    int result= 0;
173
-    uint8_t start_sequence[]= {0, 0, 1};
174
-
175
-#ifdef DEBUG
176
-    assert(data);
177
-    assert(data->cookie == MAGIC_COOKIE);
178
-#endif
179
-    assert(buf);
180
-
181
-    if (type >= 1 && type <= 23)
182
-        type = 1;              // simplify the case. (these are all the nal types used internally by the h264 codec)
183
-    switch (type) {
184
-    case 0:                    // undefined;
185
-        result= -1;
186
-        break;
187
-
188
-    case 1:
189
-        av_new_packet(pkt, len+sizeof(start_sequence));
190
-        memcpy(pkt->data, start_sequence, sizeof(start_sequence));
191
-        memcpy(pkt->data+sizeof(start_sequence), buf, len);
192
-#ifdef DEBUG
193
-        data->packet_types_received[nal & 0x1f]++;
194
-#endif
195
-        break;
196
-
197
-    case 24:                   // STAP-A (one packet, multiple nals)
198
-        // consume the STAP-A NAL
199
-        buf++;
200
-        len--;
201
-        // first we are going to figure out the total size....
202
-        {
203
-            int pass= 0;
204
-            int total_length= 0;
205
-            uint8_t *dst= NULL;
206
-
207
-            for(pass= 0; pass<2; pass++) {
208
-                const uint8_t *src= buf;
209
-                int src_len= len;
210
-
211
-                do {
212
-                    uint16_t nal_size = AV_RB16(src); // this going to be a problem if unaligned (can it be?)
213
-
214
-                    // consume the length of the aggregate...
215
-                    src += 2;
216
-                    src_len -= 2;
217
-
218
-                    if (nal_size <= src_len) {
219
-                        if(pass==0) {
220
-                            // counting...
221
-                            total_length+= sizeof(start_sequence)+nal_size;
222
-                        } else {
223
-                            // copying
224
-                            assert(dst);
225
-                            memcpy(dst, start_sequence, sizeof(start_sequence));
226
-                            dst+= sizeof(start_sequence);
227
-                            memcpy(dst, src, nal_size);
228
-#ifdef DEBUG
229
-                            data->packet_types_received[*src & 0x1f]++;
230
-#endif
231
-                            dst+= nal_size;
232
-                        }
233
-                    } else {
234
-                        av_log(ctx, AV_LOG_ERROR,
235
-                               "nal size exceeds length: %d %d\n", nal_size, src_len);
236
-                    }
237
-
238
-                    // eat what we handled...
239
-                    src += nal_size;
240
-                    src_len -= nal_size;
241
-
242
-                    if (src_len < 0)
243
-                        av_log(ctx, AV_LOG_ERROR,
244
-                               "Consumed more bytes than we got! (%d)\n", src_len);
245
-                } while (src_len > 2);      // because there could be rtp padding..
246
-
247
-                if(pass==0) {
248
-                    // now we know the total size of the packet (with the start sequences added)
249
-                    av_new_packet(pkt, total_length);
250
-                    dst= pkt->data;
251
-                } else {
252
-                    assert(dst-pkt->data==total_length);
253
-                }
254
-            }
255
-        }
256
-        break;
257
-
258
-    case 25:                   // STAP-B
259
-    case 26:                   // MTAP-16
260
-    case 27:                   // MTAP-24
261
-    case 29:                   // FU-B
262
-        av_log(ctx, AV_LOG_ERROR,
263
-               "Unhandled type (%d) (See RFC for implementation details\n",
264
-               type);
265
-        result= -1;
266
-        break;
267
-
268
-    case 28:                   // FU-A (fragmented nal)
269
-        buf++;
270
-        len--;                  // skip the fu_indicator
271
-        {
272
-            // these are the same as above, we just redo them here for clarity...
273
-            uint8_t fu_indicator = nal;
274
-            uint8_t fu_header = *buf;   // read the fu_header.
275
-            uint8_t start_bit = fu_header >> 7;
276
-//            uint8_t end_bit = (fu_header & 0x40) >> 6;
277
-            uint8_t nal_type = (fu_header & 0x1f);
278
-            uint8_t reconstructed_nal;
279
-
280
-            // reconstruct this packet's true nal; only the data follows..
281
-            reconstructed_nal = fu_indicator & (0xe0);  // the original nal forbidden bit and NRI are stored in this packet's nal;
282
-            reconstructed_nal |= nal_type;
283
-
284
-            // skip the fu_header...
285
-            buf++;
286
-            len--;
287
-
288
-#ifdef DEBUG
289
-            if (start_bit)
290
-                data->packet_types_received[nal_type]++;
291
-#endif
292
-            if(start_bit) {
293
-                // copy in the start sequence, and the reconstructed nal....
294
-                av_new_packet(pkt, sizeof(start_sequence)+sizeof(nal)+len);
295
-                memcpy(pkt->data, start_sequence, sizeof(start_sequence));
296
-                pkt->data[sizeof(start_sequence)]= reconstructed_nal;
297
-                memcpy(pkt->data+sizeof(start_sequence)+sizeof(nal), buf, len);
298
-            } else {
299
-                av_new_packet(pkt, len);
300
-                memcpy(pkt->data, buf, len);
301
-            }
302
-        }
303
-        break;
304
-
305
-    case 30:                   // undefined
306
-    case 31:                   // undefined
307
-    default:
308
-        av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)", type);
309
-        result= -1;
310
-        break;
311
-    }
312
-
313
-    pkt->stream_index = st->index;
314
-
315
-    return result;
316
-}
317
-
318
-/* ---------------- public code */
319
-static PayloadContext *h264_new_context(void)
320
-{
321
-    PayloadContext *data =
322
-        av_mallocz(sizeof(PayloadContext) +
323
-                   FF_INPUT_BUFFER_PADDING_SIZE);
324
-
325
-    if (data) {
326
-        data->cookie = MAGIC_COOKIE;
327
-    }
328
-
329
-    return data;
330
-}
331
-
332
-static void h264_free_context(PayloadContext *data)
333
-{
334
-#ifdef DEBUG
335
-    int ii;
336
-
337
-    for (ii = 0; ii < 32; ii++) {
338
-        if (data->packet_types_received[ii])
339
-            av_log(NULL, AV_LOG_DEBUG, "Received %d packets of type %d\n",
340
-                   data->packet_types_received[ii], ii);
341
-    }
342
-#endif
343
-
344
-    assert(data);
345
-    assert(data->cookie == MAGIC_COOKIE);
346
-
347
-    // avoid stale pointers (assert)
348
-    data->cookie = DEAD_COOKIE;
349
-
350
-    // and clear out this...
351
-    av_free(data);
352
-}
353
-
354
-static int parse_h264_sdp_line(AVFormatContext *s, int st_index,
355
-                               PayloadContext *h264_data, const char *line)
356
-{
357
-    AVStream *stream = s->streams[st_index];
358
-    AVCodecContext *codec = stream->codec;
359
-    const char *p = line;
360
-
361
-    assert(h264_data->cookie == MAGIC_COOKIE);
362
-
363
-    if (av_strstart(p, "framesize:", &p)) {
364
-        char buf1[50];
365
-        char *dst = buf1;
366
-
367
-        // remove the protocol identifier..
368
-        while (*p && *p == ' ') p++; // strip spaces.
369
-        while (*p && *p != ' ') p++; // eat protocol identifier
370
-        while (*p && *p == ' ') p++; // strip trailing spaces.
371
-        while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) {
372
-            *dst++ = *p++;
373
-        }
374
-        *dst = '\0';
375
-
376
-        // a='framesize:96 320-240'
377
-        // set our parameters..
378
-        codec->width = atoi(buf1);
379
-        codec->height = atoi(p + 1); // skip the -
380
-        codec->pix_fmt = PIX_FMT_YUV420P;
381
-    } else if (av_strstart(p, "fmtp:", &p)) {
382
-        char attr[256];
383
-        char value[4096];
384
-
385
-        // remove the protocol identifier..
386
-        while (*p && *p == ' ') p++; // strip spaces.
387
-        while (*p && *p != ' ') p++; // eat protocol identifier
388
-        while (*p && *p == ' ') p++; // strip trailing spaces.
389
-
390
-        /* loop on each attribute */
391
-        while (ff_rtsp_next_attr_and_value
392
-               (&p, attr, sizeof(attr), value, sizeof(value))) {
393
-            /* grab the codec extra_data from the config parameter of the fmtp line */
394
-            sdp_parse_fmtp_config_h264(stream, h264_data, attr, value);
395
-        }
396
-    } else if (av_strstart(p, "cliprect:", &p)) {
397
-        // could use this if we wanted.
398
-    }
399
-
400
-    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)
401
-
402
-    return 0;                   // keep processing it the normal way...
403
-}
404
-
405
-/**
406
-This is the structure for expanding on the dynamic rtp protocols (makes everything static. yay!)
407
-*/
408
-RTPDynamicProtocolHandler ff_h264_dynamic_handler = {
409
-    .enc_name         = "H264",
410
-    .codec_type       = CODEC_TYPE_VIDEO,
411
-    .codec_id         = CODEC_ID_H264,
412
-    .parse_sdp_a_line = parse_h264_sdp_line,
413
-    .open             = h264_new_context,
414
-    .close            = h264_free_context,
415
-    .parse_packet     = h264_handle_packet
416
-};
417 1
deleted file mode 100644
... ...
@@ -1,29 +0,0 @@
1
-/*
2
- * RTP H264 Protocol (RFC3984)
3
- * Copyright (c) 2006 Ryan Martell
4
- *
5
- * This file is part of FFmpeg.
6
- *
7
- * FFmpeg is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU Lesser General Public
9
- * License as published by the Free Software Foundation; either
10
- * version 2.1 of the License, or (at your option) any later version.
11
- *
12
- * FFmpeg is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
- * Lesser General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU Lesser General Public
18
- * License along with FFmpeg; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
- */
21
-
22
-#ifndef AVFORMAT_RTP_H264_H
23
-#define AVFORMAT_RTP_H264_H
24
-
25
-#include "rtpdec.h"
26
-
27
-extern RTPDynamicProtocolHandler ff_h264_dynamic_handler;
28
-
29
-#endif /* AVFORMAT_RTP_H264_H */
30 1
deleted file mode 100644
... ...
@@ -1,218 +0,0 @@
1
-/*
2
- * RTP Vorbis Protocol (RFC5215)
3
- * Copyright (c) 2009 Colin McQuillan
4
- *
5
- * This file is part of FFmpeg.
6
- *
7
- * FFmpeg is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU Lesser General Public
9
- * License as published by the Free Software Foundation; either
10
- * version 2.1 of the License, or (at your option) any later version.
11
- *
12
- * FFmpeg is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
- * Lesser General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU Lesser General Public
18
- * License along with FFmpeg; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
- */
21
-
22
-/**
23
- * @file libavformat/rtp_vorbis.c
24
- * @brief Vorbis / RTP Code (RFC 5215)
25
- * @author Colin McQuillan <m.niloc@gmail.com>
26
- */
27
-
28
-#include "libavutil/base64.h"
29
-#include "libavutil/avstring.h"
30
-#include "libavcodec/bytestream.h"
31
-
32
-#include <assert.h>
33
-
34
-#include "rtpdec.h"
35
-#include "rtp_vorbis.h"
36
-
37
-/**
38
- * RTP/Vorbis specific private data.
39
- */
40
-struct PayloadContext {
41
-    unsigned ident;             ///< 24-bit stream configuration identifier
42
-};
43
-
44
-/**
45
- * Length encoding described in RFC5215 section 3.1.1.
46
- */
47
-static int get_base128(const uint8_t ** buf, const uint8_t * buf_end)
48
-{
49
-    int n = 0;
50
-    for (; *buf < buf_end; ++*buf) {
51
-        n <<= 7;
52
-        n += **buf & 0x7f;
53
-        if (!(**buf & 0x80)) {
54
-            ++*buf;
55
-            return n;
56
-        }
57
-    }
58
-    return 0;
59
-}
60
-
61
-/**
62
- * Out-of-band headers, described in RFC 5251 section 3.2.1
63
- */
64
-static unsigned int
65
-parse_packed_headers(const uint8_t * packed_headers,
66
-                     const uint8_t * packed_headers_end,
67
-                     AVCodecContext * codec, PayloadContext * vorbis_data)
68
-{
69
-    unsigned num_packed, num_headers, length, length1, length2;
70
-    uint8_t *ptr;
71
-
72
-    num_packed         = bytestream_get_be32(&packed_headers);
73
-    vorbis_data->ident = bytestream_get_be24(&packed_headers);
74
-    length             = bytestream_get_be16(&packed_headers);
75
-    num_headers        = get_base128(&packed_headers, packed_headers_end);
76
-    length1            = get_base128(&packed_headers, packed_headers_end);
77
-    length2            = get_base128(&packed_headers, packed_headers_end);
78
-
79
-    if (num_packed != 1 || num_headers > 3) {
80
-        av_log(codec, AV_LOG_ERROR,
81
-               "Unimplemented number of headers: %d packed headers, %d headers\n",
82
-               num_packed, num_headers);
83
-        return AVERROR_PATCHWELCOME;
84
-    }
85
-
86
-    if (packed_headers_end - packed_headers != length ||
87
-        length1 > length || length2 > length - length1) {
88
-        av_log(codec, AV_LOG_ERROR,
89
-               "Bad packed header lengths (%d,%d,%d,%d)\n", length1,
90
-               length2, packed_headers_end - packed_headers, length);
91
-        return AVERROR_INVALIDDATA;
92
-    }
93
-
94
-    ptr = codec->extradata = av_mallocz(length + length / 255 + 64);
95
-    if (!ptr) {
96
-        av_log(codec, AV_LOG_ERROR, "Out of memory");
97
-        return AVERROR_NOMEM;
98
-    }
99
-    *ptr++ = 2;
100
-    ptr += av_xiphlacing(ptr, length1);
101
-    ptr += av_xiphlacing(ptr, length2);
102
-    memcpy(ptr, packed_headers, length);
103
-    ptr += length;
104
-    codec->extradata_size = ptr - codec->extradata;
105
-
106
-    return 0;
107
-}
108
-
109
-int
110
-ff_vorbis_parse_fmtp_config(AVCodecContext * codec,
111
-                            void *vorbis_data, char *attr, char *value)
112
-{
113
-    int result = 0;
114
-    assert(codec->codec_id == CODEC_ID_VORBIS);
115
-    assert(vorbis_data);
116
-
117
-    // The configuration value is a base64 encoded packed header
118
-    if (!strcmp(attr, "configuration")) {
119
-        uint8_t *decoded_packet = NULL;
120
-        int packet_size;
121
-        size_t decoded_alloc = strlen(value) / 4 * 3 + 4;
122
-
123
-        if (decoded_alloc <= INT_MAX) {
124
-            decoded_packet = av_malloc(decoded_alloc);
125
-            if (decoded_packet) {
126
-                packet_size =
127
-                    av_base64_decode(decoded_packet, value, decoded_alloc);
128
-
129
-                result = parse_packed_headers
130
-                    (decoded_packet, decoded_packet + packet_size, codec,
131
-                     vorbis_data);
132
-            } else {
133
-                av_log(codec, AV_LOG_ERROR,
134
-                       "Out of memory while decoding SDP configuration.\n");
135
-                result = AVERROR_NOMEM;
136
-            }
137
-        } else {
138
-            av_log(codec, AV_LOG_ERROR, "Packet too large\n");
139
-            result = AVERROR_INVALIDDATA;
140
-        }
141
-        av_free(decoded_packet);
142
-    }
143
-    return result;
144
-}
145
-
146
-static PayloadContext *vorbis_new_context(void)
147
-{
148
-    return av_mallocz(sizeof(PayloadContext));
149
-}
150
-
151
-static void vorbis_free_context(PayloadContext * data)
152
-{
153
-    av_free(data);
154
-}
155
-
156
-/**
157
- * Handle payload as described in RFC 5215 section 2.2
158
- */
159
-static int
160
-vorbis_handle_packet(AVFormatContext * ctx,
161
-                     PayloadContext * data,
162
-                     AVStream * st,
163
-                     AVPacket * pkt,
164
-                     uint32_t * timestamp,
165
-                     const uint8_t * buf, int len, int flags)
166
-{
167
-    int ident, fragmented, vdt, num_pkts, pkt_len;
168
-
169
-    if (len < 6) {
170
-        av_log(ctx, AV_LOG_ERROR, "Invalid %d byte packet\n", len);
171
-        return AVERROR_INVALIDDATA;
172
-    }
173
-
174
-    ident = AV_RB24(buf);
175
-    fragmented = buf[3] >> 6;
176
-    vdt = (buf[3] >> 4) & 3;
177
-    num_pkts = buf[3] & 7;
178
-    pkt_len = AV_RB16(buf + 4);
179
-
180
-    if (pkt_len > len - 6) {
181
-        av_log(ctx, AV_LOG_ERROR,
182
-               "Invalid packet length %d in %d byte packet\n", pkt_len,
183
-               len);
184
-        return AVERROR_INVALIDDATA;
185
-    }
186
-
187
-    if (ident != data->ident) {
188
-        av_log(ctx, AV_LOG_ERROR,
189
-               "Unimplemented Vorbis SDP configuration change detected\n");
190
-        return AVERROR_PATCHWELCOME;
191
-    }
192
-
193
-    if (fragmented != 0 || vdt != 0 || num_pkts != 1) {
194
-        av_log(ctx, AV_LOG_ERROR,
195
-               "Unimplemented RTP Vorbis packet settings (%d,%d,%d)\n",
196
-               fragmented, vdt, num_pkts);
197
-        return AVERROR_PATCHWELCOME;
198
-    }
199
-
200
-    if (av_new_packet(pkt, pkt_len)) {
201
-        av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
202
-        return AVERROR_NOMEM;
203
-    }
204
-
205
-    memcpy(pkt->data, buf + 6, pkt_len);
206
-    pkt->stream_index = st->index;
207
-    return 0;
208
-}
209
-
210
-RTPDynamicProtocolHandler ff_vorbis_dynamic_handler = {
211
-    .enc_name         = "vorbis",
212
-    .codec_type       = CODEC_TYPE_AUDIO,
213
-    .codec_id         = CODEC_ID_VORBIS,
214
-    .parse_sdp_a_line = NULL,
215
-    .open             = vorbis_new_context,
216
-    .close            = vorbis_free_context,
217
-    .parse_packet     = vorbis_handle_packet
218
-};
219 1
deleted file mode 100644
... ...
@@ -1,45 +0,0 @@
1
-/*
2
- * RTP Vorbis Protocol (RFC 5215)
3
- * Copyright (c) 2009 Colin McQuillan
4
- *
5
- * This file is part of FFmpeg.
6
- *
7
- * FFmpeg is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU Lesser General Public
9
- * License as published by the Free Software Foundation; either
10
- * version 2.1 of the License, or (at your option) any later version.
11
- *
12
- * FFmpeg is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
- * Lesser General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU Lesser General Public
18
- * License along with FFmpeg; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
- */
21
-
22
-#ifndef AVFORMAT_RTP_VORBIS_H
23
-#define AVFORMAT_RTP_VORBIS_H
24
-
25
-#include "libavcodec/avcodec.h"
26
-#include "rtpdec.h"
27
-
28
-/**
29
- * Handle a Vorbis-specific FMTP parameter
30
- *
31
- * @param codec The context of the codec
32
- * @param ctx Private Vorbis RTP context
33
- * @param attr Format-specific parameter name
34
- * @param value Format-specific paremeter value
35
- */
36
-int
37
-ff_vorbis_parse_fmtp_config(AVCodecContext * codec,
38
-                            void *ctx, char *attr, char *value);
39
-
40
-/**
41
- * Vorbis RTP callbacks.
42
- */
43
-extern RTPDynamicProtocolHandler ff_vorbis_dynamic_handler;
44
-
45
-#endif /* AVFORMAT_RTP_VORBIS_H */
... ...
@@ -30,11 +30,11 @@
30 30
 #include "network.h"
31 31
 
32 32
 #include "rtpdec.h"
33
-#include "rtp_asf.h"
34
-#include "rtp_h264.h"
35
-#include "rtp_vorbis.h"
36 33
 #include "rtpdec_amr.h"
34
+#include "rtpdec_asf.h"
37 35
 #include "rtpdec_h263.h"
36
+#include "rtpdec_h264.h"
37
+#include "rtpdec_vorbis.h"
38 38
 
39 39
 //#define DEBUG
40 40
 
41 41
new file mode 100644
... ...
@@ -0,0 +1,281 @@
0
+/*
1
+ * Microsoft RTP/ASF support.
2
+ * Copyright (c) 2008 Ronald S. Bultje
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+/**
22
+ * @file libavformat/rtpdec_asf.c
23
+ * @brief Microsoft RTP/ASF support
24
+ * @author Ronald S. Bultje <rbultje@ronald.bitfreak.net>
25
+ */
26
+
27
+#include <libavutil/base64.h>
28
+#include <libavutil/avstring.h>
29
+#include <libavutil/intreadwrite.h>
30
+#include "rtp.h"
31
+#include "rtpdec_asf.h"
32
+#include "rtsp.h"
33
+#include "asf.h"
34
+
35
+/**
36
+ * From MSDN 2.2.1.4, we learn that ASF data packets over RTP should not
37
+ * contain any padding. Unfortunately, the header min/max_pktsize are not
38
+ * updated (thus making min_pktsize invalid). Here, we "fix" these faulty
39
+ * min_pktsize values in the ASF file header.
40
+ * @return 0 on success, <0 on failure (currently -1).
41
+ */
42
+static int rtp_asf_fix_header(uint8_t *buf, int len)
43
+{
44
+    uint8_t *p = buf, *end = buf + len;
45
+
46
+    if (len < sizeof(ff_asf_guid) * 2 + 22 ||
47
+        memcmp(p, ff_asf_header, sizeof(ff_asf_guid))) {
48
+        return -1;
49
+    }
50
+    p += sizeof(ff_asf_guid) + 14;
51
+    do {
52
+        uint64_t chunksize = AV_RL64(p + sizeof(ff_asf_guid));
53
+        if (memcmp(p, ff_asf_file_header, sizeof(ff_asf_guid))) {
54
+            if (chunksize > end - p)
55
+                return -1;
56
+            p += chunksize;
57
+            continue;
58
+        }
59
+
60
+        /* skip most of the file header, to min_pktsize */
61
+        p += 6 * 8 + 3 * 4 + sizeof(ff_asf_guid) * 2;
62
+        if (p + 8 <= end && AV_RL32(p) == AV_RL32(p + 4)) {
63
+            /* and set that to zero */
64
+            AV_WL32(p, 0);
65
+            return 0;
66
+        }
67
+        break;
68
+    } while (end - p >= sizeof(ff_asf_guid) + 8);
69
+
70
+    return -1;
71
+}
72
+
73
+/**
74
+ * The following code is basically a buffered ByteIOContext,
75
+ * with the added benefit of returning -EAGAIN (instead of 0)
76
+ * on packet boundaries, such that the ASF demuxer can return
77
+ * safely and resume business at the next packet.
78
+ */
79
+static int packetizer_read(void *opaque, uint8_t *buf, int buf_size)
80
+{
81
+    return AVERROR(EAGAIN);
82
+}
83
+
84
+static void init_packetizer(ByteIOContext *pb, uint8_t *buf, int len)
85
+{
86
+    init_put_byte(pb, buf, len, 0, NULL, packetizer_read, NULL, NULL);
87
+
88
+    /* this "fills" the buffer with its current content */
89
+    pb->pos     = len;
90
+    pb->buf_end = buf + len;
91
+}
92
+
93
+void ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p)
94
+{
95
+    if (av_strstart(p, "pgmpu:data:application/vnd.ms.wms-hdr.asfv1;base64,", &p)) {
96
+        ByteIOContext pb;
97
+        RTSPState *rt = s->priv_data;
98
+        int len = strlen(p) * 6 / 8;
99
+        char *buf = av_mallocz(len);
100
+        av_base64_decode(buf, p, len);
101
+
102
+        if (rtp_asf_fix_header(buf, len) < 0)
103
+            av_log(s, AV_LOG_ERROR,
104
+                   "Failed to fix invalid RTSP-MS/ASF min_pktsize\n");
105
+        init_packetizer(&pb, buf, len);
106
+        if (rt->asf_ctx) {
107
+            av_close_input_stream(rt->asf_ctx);
108
+            rt->asf_ctx = NULL;
109
+        }
110
+        av_open_input_stream(&rt->asf_ctx, &pb, "", &asf_demuxer, NULL);
111
+        rt->asf_pb_pos = url_ftell(&pb);
112
+        av_free(buf);
113
+        rt->asf_ctx->pb = NULL;
114
+    }
115
+}
116
+
117
+static int asfrtp_parse_sdp_line(AVFormatContext *s, int stream_index,
118
+                                 PayloadContext *asf, const char *line)
119
+{
120
+    if (av_strstart(line, "stream:", &line)) {
121
+        RTSPState *rt = s->priv_data;
122
+
123
+        s->streams[stream_index]->id = strtol(line, NULL, 10);
124
+
125
+        if (rt->asf_ctx) {
126
+            int i;
127
+
128
+            for (i = 0; i < rt->asf_ctx->nb_streams; i++) {
129
+                if (s->streams[stream_index]->id == rt->asf_ctx->streams[i]->id) {
130
+                    *s->streams[stream_index]->codec =
131
+                        *rt->asf_ctx->streams[i]->codec;
132
+                    rt->asf_ctx->streams[i]->codec->extradata_size = 0;
133
+                    rt->asf_ctx->streams[i]->codec->extradata = NULL;
134
+                    av_set_pts_info(s->streams[stream_index], 32, 1, 1000);
135
+                }
136
+           }
137
+        }
138
+    }
139
+
140
+    return 0;
141
+}
142
+
143
+struct PayloadContext {
144
+    ByteIOContext *pktbuf, pb;
145
+    char *buf;
146
+};
147
+
148
+/**
149
+ * @return 0 when a packet was written into /p pkt, and no more data is left;
150
+ *         1 when a packet was written into /p pkt, and more packets might be left;
151
+ *        <0 when not enough data was provided to return a full packet, or on error.
152
+ */
153
+static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,
154
+                               AVStream *st, AVPacket *pkt,
155
+                               uint32_t *timestamp,
156
+                               const uint8_t *buf, int len, int flags)
157
+{
158
+    ByteIOContext *pb = &asf->pb;
159
+    int res, mflags, len_off;
160
+    RTSPState *rt = s->priv_data;
161
+
162
+    if (!rt->asf_ctx)
163
+        return -1;
164
+
165
+    if (len > 0) {
166
+        int off, out_len;
167
+
168
+        if (len < 4)
169
+            return -1;
170
+
171
+        init_put_byte(pb, buf, len, 0, NULL, NULL, NULL, NULL);
172
+        mflags = get_byte(pb);
173
+        if (mflags & 0x80)
174
+            flags |= RTP_FLAG_KEY;
175
+        len_off = get_be24(pb);
176
+        if (mflags & 0x20)   /**< relative timestamp */
177
+            url_fskip(pb, 4);
178
+        if (mflags & 0x10)   /**< has duration */
179
+            url_fskip(pb, 4);
180
+        if (mflags & 0x8)    /**< has location ID */
181
+            url_fskip(pb, 4);
182
+        off = url_ftell(pb);
183
+
184
+        av_freep(&asf->buf);
185
+        if (!(mflags & 0x40)) {
186
+            /**
187
+             * If 0x40 is not set, the len_off field specifies an offset of this
188
+             * packet's payload data in the complete (reassembled) ASF packet.
189
+             * This is used to spread one ASF packet over multiple RTP packets.
190
+             */
191
+            if (asf->pktbuf && len_off != url_ftell(asf->pktbuf)) {
192
+                uint8_t *p;
193
+                url_close_dyn_buf(asf->pktbuf, &p);
194
+                asf->pktbuf = NULL;
195
+                av_free(p);
196
+            }
197
+            if (!len_off && !asf->pktbuf &&
198
+                (res = url_open_dyn_buf(&asf->pktbuf)) < 0)
199
+                return res;
200
+            if (!asf->pktbuf)
201
+                return AVERROR(EIO);
202
+
203
+            put_buffer(asf->pktbuf, buf + off, len - off);
204
+            if (!(flags & RTP_FLAG_MARKER))
205
+                return -1;
206
+            out_len     = url_close_dyn_buf(asf->pktbuf, &asf->buf);
207
+            asf->pktbuf = NULL;
208
+        } else {
209
+            /**
210
+             * If 0x40 is set, the len_off field specifies the length of the
211
+             * next ASF packet that can be read from this payload data alone.
212
+             * This is commonly the same as the payload size, but could be
213
+             * less in case of packet splitting (i.e. multiple ASF packets in
214
+             * one RTP packet).
215
+             */
216
+            if (len_off != len) {
217
+                av_log_missing_feature(s,
218
+                    "RTSP-MS packet splitting", 1);
219
+                return -1;
220
+            }
221
+            asf->buf = av_malloc(len - off);
222
+            out_len  = len - off;
223
+            memcpy(asf->buf, buf + off, len - off);
224
+        }
225
+
226
+        init_packetizer(pb, asf->buf, out_len);
227
+        pb->pos += rt->asf_pb_pos;
228
+        pb->eof_reached = 0;
229
+        rt->asf_ctx->pb = pb;
230
+    }
231
+
232
+    for (;;) {
233
+        int i;
234
+
235
+        res = av_read_packet(rt->asf_ctx, pkt);
236
+        rt->asf_pb_pos = url_ftell(pb);
237
+        if (res != 0)
238
+            break;
239
+        for (i = 0; i < s->nb_streams; i++) {
240
+            if (s->streams[i]->id == rt->asf_ctx->streams[pkt->stream_index]->id) {
241
+                pkt->stream_index = i;
242
+                return 1; // FIXME: return 0 if last packet
243
+            }
244
+        }
245
+        av_free_packet(pkt);
246
+    }
247
+
248
+    return res == 1 ? -1 : res;
249
+}
250
+
251
+static PayloadContext *asfrtp_new_context(void)
252
+{
253
+    return av_mallocz(sizeof(PayloadContext));
254
+}
255
+
256
+static void asfrtp_free_context(PayloadContext *asf)
257
+{
258
+    if (asf->pktbuf) {
259
+        uint8_t *p = NULL;
260
+        url_close_dyn_buf(asf->pktbuf, &p);
261
+        asf->pktbuf = NULL;
262
+        av_free(p);
263
+    }
264
+    av_freep(&asf->buf);
265
+    av_free(asf);
266
+}
267
+
268
+#define RTP_ASF_HANDLER(n, s, t) \
269
+RTPDynamicProtocolHandler ff_ms_rtp_ ## n ## _handler = { \
270
+    .enc_name         = s, \
271
+    .codec_type       = t, \
272
+    .codec_id         = CODEC_ID_NONE, \
273
+    .parse_sdp_a_line = asfrtp_parse_sdp_line, \
274
+    .open             = asfrtp_new_context, \
275
+    .close            = asfrtp_free_context, \
276
+    .parse_packet     = asfrtp_parse_packet,   \
277
+};
278
+
279
+RTP_ASF_HANDLER(asf_pfv, "x-asf-pf",  CODEC_TYPE_VIDEO);
280
+RTP_ASF_HANDLER(asf_pfa, "x-asf-pf",  CODEC_TYPE_AUDIO);
0 281
new file mode 100644
... ...
@@ -0,0 +1,43 @@
0
+/*
1
+ * Microsoft RTP/ASF support.
2
+ * Copyright (c) 2008 Ronald S. Bultje
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#ifndef AVFORMAT_RTPDEC_ASF_H
22
+#define AVFORMAT_RTPDEC_ASF_H
23
+
24
+#include "avformat.h"
25
+#include "rtpdec.h"
26
+
27
+/**
28
+ * Parse a Windows Media Server-specific SDP line
29
+ *
30
+ * @param s RTSP demux context
31
+ * @param line the SDP line to be parsed
32
+ */
33
+void ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p);
34
+
35
+/**
36
+ * Handlers for the x-asf-pf payloads (the payload ID for RTP/ASF).
37
+ * Defined and implemented in rtp_asf.c, registered in rtpdec.c.
38
+ */
39
+extern RTPDynamicProtocolHandler ff_ms_rtp_asf_pfv_handler,
40
+                                 ff_ms_rtp_asf_pfa_handler;
41
+
42
+#endif /* AVFORMAT_RTPDEC_ASF_H */
0 43
new file mode 100644
... ...
@@ -0,0 +1,416 @@
0
+/*
1
+ * RTP H264 Protocol (RFC3984)
2
+ * Copyright (c) 2006 Ryan Martell
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+/**
22
+* @file libavformat/rtpdec_h264.c
23
+ * @brief H.264 / RTP Code (RFC3984)
24
+ * @author Ryan Martell <rdm4@martellventures.com>
25
+ *
26
+ * @note Notes:
27
+ * Notes:
28
+ * This currently supports packetization mode:
29
+ * Single Nal Unit Mode (0), or
30
+ * Non-Interleaved Mode (1).  It currently does not support
31
+ * Interleaved Mode (2). (This requires implementing STAP-B, MTAP16, MTAP24, FU-B packet types)
32
+ *
33
+ * @note TODO:
34
+ * 1) RTCP sender reports for udp streams are required..
35
+ *
36
+ */
37
+
38
+#include "libavutil/base64.h"
39
+#include "libavutil/avstring.h"
40
+#include "libavcodec/get_bits.h"
41
+#include "avformat.h"
42
+#include "mpegts.h"
43
+
44
+#include <unistd.h>
45
+#include "network.h"
46
+#include <assert.h>
47
+
48
+#include "rtpdec.h"
49
+#include "rtpdec_h264.h"
50
+
51
+/**
52
+    RTP/H264 specific private data.
53
+*/
54
+struct PayloadContext {
55
+    unsigned long cookie;       ///< sanity check, to make sure we get the pointer we're expecting.
56
+
57
+    //sdp setup parameters
58
+    uint8_t profile_idc;        ///< from the sdp setup parameters.
59
+    uint8_t profile_iop;        ///< from the sdp setup parameters.
60
+    uint8_t level_idc;          ///< from the sdp setup parameters.
61
+    int packetization_mode;     ///< from the sdp setup parameters.
62
+#ifdef DEBUG
63
+    int packet_types_received[32];
64
+#endif
65
+};
66
+
67
+#define MAGIC_COOKIE (0xdeadbeef)       ///< Cookie for the extradata; to verify we are what we think we are, and that we haven't been freed.
68
+#define DEAD_COOKIE (0xdeaddead)        ///< Cookie for the extradata; once it is freed.
69
+
70
+/* ---------------- private code */
71
+static void sdp_parse_fmtp_config_h264(AVStream * stream,
72
+                                       PayloadContext * h264_data,
73
+                                       char *attr, char *value)
74
+{
75
+    AVCodecContext *codec = stream->codec;
76
+    assert(codec->codec_id == CODEC_ID_H264);
77
+    assert(h264_data != NULL);
78
+
79
+    if (!strcmp(attr, "packetization-mode")) {
80
+        av_log(codec, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value));
81
+        h264_data->packetization_mode = atoi(value);
82
+        /*
83
+           Packetization Mode:
84
+           0 or not present: Single NAL mode (Only nals from 1-23 are allowed)
85
+           1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed.
86
+           2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), and 29 (FU-B) are allowed.
87
+         */
88
+        if (h264_data->packetization_mode > 1)
89
+            av_log(codec, AV_LOG_ERROR,
90
+                   "Interleaved RTP mode is not supported yet.");
91
+    } else if (!strcmp(attr, "profile-level-id")) {
92
+        if (strlen(value) == 6) {
93
+            char buffer[3];
94
+            // 6 characters=3 bytes, in hex.
95
+            uint8_t profile_idc;
96
+            uint8_t profile_iop;
97
+            uint8_t level_idc;
98
+
99
+            buffer[0] = value[0]; buffer[1] = value[1]; buffer[2] = '\0';
100
+            profile_idc = strtol(buffer, NULL, 16);
101
+            buffer[0] = value[2]; buffer[1] = value[3];
102
+            profile_iop = strtol(buffer, NULL, 16);
103
+            buffer[0] = value[4]; buffer[1] = value[5];
104
+            level_idc = strtol(buffer, NULL, 16);
105
+
106
+            // set the parameters...
107
+            av_log(codec, AV_LOG_DEBUG,
108
+                   "RTP Profile IDC: %x Profile IOP: %x Level: %x\n",
109
+                   profile_idc, profile_iop, level_idc);
110
+            h264_data->profile_idc = profile_idc;
111
+            h264_data->profile_iop = profile_iop;
112
+            h264_data->level_idc = level_idc;
113
+        }
114
+    } else  if (!strcmp(attr, "sprop-parameter-sets")) {
115
+        uint8_t start_sequence[]= { 0, 0, 1 };
116
+        codec->extradata_size= 0;
117
+        codec->extradata= NULL;
118
+
119
+        while (*value) {
120
+            char base64packet[1024];
121
+            uint8_t decoded_packet[1024];
122
+            uint32_t packet_size;
123
+            char *dst = base64packet;
124
+
125
+            while (*value && *value != ','
126
+                   && (dst - base64packet) < sizeof(base64packet) - 1) {
127
+                *dst++ = *value++;
128
+            }
129
+            *dst++ = '\0';
130
+
131
+            if (*value == ',')
132
+                value++;
133
+
134
+            packet_size= av_base64_decode(decoded_packet, base64packet, sizeof(decoded_packet));
135
+            if (packet_size) {
136
+                uint8_t *dest= av_malloc(packet_size+sizeof(start_sequence)+codec->extradata_size);
137
+                if(dest)
138
+                {
139
+                    if(codec->extradata_size)
140
+                    {
141
+                        // av_realloc?
142
+                        memcpy(dest, codec->extradata, codec->extradata_size);
143
+                        av_free(codec->extradata);
144
+                    }
145
+
146
+                    memcpy(dest+codec->extradata_size, start_sequence, sizeof(start_sequence));
147
+                    memcpy(dest+codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size);
148
+
149
+                    codec->extradata= dest;
150
+                    codec->extradata_size+= sizeof(start_sequence)+packet_size;
151
+                } else {
152
+                    av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!");
153
+                }
154
+            }
155
+        }
156
+        av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!", codec->extradata, codec->extradata_size);
157
+    }
158
+}
159
+
160
+// return 0 on packet, no more left, 1 on packet, 1 on partial packet...
161
+static int h264_handle_packet(AVFormatContext *ctx,
162
+                              PayloadContext *data,
163
+                              AVStream *st,
164
+                              AVPacket * pkt,
165
+                              uint32_t * timestamp,
166
+                              const uint8_t * buf,
167
+                              int len, int flags)
168
+{
169
+    uint8_t nal = buf[0];
170
+    uint8_t type = (nal & 0x1f);
171
+    int result= 0;
172
+    uint8_t start_sequence[]= {0, 0, 1};
173
+
174
+#ifdef DEBUG
175
+    assert(data);
176
+    assert(data->cookie == MAGIC_COOKIE);
177
+#endif
178
+    assert(buf);
179
+
180
+    if (type >= 1 && type <= 23)
181
+        type = 1;              // simplify the case. (these are all the nal types used internally by the h264 codec)
182
+    switch (type) {
183
+    case 0:                    // undefined;
184
+        result= -1;
185
+        break;
186
+
187
+    case 1:
188
+        av_new_packet(pkt, len+sizeof(start_sequence));
189
+        memcpy(pkt->data, start_sequence, sizeof(start_sequence));
190
+        memcpy(pkt->data+sizeof(start_sequence), buf, len);
191
+#ifdef DEBUG
192
+        data->packet_types_received[nal & 0x1f]++;
193
+#endif
194
+        break;
195
+
196
+    case 24:                   // STAP-A (one packet, multiple nals)
197
+        // consume the STAP-A NAL
198
+        buf++;
199
+        len--;
200
+        // first we are going to figure out the total size....
201
+        {
202
+            int pass= 0;
203
+            int total_length= 0;
204
+            uint8_t *dst= NULL;
205
+
206
+            for(pass= 0; pass<2; pass++) {
207
+                const uint8_t *src= buf;
208
+                int src_len= len;
209
+
210
+                do {
211
+                    uint16_t nal_size = AV_RB16(src); // this going to be a problem if unaligned (can it be?)
212
+
213
+                    // consume the length of the aggregate...
214
+                    src += 2;
215
+                    src_len -= 2;
216
+
217
+                    if (nal_size <= src_len) {
218
+                        if(pass==0) {
219
+                            // counting...
220
+                            total_length+= sizeof(start_sequence)+nal_size;
221
+                        } else {
222
+                            // copying
223
+                            assert(dst);
224
+                            memcpy(dst, start_sequence, sizeof(start_sequence));
225
+                            dst+= sizeof(start_sequence);
226
+                            memcpy(dst, src, nal_size);
227
+#ifdef DEBUG
228
+                            data->packet_types_received[*src & 0x1f]++;
229
+#endif
230
+                            dst+= nal_size;
231
+                        }
232
+                    } else {
233
+                        av_log(ctx, AV_LOG_ERROR,
234
+                               "nal size exceeds length: %d %d\n", nal_size, src_len);
235
+                    }
236
+
237
+                    // eat what we handled...
238
+                    src += nal_size;
239
+                    src_len -= nal_size;
240
+
241
+                    if (src_len < 0)
242
+                        av_log(ctx, AV_LOG_ERROR,
243
+                               "Consumed more bytes than we got! (%d)\n", src_len);
244
+                } while (src_len > 2);      // because there could be rtp padding..
245
+
246
+                if(pass==0) {
247
+                    // now we know the total size of the packet (with the start sequences added)
248
+                    av_new_packet(pkt, total_length);
249
+                    dst= pkt->data;
250
+                } else {
251
+                    assert(dst-pkt->data==total_length);
252
+                }
253
+            }
254
+        }
255
+        break;
256
+
257
+    case 25:                   // STAP-B
258
+    case 26:                   // MTAP-16
259
+    case 27:                   // MTAP-24
260
+    case 29:                   // FU-B
261
+        av_log(ctx, AV_LOG_ERROR,
262
+               "Unhandled type (%d) (See RFC for implementation details\n",
263
+               type);
264
+        result= -1;
265
+        break;
266
+
267
+    case 28:                   // FU-A (fragmented nal)
268
+        buf++;
269
+        len--;                  // skip the fu_indicator
270
+        {
271
+            // these are the same as above, we just redo them here for clarity...
272
+            uint8_t fu_indicator = nal;
273
+            uint8_t fu_header = *buf;   // read the fu_header.
274
+            uint8_t start_bit = fu_header >> 7;
275
+//            uint8_t end_bit = (fu_header & 0x40) >> 6;
276
+            uint8_t nal_type = (fu_header & 0x1f);
277
+            uint8_t reconstructed_nal;
278
+
279
+            // reconstruct this packet's true nal; only the data follows..
280
+            reconstructed_nal = fu_indicator & (0xe0);  // the original nal forbidden bit and NRI are stored in this packet's nal;
281
+            reconstructed_nal |= nal_type;
282
+
283
+            // skip the fu_header...
284
+            buf++;
285
+            len--;
286
+
287
+#ifdef DEBUG
288
+            if (start_bit)
289
+                data->packet_types_received[nal_type]++;
290
+#endif
291
+            if(start_bit) {
292
+                // copy in the start sequence, and the reconstructed nal....
293
+                av_new_packet(pkt, sizeof(start_sequence)+sizeof(nal)+len);
294
+                memcpy(pkt->data, start_sequence, sizeof(start_sequence));
295
+                pkt->data[sizeof(start_sequence)]= reconstructed_nal;
296
+                memcpy(pkt->data+sizeof(start_sequence)+sizeof(nal), buf, len);
297
+            } else {
298
+                av_new_packet(pkt, len);
299
+                memcpy(pkt->data, buf, len);
300
+            }
301
+        }
302
+        break;
303
+
304
+    case 30:                   // undefined
305
+    case 31:                   // undefined
306
+    default:
307
+        av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)", type);
308
+        result= -1;
309
+        break;
310
+    }
311
+
312
+    pkt->stream_index = st->index;
313
+
314
+    return result;
315
+}
316
+
317
+/* ---------------- public code */
318
+static PayloadContext *h264_new_context(void)
319
+{
320
+    PayloadContext *data =
321
+        av_mallocz(sizeof(PayloadContext) +
322
+                   FF_INPUT_BUFFER_PADDING_SIZE);
323
+
324
+    if (data) {
325
+        data->cookie = MAGIC_COOKIE;
326
+    }
327
+
328
+    return data;
329
+}
330
+
331
+static void h264_free_context(PayloadContext *data)
332
+{
333
+#ifdef DEBUG
334
+    int ii;
335
+
336
+    for (ii = 0; ii < 32; ii++) {
337
+        if (data->packet_types_received[ii])
338
+            av_log(NULL, AV_LOG_DEBUG, "Received %d packets of type %d\n",
339
+                   data->packet_types_received[ii], ii);
340
+    }
341
+#endif
342
+
343
+    assert(data);
344
+    assert(data->cookie == MAGIC_COOKIE);
345
+
346
+    // avoid stale pointers (assert)
347
+    data->cookie = DEAD_COOKIE;
348
+
349
+    // and clear out this...
350
+    av_free(data);
351
+}
352
+
353
+static int parse_h264_sdp_line(AVFormatContext *s, int st_index,
354
+                               PayloadContext *h264_data, const char *line)
355
+{
356
+    AVStream *stream = s->streams[st_index];
357
+    AVCodecContext *codec = stream->codec;
358
+    const char *p = line;
359
+
360
+    assert(h264_data->cookie == MAGIC_COOKIE);
361
+
362
+    if (av_strstart(p, "framesize:", &p)) {
363
+        char buf1[50];
364
+        char *dst = buf1;
365
+
366
+        // remove the protocol identifier..
367
+        while (*p && *p == ' ') p++; // strip spaces.
368
+        while (*p && *p != ' ') p++; // eat protocol identifier
369
+        while (*p && *p == ' ') p++; // strip trailing spaces.
370
+        while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) {
371
+            *dst++ = *p++;
372
+        }
373
+        *dst = '\0';
374
+
375
+        // a='framesize:96 320-240'
376
+        // set our parameters..
377
+        codec->width = atoi(buf1);
378
+        codec->height = atoi(p + 1); // skip the -
379
+        codec->pix_fmt = PIX_FMT_YUV420P;
380
+    } else if (av_strstart(p, "fmtp:", &p)) {
381
+        char attr[256];
382
+        char value[4096];
383
+
384
+        // remove the protocol identifier..
385
+        while (*p && *p == ' ') p++; // strip spaces.
386
+        while (*p && *p != ' ') p++; // eat protocol identifier
387
+        while (*p && *p == ' ') p++; // strip trailing spaces.
388
+
389
+        /* loop on each attribute */
390
+        while (ff_rtsp_next_attr_and_value
391
+               (&p, attr, sizeof(attr), value, sizeof(value))) {
392
+            /* grab the codec extra_data from the config parameter of the fmtp line */
393
+            sdp_parse_fmtp_config_h264(stream, h264_data, attr, value);
394
+        }
395
+    } else if (av_strstart(p, "cliprect:", &p)) {
396
+        // could use this if we wanted.
397
+    }
398
+
399
+    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)
400
+
401
+    return 0;                   // keep processing it the normal way...
402
+}
403
+
404
+/**
405
+This is the structure for expanding on the dynamic rtp protocols (makes everything static. yay!)
406
+*/
407
+RTPDynamicProtocolHandler ff_h264_dynamic_handler = {
408
+    .enc_name         = "H264",
409
+    .codec_type       = CODEC_TYPE_VIDEO,
410
+    .codec_id         = CODEC_ID_H264,
411
+    .parse_sdp_a_line = parse_h264_sdp_line,
412
+    .open             = h264_new_context,
413
+    .close            = h264_free_context,
414
+    .parse_packet     = h264_handle_packet
415
+};
0 416
new file mode 100644
... ...
@@ -0,0 +1,29 @@
0
+/*
1
+ * RTP H264 Protocol (RFC3984)
2
+ * Copyright (c) 2006 Ryan Martell
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#ifndef AVFORMAT_RTPDEC_H264_H
22
+#define AVFORMAT_RTPDEC_H264_H
23
+
24
+#include "rtpdec.h"
25
+
26
+extern RTPDynamicProtocolHandler ff_h264_dynamic_handler;
27
+
28
+#endif /* AVFORMAT_RTPDEC_H264_H */
0 29
new file mode 100644
... ...
@@ -0,0 +1,218 @@
0
+/*
1
+ * RTP Vorbis Protocol (RFC5215)
2
+ * Copyright (c) 2009 Colin McQuillan
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+/**
22
+ * @file libavformat/rtpdec_vorbis.c
23
+ * @brief Vorbis / RTP Code (RFC 5215)
24
+ * @author Colin McQuillan <m.niloc@gmail.com>
25
+ */
26
+
27
+#include "libavutil/base64.h"
28
+#include "libavutil/avstring.h"
29
+#include "libavcodec/bytestream.h"
30
+
31
+#include <assert.h>
32
+
33
+#include "rtpdec.h"
34
+#include "rtpdec_vorbis.h"
35
+
36
+/**
37
+ * RTP/Vorbis specific private data.
38
+ */
39
+struct PayloadContext {
40
+    unsigned ident;             ///< 24-bit stream configuration identifier
41
+};
42
+
43
+/**
44
+ * Length encoding described in RFC5215 section 3.1.1.
45
+ */
46
+static int get_base128(const uint8_t ** buf, const uint8_t * buf_end)
47
+{
48
+    int n = 0;
49
+    for (; *buf < buf_end; ++*buf) {
50
+        n <<= 7;
51
+        n += **buf & 0x7f;
52
+        if (!(**buf & 0x80)) {
53
+            ++*buf;
54
+            return n;
55
+        }
56
+    }
57
+    return 0;
58
+}
59
+
60
+/**
61
+ * Out-of-band headers, described in RFC 5251 section 3.2.1
62
+ */
63
+static unsigned int
64
+parse_packed_headers(const uint8_t * packed_headers,
65
+                     const uint8_t * packed_headers_end,
66
+                     AVCodecContext * codec, PayloadContext * vorbis_data)
67
+{
68
+    unsigned num_packed, num_headers, length, length1, length2;
69
+    uint8_t *ptr;
70
+
71
+    num_packed         = bytestream_get_be32(&packed_headers);
72
+    vorbis_data->ident = bytestream_get_be24(&packed_headers);
73
+    length             = bytestream_get_be16(&packed_headers);
74
+    num_headers        = get_base128(&packed_headers, packed_headers_end);
75
+    length1            = get_base128(&packed_headers, packed_headers_end);
76
+    length2            = get_base128(&packed_headers, packed_headers_end);
77
+
78
+    if (num_packed != 1 || num_headers > 3) {
79
+        av_log(codec, AV_LOG_ERROR,
80
+               "Unimplemented number of headers: %d packed headers, %d headers\n",
81
+               num_packed, num_headers);
82
+        return AVERROR_PATCHWELCOME;
83
+    }
84
+
85
+    if (packed_headers_end - packed_headers != length ||
86
+        length1 > length || length2 > length - length1) {
87
+        av_log(codec, AV_LOG_ERROR,
88
+               "Bad packed header lengths (%d,%d,%d,%d)\n", length1,
89
+               length2, packed_headers_end - packed_headers, length);
90
+        return AVERROR_INVALIDDATA;
91
+    }
92
+
93
+    ptr = codec->extradata = av_mallocz(length + length / 255 + 64);
94
+    if (!ptr) {
95
+        av_log(codec, AV_LOG_ERROR, "Out of memory");
96
+        return AVERROR_NOMEM;
97
+    }
98
+    *ptr++ = 2;
99
+    ptr += av_xiphlacing(ptr, length1);
100
+    ptr += av_xiphlacing(ptr, length2);
101
+    memcpy(ptr, packed_headers, length);
102
+    ptr += length;
103
+    codec->extradata_size = ptr - codec->extradata;
104
+
105
+    return 0;
106
+}
107
+
108
+int
109
+ff_vorbis_parse_fmtp_config(AVCodecContext * codec,
110
+                            void *vorbis_data, char *attr, char *value)
111
+{
112
+    int result = 0;
113
+    assert(codec->codec_id == CODEC_ID_VORBIS);
114
+    assert(vorbis_data);
115
+
116
+    // The configuration value is a base64 encoded packed header
117
+    if (!strcmp(attr, "configuration")) {
118
+        uint8_t *decoded_packet = NULL;
119
+        int packet_size;
120
+        size_t decoded_alloc = strlen(value) / 4 * 3 + 4;
121
+
122
+        if (decoded_alloc <= INT_MAX) {
123
+            decoded_packet = av_malloc(decoded_alloc);
124
+            if (decoded_packet) {
125
+                packet_size =
126
+                    av_base64_decode(decoded_packet, value, decoded_alloc);
127
+
128
+                result = parse_packed_headers
129
+                    (decoded_packet, decoded_packet + packet_size, codec,
130
+                     vorbis_data);
131
+            } else {
132
+                av_log(codec, AV_LOG_ERROR,
133
+                       "Out of memory while decoding SDP configuration.\n");
134
+                result = AVERROR_NOMEM;
135
+            }
136
+        } else {
137
+            av_log(codec, AV_LOG_ERROR, "Packet too large\n");
138
+            result = AVERROR_INVALIDDATA;
139
+        }
140
+        av_free(decoded_packet);
141
+    }
142
+    return result;
143
+}
144
+
145
+static PayloadContext *vorbis_new_context(void)
146
+{
147
+    return av_mallocz(sizeof(PayloadContext));
148
+}
149
+
150
+static void vorbis_free_context(PayloadContext * data)
151
+{
152
+    av_free(data);
153
+}
154
+
155
+/**
156
+ * Handle payload as described in RFC 5215 section 2.2
157
+ */
158
+static int
159
+vorbis_handle_packet(AVFormatContext * ctx,
160
+                     PayloadContext * data,
161
+                     AVStream * st,
162
+                     AVPacket * pkt,
163
+                     uint32_t * timestamp,
164
+                     const uint8_t * buf, int len, int flags)
165
+{
166
+    int ident, fragmented, vdt, num_pkts, pkt_len;
167
+
168
+    if (len < 6) {
169
+        av_log(ctx, AV_LOG_ERROR, "Invalid %d byte packet\n", len);
170
+        return AVERROR_INVALIDDATA;
171
+    }
172
+
173
+    ident = AV_RB24(buf);
174
+    fragmented = buf[3] >> 6;
175
+    vdt = (buf[3] >> 4) & 3;
176
+    num_pkts = buf[3] & 7;
177
+    pkt_len = AV_RB16(buf + 4);
178
+
179
+    if (pkt_len > len - 6) {
180
+        av_log(ctx, AV_LOG_ERROR,
181
+               "Invalid packet length %d in %d byte packet\n", pkt_len,
182
+               len);
183
+        return AVERROR_INVALIDDATA;
184
+    }
185
+
186
+    if (ident != data->ident) {
187
+        av_log(ctx, AV_LOG_ERROR,
188
+               "Unimplemented Vorbis SDP configuration change detected\n");
189
+        return AVERROR_PATCHWELCOME;
190
+    }
191
+
192
+    if (fragmented != 0 || vdt != 0 || num_pkts != 1) {
193
+        av_log(ctx, AV_LOG_ERROR,
194
+               "Unimplemented RTP Vorbis packet settings (%d,%d,%d)\n",
195
+               fragmented, vdt, num_pkts);
196
+        return AVERROR_PATCHWELCOME;
197
+    }
198
+
199
+    if (av_new_packet(pkt, pkt_len)) {
200
+        av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
201
+        return AVERROR_NOMEM;
202
+    }
203
+
204
+    memcpy(pkt->data, buf + 6, pkt_len);
205
+    pkt->stream_index = st->index;
206
+    return 0;
207
+}
208
+
209
+RTPDynamicProtocolHandler ff_vorbis_dynamic_handler = {
210
+    .enc_name         = "vorbis",
211
+    .codec_type       = CODEC_TYPE_AUDIO,
212
+    .codec_id         = CODEC_ID_VORBIS,
213
+    .parse_sdp_a_line = NULL,
214
+    .open             = vorbis_new_context,
215
+    .close            = vorbis_free_context,
216
+    .parse_packet     = vorbis_handle_packet
217
+};
0 218
new file mode 100644
... ...
@@ -0,0 +1,45 @@
0
+/*
1
+ * RTP Vorbis Protocol (RFC 5215)
2
+ * Copyright (c) 2009 Colin McQuillan
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#ifndef AVFORMAT_RTPDEC_VORBIS_H
22
+#define AVFORMAT_RTPDEC_VORBIS_H
23
+
24
+#include "libavcodec/avcodec.h"
25
+#include "rtpdec.h"
26
+
27
+/**
28
+ * Handle a Vorbis-specific FMTP parameter
29
+ *
30
+ * @param codec The context of the codec
31
+ * @param ctx Private Vorbis RTP context
32
+ * @param attr Format-specific parameter name
33
+ * @param value Format-specific paremeter value
34
+ */
35
+int
36
+ff_vorbis_parse_fmtp_config(AVCodecContext * codec,
37
+                            void *ctx, char *attr, char *value);
38
+
39
+/**
40
+ * Vorbis RTP callbacks.
41
+ */
42
+extern RTPDynamicProtocolHandler ff_vorbis_dynamic_handler;
43
+
44
+#endif /* AVFORMAT_RTPDEC_VORBIS_H */
... ...
@@ -37,8 +37,8 @@
37 37
 
38 38
 #include "rtpdec.h"
39 39
 #include "rdt.h"
40
-#include "rtp_asf.h"
41
-#include "rtp_vorbis.h"
40
+#include "rtpdec_asf.h"
41
+#include "rtpdec_vorbis.h"
42 42
 
43 43
 //#define DEBUG
44 44
 //#define DEBUG_RTP_TCP