annotate rtmpproto.c @ 5565:befe2f0f9a00 libavformat

Use the configure check from r21351 and use it to properly define struct sockaddr (in case it's not missing) so it always works on the system that we are defining it for, in a RFC-2553/3493-compliant way (i.e. containing a ss_family field). which is used in udp.c. Patch by Martin Storsj <$firstname $firstname st>.
author rbultje
date Wed, 20 Jan 2010 17:26:14 +0000
parents 043b36cefe89
children 32fe8ab7e6b6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
1 /*
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
2 * RTMP network protocol
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
3 * Copyright (c) 2009 Kostya Shishkov
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
4 *
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
5 * This file is part of FFmpeg.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
6 *
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
11 *
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
15 * Lesser General Public License for more details.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
16 *
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
20 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
21
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
22 /**
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
23 * @file libavformat/rtmpproto.c
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
24 * RTMP protocol
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
25 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
26
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
27 #include "libavcodec/bytestream.h"
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
28 #include "libavutil/avstring.h"
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
29 #include "libavutil/lfg.h"
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
30 #include "libavutil/sha.h"
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
31 #include "avformat.h"
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
32
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
33 #include "network.h"
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
34
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
35 #include "flv.h"
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
36 #include "rtmp.h"
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
37 #include "rtmppkt.h"
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
38
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
39 /* we can't use av_log() with URLContext yet... */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
40 #if LIBAVFORMAT_VERSION_MAJOR < 53
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
41 #define LOG_CONTEXT NULL
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
42 #else
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
43 #define LOG_CONTEXT s
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
44 #endif
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
45
5432
f282f7758d6e Dump RTMP packet contents in debug mode
kostya
parents: 5431
diff changeset
46 //#define DEBUG
f282f7758d6e Dump RTMP packet contents in debug mode
kostya
parents: 5431
diff changeset
47
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
48 /** RTMP protocol handler state */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
49 typedef enum {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
50 STATE_START, ///< client has not done anything yet
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
51 STATE_HANDSHAKED, ///< client has performed handshake
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
52 STATE_RELEASING, ///< client releasing stream before publish it (for output)
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
53 STATE_FCPUBLISH, ///< client FCPublishing stream (for output)
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
54 STATE_CONNECTING, ///< client connected to server successfully
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
55 STATE_READY, ///< client has sent all needed commands and waits for server reply
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
56 STATE_PLAYING, ///< client has started receiving multimedia data from server
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
57 STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
5430
bbfed6be7f29 Do not try to interact with RTMP server after "stop" command was received.
kostya
parents: 5420
diff changeset
58 STATE_STOPPED, ///< the broadcast has been stopped
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
59 } ClientState;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
60
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
61 /** protocol handler context */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
62 typedef struct RTMPContext {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
63 URLContext* stream; ///< TCP stream used in interactions with RTMP server
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
64 RTMPPacket prev_pkt[2][RTMP_CHANNELS]; ///< packet history used when reading and sending packets
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
65 int chunk_size; ///< size of the chunks RTMP packets are divided into
5407
b7ef0aa415d0 Move is_input flag into RTMP protocol context.
kostya
parents: 5402
diff changeset
66 int is_input; ///< input/output flag
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
67 char playpath[256]; ///< path to filename to play (with possible "mp4:" prefix)
5411
1f27e6bd85c3 Move "app" string into RTMP protocol context.
kostya
parents: 5407
diff changeset
68 char app[128]; ///< application
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
69 ClientState state; ///< current state
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
70 int main_channel_id; ///< an additional channel ID which is used for some invocations
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
71 uint8_t* flv_data; ///< buffer with data for demuxer
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
72 int flv_size; ///< current buffer size
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
73 int flv_off; ///< number of bytes read from current buffer
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
74 RTMPPacket out_pkt; ///< rtmp packet, created from flv a/v or metadata (for output)
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
75 } RTMPContext;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
76
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
77 #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
78 /** Client key used for digest signing */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
79 static const uint8_t rtmp_player_key[] = {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
80 'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
81 'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1',
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
82
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
83 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
84 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
85 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
86 };
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
87
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
88 #define SERVER_KEY_OPEN_PART_LEN 36 ///< length of partial key used for first server digest signing
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
89 /** Key used for RTMP server digest signing */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
90 static const uint8_t rtmp_server_key[] = {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
91 'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
92 'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
93 'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1',
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
94
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
95 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
96 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
97 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
98 };
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
99
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
100 /**
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
101 * Generates 'connect' call and sends it to the server.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
102 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
103 static void gen_connect(URLContext *s, RTMPContext *rt, const char *proto,
5411
1f27e6bd85c3 Move "app" string into RTMP protocol context.
kostya
parents: 5407
diff changeset
104 const char *host, int port)
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
105 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
106 RTMPPacket pkt;
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
107 uint8_t ver[64], *p;
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
108 char tcurl[512];
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
109
5412
95bc775d22ff Send connect() and createStream() in RTMP system channel, not video channel.
kostya
parents: 5411
diff changeset
110 ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 4096);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
111 p = pkt.data;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
112
5411
1f27e6bd85c3 Move "app" string into RTMP protocol context.
kostya
parents: 5407
diff changeset
113 snprintf(tcurl, sizeof(tcurl), "%s://%s:%d/%s", proto, host, port, rt->app);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
114 ff_amf_write_string(&p, "connect");
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
115 ff_amf_write_number(&p, 1.0);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
116 ff_amf_write_object_start(&p);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
117 ff_amf_write_field_name(&p, "app");
5411
1f27e6bd85c3 Move "app" string into RTMP protocol context.
kostya
parents: 5407
diff changeset
118 ff_amf_write_string(&p, rt->app);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
119
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
120 if (rt->is_input) {
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
121 snprintf(ver, sizeof(ver), "%s %d,%d,%d,%d", RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1,
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
122 RTMP_CLIENT_VER2, RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
123 } else {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
124 snprintf(ver, sizeof(ver), "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
125 ff_amf_write_field_name(&p, "type");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
126 ff_amf_write_string(&p, "nonprivate");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
127 }
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
128 ff_amf_write_field_name(&p, "flashVer");
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
129 ff_amf_write_string(&p, ver);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
130 ff_amf_write_field_name(&p, "tcUrl");
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
131 ff_amf_write_string(&p, tcurl);
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
132 if (rt->is_input) {
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
133 ff_amf_write_field_name(&p, "fpad");
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
134 ff_amf_write_bool(&p, 0);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
135 ff_amf_write_field_name(&p, "capabilities");
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
136 ff_amf_write_number(&p, 15.0);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
137 ff_amf_write_field_name(&p, "audioCodecs");
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
138 ff_amf_write_number(&p, 1639.0);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
139 ff_amf_write_field_name(&p, "videoCodecs");
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
140 ff_amf_write_number(&p, 252.0);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
141 ff_amf_write_field_name(&p, "videoFunction");
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
142 ff_amf_write_number(&p, 1.0);
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
143 }
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
144 ff_amf_write_object_end(&p);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
145
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
146 pkt.data_size = p - pkt.data;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
147
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
148 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
5431
b0eb87793222 5l trocadero: don't forget to free packet in gen_connect()
kostya
parents: 5430
diff changeset
149 ff_rtmp_packet_destroy(&pkt);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
150 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
151
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
152 /**
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
153 * Generates 'releaseStream' call and sends it to the server. It should make
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
154 * the server release some channel for media streams.
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
155 */
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
156 static void gen_release_stream(URLContext *s, RTMPContext *rt)
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
157 {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
158 RTMPPacket pkt;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
159 uint8_t *p;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
160
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
161 ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0,
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
162 29 + strlen(rt->playpath));
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
163
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
164 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Releasing stream...\n");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
165 p = pkt.data;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
166 ff_amf_write_string(&p, "releaseStream");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
167 ff_amf_write_number(&p, 2.0);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
168 ff_amf_write_null(&p);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
169 ff_amf_write_string(&p, rt->playpath);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
170
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
171 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
172 ff_rtmp_packet_destroy(&pkt);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
173 }
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
174
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
175 /**
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
176 * Generates 'FCPublish' call and sends it to the server. It should make
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
177 * the server preapare for receiving media streams.
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
178 */
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
179 static void gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
180 {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
181 RTMPPacket pkt;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
182 uint8_t *p;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
183
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
184 ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0,
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
185 25 + strlen(rt->playpath));
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
186
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
187 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "FCPublish stream...\n");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
188 p = pkt.data;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
189 ff_amf_write_string(&p, "FCPublish");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
190 ff_amf_write_number(&p, 3.0);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
191 ff_amf_write_null(&p);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
192 ff_amf_write_string(&p, rt->playpath);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
193
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
194 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
195 ff_rtmp_packet_destroy(&pkt);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
196 }
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
197
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
198 /**
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
199 * Generates 'FCUnpublish' call and sends it to the server. It should make
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
200 * the server destroy stream.
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
201 */
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
202 static void gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
203 {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
204 RTMPPacket pkt;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
205 uint8_t *p;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
206
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
207 ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0,
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
208 27 + strlen(rt->playpath));
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
209
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
210 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "UnPublishing stream...\n");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
211 p = pkt.data;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
212 ff_amf_write_string(&p, "FCUnpublish");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
213 ff_amf_write_number(&p, 5.0);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
214 ff_amf_write_null(&p);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
215 ff_amf_write_string(&p, rt->playpath);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
216
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
217 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
218 ff_rtmp_packet_destroy(&pkt);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
219 }
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
220
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
221 /**
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
222 * Generates 'createStream' call and sends it to the server. It should make
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
223 * the server allocate some channel for media streams.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
224 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
225 static void gen_create_stream(URLContext *s, RTMPContext *rt)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
226 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
227 RTMPPacket pkt;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
228 uint8_t *p;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
229
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
230 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Creating stream...\n");
5412
95bc775d22ff Send connect() and createStream() in RTMP system channel, not video channel.
kostya
parents: 5411
diff changeset
231 ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 25);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
232
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
233 p = pkt.data;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
234 ff_amf_write_string(&p, "createStream");
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
235 ff_amf_write_number(&p, rt->is_input ? 3.0 : 4.0);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
236 ff_amf_write_null(&p);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
237
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
238 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
239 ff_rtmp_packet_destroy(&pkt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
240 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
241
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
242
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
243 /**
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
244 * Generates 'deleteStream' call and sends it to the server. It should make
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
245 * the server remove some channel for media streams.
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
246 */
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
247 static void gen_delete_stream(URLContext *s, RTMPContext *rt)
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
248 {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
249 RTMPPacket pkt;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
250 uint8_t *p;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
251
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
252 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Deleting stream...\n");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
253 ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 34);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
254
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
255 p = pkt.data;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
256 ff_amf_write_string(&p, "deleteStream");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
257 ff_amf_write_number(&p, 0.0);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
258 ff_amf_write_null(&p);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
259 ff_amf_write_number(&p, rt->main_channel_id);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
260
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
261 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
262 ff_rtmp_packet_destroy(&pkt);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
263 }
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
264
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
265 /**
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
266 * Generates 'play' call and sends it to the server, then pings the server
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
267 * to start actual playing.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
268 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
269 static void gen_play(URLContext *s, RTMPContext *rt)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
270 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
271 RTMPPacket pkt;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
272 uint8_t *p;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
273
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
274 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
275 ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE, 0,
5295
08ec48911f20 Last parameter in RTMP "play" call was optional and some servers seem not to
kostya
parents: 5214
diff changeset
276 20 + strlen(rt->playpath));
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
277 pkt.extra = rt->main_channel_id;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
278
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
279 p = pkt.data;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
280 ff_amf_write_string(&p, "play");
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
281 ff_amf_write_number(&p, 0.0);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
282 ff_amf_write_null(&p);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
283 ff_amf_write_string(&p, rt->playpath);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
284
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
285 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
286 ff_rtmp_packet_destroy(&pkt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
287
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
288 // set client buffer time disguised in ping packet
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
289 ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, 1, 10);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
290
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
291 p = pkt.data;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
292 bytestream_put_be16(&p, 3);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
293 bytestream_put_be32(&p, 1);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
294 bytestream_put_be32(&p, 256); //TODO: what is a good value here?
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
295
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
296 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
297 ff_rtmp_packet_destroy(&pkt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
298 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
299
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
300 /**
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
301 * Generates 'publish' call and sends it to the server.
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
302 */
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
303 static void gen_publish(URLContext *s, RTMPContext *rt)
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
304 {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
305 RTMPPacket pkt;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
306 uint8_t *p;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
307
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
308 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
309 ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE, 0,
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
310 30 + strlen(rt->playpath));
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
311 pkt.extra = rt->main_channel_id;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
312
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
313 p = pkt.data;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
314 ff_amf_write_string(&p, "publish");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
315 ff_amf_write_number(&p, 0.0);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
316 ff_amf_write_null(&p);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
317 ff_amf_write_string(&p, rt->playpath);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
318 ff_amf_write_string(&p, "live");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
319
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
320 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
321 ff_rtmp_packet_destroy(&pkt);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
322 }
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
323
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
324 /**
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
325 * Generates ping reply and sends it to the server.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
326 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
327 static void gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
328 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
329 RTMPPacket pkt;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
330 uint8_t *p;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
331
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
332 ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, ppkt->timestamp + 1, 6);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
333 p = pkt.data;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
334 bytestream_put_be16(&p, 7);
5465
4ee5aa5e013c Reply to RTMP ping with the same value as received by client.
kostya
parents: 5432
diff changeset
335 bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
336 ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
337 ff_rtmp_packet_destroy(&pkt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
338 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
339
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
340 //TODO: Move HMAC code somewhere. Eventually.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
341 #define HMAC_IPAD_VAL 0x36
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
342 #define HMAC_OPAD_VAL 0x5C
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
343
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
344 /**
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
345 * Calculates HMAC-SHA2 digest for RTMP handshake packets.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
346 *
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
347 * @param src input buffer
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
348 * @param len input buffer length (should be 1536)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
349 * @param gap offset in buffer where 32 bytes should not be taken into account
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
350 * when calculating digest (since it will be used to store that digest)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
351 * @param key digest key
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
352 * @param keylen digest key length
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
353 * @param dst buffer where calculated digest will be stored (32 bytes)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
354 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
355 static void rtmp_calc_digest(const uint8_t *src, int len, int gap,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
356 const uint8_t *key, int keylen, uint8_t *dst)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
357 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
358 struct AVSHA *sha;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
359 uint8_t hmac_buf[64+32] = {0};
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
360 int i;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
361
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
362 sha = av_mallocz(av_sha_size);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
363
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
364 if (keylen < 64) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
365 memcpy(hmac_buf, key, keylen);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
366 } else {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
367 av_sha_init(sha, 256);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
368 av_sha_update(sha,key, keylen);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
369 av_sha_final(sha, hmac_buf);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
370 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
371 for (i = 0; i < 64; i++)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
372 hmac_buf[i] ^= HMAC_IPAD_VAL;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
373
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
374 av_sha_init(sha, 256);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
375 av_sha_update(sha, hmac_buf, 64);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
376 if (gap <= 0) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
377 av_sha_update(sha, src, len);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
378 } else { //skip 32 bytes used for storing digest
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
379 av_sha_update(sha, src, gap);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
380 av_sha_update(sha, src + gap + 32, len - gap - 32);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
381 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
382 av_sha_final(sha, hmac_buf + 64);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
383
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
384 for (i = 0; i < 64; i++)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
385 hmac_buf[i] ^= HMAC_IPAD_VAL ^ HMAC_OPAD_VAL; //reuse XORed key for opad
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
386 av_sha_init(sha, 256);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
387 av_sha_update(sha, hmac_buf, 64+32);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
388 av_sha_final(sha, dst);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
389
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
390 av_free(sha);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
391 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
392
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
393 /**
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
394 * Puts HMAC-SHA2 digest of packet data (except for the bytes where this digest
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
395 * will be stored) into that packet.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
396 *
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
397 * @param buf handshake data (1536 bytes)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
398 * @return offset to the digest inside input data
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
399 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
400 static int rtmp_handshake_imprint_with_digest(uint8_t *buf)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
401 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
402 int i, digest_pos = 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
403
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
404 for (i = 8; i < 12; i++)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
405 digest_pos += buf[i];
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
406 digest_pos = (digest_pos % 728) + 12;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
407
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
408 rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
409 rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
410 buf + digest_pos);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
411 return digest_pos;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
412 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
413
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
414 /**
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
415 * Verifies that the received server response has the expected digest value.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
416 *
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
417 * @param buf handshake data received from the server (1536 bytes)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
418 * @param off position to search digest offset from
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
419 * @return 0 if digest is valid, digest position otherwise
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
420 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
421 static int rtmp_validate_digest(uint8_t *buf, int off)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
422 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
423 int i, digest_pos = 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
424 uint8_t digest[32];
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
425
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
426 for (i = 0; i < 4; i++)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
427 digest_pos += buf[i + off];
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
428 digest_pos = (digest_pos % 728) + off + 4;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
429
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
430 rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
431 rtmp_server_key, SERVER_KEY_OPEN_PART_LEN,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
432 digest);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
433 if (!memcmp(digest, buf + digest_pos, 32))
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
434 return digest_pos;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
435 return 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
436 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
437
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
438 /**
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
439 * Performs handshake with the server by means of exchanging pseudorandom data
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
440 * signed with HMAC-SHA2 digest.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
441 *
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
442 * @return 0 if handshake succeeds, negative value otherwise
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
443 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
444 static int rtmp_handshake(URLContext *s, RTMPContext *rt)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
445 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
446 AVLFG rnd;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
447 uint8_t tosend [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
448 3, // unencrypted data
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
449 0, 0, 0, 0, // client uptime
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
450 RTMP_CLIENT_VER1,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
451 RTMP_CLIENT_VER2,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
452 RTMP_CLIENT_VER3,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
453 RTMP_CLIENT_VER4,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
454 };
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
455 uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE];
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
456 uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1];
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
457 int i;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
458 int server_pos, client_pos;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
459 uint8_t digest[32];
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
460
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
461 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Handshaking...\n");
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
462
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
463 av_lfg_init(&rnd, 0xDEADC0DE);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
464 // generate handshake packet - 1536 bytes of pseudorandom data
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
465 for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
466 tosend[i] = av_lfg_get(&rnd) >> 24;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
467 client_pos = rtmp_handshake_imprint_with_digest(tosend + 1);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
468
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
469 url_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE + 1);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
470 i = url_read_complete(rt->stream, serverdata, RTMP_HANDSHAKE_PACKET_SIZE + 1);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
471 if (i != RTMP_HANDSHAKE_PACKET_SIZE + 1) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
472 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
473 return -1;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
474 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
475 i = url_read_complete(rt->stream, clientdata, RTMP_HANDSHAKE_PACKET_SIZE);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
476 if (i != RTMP_HANDSHAKE_PACKET_SIZE) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
477 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
478 return -1;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
479 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
480
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
481 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
482 serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
483
5523
d854655b2042 Use old-style RTMP handshake for old servers.
kostya
parents: 5465
diff changeset
484 if (rt->is_input && serverdata[5] >= 3) {
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
485 server_pos = rtmp_validate_digest(serverdata + 1, 772);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
486 if (!server_pos) {
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
487 server_pos = rtmp_validate_digest(serverdata + 1, 8);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
488 if (!server_pos) {
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
489 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Server response validating failed\n");
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
490 return -1;
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
491 }
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
492 }
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
493
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
494 rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
495 rtmp_server_key, sizeof(rtmp_server_key),
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
496 digest);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
497 rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE-32, 0,
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
498 digest, 32,
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
499 digest);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
500 if (memcmp(digest, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
501 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Signature mismatch\n");
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
502 return -1;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
503 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
504
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
505 for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
506 tosend[i] = av_lfg_get(&rnd) >> 24;
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
507 rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
508 rtmp_player_key, sizeof(rtmp_player_key),
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
509 digest);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
510 rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
511 digest, 32,
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
512 tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
513
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
514 // write reply back to the server
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
515 url_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE);
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
516 } else {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
517 url_write(rt->stream, serverdata+1, RTMP_HANDSHAKE_PACKET_SIZE);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
518 }
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
519
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
520 return 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
521 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
522
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
523 /**
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
524 * Parses received packet and may perform some action depending on
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
525 * the packet contents.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
526 * @return 0 for no errors, negative values for serious errors which prevent
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
527 * further communications, positive values for uncritical errors
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
528 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
529 static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
530 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
531 int i, t;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
532 const uint8_t *data_end = pkt->data + pkt->data_size;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
533
5432
f282f7758d6e Dump RTMP packet contents in debug mode
kostya
parents: 5431
diff changeset
534 #ifdef DEBUG
f282f7758d6e Dump RTMP packet contents in debug mode
kostya
parents: 5431
diff changeset
535 ff_rtmp_packet_dump(LOG_CONTEXT, pkt);
f282f7758d6e Dump RTMP packet contents in debug mode
kostya
parents: 5431
diff changeset
536 #endif
f282f7758d6e Dump RTMP packet contents in debug mode
kostya
parents: 5431
diff changeset
537
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
538 switch (pkt->type) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
539 case RTMP_PT_CHUNK_SIZE:
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
540 if (pkt->data_size != 4) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
541 av_log(LOG_CONTEXT, AV_LOG_ERROR,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
542 "Chunk size change packet is not 4 bytes long (%d)\n", pkt->data_size);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
543 return -1;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
544 }
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
545 if (!rt->is_input)
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
546 ff_rtmp_packet_write(rt->stream, pkt, rt->chunk_size, rt->prev_pkt[1]);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
547 rt->chunk_size = AV_RB32(pkt->data);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
548 if (rt->chunk_size <= 0) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
549 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Incorrect chunk size %d\n", rt->chunk_size);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
550 return -1;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
551 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
552 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "New chunk size = %d\n", rt->chunk_size);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
553 break;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
554 case RTMP_PT_PING:
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
555 t = AV_RB16(pkt->data);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
556 if (t == 6)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
557 gen_pong(s, rt, pkt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
558 break;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
559 case RTMP_PT_INVOKE:
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
560 //TODO: check for the messages sent for wrong state?
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
561 if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
562 uint8_t tmpstr[256];
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
563
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
564 if (!ff_amf_get_field_value(pkt->data + 9, data_end,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
565 "description", tmpstr, sizeof(tmpstr)))
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
566 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
567 return -1;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
568 } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
569 switch (rt->state) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
570 case STATE_HANDSHAKED:
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
571 if (!rt->is_input) {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
572 gen_release_stream(s, rt);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
573 gen_fcpublish_stream(s, rt);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
574 rt->state = STATE_RELEASING;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
575 } else {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
576 rt->state = STATE_CONNECTING;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
577 }
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
578 gen_create_stream(s, rt);
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
579 break;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
580 case STATE_FCPUBLISH:
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
581 rt->state = STATE_CONNECTING;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
582 break;
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
583 case STATE_RELEASING:
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
584 rt->state = STATE_FCPUBLISH;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
585 /* hack for Wowza Media Server, it does not send result for
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
586 * releaseStream and FCPublish calls */
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
587 if (!pkt->data[10]) {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
588 int pkt_id = (int) av_int2dbl(AV_RB64(pkt->data + 11));
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
589 if (pkt_id == 4)
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
590 rt->state = STATE_CONNECTING;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
591 }
5420
62329840eb7c cosmetics: insert space between codeword and left parenthesis
kostya
parents: 5419
diff changeset
592 if (rt->state != STATE_CONNECTING)
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
593 break;
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
594 case STATE_CONNECTING:
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
595 //extract a number from the result
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
596 if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
597 av_log(LOG_CONTEXT, AV_LOG_WARNING, "Unexpected reply on connect()\n");
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
598 } else {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
599 rt->main_channel_id = (int) av_int2dbl(AV_RB64(pkt->data + 21));
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
600 }
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
601 if (rt->is_input) {
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
602 gen_play(s, rt);
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
603 } else {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
604 gen_publish(s, rt);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
605 }
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
606 rt->state = STATE_READY;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
607 break;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
608 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
609 } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
610 const uint8_t* ptr = pkt->data + 11;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
611 uint8_t tmpstr[256];
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
612
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
613 for (i = 0; i < 2; i++) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
614 t = ff_amf_tag_size(ptr, data_end);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
615 if (t < 0)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
616 return 1;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
617 ptr += t;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
618 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
619 t = ff_amf_get_field_value(ptr, data_end,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
620 "level", tmpstr, sizeof(tmpstr));
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
621 if (!t && !strcmp(tmpstr, "error")) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
622 if (!ff_amf_get_field_value(ptr, data_end,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
623 "description", tmpstr, sizeof(tmpstr)))
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
624 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
625 return -1;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
626 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
627 t = ff_amf_get_field_value(ptr, data_end,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
628 "code", tmpstr, sizeof(tmpstr));
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
629 if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
5430
bbfed6be7f29 Do not try to interact with RTMP server after "stop" command was received.
kostya
parents: 5420
diff changeset
630 if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
bbfed6be7f29 Do not try to interact with RTMP server after "stop" command was received.
kostya
parents: 5420
diff changeset
631 if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
632 if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
633 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
634 break;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
635 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
636 return 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
637 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
638
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
639 /**
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
640 * Interacts with the server by receiving and sending RTMP packets until
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
641 * there is some significant data (media data or expected status notification).
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
642 *
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
643 * @param s reading context
5367
f0711d97bff4 Split overly long line in doxy.
stefano
parents: 5295
diff changeset
644 * @param for_header non-zero value tells function to work until it
f0711d97bff4 Split overly long line in doxy.
stefano
parents: 5295
diff changeset
645 * gets notification from the server that playing has been started,
f0711d97bff4 Split overly long line in doxy.
stefano
parents: 5295
diff changeset
646 * otherwise function will work until some media data is received (or
f0711d97bff4 Split overly long line in doxy.
stefano
parents: 5295
diff changeset
647 * an error happens)
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
648 * @return 0 for successful operation, negative value in case of error
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
649 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
650 static int get_packet(URLContext *s, int for_header)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
651 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
652 RTMPContext *rt = s->priv_data;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
653 int ret;
5524
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
654 uint8_t *p;
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
655 const uint8_t *next;
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
656 uint32_t data_size;
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
657 uint32_t ts, cts, pts=0;
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
658
5430
bbfed6be7f29 Do not try to interact with RTMP server after "stop" command was received.
kostya
parents: 5420
diff changeset
659 if (rt->state == STATE_STOPPED)
bbfed6be7f29 Do not try to interact with RTMP server after "stop" command was received.
kostya
parents: 5420
diff changeset
660 return AVERROR_EOF;
bbfed6be7f29 Do not try to interact with RTMP server after "stop" command was received.
kostya
parents: 5420
diff changeset
661
5420
62329840eb7c cosmetics: insert space between codeword and left parenthesis
kostya
parents: 5419
diff changeset
662 for (;;) {
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
663 RTMPPacket rpkt;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
664 if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
665 rt->chunk_size, rt->prev_pkt[0])) != 0) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
666 if (ret > 0) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
667 return AVERROR(EAGAIN);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
668 } else {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
669 return AVERROR(EIO);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
670 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
671 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
672
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
673 ret = rtmp_parse_result(s, rt, &rpkt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
674 if (ret < 0) {//serious error in current packet
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
675 ff_rtmp_packet_destroy(&rpkt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
676 return -1;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
677 }
5430
bbfed6be7f29 Do not try to interact with RTMP server after "stop" command was received.
kostya
parents: 5420
diff changeset
678 if (rt->state == STATE_STOPPED) {
bbfed6be7f29 Do not try to interact with RTMP server after "stop" command was received.
kostya
parents: 5420
diff changeset
679 ff_rtmp_packet_destroy(&rpkt);
bbfed6be7f29 Do not try to interact with RTMP server after "stop" command was received.
kostya
parents: 5420
diff changeset
680 return AVERROR_EOF;
bbfed6be7f29 Do not try to interact with RTMP server after "stop" command was received.
kostya
parents: 5420
diff changeset
681 }
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
682 if (for_header && (rt->state == STATE_PLAYING || rt->state == STATE_PUBLISHING)) {
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
683 ff_rtmp_packet_destroy(&rpkt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
684 return 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
685 }
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
686 if (!rpkt.data_size || !rt->is_input) {
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
687 ff_rtmp_packet_destroy(&rpkt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
688 continue;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
689 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
690 if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
5376
f31fa4114750 Pass only useful FLV metadata from RTMP stream
kostya
parents: 5367
diff changeset
691 (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
5524
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
692 ts = rpkt.timestamp;
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
693
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
694 // generate packet header and put data into buffer for FLV demuxer
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
695 rt->flv_off = 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
696 rt->flv_size = rpkt.data_size + 15;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
697 rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
698 bytestream_put_byte(&p, rpkt.type);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
699 bytestream_put_be24(&p, rpkt.data_size);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
700 bytestream_put_be24(&p, ts);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
701 bytestream_put_byte(&p, ts >> 24);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
702 bytestream_put_be24(&p, 0);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
703 bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
704 bytestream_put_be32(&p, 0);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
705 ff_rtmp_packet_destroy(&rpkt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
706 return 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
707 } else if (rpkt.type == RTMP_PT_METADATA) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
708 // we got raw FLV data, make it available for FLV demuxer
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
709 rt->flv_off = 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
710 rt->flv_size = rpkt.data_size;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
711 rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
5524
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
712 /* rewrite timestamps */
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
713 next = rpkt.data;
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
714 ts = rpkt.timestamp;
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
715 while (next - rpkt.data < rpkt.data_size - 11) {
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
716 next++;
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
717 data_size = bytestream_get_be24(&next);
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
718 p=next;
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
719 cts = bytestream_get_be24(&next);
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
720 cts |= bytestream_get_byte(&next);
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
721 if (pts==0)
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
722 pts=cts;
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
723 ts += cts - pts;
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
724 pts = cts;
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
725 bytestream_put_be24(&p, ts);
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
726 bytestream_put_byte(&p, ts >> 24);
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
727 next += data_size + 3 + 4;
043b36cefe89 Correct timestamps inside FLV data received by RTMP.
kostya
parents: 5523
diff changeset
728 }
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
729 memcpy(rt->flv_data, rpkt.data, rpkt.data_size);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
730 ff_rtmp_packet_destroy(&rpkt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
731 return 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
732 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
733 ff_rtmp_packet_destroy(&rpkt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
734 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
735 return 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
736 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
737
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
738 static int rtmp_close(URLContext *h)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
739 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
740 RTMPContext *rt = h->priv_data;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
741
5420
62329840eb7c cosmetics: insert space between codeword and left parenthesis
kostya
parents: 5419
diff changeset
742 if (!rt->is_input) {
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
743 rt->flv_data = NULL;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
744 if (rt->out_pkt.data_size)
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
745 ff_rtmp_packet_destroy(&rt->out_pkt);
5419
006c95a7a3d2 Do not send invokes to RTMP server if we are not connected to it.
kostya
parents: 5417
diff changeset
746 if (rt->state > STATE_FCPUBLISH)
006c95a7a3d2 Do not send invokes to RTMP server if we are not connected to it.
kostya
parents: 5417
diff changeset
747 gen_fcunpublish_stream(h, rt);
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
748 }
5419
006c95a7a3d2 Do not send invokes to RTMP server if we are not connected to it.
kostya
parents: 5417
diff changeset
749 if (rt->state > STATE_HANDSHAKED)
006c95a7a3d2 Do not send invokes to RTMP server if we are not connected to it.
kostya
parents: 5417
diff changeset
750 gen_delete_stream(h, rt);
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
751
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
752 av_freep(&rt->flv_data);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
753 url_close(rt->stream);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
754 av_free(rt);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
755 return 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
756 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
757
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
758 /**
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
759 * Opens RTMP connection and verifies that the stream can be played.
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
760 *
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
761 * URL syntax: rtmp://server[:port][/app][/playpath]
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
762 * where 'app' is first one or two directories in the path
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
763 * (e.g. /ondemand/, /flash/live/, etc.)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
764 * and 'playpath' is a file name (the rest of the path,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
765 * may be prefixed with "mp4:")
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
766 */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
767 static int rtmp_open(URLContext *s, const char *uri, int flags)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
768 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
769 RTMPContext *rt;
5411
1f27e6bd85c3 Move "app" string into RTMP protocol context.
kostya
parents: 5407
diff changeset
770 char proto[8], hostname[256], path[1024], *fname;
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
771 uint8_t buf[2048];
5407
b7ef0aa415d0 Move is_input flag into RTMP protocol context.
kostya
parents: 5402
diff changeset
772 int port;
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
773 int ret;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
774
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
775 rt = av_mallocz(sizeof(RTMPContext));
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
776 if (!rt)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
777 return AVERROR(ENOMEM);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
778 s->priv_data = rt;
5407
b7ef0aa415d0 Move is_input flag into RTMP protocol context.
kostya
parents: 5402
diff changeset
779 rt->is_input = !(flags & URL_WRONLY);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
780
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
781 url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
782 path, sizeof(path), s->filename);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
783
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
784 if (port < 0)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
785 port = RTMP_DEFAULT_PORT;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
786 snprintf(buf, sizeof(buf), "tcp://%s:%d", hostname, port);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
787
5377
9313acce85fc Print error when RTMP protocol can't open connection
kostya
parents: 5376
diff changeset
788 if (url_open(&rt->stream, buf, URL_RDWR) < 0) {
9313acce85fc Print error when RTMP protocol can't open connection
kostya
parents: 5376
diff changeset
789 av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot open connection %s\n", buf);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
790 goto fail;
5377
9313acce85fc Print error when RTMP protocol can't open connection
kostya
parents: 5376
diff changeset
791 }
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
792
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
793 rt->state = STATE_START;
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
794 if (rtmp_handshake(s, rt))
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
795 return -1;
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
796
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
797 rt->chunk_size = 128;
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
798 rt->state = STATE_HANDSHAKED;
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
799 //extract "app" part from path
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
800 if (!strncmp(path, "/ondemand/", 10)) {
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
801 fname = path + 10;
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
802 memcpy(rt->app, "ondemand", 9);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
803 } else {
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
804 char *p = strchr(path + 1, '/');
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
805 if (!p) {
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
806 fname = path + 1;
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
807 rt->app[0] = '\0';
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
808 } else {
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
809 char *c = strchr(p + 1, ':');
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
810 fname = strchr(p + 1, '/');
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
811 if (!fname || c < fname) {
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
812 fname = p + 1;
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
813 av_strlcpy(rt->app, path + 1, p - path);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
814 } else {
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
815 fname++;
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
816 av_strlcpy(rt->app, path + 1, fname - path - 1);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
817 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
818 }
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
819 }
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
820 if (!strchr(fname, ':') &&
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
821 (!strcmp(fname + strlen(fname) - 4, ".f4v") ||
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
822 !strcmp(fname + strlen(fname) - 4, ".mp4"))) {
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
823 memcpy(rt->playpath, "mp4:", 5);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
824 } else {
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
825 rt->playpath[0] = 0;
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
826 }
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
827 strncat(rt->playpath, fname, sizeof(rt->playpath) - 5);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
828
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
829 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
830 proto, path, rt->app, rt->playpath);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
831 gen_connect(s, rt, proto, hostname, port);
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
832
5417
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
833 do {
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
834 ret = get_packet(s, 1);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
835 } while (ret == EAGAIN);
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
836 if (ret < 0)
9d7de5529047 cosmetics: reindent after last commit
kostya
parents: 5416
diff changeset
837 goto fail;
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
838
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
839 if (rt->is_input) {
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
840 // generate FLV header for demuxer
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
841 rt->flv_size = 13;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
842 rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
843 rt->flv_off = 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
844 memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
845 } else {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
846 rt->flv_size = 0;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
847 rt->flv_data = NULL;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
848 rt->flv_off = 0;
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
849 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
850
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
851 s->max_packet_size = url_get_max_packet_size(rt->stream);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
852 s->is_streamed = 1;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
853 return 0;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
854
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
855 fail:
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
856 rtmp_close(s);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
857 return AVERROR(EIO);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
858 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
859
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
860 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
861 {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
862 RTMPContext *rt = s->priv_data;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
863 int orig_size = size;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
864 int ret;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
865
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
866 while (size > 0) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
867 int data_left = rt->flv_size - rt->flv_off;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
868
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
869 if (data_left >= size) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
870 memcpy(buf, rt->flv_data + rt->flv_off, size);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
871 rt->flv_off += size;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
872 return orig_size;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
873 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
874 if (data_left > 0) {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
875 memcpy(buf, rt->flv_data + rt->flv_off, data_left);
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
876 buf += data_left;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
877 size -= data_left;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
878 rt->flv_off = rt->flv_size;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
879 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
880 if ((ret = get_packet(s, 0)) < 0)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
881 return ret;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
882 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
883 return orig_size;
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
884 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
885
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
886 static int rtmp_write(URLContext *h, uint8_t *buf, int size)
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
887 {
5416
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
888 RTMPContext *rt = h->priv_data;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
889 int size_temp = size;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
890 int pktsize, pkttype;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
891 uint32_t ts;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
892 const uint8_t *buf_temp = buf;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
893
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
894 if (size < 11) {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
895 av_log(LOG_CONTEXT, AV_LOG_DEBUG, "FLV packet too small %d\n", size);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
896 return 0;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
897 }
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
898
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
899 do {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
900 if (!rt->flv_off) {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
901 //skip flv header
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
902 if (buf_temp[0] == 'F' && buf_temp[1] == 'L' && buf_temp[2] == 'V') {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
903 buf_temp += 9 + 4;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
904 size_temp -= 9 + 4;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
905 }
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
906
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
907 pkttype = bytestream_get_byte(&buf_temp);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
908 pktsize = bytestream_get_be24(&buf_temp);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
909 ts = bytestream_get_be24(&buf_temp);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
910 ts |= bytestream_get_byte(&buf_temp) << 24;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
911 bytestream_get_be24(&buf_temp);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
912 size_temp -= 11;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
913 rt->flv_size = pktsize;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
914
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
915 //force 12bytes header
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
916 if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
917 pkttype == RTMP_PT_NOTIFY) {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
918 if (pkttype == RTMP_PT_NOTIFY)
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
919 pktsize += 16;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
920 rt->prev_pkt[1][RTMP_SOURCE_CHANNEL].channel_id = 0;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
921 }
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
922
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
923 //this can be a big packet, it's better to send it right here
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
924 ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL, pkttype, ts, pktsize);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
925 rt->out_pkt.extra = rt->main_channel_id;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
926 rt->flv_data = rt->out_pkt.data;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
927
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
928 if (pkttype == RTMP_PT_NOTIFY)
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
929 ff_amf_write_string(&rt->flv_data, "@setDataFrame");
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
930 }
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
931
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
932 if (rt->flv_size - rt->flv_off > size_temp) {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
933 bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
934 rt->flv_off += size_temp;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
935 } else {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
936 bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
937 rt->flv_off += rt->flv_size - rt->flv_off;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
938 }
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
939
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
940 if (rt->flv_off == rt->flv_size) {
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
941 bytestream_get_be32(&buf_temp);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
942
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
943 ff_rtmp_packet_write(rt->stream, &rt->out_pkt, rt->chunk_size, rt->prev_pkt[1]);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
944 ff_rtmp_packet_destroy(&rt->out_pkt);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
945 rt->flv_size = 0;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
946 rt->flv_off = 0;
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
947 }
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
948 } while (buf_temp - buf < size_temp);
e01b6917b3cf Implement RTMP output (publishing FLV stream to RTMP server).
kostya
parents: 5414
diff changeset
949 return size;
5123
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
950 }
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
951
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
952 URLProtocol rtmp_protocol = {
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
953 "rtmp",
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
954 rtmp_open,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
955 rtmp_read,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
956 rtmp_write,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
957 NULL, /* seek */
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
958 rtmp_close,
cc34279f0fab RTMP protocol support (as a client)
kostya
parents:
diff changeset
959 };