51 #define APP_MAX_LENGTH 1024 
   52 #define PLAYPATH_MAX_LENGTH 256 
   53 #define TCURL_MAX_LENGTH 512 
   54 #define FLASHVER_MAX_LENGTH 64 
   55 #define RTMP_PKTDATA_DEFAULT_SIZE 4096 
  126 #define PLAYER_KEY_OPEN_PART_LEN 30    
  129     'G', 
'e', 
'n', 
'u', 
'i', 
'n', 
'e', 
' ', 
'A', 
'd', 
'o', 
'b', 
'e', 
' ',
 
  130     'F', 
'l', 
'a', 
's', 
'h', 
' ', 
'P', 
'l', 
'a', 
'y', 
'e', 
'r', 
' ', 
'0', 
'0', 
'1',
 
  132     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
 
  133     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
 
  134     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
 
  137 #define SERVER_KEY_OPEN_PART_LEN 36    
  140     'G', 
'e', 
'n', 
'u', 
'i', 
'n', 
'e', 
' ', 
'A', 
'd', 
'o', 
'b', 
'e', 
' ',
 
  141     'F', 
'l', 
'a', 
's', 
'h', 
' ', 
'M', 
'e', 
'd', 
'i', 
'a', 
' ',
 
  142     'S', 
'e', 
'r', 
'v', 
'e', 
'r', 
' ', 
'0', 
'0', 
'1',
 
  144     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
 
  145     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
 
  146     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
 
  179                                char **tracked_method)
 
  255     if (param[0] && param[1] == 
':') {
 
  258     } 
else if (param[0] == 
'N' && param[1] && param[2] == 
':') {
 
  261         value = strchr(field, 
':');
 
  362         char *param = rt->
conn;
 
  365         while (param != NULL) {
 
  367             param += strspn(param, 
" ");
 
  370             sep = strchr(param, 
' ');
 
  413     if (strcmp(command, 
"connect")) {
 
  424                                  "app", tmpstr, 
sizeof(tmpstr));
 
  427     if (!ret && strcmp(tmpstr, rt->
app))
 
  450     bytestream_put_byte(&p, 2); 
 
  464     bytestream_put_be16(&p, 0); 
 
  465     bytestream_put_be32(&p, 0);
 
  672     bytestream_put_be16(&p, 3);
 
  754     bytestream_put_be16(&p, 7);
 
  775     bytestream_put_be16(&p, 27);
 
  841                                   const char *subscribe)
 
  848                                      0, 27 + strlen(subscribe))) < 0)
 
  872         memcpy(hmac_buf, key, keylen);
 
  878     for (i = 0; i < 64; i++)
 
  891     for (i = 0; i < 64; i++)
 
  905     int i, digest_pos = 0;
 
  907     for (i = 0; i < 4; i++)
 
  908         digest_pos += buf[i + off];
 
  909     digest_pos = digest_pos % mod_val + add_val;
 
  960     if (!memcmp(digest, buf + digest_pos, 32))
 
  973                "Hash of the decompressed SWF file is not 32 bytes long.\n");
 
  978     bytestream_put_byte(&p, 1);
 
  979     bytestream_put_byte(&p, 1);
 
  980     bytestream_put_be32(&p, rt->
swfsize);
 
  981     bytestream_put_be32(&p, rt->
swfsize);
 
  990 static int rtmp_uncompress_swfplayer(
uint8_t *in_data, int64_t in_size,
 
  991                                      uint8_t **out_data, int64_t *out_size)
 
  998     zs.avail_in = in_size;
 
  999     zs.next_in  = in_data;
 
 1000     ret = inflateInit(&zs);
 
 1007         zs.avail_out = 
sizeof(tmp_buf);
 
 1008         zs.next_out  = tmp_buf;
 
 1010         ret = inflate(&zs, Z_NO_FLUSH);
 
 1011         if (ret != Z_OK && ret != Z_STREAM_END) {
 
 1016         size = 
sizeof(tmp_buf) - zs.avail_out;
 
 1017         if (!(ptr = 
av_realloc(*out_data, *out_size + size))) {
 
 1023         memcpy(*out_data + *out_size, tmp_buf, size);
 
 1025     } 
while (zs.avail_out == 0);
 
 1036     uint8_t *in_data = NULL, *out_data = NULL, *swfdata;
 
 1037     int64_t in_size, out_size;
 
 1068     if (!memcmp(in_data, 
"CWS", 3)) {
 
 1075         memcpy(out_data, in_data, 8);
 
 1079         if ((ret = rtmp_uncompress_swfplayer(in_data + 8, in_size - 8,
 
 1080                                              &out_data, &out_size)) < 0)
 
 1084                "Zlib is required for decompressing the SWF player file.\n");
 
 1097                                    "Genuine Adobe Flash Player 001", 30,
 
 1132     int server_pos, client_pos;
 
 1143     if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->
encrypted) {
 
 1183            serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
 
 1185     if (rt->
is_input && serverdata[5] >= 3) {
 
 1217                                   0, digest, 32, signature);
 
 1221         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->
encrypted) {
 
 1225                                                    tosend + 1, type)) < 0)
 
 1247                                   tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
 
 1251         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->
encrypted) {
 
 1254                                  RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
 
 1260                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
 
 1263         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->
encrypted) {
 
 1269         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->
encrypted) {
 
 1273                             tosend + 1, 1)) < 0)
 
 1276             if (serverdata[0] == 9) {
 
 1287         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->
encrypted) {
 
 1298                                   uint32_t *second_int, 
char *arraydata,
 
 1309                " not following standard\n", (
int)inoutsize);
 
 1313     *first_int  = 
AV_RB32(arraydata);
 
 1314     *second_int = 
AV_RB32(arraydata + 4);
 
 1319                                uint32_t second_int, 
char *arraydata, 
int size)
 
 1323     AV_WB32(arraydata, first_int);
 
 1324     AV_WB32(arraydata + 4, first_int);
 
 1342     uint32_t hs_my_epoch;
 
 1352     if (inoutsize <= 0) {
 
 1357     if (buffer[0] != 3) {
 
 1363                "Unable to write answer - RTMP S0\n");
 
 1377     hs_my_epoch = hs_epoch;
 
 1403     if (temp != hs_my_epoch)
 
 1405                "Erroneous C2 Message epoch does not match up with C1 epoch\n");
 
 1406     if (memcmp(buffer + 8, hs_s1 + 8,
 
 1409                "Erroneous C2 Message random does not match up\n");
 
 1421                "Too short chunk size change packet (%d)\n",
 
 1460         if ((ret = 
gen_pong(s, rt, pkt)) < 0)
 
 1462     } 
else if (t == 26) {
 
 1480                "Client bandwidth report packet is less than 4 bytes long (%d)\n",
 
 1504                "Too short server bandwidth report packet (%d)\n",
 
 1521                          const char *opaque, 
const char *challenge)
 
 1549              "?authmod=%s&user=%s&challenge=%s&response=%s",
 
 1550              "adobe", user, challenge2, hashstr);
 
 1553                     "&opaque=%s", opaque);
 
 1562     char hashstr1[33], hashstr2[33];
 
 1563     const char *realm = 
"live";
 
 1564     const char *method = 
"publish";
 
 1565     const char *qop = 
"auth";
 
 1566     const char *nc = 
"00000001";
 
 1582     hashstr1[32] = 
'\0';
 
 1590     hashstr2[32] = 
'\0';
 
 1609              "?authmod=%s&user=%s&nonce=%s&cnonce=%s&nc=%s&response=%s",
 
 1610              "llnw", user, nonce, cnonce, nc, hashstr1);
 
 1619     char buf[300], *ptr, authmod[15];
 
 1621     const char *user = 
"", *salt = 
"", *opaque = NULL,
 
 1622                *challenge = NULL, *cptr = NULL, *nonce = NULL;
 
 1624     if (!(cptr = strstr(desc, 
"authmod=adobe")) &&
 
 1625         !(cptr = strstr(desc, 
"authmod=llnw"))) {
 
 1627                "Unknown connect error (unsupported authentication method?)\n");
 
 1630     cptr += strlen(
"authmod=");
 
 1631     while (*cptr && *cptr != 
' ' && i < 
sizeof(authmod) - 1)
 
 1632         authmod[i++] = *cptr++;
 
 1640     if (strstr(desc, 
"?reason=authfailed")) {
 
 1643     } 
