| @@ -40,6 +40,7 @@ version <next>: | |||||
| - JPEG 2000 encoding support through OpenJPEG | - JPEG 2000 encoding support through OpenJPEG | ||||
| - G.723.1 demuxer and decoder | - G.723.1 demuxer and decoder | ||||
| - RTMPE protocol support | - RTMPE protocol support | ||||
| - RTMPTE protocol support | |||||
| version 0.8: | version 0.8: | ||||
| @@ -1569,6 +1569,7 @@ rtmpe_protocol_select="ffrtmpcrypt_protocol" | |||||
| rtmps_protocol_deps="!librtmp_protocol" | rtmps_protocol_deps="!librtmp_protocol" | ||||
| rtmps_protocol_select="tls_protocol" | rtmps_protocol_select="tls_protocol" | ||||
| rtmpt_protocol_select="ffrtmphttp_protocol" | rtmpt_protocol_select="ffrtmphttp_protocol" | ||||
| rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol" | |||||
| rtmpts_protocol_select="ffrtmphttp_protocol" | rtmpts_protocol_select="ffrtmphttp_protocol" | ||||
| rtp_protocol_select="udp_protocol" | rtp_protocol_select="udp_protocol" | ||||
| sctp_protocol_deps="network netinet_sctp_h" | sctp_protocol_deps="network netinet_sctp_h" | ||||
| @@ -847,7 +847,7 @@ performance on systems without hardware floating point support). | |||||
| @item RTMPE @tab X | @item RTMPE @tab X | ||||
| @item RTMPS @tab X | @item RTMPS @tab X | ||||
| @item RTMPT @tab X | @item RTMPT @tab X | ||||
| @item RTMPTE @tab E | |||||
| @item RTMPTE @tab X | |||||
| @item RTMPTS @tab X | @item RTMPTS @tab X | ||||
| @item RTP @tab X | @item RTP @tab X | ||||
| @item SCTP @tab X | @item SCTP @tab X | ||||
| @@ -271,6 +271,14 @@ The Real-Time Messaging Protocol tunneled through HTTP (RTMPT) is used | |||||
| for streaming multimedia content within HTTP requests to traverse | for streaming multimedia content within HTTP requests to traverse | ||||
| firewalls. | firewalls. | ||||
| @section rtmpte | |||||
| Encrypted Real-Time Messaging Protocol tunneled through HTTP. | |||||
| The Encrypted Real-Time Messaging Protocol tunneled through HTTP (RTMPTE) | |||||
| is used for streaming multimedia content within HTTP requests to traverse | |||||
| firewalls. | |||||
| @section rtmpts | @section rtmpts | ||||
| Real-Time Messaging Protocol tunneled through HTTPS. | Real-Time Messaging Protocol tunneled through HTTPS. | ||||
| @@ -357,6 +357,7 @@ OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmppkt.o | |||||
| OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmppkt.o | OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmppkt.o | ||||
| OBJS-$(CONFIG_RTMPS_PROTOCOL) += rtmpproto.o rtmppkt.o | OBJS-$(CONFIG_RTMPS_PROTOCOL) += rtmpproto.o rtmppkt.o | ||||
| OBJS-$(CONFIG_RTMPT_PROTOCOL) += rtmpproto.o rtmppkt.o | OBJS-$(CONFIG_RTMPT_PROTOCOL) += rtmpproto.o rtmppkt.o | ||||
| OBJS-$(CONFIG_RTMPTE_PROTOCOL) += rtmpproto.o rtmppkt.o | |||||
| OBJS-$(CONFIG_RTMPTS_PROTOCOL) += rtmpproto.o rtmppkt.o | OBJS-$(CONFIG_RTMPTS_PROTOCOL) += rtmpproto.o rtmppkt.o | ||||
| OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o | OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o | ||||
| OBJS-$(CONFIG_SCTP_PROTOCOL) += sctp.o | OBJS-$(CONFIG_SCTP_PROTOCOL) += sctp.o | ||||
| @@ -263,6 +263,7 @@ void av_register_all(void) | |||||
| REGISTER_PROTOCOL (RTMPE, rtmpe); | REGISTER_PROTOCOL (RTMPE, rtmpe); | ||||
| REGISTER_PROTOCOL (RTMPS, rtmps); | REGISTER_PROTOCOL (RTMPS, rtmps); | ||||
| REGISTER_PROTOCOL (RTMPT, rtmpt); | REGISTER_PROTOCOL (RTMPT, rtmpt); | ||||
| REGISTER_PROTOCOL (RTMPTE, rtmpte); | |||||
| REGISTER_PROTOCOL (RTMPTS, rtmpts); | REGISTER_PROTOCOL (RTMPTS, rtmpts); | ||||
| REGISTER_PROTOCOL (RTP, rtp); | REGISTER_PROTOCOL (RTP, rtp); | ||||
| REGISTER_PROTOCOL (SCTP, sctp); | REGISTER_PROTOCOL (SCTP, sctp); | ||||
| @@ -26,6 +26,7 @@ | |||||
| #include "libavutil/blowfish.h" | #include "libavutil/blowfish.h" | ||||
| #include "libavutil/intreadwrite.h" | #include "libavutil/intreadwrite.h" | ||||
| #include "libavutil/opt.h" | |||||
| #include "libavutil/rc4.h" | #include "libavutil/rc4.h" | ||||
| #include "libavutil/xtea.h" | #include "libavutil/xtea.h" | ||||
| @@ -37,11 +38,13 @@ | |||||
| /* protocol handler context */ | /* protocol handler context */ | ||||
| typedef struct RTMPEContext { | typedef struct RTMPEContext { | ||||
| const AVClass *class; | |||||
| URLContext *stream; ///< TCP stream | URLContext *stream; ///< TCP stream | ||||
| FF_DH *dh; ///< Diffie-Hellman context | FF_DH *dh; ///< Diffie-Hellman context | ||||
| struct AVRC4 key_in; ///< RC4 key used for decrypt data | struct AVRC4 key_in; ///< RC4 key used for decrypt data | ||||
| struct AVRC4 key_out; ///< RC4 key used for encrypt data | struct AVRC4 key_out; ///< RC4 key used for encrypt data | ||||
| int handshaked; ///< flag indicating when the handshake is performed | int handshaked; ///< flag indicating when the handshake is performed | ||||
| int tunneling; ///< use a HTTP connection (RTMPTE) | |||||
| } RTMPEContext; | } RTMPEContext; | ||||
| static const uint8_t rtmpe8_keys[16][16] = { | static const uint8_t rtmpe8_keys[16][16] = { | ||||
| @@ -248,11 +251,17 @@ static int rtmpe_open(URLContext *h, const char *uri, int flags) | |||||
| av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, uri); | av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, uri); | ||||
| if (port < 0) | |||||
| port = 1935; | |||||
| if (rt->tunneling) { | |||||
| if (port < 0) | |||||
| port = 80; | |||||
| ff_url_join(url, sizeof(url), "ffrtmphttp", NULL, host, port, NULL); | |||||
| } else { | |||||
| if (port < 0) | |||||
| port = 1935; | |||||
| ff_url_join(url, sizeof(url), "tcp", NULL, host, port, NULL); | |||||
| } | |||||
| /* open the tcp connection */ | |||||
| ff_url_join(url, sizeof(url), "tcp", NULL, host, port, NULL); | |||||
| /* open the tcp or ffrtmphttp connection */ | |||||
| if ((ret = ffurl_open(&rt->stream, url, AVIO_FLAG_READ_WRITE, | if ((ret = ffurl_open(&rt->stream, url, AVIO_FLAG_READ_WRITE, | ||||
| &h->interrupt_callback, NULL)) < 0) { | &h->interrupt_callback, NULL)) < 0) { | ||||
| rtmpe_close(h); | rtmpe_close(h); | ||||
| @@ -298,6 +307,21 @@ static int rtmpe_write(URLContext *h, const uint8_t *buf, int size) | |||||
| return size; | return size; | ||||
| } | } | ||||
| #define OFFSET(x) offsetof(RTMPEContext, x) | |||||
| #define DEC AV_OPT_FLAG_DECODING_PARAM | |||||
| static const AVOption ffrtmpcrypt_options[] = { | |||||
| {"ffrtmpcrypt_tunneling", "Use a HTTP tunneling connection (RTMPTE).", OFFSET(tunneling), AV_OPT_TYPE_INT, {0}, 0, 1, DEC}, | |||||
| { NULL }, | |||||
| }; | |||||
| static const AVClass ffrtmpcrypt_class = { | |||||
| .class_name = "ffrtmpcrypt", | |||||
| .item_name = av_default_item_name, | |||||
| .option = ffrtmpcrypt_options, | |||||
| .version = LIBAVUTIL_VERSION_INT, | |||||
| }; | |||||
| URLProtocol ff_ffrtmpcrypt_protocol = { | URLProtocol ff_ffrtmpcrypt_protocol = { | ||||
| .name = "ffrtmpcrypt", | .name = "ffrtmpcrypt", | ||||
| .url_open = rtmpe_open, | .url_open = rtmpe_open, | ||||
| @@ -306,4 +330,5 @@ URLProtocol ff_ffrtmpcrypt_protocol = { | |||||
| .url_close = rtmpe_close, | .url_close = rtmpe_close, | ||||
| .priv_data_size = sizeof(RTMPEContext), | .priv_data_size = sizeof(RTMPEContext), | ||||
| .flags = URL_PROTOCOL_FLAG_NETWORK, | .flags = URL_PROTOCOL_FLAG_NETWORK, | ||||
| .priv_data_class = &ffrtmpcrypt_class, | |||||
| }; | }; | ||||
| @@ -1192,7 +1192,10 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) | |||||
| if (port < 0) | if (port < 0) | ||||
| port = RTMPS_DEFAULT_PORT; | port = RTMPS_DEFAULT_PORT; | ||||
| ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL); | ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL); | ||||
| } else if (!strcmp(proto, "rtmpe")) { | |||||
| } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) { | |||||
| if (!strcmp(proto, "rtmpte")) | |||||
| av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1); | |||||
| /* open the encrypted connection */ | /* open the encrypted connection */ | ||||
| ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL); | ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL); | ||||
| rt->encrypted = 1; | rt->encrypted = 1; | ||||
| @@ -1574,6 +1577,24 @@ URLProtocol ff_rtmpt_protocol = { | |||||
| .priv_data_class = &rtmpt_class, | .priv_data_class = &rtmpt_class, | ||||
| }; | }; | ||||
| static const AVClass rtmpte_class = { | |||||
| .class_name = "rtmpte", | |||||
| .item_name = av_default_item_name, | |||||
| .option = rtmp_options, | |||||
| .version = LIBAVUTIL_VERSION_INT, | |||||
| }; | |||||
| URLProtocol ff_rtmpte_protocol = { | |||||
| .name = "rtmpte", | |||||
| .url_open = rtmp_open, | |||||
| .url_read = rtmp_read, | |||||
| .url_write = rtmp_write, | |||||
| .url_close = rtmp_close, | |||||
| .priv_data_size = sizeof(RTMPContext), | |||||
| .flags = URL_PROTOCOL_FLAG_NETWORK, | |||||
| .priv_data_class = &rtmpte_class, | |||||
| }; | |||||
| static const AVClass rtmpts_class = { | static const AVClass rtmpts_class = { | ||||
| .class_name = "rtmpts", | .class_name = "rtmpts", | ||||
| .item_name = av_default_item_name, | .item_name = av_default_item_name, | ||||
| @@ -30,7 +30,7 @@ | |||||
| #include "libavutil/avutil.h" | #include "libavutil/avutil.h" | ||||
| #define LIBAVFORMAT_VERSION_MAJOR 54 | #define LIBAVFORMAT_VERSION_MAJOR 54 | ||||
| #define LIBAVFORMAT_VERSION_MINOR 11 | |||||
| #define LIBAVFORMAT_VERSION_MINOR 12 | |||||
| #define LIBAVFORMAT_VERSION_MICRO 0 | #define LIBAVFORMAT_VERSION_MICRO 0 | ||||
| #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | ||||