Browse code

Add support for H.263 video in the RTP muxer patch by Martin Storsjö (martin AT martin DOT st)

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

Martin Storsjö authored on 2009/04/07 15:41:55
Showing 6 changed files
... ...
@@ -6,6 +6,7 @@ version <next>:
6 6
 - VQF demuxer
7 7
 - Alpha channel scaler
8 8
 - PCX encoder
9
+- RTP packetization of H.263
9 10
 
10 11
 
11 12
 
... ...
@@ -189,6 +189,7 @@ OBJS-$(CONFIG_RPL_DEMUXER)               += rpl.o
189 189
 OBJS-$(CONFIG_RTP_MUXER)                 += rtp.o         \
190 190
                                             rtp_aac.o     \
191 191
                                             rtp_asf.o     \
192
+                                            rtp_h263.o    \
192 193
                                             rtp_mpv.o     \
193 194
                                             rtpenc.o      \
194 195
                                             rtpenc_h264.o \
195 196
new file mode 100644
... ...
@@ -0,0 +1,80 @@
0
+/*
1
+ * RTP packetization for H.263 video
2
+ * Copyright (c) 2009 Luca Abeni
3
+ * Copyright (c) 2007 Martin Storsjo
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
+#include "avformat.h"
23
+#include "rtpenc.h"
24
+
25
+static const uint8_t *find_resync_marker_reverse(const uint8_t *restrict start,
26
+                                                 const uint8_t *restrict end)
27
+{
28
+    const uint8_t *p = end - 1;
29
+    start += 1; /* Make sure we never return the original start. */
30
+    for (; p > start; p -= 2) {
31
+        if (!*p) {
32
+            if      (!p[ 1] && p[2]) return p;
33
+            else if (!p[-1] && p[1]) return p - 1;
34
+        }
35
+    }
36
+    return end;
37
+}
38
+
39
+/**
40
+ * Packetize H.263 frames into RTP packets according to RFC 4629
41
+ */
42
+void ff_rtp_send_h263(AVFormatContext *s1, const uint8_t *buf1, int size)
43
+{
44
+    RTPMuxContext *s = s1->priv_data;
45
+    int len, max_packet_size;
46
+    uint8_t *q;
47
+
48
+    max_packet_size = s->max_payload_size;
49
+
50
+    while (size > 0) {
51
+        q = s->buf;
52
+        if ((buf1[0] == 0) && (buf1[1] == 0)) {
53
+            *q++ = 0x04;
54
+            buf1 += 2;
55
+            size -= 2;
56
+        } else {
57
+            *q++ = 0;
58
+        }
59
+        *q++ = 0;
60
+
61
+        len = FFMIN(max_packet_size - 2, size);
62
+
63
+        /* Look for a better place to split the frame into packets. */
64
+        if (len < size) {
65
+            const uint8_t *end = find_resync_marker_reverse(buf1, buf1 + len);
66
+            len = end - buf1;
67
+        }
68
+
69
+        memcpy(q, buf1, len);
70
+        q += len;
71
+
72
+        /* 90 KHz time stamp */
73
+        s->timestamp = s->cur_timestamp;
74
+        ff_rtp_send_data(s1, s->buf, q - s->buf, (len == size));
75
+
76
+        buf1 += len;
77
+        size -= len;
78
+    }
79
+}
... ...
@@ -42,6 +42,8 @@ static uint64_t ntp_time(void)
42 42
 static int is_supported(enum CodecID id)
43 43
 {
44 44
     switch(id) {
45
+    case CODEC_ID_H263:
46
+    case CODEC_ID_H263P:
45 47
     case CODEC_ID_H264:
46 48
     case CODEC_ID_MPEG1VIDEO:
47 49
     case CODEC_ID_MPEG2VIDEO:
... ...
@@ -370,6 +372,10 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
370 370
     case CODEC_ID_H264:
371 371
         ff_rtp_send_h264(s1, buf1, size);
372 372
         break;
373
+    case CODEC_ID_H263:
374
+    case CODEC_ID_H263P:
375
+        ff_rtp_send_h263(s1, buf1, size);
376
+        break;
373 377
     default:
374 378
         /* better than nothing : send the codec raw data */
375 379
         rtp_send_raw(s1, buf1, size);
... ...
@@ -57,6 +57,7 @@ typedef struct RTPMuxContext RTPMuxContext;
57 57
 void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m);
58 58
 
59 59
 void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size);
60
+void ff_rtp_send_h263(AVFormatContext *s1, const uint8_t *buf1, int size);
60 61
 void ff_rtp_send_aac(AVFormatContext *s1, const uint8_t *buff, int size);
61 62
 void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size);
62 63
 
... ...
@@ -177,6 +177,10 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
177 177
                                      payload_type,
178 178
                                      payload_type, config ? config : "");
179 179
             break;
180
+        case CODEC_ID_H263:
181
+        case CODEC_ID_H263P:
182
+            av_strlcatf(buff, size, "a=rtpmap:%d H263-2000/90000\r\n", payload_type);
183
+            break;
180 184
         case CODEC_ID_MPEG4:
181 185
             if (c->extradata_size) {
182 186
                 config = extradata2config(c);