Browse code

RTMPTE protocol support

Signed-off-by: Martin Storsjö <martin@martin.st>

Samuel Pitoiset authored on 2012/07/20 23:36:47
Showing 9 changed files
... ...
@@ -40,6 +40,7 @@ version <next>:
40 40
 - JPEG 2000 encoding support through OpenJPEG
41 41
 - G.723.1 demuxer and decoder
42 42
 - RTMPE protocol support
43
+- RTMPTE protocol support
43 44
 
44 45
 
45 46
 version 0.8:
... ...
@@ -1569,6 +1569,7 @@ rtmpe_protocol_select="ffrtmpcrypt_protocol"
1569 1569
 rtmps_protocol_deps="!librtmp_protocol"
1570 1570
 rtmps_protocol_select="tls_protocol"
1571 1571
 rtmpt_protocol_select="ffrtmphttp_protocol"
1572
+rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
1572 1573
 rtmpts_protocol_select="ffrtmphttp_protocol"
1573 1574
 rtp_protocol_select="udp_protocol"
1574 1575
 sctp_protocol_deps="network netinet_sctp_h"
... ...
@@ -847,7 +847,7 @@ performance on systems without hardware floating point support).
847 847
 @item RTMPE        @tab X
848 848
 @item RTMPS        @tab X
849 849
 @item RTMPT        @tab X
850
-@item RTMPTE       @tab E
850
+@item RTMPTE       @tab X
851 851
 @item RTMPTS       @tab X
852 852
 @item RTP          @tab X
853 853
 @item SCTP         @tab X
... ...
@@ -271,6 +271,14 @@ The Real-Time Messaging Protocol tunneled through HTTP (RTMPT) is used
271 271
 for streaming multimedia content within HTTP requests to traverse
272 272
 firewalls.
273 273
 
274
+@section rtmpte
275
+
276
+Encrypted Real-Time Messaging Protocol tunneled through HTTP.
277
+
278
+The Encrypted Real-Time Messaging Protocol tunneled through HTTP (RTMPTE)
279
+is used for streaming multimedia content within HTTP requests to traverse
280
+firewalls.
281
+
274 282
 @section rtmpts
275 283
 
276 284
 Real-Time Messaging Protocol tunneled through HTTPS.
... ...
@@ -357,6 +357,7 @@ OBJS-$(CONFIG_RTMP_PROTOCOL)             += rtmpproto.o rtmppkt.o
357 357
 OBJS-$(CONFIG_RTMPE_PROTOCOL)            += rtmpproto.o rtmppkt.o
358 358
 OBJS-$(CONFIG_RTMPS_PROTOCOL)            += rtmpproto.o rtmppkt.o
359 359
 OBJS-$(CONFIG_RTMPT_PROTOCOL)            += rtmpproto.o rtmppkt.o
360
+OBJS-$(CONFIG_RTMPTE_PROTOCOL)           += rtmpproto.o rtmppkt.o
360 361
 OBJS-$(CONFIG_RTMPTS_PROTOCOL)           += rtmpproto.o rtmppkt.o
361 362
 OBJS-$(CONFIG_RTP_PROTOCOL)              += rtpproto.o
362 363
 OBJS-$(CONFIG_SCTP_PROTOCOL)             += sctp.o
... ...
@@ -263,6 +263,7 @@ void av_register_all(void)
263 263
     REGISTER_PROTOCOL (RTMPE, rtmpe);
264 264
     REGISTER_PROTOCOL (RTMPS, rtmps);
265 265
     REGISTER_PROTOCOL (RTMPT, rtmpt);
266
+    REGISTER_PROTOCOL (RTMPTE, rtmpte);
266 267
     REGISTER_PROTOCOL (RTMPTS, rtmpts);
267 268
     REGISTER_PROTOCOL (RTP, rtp);
268 269
     REGISTER_PROTOCOL (SCTP, sctp);
... ...
@@ -26,6 +26,7 @@
26 26
 
27 27
 #include "libavutil/blowfish.h"
28 28
 #include "libavutil/intreadwrite.h"
29
+#include "libavutil/opt.h"
29 30
 #include "libavutil/rc4.h"
30 31
 #include "libavutil/xtea.h"
31 32
 
... ...
@@ -37,11 +38,13 @@
37 37
 
38 38
 /* protocol handler context */
39 39
 typedef struct RTMPEContext {
40
+    const AVClass *class;
40 41
     URLContext   *stream;            ///< TCP stream
41 42
     FF_DH        *dh;                ///< Diffie-Hellman context
42 43
     struct AVRC4 key_in;             ///< RC4 key used for decrypt data
43 44
     struct AVRC4 key_out;            ///< RC4 key used for encrypt data
44 45
     int          handshaked;         ///< flag indicating when the handshake is performed
46
+    int          tunneling;          ///< use a HTTP connection (RTMPTE)
45 47
 } RTMPEContext;