else if (strstr(desc, 
"?reason=nosuchuser")) {
 
 1655     if (strstr(desc, 
"code=403 need auth")) {
 
 1657                  "?authmod=%s&user=%s", authmod, rt->
username);
 
 1661     if (!(cptr = strstr(desc, 
"?reason=needauth"))) {
 
 1670         char *next  = strchr(ptr, 
'&');
 
 1671         char *
value = strchr(ptr, 
'=');
 
 1676         if (!strcmp(ptr, 
"user")) {
 
 1678         } 
else if (!strcmp(ptr, 
"salt")) {
 
 1680         } 
else if (!strcmp(ptr, 
"opaque")) {
 
 1682         } 
else if (!strcmp(ptr, 
"challenge")) {
 
 1684         } 
else if (!strcmp(ptr, 
"nonce")) {
 
 1690     if (!strcmp(authmod, 
"adobe")) {
 
 1691         if ((ret = 
do_adobe_auth(rt, user, salt, opaque, challenge)) < 0)
 
 1706     char *tracked_method = NULL;
 
 1715                                 "description", tmpstr, 
sizeof(tmpstr))) {
 
 1716         if (tracked_method && (!strcmp(tracked_method, 
"_checkbw")      ||
 
 1717                                !strcmp(tracked_method, 
"releaseStream") ||
 
 1718                                !strcmp(tracked_method, 
"FCSubscribe")   ||
 
 1719                                !strcmp(tracked_method, 
"FCPublish"))) {
 
 1723         } 
else if (tracked_method && !strcmp(tracked_method, 
"connect")) {
 
 1731         av_log(s, level, 
"Server error: %s\n", tmpstr);
 
 1744     char statusmsg[128];
 
 1766     if (!strcmp(command, 
"FCPublish") ||
 
 1767         !strcmp(command, 
"publish")) {
 
 1769                                  sizeof(filename), &stringlen);
 
 1775                        "Unable to find / in url %s, bad format\n",
 
 1780             if (strcmp(pchar, filename))
 
 1782                        " %s\n", filename, pchar);
 
 1787     if (!strcmp(command, 
"FCPublish")) {
 
 1796     } 
else if (!strcmp(command, 
"publish")) {
 
 1806         bytestream2_put_be16(&pbc, 0);          
 
 1833         snprintf(statusmsg, 
sizeof(statusmsg),
 
 1834                  "%s is now published", filename);
 
 1854         if (!strcmp(command, 
"createStream")) {
 
 1874     char *tracked_method = NULL;
 
 1880     if (!tracked_method) {
 
 1885     if (!memcmp(tracked_method, 
"connect", 7)) {
 
 1906             } 
else if (rt->
live == -1) {
 
 1911     } 
else if (!memcmp(tracked_method, 
"createStream", 12)) {
 
 1913         if (pkt->
data[10] || pkt->
data[19] != 5 || pkt->
data[20]) {
 
 1943     for (i = 0; i < 2; i++) {
 
 1951     if (!t && !strcmp(tmpstr, 
"error")) {
 
 1953                                     "description", tmpstr, 
sizeof(tmpstr)))
 
 1961     if (!t && !strcmp(tmpstr, 
"NetStream.Play.UnpublishNotify")) rt->
state = 
STATE_STOPPED;
 
 1973     if (!memcmp(pkt->
data, 
"\002\000\006_error", 9)) {
 
 1976     } 
else if (!memcmp(pkt->
data, 
"\002\000\007_result", 10)) {
 
 1979     } 
else if (!memcmp(pkt->
data, 
"\002\000\010onStatus", 11)) {
 
 1982     } 
else if (!memcmp(pkt->
data, 
"\002\000\010onBWDone", 11)) {
 
 1985     } 
else if (!memcmp(pkt->
data, 
"\002\000\015releaseStream", 16) ||
 
 1986                !memcmp(pkt->
data, 
"\002\000\011FCPublish", 12)     ||
 
 1987                !memcmp(pkt->
data, 
"\002\000\007publish", 10)       ||
 
 1988                !memcmp(pkt->
data, 
"\002\000\010_checkbw", 11)      ||
 
 1989                !memcmp(pkt->
data, 
"\002\000\014createStream", 15)) {
 
 2002     char statusmsg[128];
 
 2009     unsigned datatowritelength;
 
 2016     if (!strcmp(commandbuffer, 
"@setDataFrame")) {
 
 2017         datatowrite       = gbc.
buffer;
 
 2020                                sizeof(statusmsg), &stringlen))
 
 2022         if (strcmp(statusmsg, 
"onMetaData")) {
 
 2034             rt->
flv_size += datatowritelength + 15;
 
 2037             rt->
flv_size = datatowritelength + 15;
 
 2047         bytestream2_put_byte(&pbc, pkt->
type);
 
 2048         bytestream2_put_be24(&pbc, datatowritelength);
 
 2049         bytestream2_put_be24(&pbc, ts);
 
 2050         bytestream2_put_byte(&pbc, ts >> 24);
 
 2051         bytestream2_put_be24(&pbc, 0);
 
 2053         bytestream2_put_be32(&pbc, 0);
 
 2072     switch (pkt->
type) {
 
 2074         av_dlog(s, 
"received bytes read report\n");
 
 2127     uint32_t ts, cts, pts=0;
 
 2181             bytestream_put_byte(&p, rpkt.
type);
 
 2182             bytestream_put_be24(&p, rpkt.
data_size);
 
 2183             bytestream_put_be24(&p, ts);
 
 2184             bytestream_put_byte(&p, ts >> 24);
 
 2185             bytestream_put_be24(&p, 0);
 
 2187             bytestream_put_be32(&p, 0);
 
 2208                 data_size = bytestream_get_be24(&next);
 
 2210                 cts = bytestream_get_be24(&next);
 
 2211                 cts |= bytestream_get_byte(&next) << 24;
 
 2216                 bytestream_put_be24(&p, ts);
 
 2217                 bytestream_put_byte(&p, ts >> 24);
 
 2218                 next += data_size + 3 + 4;
 
 2261     char proto[8], hostname[256], path[1024], auth[100], *fname;
 
 2274                  hostname, 
sizeof(hostname), &port,
 
 2278         char *ptr = strchr(auth, 
':');
 
 2286     if (rt->
listen && strcmp(proto, 
"rtmp")) {
 
 2291     if (!strcmp(proto, 
"rtmpt") || !strcmp(proto, 
"rtmpts")) {
 
 2292         if (!strcmp(proto, 
"rtmpts"))
 
 2296         ff_url_join(buf, 
sizeof(buf), 
"ffrtmphttp", NULL, hostname, port, NULL);
 
 2297     } 
else if (!strcmp(proto, 
"rtmps")) {
 
 2301         ff_url_join(buf, 
sizeof(buf), 
"tls", NULL, hostname, port, NULL);
 
 2302     } 
else if (!strcmp(proto, 
"rtmpe") || (!strcmp(proto, 
"rtmpte"))) {
 
 2303         if (!strcmp(proto, 
"rtmpte"))
 
 2304             av_dict_set(&opts, 
"ffrtmpcrypt_tunneling", 
"1", 1);
 
 2307         ff_url_join(buf, 
sizeof(buf), 
"ffrtmpcrypt", NULL, hostname, port, NULL);
 
 2314             ff_url_join(buf, 
sizeof(buf), 
"tcp", NULL, hostname, port,
 
 2315                         "?listen&listen_timeout=%d",
 
 2318             ff_url_join(buf, 
sizeof(buf), 
"tcp", NULL, hostname, port, NULL);
 
 2353     if (!strncmp(path, 
"/ondemand/", 10)) {
 
 2355         memcpy(rt->
app, 
"ondemand", 9);
 
 2357         char *next = *path ? path + 1 : path;
 
 2358         char *p = strchr(next, 
'/');
 
 2364             char *
c = strchr(p + 1, 
':');
 
 2365             fname = strchr(p + 1, 
'/');
 
 2366             if (!fname || (c && c < fname)) {
 
 2387         int len = strlen(fname);
 
 2395         if (!strchr(fname, 
':') && len >= 4 &&
 
 2396             (!strcmp(fname + len - 4, 
".f4v") ||
 
 2397              !strcmp(fname + len - 4, 
".mp4"))) {
 
 2399         } 
else if (len >= 4 && !strcmp(fname + len - 4, 
".flv")) {
 
 2400             fname[len - 4] = 
'\0';
 
 2414                     port, 
"/%s", rt->
app);
 
 2451     } 
while (ret == EAGAIN);
 
 2491     int orig_size = 
size;
 
 2497         if (data_left >= size) {
 
 2502         if (data_left > 0) {
 
 2518     int size_temp = 
size;
 
 2519     int pktsize, pkttype;
 
 2543             pkttype = bytestream_get_byte(&header);
 
 2544             pktsize = bytestream_get_be24(&header);
 
 2545             ts = bytestream_get_be24(&header);
 
 2546             ts |= bytestream_get_byte(&header) << 24;
 
 2547             bytestream_get_be24(&header);
 
 2560                                              pkttype, ts, pktsize)) < 0)
 
 2590     } 
while (buf_temp - buf < size);
 
 2608     } 
else if (ret < 0) {
 
 2610     } 
else if (ret == 1) {
 
 2627 #define OFFSET(x) offsetof(RTMPContext, x) 
 2628 #define DEC AV_OPT_FLAG_DECODING_PARAM 
 2629 #define ENC AV_OPT_FLAG_ENCODING_PARAM 
 2633     {
"rtmp_buffer", 
"Set buffer time in milliseconds. The default is 3000.", 
OFFSET(client_buffer_time), 
AV_OPT_TYPE_INT, {.i64 = 3000}, 0, INT_MAX, 
DEC|
ENC},
 
 2635     {
"rtmp_flashver", 
"Version of the Flash plugin used to run the SWF player.", 
OFFSET(flashver), 
AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, 
DEC|
ENC},
 
 2636     {
"rtmp_flush_interval", 
"Number of packets flushed in the same request (RTMPT only).", 
OFFSET(flush_interval), 
AV_OPT_TYPE_INT, {.i64 = 10}, 0, INT_MAX, 
ENC},
 
 2637     {
"rtmp_live", 
"Specify that the media is a live stream.", 
OFFSET(live), 
AV_OPT_TYPE_INT, {.i64 = -2}, INT_MIN, INT_MAX, 
DEC, 
"rtmp_live"},
 
 2641     {
"rtmp_pageurl", 
"URL of the web page in which the media was embedded. By default no value will be sent.", 
OFFSET(pageurl), 
AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, 
DEC},
 
 2643     {
"rtmp_subscribe", 
"Name of live stream to subscribe to. Defaults to rtmp_playpath.", 
OFFSET(subscribe), 
AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, 
DEC},
 
 2645     {
"rtmp_swfsize", 
"Size of the decompressed SWF file, required for SWFVerification.", 
OFFSET(swfsize), 
AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, 
DEC},
 
 2647     {
"rtmp_swfverify", 
"URL to player swf file, compute hash/size automatically.", 
OFFSET(swfverify), 
AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, 
DEC},
 
 2648     {
"rtmp_tcurl", 
"URL of the target stream. Defaults to proto://host[:port]/app.", 
OFFSET(tcurl), 
AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, 
DEC|
ENC},
 
 2649     {
"rtmp_listen", 
"Listen for incoming rtmp connections", 
OFFSET(listen), 
AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, 
DEC, 
"rtmp_listen" },
 
 2650     {
"timeout", 
"Maximum timeout (in seconds) to wait for incoming connections. -1 is infinite. Implies -rtmp_listen 1",  
OFFSET(listen_timeout), 
AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, 
DEC, 
"rtmp_listen" },
 
 2654 #define RTMP_PROTOCOL(flavor)                    \ 
 2655 static const AVClass flavor##_class = {          \ 
 2656     .class_name = #flavor,                       \ 
 2657     .item_name  = av_default_item_name,          \ 
 2658     .option     = rtmp_options,                  \ 
 2659     .version    = LIBAVUTIL_VERSION_INT,         \ 
 2662 URLProtocol ff_##flavor##_protocol = {           \ 
 2664     .url_open       = rtmp_open,                 \ 
 2665     .url_read       = rtmp_read,                 \ 
 2666     .url_write      = rtmp_write,                \ 
 2667     .url_close      = rtmp_close,                \ 
 2668     .priv_data_size = sizeof(RTMPContext),       \ 
 2669     .flags          = URL_PROTOCOL_FLAG_NETWORK, \ 
 2670     .priv_data_class= &flavor##_class,           \