46 48
 
47 49
 static const uint8_t rtmpe8_keys[16][16] = {
... ...
@@ -248,11 +251,17 @@ static int rtmpe_open(URLContext *h, const char *uri, int flags)
248 248
 
249 249
     av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, uri);
250 250
 
251
-    if (port < 0)
252
-        port = 1935;
251
+    if (rt->tunneling) {
252
+        if (port < 0)
253
+            port = 80;
254
+        ff_url_join(url, sizeof(url), "ffrtmphttp", NULL, host, port, NULL);
255
+    } else {
256
+        if (port < 0)
257
+            port = 1935;
258
+        ff_url_join(url, sizeof(url), "tcp", NULL, host, port, NULL);
259
+    }
253 260
 
254
-    /* open the tcp connection */
255
-    ff_url_join(url, sizeof(url), "tcp", NULL, host, port, NULL);
261
+    /* open the tcp or ffrtmphttp connection */
256 262
     if ((ret = ffurl_open(&rt->stream, url, AVIO_FLAG_READ_WRITE,
257 263
                           &h->interrupt_callback, NULL)) < 0) {
258 264
         rtmpe_close(h);
... ...
@@ -298,6 +307,21 @@ static int rtmpe_write(URLContext *h, const uint8_t *buf, int size)
298 298
     return size;
299 299
 }
300 300
 
301
+#define OFFSET(x) offsetof(RTMPEContext, x)
302
+#define DEC AV_OPT_FLAG_DECODING_PARAM
303
+
304
+static const AVOption ffrtmpcrypt_options[] = {
305
+    {"ffrtmpcrypt_tunneling", "Use a HTTP tunneling connection (RTMPTE).", OFFSET(tunneling), AV_OPT_TYPE_INT, {0}, 0, 1, DEC},
306
+    { NULL },
307
+};
308
+
309
+static const AVClass ffrtmpcrypt_class = {
310
+    .class_name = "ffrtmpcrypt",
311
+    .item_name  = av_default_item_name,
312
+    .option     = ffrtmpcrypt_options,
313
+    .version    = LIBAVUTIL_VERSION_INT,
314
+};
315
+
301 316
 URLProtocol ff_ffrtmpcrypt_protocol = {
302 317
     .name            = "ffrtmpcrypt",
303 318
     .url_open        = rtmpe_open,
... ...
@@ -306,4 +330,5 @@ URLProtocol ff_ffrtmpcrypt_protocol = {
306 306
     .url_close       = rtmpe_close,
307 307
     .priv_data_size  = sizeof(RTMPEContext),
308 308
     .flags           = URL_PROTOCOL_FLAG_NETWORK,
309
+    .priv_data_class = &ffrtmpcrypt_class,
309 310
 };
... ...
@@ -1192,7 +1192,10 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
1192 1192
         if (port < 0)
1193 1193
             port = RTMPS_DEFAULT_PORT;
1194 1194
         ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
1195
-    } else if (!strcmp(proto, "rtmpe")) {
1195
+    } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
1196
+        if (!strcmp(proto, "rtmpte"))
1197
+            av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
1198
+
1196 1199
         /* open the encrypted connection */
1197 1200
         ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
1198 1201
         rt->encrypted = 1;
... ...
@@ -1574,6 +1577,24 @@ URLProtocol ff_rtmpt_protocol = {
1574 1574
     .priv_data_class = &rtmpt_class,
1575 1575
 };
1576 1576
 
1577
+static const AVClass rtmpte_class = {
1578
+    .class_name = "rtmpte",
1579
+    .item_name  = av_default_item_name,
1580
+    .option     = rtmp_options,
1581
+    .version    = LIBAVUTIL_VERSION_INT,
1582
+};
1583
+
1584
+URLProtocol ff_rtmpte_protocol = {
1585
+    .name            = "rtmpte",
1586
+    .url_open        = rtmp_open,
1587
+    .url_read        = rtmp_read,
1588
+    .url_write       = rtmp_write,
1589
+    .url_close       = rtmp_close,
1590
+    .priv_data_size  = sizeof(RTMPContext),
1591
+    .flags           = URL_PROTOCOL_FLAG_NETWORK,
1592
+    .priv_data_class = &rtmpte_class,
1593
+};
1594
+
1577 1595
 static const AVClass rtmpts_class = {
1578 1596
     .class_name = "rtmpts",
1579 1597
     .item_name  = av_default_item_name,
... ...
@@ -30,7 +30,7 @@
30 30
 #include "libavutil/avutil.h"
31 31
 
32 32
 #define LIBAVFORMAT_VERSION_MAJOR 54
33
-#define LIBAVFORMAT_VERSION_MINOR 11
33
+#define LIBAVFORMAT_VERSION_MINOR 12
34 34
 #define LIBAVFORMAT_VERSION_MICRO  0
35 35
 
36 36
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \