Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6147 serge 1
/*
2
 * RTMP network protocol
3
 * Copyright (c) 2009 Konstantin Shishkov
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
 
22
/**
23
 * @file
24
 * RTMP protocol
25
 */
26
 
27
#include "libavcodec/bytestream.h"
28
#include "libavutil/avstring.h"
29
#include "libavutil/base64.h"
30
#include "libavutil/hmac.h"
31
#include "libavutil/intfloat.h"
32
#include "libavutil/lfg.h"
33
#include "libavutil/md5.h"
34
#include "libavutil/opt.h"
35
#include "libavutil/random_seed.h"
36
#include "avformat.h"
37
#include "internal.h"
38
 
39
#include "network.h"
40
 
41
#include "flv.h"
42
#include "rtmp.h"
43
#include "rtmpcrypt.h"
44
#include "rtmppkt.h"
45
#include "url.h"
46
 
47
#if CONFIG_ZLIB
48
#include 
49
#endif
50
 
51
#define APP_MAX_LENGTH 1024
52
#define PLAYPATH_MAX_LENGTH 512
53
#define TCURL_MAX_LENGTH 1024
54
#define FLASHVER_MAX_LENGTH 64
55
#define RTMP_PKTDATA_DEFAULT_SIZE 4096
56
#define RTMP_HEADER 11
57
 
58
/** RTMP protocol handler state */
59
typedef enum {
60
    STATE_START,      ///< client has not done anything yet
61
    STATE_HANDSHAKED, ///< client has performed handshake
62
    STATE_FCPUBLISH,  ///< client FCPublishing stream (for output)
63
    STATE_PLAYING,    ///< client has started receiving multimedia data from server
64
    STATE_SEEKING,    ///< client has started the seek operation. Back on STATE_PLAYING when the time comes
65
    STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
66
    STATE_RECEIVING,  ///< received a publish command (for input)
67
    STATE_SENDING,    ///< received a play command (for output)
68
    STATE_STOPPED,    ///< the broadcast has been stopped
69
} ClientState;
70
 
71
typedef struct TrackedMethod {
72
    char *name;
73
    int id;
74
} TrackedMethod;
75
 
76
/** protocol handler context */
77
typedef struct RTMPContext {
78
    const AVClass *class;
79
    URLContext*   stream;                     ///< TCP stream used in interactions with RTMP server
80
    RTMPPacket    *prev_pkt[2];               ///< packet history used when reading and sending packets ([0] for reading, [1] for writing)
81
    int           nb_prev_pkt[2];             ///< number of elements in prev_pkt
82
    int           in_chunk_size;              ///< size of the chunks incoming RTMP packets are divided into
83
    int           out_chunk_size;             ///< size of the chunks outgoing RTMP packets are divided into
84
    int           is_input;                   ///< input/output flag
85
    char          *playpath;                  ///< stream identifier to play (with possible "mp4:" prefix)
86
    int           live;                       ///< 0: recorded, -1: live, -2: both
87
    char          *app;                       ///< name of application
88
    char          *conn;                      ///< append arbitrary AMF data to the Connect message
89
    ClientState   state;                      ///< current state
90
    int           stream_id;                  ///< ID assigned by the server for the stream
91
    uint8_t*      flv_data;                   ///< buffer with data for demuxer
92
    int           flv_size;                   ///< current buffer size
93
    int           flv_off;                    ///< number of bytes read from current buffer
94
    int           flv_nb_packets;             ///< number of flv packets published
95
    RTMPPacket    out_pkt;                    ///< rtmp packet, created from flv a/v or metadata (for output)
96
    uint32_t      client_report_size;         ///< number of bytes after which client should report to server
97
    uint32_t      bytes_read;                 ///< number of bytes read from server
98
    uint32_t      last_bytes_read;            ///< number of bytes read last reported to server
99
    uint32_t      last_timestamp;             ///< last timestamp received in a packet
100
    int           skip_bytes;                 ///< number of bytes to skip from the input FLV stream in the next write call
101
    int           has_audio;                  ///< presence of audio data
102
    int           has_video;                  ///< presence of video data
103
    int           received_metadata;          ///< Indicates if we have received metadata about the streams
104
    uint8_t       flv_header[RTMP_HEADER];    ///< partial incoming flv packet header
105
    int           flv_header_bytes;           ///< number of initialized bytes in flv_header
106
    int           nb_invokes;                 ///< keeps track of invoke messages
107
    char*         tcurl;                      ///< url of the target stream
108
    char*         flashver;                   ///< version of the flash plugin
109
    char*         swfhash;                    ///< SHA256 hash of the decompressed SWF file (32 bytes)
110
    int           swfhash_len;                ///< length of the SHA256 hash
111
    int           swfsize;                    ///< size of the decompressed SWF file
112
    char*         swfurl;                     ///< url of the swf player
113
    char*         swfverify;                  ///< URL to player swf file, compute hash/size automatically
114
    char          swfverification[42];        ///< hash of the SWF verification
115
    char*         pageurl;                    ///< url of the web page
116
    char*         subscribe;                  ///< name of live stream to subscribe
117
    int           server_bw;                  ///< server bandwidth
118
    int           client_buffer_time;         ///< client buffer time in ms
119
    int           flush_interval;             ///< number of packets flushed in the same request (RTMPT only)
120
    int           encrypted;                  ///< use an encrypted connection (RTMPE only)
121
    TrackedMethod*tracked_methods;            ///< tracked methods buffer
122
    int           nb_tracked_methods;         ///< number of tracked methods
123
    int           tracked_methods_size;       ///< size of the tracked methods buffer
124
    int           listen;                     ///< listen mode flag
125
    int           listen_timeout;             ///< listen timeout to wait for new connections
126
    int           nb_streamid;                ///< The next stream id to return on createStream calls
127
    double        duration;                   ///< Duration of the stream in seconds as returned by the server (only valid if non-zero)
128
    char          username[50];
129
    char          password[50];
130
    char          auth_params[500];
131
    int           do_reconnect;
132
    int           auth_tried;
133
} RTMPContext;
134
 
135
#define PLAYER_KEY_OPEN_PART_LEN 30   ///< length of partial key used for first client digest signing
136
/** Client key used for digest signing */
137
static const uint8_t rtmp_player_key[] = {
138
    'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
139
    'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1',
140
 
141
    0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
142
    0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
143
    0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
144
};
145
 
146
#define SERVER_KEY_OPEN_PART_LEN 36   ///< length of partial key used for first server digest signing
147
/** Key used for RTMP server digest signing */
148
static const uint8_t rtmp_server_key[] = {
149
    'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
150
    'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
151
    'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1',
152
 
153
    0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
154
    0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
155
    0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
156
};
157
 
158
static int handle_chunk_size(URLContext *s, RTMPPacket *pkt);
159
 
160
static int add_tracked_method(RTMPContext *rt, const char *name, int id)
161
{
162
    int err;
163
 
164
    if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
165
        rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
166
        if ((err = av_reallocp(&rt->tracked_methods, rt->tracked_methods_size *
167
                               sizeof(*rt->tracked_methods))) < 0) {
168
            rt->nb_tracked_methods = 0;
169
            rt->tracked_methods_size = 0;
170
            return err;
171
        }
172
    }
173
 
174
    rt->tracked_methods[rt->nb_tracked_methods].name = av_strdup(name);
175
    if (!rt->tracked_methods[rt->nb_tracked_methods].name)
176
        return AVERROR(ENOMEM);
177
    rt->tracked_methods[rt->nb_tracked_methods].id = id;
178
    rt->nb_tracked_methods++;
179
 
180
    return 0;
181
}
182
 
183
static void del_tracked_method(RTMPContext *rt, int index)
184
{
185
    memmove(&rt->tracked_methods[index], &rt->tracked_methods[index + 1],
186
            sizeof(*rt->tracked_methods) * (rt->nb_tracked_methods - index - 1));
187
    rt->nb_tracked_methods--;
188
}
189
 
190
static int find_tracked_method(URLContext *s, RTMPPacket *pkt, int offset,
191
                               char **tracked_method)
192
{
193
    RTMPContext *rt = s->priv_data;
194
    GetByteContext gbc;
195
    double pkt_id;
196
    int ret;
197
    int i;
198
 
199
    bytestream2_init(&gbc, pkt->data + offset, pkt->size - offset);
200
    if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
201
        return ret;
202
 
203
    for (i = 0; i < rt->nb_tracked_methods; i++) {
204
        if (rt->tracked_methods[i].id != pkt_id)
205
            continue;
206
 
207
        *tracked_method = rt->tracked_methods[i].name;
208
        del_tracked_method(rt, i);
209
        break;
210
    }
211
 
212
    return 0;
213
}
214
 
215
static void free_tracked_methods(RTMPContext *rt)
216
{
217
    int i;
218
 
219
    for (i = 0; i < rt->nb_tracked_methods; i ++)
220
        av_freep(&rt->tracked_methods[i].name);
221
    av_freep(&rt->tracked_methods);
222
    rt->tracked_methods_size = 0;
223
    rt->nb_tracked_methods   = 0;
224
}
225
 
226
static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
227
{
228
    int ret;
229
 
230
    if (pkt->type == RTMP_PT_INVOKE && track) {
231
        GetByteContext gbc;
232
        char name[128];
233
        double pkt_id;
234
        int len;
235
 
236
        bytestream2_init(&gbc, pkt->data, pkt->size);
237
        if ((ret = ff_amf_read_string(&gbc, name, sizeof(name), &len)) < 0)
238
            goto fail;
239
 
240
        if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
241
            goto fail;
242
 
243
        if ((ret = add_tracked_method(rt, name, pkt_id)) < 0)
244
            goto fail;
245
    }
246
 
247
    ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
248
                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
249
fail:
250
    ff_rtmp_packet_destroy(pkt);
251
    return ret;
252
}
253
 
254
static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p)
255
{
256
    char *field, *value;
257
    char type;
258
 
259
    /* The type must be B for Boolean, N for number, S for string, O for
260
     * object, or Z for null. For Booleans the data must be either 0 or 1 for
261
     * FALSE or TRUE, respectively. Likewise for Objects the data must be
262
     * 0 or 1 to end or begin an object, respectively. Data items in subobjects
263
     * may be named, by prefixing the type with 'N' and specifying the name
264
     * before the value (ie. NB:myFlag:1). This option may be used multiple times
265
     * to construct arbitrary AMF sequences. */
266
    if (param[0] && param[1] == ':') {
267
        type = param[0];
268
        value = param + 2;
269
    } else if (param[0] == 'N' && param[1] && param[2] == ':') {
270
        type = param[1];
271
        field = param + 3;
272
        value = strchr(field, ':');
273
        if (!value)
274
            goto fail;
275
        *value = '\0';
276
        value++;
277
 
278
        ff_amf_write_field_name(p, field);
279
    } else {
280
        goto fail;
281
    }
282
 
283
    switch (type) {
284
    case 'B':
285
        ff_amf_write_bool(p, value[0] != '0');
286
        break;
287
    case 'S':
288
        ff_amf_write_string(p, value);
289
        break;
290
    case 'N':
291
        ff_amf_write_number(p, strtod(value, NULL));
292
        break;
293
    case 'Z':
294
        ff_amf_write_null(p);
295
        break;
296
    case 'O':
297
        if (value[0] != '0')
298
            ff_amf_write_object_start(p);
299
        else
300
            ff_amf_write_object_end(p);
301
        break;
302
    default:
303
        goto fail;
304
        break;
305
    }
306
 
307
    return 0;
308
 
309
fail:
310
    av_log(s, AV_LOG_ERROR, "Invalid AMF parameter: %s\n", param);
311
    return AVERROR(EINVAL);
312
}
313
 
314
/**
315
 * Generate 'connect' call and send it to the server.
316
 */
317
static int gen_connect(URLContext *s, RTMPContext *rt)
318
{
319
    RTMPPacket pkt;
320
    uint8_t *p;
321
    int ret;
322
 
323
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
324
                                     0, 4096 + APP_MAX_LENGTH)) < 0)
325
        return ret;
326
 
327
    p = pkt.data;
328
 
329
    ff_amf_write_string(&p, "connect");
330
    ff_amf_write_number(&p, ++rt->nb_invokes);
331
    ff_amf_write_object_start(&p);
332
    ff_amf_write_field_name(&p, "app");
333
    ff_amf_write_string2(&p, rt->app, rt->auth_params);
334
 
335
    if (!rt->is_input) {
336
        ff_amf_write_field_name(&p, "type");
337
        ff_amf_write_string(&p, "nonprivate");
338
    }
339
    ff_amf_write_field_name(&p, "flashVer");
340
    ff_amf_write_string(&p, rt->flashver);
341
 
342
    if (rt->swfurl) {
343
        ff_amf_write_field_name(&p, "swfUrl");
344
        ff_amf_write_string(&p, rt->swfurl);
345
    }
346
 
347
    ff_amf_write_field_name(&p, "tcUrl");
348
    ff_amf_write_string2(&p, rt->tcurl, rt->auth_params);
349
    if (rt->is_input) {
350
        ff_amf_write_field_name(&p, "fpad");
351
        ff_amf_write_bool(&p, 0);
352
        ff_amf_write_field_name(&p, "capabilities");
353
        ff_amf_write_number(&p, 15.0);
354
 
355
        /* Tell the server we support all the audio codecs except
356
         * SUPPORT_SND_INTEL (0x0008) and SUPPORT_SND_UNUSED (0x0010)
357
         * which are unused in the RTMP protocol implementation. */
358
        ff_amf_write_field_name(&p, "audioCodecs");
359
        ff_amf_write_number(&p, 4071.0);
360
        ff_amf_write_field_name(&p, "videoCodecs");
361
        ff_amf_write_number(&p, 252.0);
362
        ff_amf_write_field_name(&p, "videoFunction");
363
        ff_amf_write_number(&p, 1.0);
364
 
365
        if (rt->pageurl) {
366
            ff_amf_write_field_name(&p, "pageUrl");
367
            ff_amf_write_string(&p, rt->pageurl);
368
        }
369
    }
370
    ff_amf_write_object_end(&p);
371
 
372
    if (rt->conn) {
373
        char *param = rt->conn;
374
 
375
        // Write arbitrary AMF data to the Connect message.
376
        while (param) {
377
            char *sep;
378
            param += strspn(param, " ");
379
            if (!*param)
380
                break;
381
            sep = strchr(param, ' ');
382
            if (sep)
383
                *sep = '\0';
384
            if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) {
385
                // Invalid AMF parameter.
386
                ff_rtmp_packet_destroy(&pkt);
387
                return ret;
388
            }
389
 
390
            if (sep)
391
                param = sep + 1;
392
            else
393
                break;
394
        }
395
    }
396
 
397
    pkt.size = p - pkt.data;
398
 
399
    return rtmp_send_packet(rt, &pkt, 1);
400
}
401
 
402
static int read_connect(URLContext *s, RTMPContext *rt)
403
{
404
    RTMPPacket pkt = { 0 };
405
    uint8_t *p;
406
    const uint8_t *cp;
407
    int ret;
408
    char command[64];
409
    int stringlen;
410
    double seqnum;
411
    uint8_t tmpstr[256];
412
    GetByteContext gbc;
413
 
414
    if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
415
                                   &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
416
        return ret;
417
 
418
    if (pkt.type == RTMP_PT_CHUNK_SIZE) {
419
        if ((ret = handle_chunk_size(s, &pkt)) < 0)
420
            return ret;
421
 
422
        ff_rtmp_packet_destroy(&pkt);
423
        if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
424
                                       &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
425
            return ret;
426
    }
427
 
428
    cp = pkt.data;
429
    bytestream2_init(&gbc, cp, pkt.size);
430
    if (ff_amf_read_string(&gbc, command, sizeof(command), &stringlen)) {
431
        av_log(s, AV_LOG_ERROR, "Unable to read command string\n");
432
        ff_rtmp_packet_destroy(&pkt);
433
        return AVERROR_INVALIDDATA;
434
    }
435
    if (strcmp(command, "connect")) {
436
        av_log(s, AV_LOG_ERROR, "Expecting connect, got %s\n", command);
437
        ff_rtmp_packet_destroy(&pkt);
438
        return AVERROR_INVALIDDATA;
439
    }
440
    ret = ff_amf_read_number(&gbc, &seqnum);
441
    if (ret)
442
        av_log(s, AV_LOG_WARNING, "SeqNum not found\n");
443
    /* Here one could parse an AMF Object with data as flashVers and others. */
444
    ret = ff_amf_get_field_value(gbc.buffer,
445
                                 gbc.buffer + bytestream2_get_bytes_left(&gbc),
446
                                 "app", tmpstr, sizeof(tmpstr));
447
    if (ret)
448
        av_log(s, AV_LOG_WARNING, "App field not found in connect\n");
449
    if (!ret && strcmp(tmpstr, rt->app))
450
        av_log(s, AV_LOG_WARNING, "App field don't match up: %s <-> %s\n",
451
               tmpstr, rt->app);
452
    ff_rtmp_packet_destroy(&pkt);
453
 
454
    // Send Window Acknowledgement Size (as defined in speficication)
455
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
456
                                     RTMP_PT_SERVER_BW, 0, 4)) < 0)
457
        return ret;
458
    p = pkt.data;
459
    bytestream_put_be32(&p, rt->server_bw);
460
    pkt.size = p - pkt.data;
461
    ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
462
                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
463
    ff_rtmp_packet_destroy(&pkt);
464
    if (ret < 0)
465
        return ret;
466
    // Send Peer Bandwidth
467
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
468
                                     RTMP_PT_CLIENT_BW, 0, 5)) < 0)
469
        return ret;
470
    p = pkt.data;
471
    bytestream_put_be32(&p, rt->server_bw);
472
    bytestream_put_byte(&p, 2); // dynamic
473
    pkt.size = p - pkt.data;
474
    ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
475
                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
476
    ff_rtmp_packet_destroy(&pkt);
477
    if (ret < 0)
478
        return ret;
479
 
480
    // Ping request
481
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
482
                                     RTMP_PT_PING, 0, 6)) < 0)
483
        return ret;
484
 
485
    p = pkt.data;
486
    bytestream_put_be16(&p, 0); // 0 -> Stream Begin
487
    bytestream_put_be32(&p, 0);
488
    ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
489
                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
490
    ff_rtmp_packet_destroy(&pkt);
491
    if (ret < 0)
492
        return ret;
493
 
494
    // Chunk size
495
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
496
                                     RTMP_PT_CHUNK_SIZE, 0, 4)) < 0)
497
        return ret;
498
 
499
    p = pkt.data;
500
    bytestream_put_be32(&p, rt->out_chunk_size);
501
    ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
502
                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
503
    ff_rtmp_packet_destroy(&pkt);
504
    if (ret < 0)
505
        return ret;
506
 
507
    // Send _result NetConnection.Connect.Success to connect
508
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
509
                                     RTMP_PT_INVOKE, 0,
510
                                     RTMP_PKTDATA_DEFAULT_SIZE)) < 0)
511
        return ret;
512
 
513
    p = pkt.data;
514
    ff_amf_write_string(&p, "_result");
515
    ff_amf_write_number(&p, seqnum);
516
 
517
    ff_amf_write_object_start(&p);
518
    ff_amf_write_field_name(&p, "fmsVer");
519
    ff_amf_write_string(&p, "FMS/3,0,1,123");
520
    ff_amf_write_field_name(&p, "capabilities");
521
    ff_amf_write_number(&p, 31);
522
    ff_amf_write_object_end(&p);
523
 
524
    ff_amf_write_object_start(&p);
525
    ff_amf_write_field_name(&p, "level");
526
    ff_amf_write_string(&p, "status");
527
    ff_amf_write_field_name(&p, "code");
528
    ff_amf_write_string(&p, "NetConnection.Connect.Success");
529
    ff_amf_write_field_name(&p, "description");
530
    ff_amf_write_string(&p, "Connection succeeded.");
531
    ff_amf_write_field_name(&p, "objectEncoding");
532
    ff_amf_write_number(&p, 0);
533
    ff_amf_write_object_end(&p);
534
 
535
    pkt.size = p - pkt.data;
536
    ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
537
                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
538
    ff_rtmp_packet_destroy(&pkt);
539
    if (ret < 0)
540
        return ret;
541
 
542
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
543
                                     RTMP_PT_INVOKE, 0, 30)) < 0)
544
        return ret;
545
    p = pkt.data;
546
    ff_amf_write_string(&p, "onBWDone");
547
    ff_amf_write_number(&p, 0);
548
    ff_amf_write_null(&p);
549
    ff_amf_write_number(&p, 8192);
550
    pkt.size = p - pkt.data;
551
    ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
552
                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
553
    ff_rtmp_packet_destroy(&pkt);
554
 
555
    return ret;
556
}
557
 
558
/**
559
 * Generate 'releaseStream' call and send it to the server. It should make
560
 * the server release some channel for media streams.
561
 */
562
static int gen_release_stream(URLContext *s, RTMPContext *rt)
563
{
564
    RTMPPacket pkt;
565
    uint8_t *p;
566
    int ret;
567
 
568
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
569
                                     0, 29 + strlen(rt->playpath))) < 0)
570
        return ret;
571
 
572
    av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
573
    p = pkt.data;
574
    ff_amf_write_string(&p, "releaseStream");
575
    ff_amf_write_number(&p, ++rt->nb_invokes);
576
    ff_amf_write_null(&p);
577
    ff_amf_write_string(&p, rt->playpath);
578
 
579
    return rtmp_send_packet(rt, &pkt, 1);
580
}
581
 
582
/**
583
 * Generate 'FCPublish' call and send it to the server. It should make
584
 * the server preapare for receiving media streams.
585
 */
586
static int gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
587
{
588
    RTMPPacket pkt;
589
    uint8_t *p;
590
    int ret;
591
 
592
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
593
                                     0, 25 + strlen(rt->playpath))) < 0)
594
        return ret;
595
 
596
    av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
597
    p = pkt.data;
598
    ff_amf_write_string(&p, "FCPublish");
599
    ff_amf_write_number(&p, ++rt->nb_invokes);
600
    ff_amf_write_null(&p);
601
    ff_amf_write_string(&p, rt->playpath);
602
 
603
    return rtmp_send_packet(rt, &pkt, 1);
604
}
605
 
606
/**
607
 * Generate 'FCUnpublish' call and send it to the server. It should make
608
 * the server destroy stream.
609
 */
610
static int gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
611
{
612
    RTMPPacket pkt;
613
    uint8_t *p;
614
    int ret;
615
 
616
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
617
                                     0, 27 + strlen(rt->playpath))) < 0)
618
        return ret;
619
 
620
    av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
621
    p = pkt.data;
622
    ff_amf_write_string(&p, "FCUnpublish");
623
    ff_amf_write_number(&p, ++rt->nb_invokes);
624
    ff_amf_write_null(&p);
625
    ff_amf_write_string(&p, rt->playpath);
626
 
627
    return rtmp_send_packet(rt, &pkt, 0);
628
}
629
 
630
/**
631
 * Generate 'createStream' call and send it to the server. It should make
632
 * the server allocate some channel for media streams.
633
 */
634
static int gen_create_stream(URLContext *s, RTMPContext *rt)
635
{
636
    RTMPPacket pkt;
637
    uint8_t *p;
638
    int ret;
639
 
640
    av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
641
 
642
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
643
                                     0, 25)) < 0)
644
        return ret;
645
 
646
    p = pkt.data;
647
    ff_amf_write_string(&p, "createStream");
648
    ff_amf_write_number(&p, ++rt->nb_invokes);
649
    ff_amf_write_null(&p);
650
 
651
    return rtmp_send_packet(rt, &pkt, 1);
652
}
653
 
654
 
655
/**
656
 * Generate 'deleteStream' call and send it to the server. It should make
657
 * the server remove some channel for media streams.
658
 */
659
static int gen_delete_stream(URLContext *s, RTMPContext *rt)
660
{
661
    RTMPPacket pkt;
662
    uint8_t *p;
663
    int ret;
664
 
665
    av_log(s, AV_LOG_DEBUG, "Deleting stream...\n");
666
 
667
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
668
                                     0, 34)) < 0)
669
        return ret;
670
 
671
    p = pkt.data;
672
    ff_amf_write_string(&p, "deleteStream");
673
    ff_amf_write_number(&p, ++rt->nb_invokes);
674
    ff_amf_write_null(&p);
675
    ff_amf_write_number(&p, rt->stream_id);
676
 
677
    return rtmp_send_packet(rt, &pkt, 0);
678
}
679
 
680
/**
681
 * Generate 'getStreamLength' call and send it to the server. If the server
682
 * knows the duration of the selected stream, it will reply with the duration
683
 * in seconds.
684
 */
685
static int gen_get_stream_length(URLContext *s, RTMPContext *rt)
686
{
687
    RTMPPacket pkt;
688
    uint8_t *p;
689
    int ret;
690
 
691
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
692
                                     0, 31 + strlen(rt->playpath))) < 0)
693
        return ret;
694
 
695
    p = pkt.data;
696
    ff_amf_write_string(&p, "getStreamLength");
697
    ff_amf_write_number(&p, ++rt->nb_invokes);
698
    ff_amf_write_null(&p);
699
    ff_amf_write_string(&p, rt->playpath);
700
 
701
    return rtmp_send_packet(rt, &pkt, 1);
702
}
703
 
704
/**
705
 * Generate client buffer time and send it to the server.
706
 */
707
static int gen_buffer_time(URLContext *s, RTMPContext *rt)
708
{
709
    RTMPPacket pkt;
710
    uint8_t *p;
711
    int ret;
712
 
713
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
714
                                     1, 10)) < 0)
715
        return ret;
716
 
717
    p = pkt.data;
718
    bytestream_put_be16(&p, 3);
719
    bytestream_put_be32(&p, rt->stream_id);
720
    bytestream_put_be32(&p, rt->client_buffer_time);
721
 
722
    return rtmp_send_packet(rt, &pkt, 0);
723
}
724
 
725
/**
726
 * Generate 'play' call and send it to the server, then ping the server
727
 * to start actual playing.
728
 */
729
static int gen_play(URLContext *s, RTMPContext *rt)
730
{
731
    RTMPPacket pkt;
732
    uint8_t *p;
733
    int ret;
734
 
735
    av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
736
 
737
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
738
                                     0, 29 + strlen(rt->playpath))) < 0)
739
        return ret;
740
 
741
    pkt.extra = rt->stream_id;
742
 
743
    p = pkt.data;
744
    ff_amf_write_string(&p, "play");
745
    ff_amf_write_number(&p, ++rt->nb_invokes);
746
    ff_amf_write_null(&p);
747
    ff_amf_write_string(&p, rt->playpath);
748
    ff_amf_write_number(&p, rt->live * 1000);
749
 
750
    return rtmp_send_packet(rt, &pkt, 1);
751
}
752
 
753
static int gen_seek(URLContext *s, RTMPContext *rt, int64_t timestamp)
754
{
755
    RTMPPacket pkt;
756
    uint8_t *p;
757
    int ret;
758
 
759
    av_log(s, AV_LOG_DEBUG, "Sending seek command for timestamp %"PRId64"\n",
760
           timestamp);
761
 
762
    if ((ret = ff_rtmp_packet_create(&pkt, 3, RTMP_PT_INVOKE, 0, 26)) < 0)
763
        return ret;
764
 
765
    pkt.extra = rt->stream_id;
766
 
767
    p = pkt.data;
768
    ff_amf_write_string(&p, "seek");
769
    ff_amf_write_number(&p, 0); //no tracking back responses
770
    ff_amf_write_null(&p); //as usual, the first null param
771
    ff_amf_write_number(&p, timestamp); //where we want to jump
772
 
773
    return rtmp_send_packet(rt, &pkt, 1);
774
}
775
 
776
/**
777
 * Generate a pause packet that either pauses or unpauses the current stream.
778
 */
779
static int gen_pause(URLContext *s, RTMPContext *rt, int pause, uint32_t timestamp)
780
{
781
    RTMPPacket pkt;
782
    uint8_t *p;
783
    int ret;
784
 
785
    av_log(s, AV_LOG_DEBUG, "Sending pause command for timestamp %d\n",
786
           timestamp);
787
 
788
    if ((ret = ff_rtmp_packet_create(&pkt, 3, RTMP_PT_INVOKE, 0, 29)) < 0)
789
        return ret;
790
 
791
    pkt.extra = rt->stream_id;
792
 
793
    p = pkt.data;
794
    ff_amf_write_string(&p, "pause");
795
    ff_amf_write_number(&p, 0); //no tracking back responses
796
    ff_amf_write_null(&p); //as usual, the first null param
797
    ff_amf_write_bool(&p, pause); // pause or unpause
798
    ff_amf_write_number(&p, timestamp); //where we pause the stream
799
 
800
    return rtmp_send_packet(rt, &pkt, 1);
801
}
802
 
803
/**
804
 * Generate 'publish' call and send it to the server.
805
 */
806
static int gen_publish(URLContext *s, RTMPContext *rt)
807
{
808
    RTMPPacket pkt;
809
    uint8_t *p;
810
    int ret;
811
 
812
    av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
813
 
814
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
815
                                     0, 30 + strlen(rt->playpath))) < 0)
816
        return ret;
817
 
818
    pkt.extra = rt->stream_id;
819
 
820
    p = pkt.data;
821
    ff_amf_write_string(&p, "publish");
822
    ff_amf_write_number(&p, ++rt->nb_invokes);
823
    ff_amf_write_null(&p);
824
    ff_amf_write_string(&p, rt->playpath);
825
    ff_amf_write_string(&p, "live");
826
 
827
    return rtmp_send_packet(rt, &pkt, 1);
828
}
829
 
830
/**
831
 * Generate ping reply and send it to the server.
832
 */
833
static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
834
{
835
    RTMPPacket pkt;
836
    uint8_t *p;
837
    int ret;
838
 
839
    if (ppkt->size < 6) {
840
        av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
841
               ppkt->size);
842
        return AVERROR_INVALIDDATA;
843
    }
844
 
845
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
846
                                     ppkt->timestamp + 1, 6)) < 0)
847
        return ret;
848
 
849
    p = pkt.data;
850
    bytestream_put_be16(&p, 7);
851
    bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
852
 
853
    return rtmp_send_packet(rt, &pkt, 0);
854
}
855
 
856
/**
857
 * Generate SWF verification message and send it to the server.
858
 */
859
static int gen_swf_verification(URLContext *s, RTMPContext *rt)
860
{
861
    RTMPPacket pkt;
862
    uint8_t *p;
863
    int ret;
864
 
865
    av_log(s, AV_LOG_DEBUG, "Sending SWF verification...\n");
866
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
867
                                     0, 44)) < 0)
868
        return ret;
869
 
870
    p = pkt.data;
871
    bytestream_put_be16(&p, 27);
872
    memcpy(p, rt->swfverification, 42);
873
 
874
    return rtmp_send_packet(rt, &pkt, 0);
875
}
876
 
877
/**
878
 * Generate server bandwidth message and send it to the server.
879
 */
880
static int gen_server_bw(URLContext *s, RTMPContext *rt)
881
{
882
    RTMPPacket pkt;
883
    uint8_t *p;
884
    int ret;
885
 
886
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_SERVER_BW,
887
                                     0, 4)) < 0)
888
        return ret;
889
 
890
    p = pkt.data;
891
    bytestream_put_be32(&p, rt->server_bw);
892
 
893
    return rtmp_send_packet(rt, &pkt, 0);
894
}
895
 
896
/**
897
 * Generate check bandwidth message and send it to the server.
898
 */
899
static int gen_check_bw(URLContext *s, RTMPContext *rt)
900
{
901
    RTMPPacket pkt;
902
    uint8_t *p;
903
    int ret;
904
 
905
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
906
                                     0, 21)) < 0)
907
        return ret;
908
 
909
    p = pkt.data;
910
    ff_amf_write_string(&p, "_checkbw");
911
    ff_amf_write_number(&p, ++rt->nb_invokes);
912
    ff_amf_write_null(&p);
913
 
914
    return rtmp_send_packet(rt, &pkt, 1);
915
}
916
 
917
/**
918
 * Generate report on bytes read so far and send it to the server.
919
 */
920
static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
921
{
922
    RTMPPacket pkt;
923
    uint8_t *p;
924
    int ret;
925
 
926
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ,
927
                                     ts, 4)) < 0)
928
        return ret;
929
 
930
    p = pkt.data;
931
    bytestream_put_be32(&p, rt->bytes_read);
932
 
933
    return rtmp_send_packet(rt, &pkt, 0);
934
}
935
 
936
static int gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt,
937
                                  const char *subscribe)
938
{
939
    RTMPPacket pkt;
940
    uint8_t *p;
941
    int ret;
942
 
943
    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
944
                                     0, 27 + strlen(subscribe))) < 0)
945
        return ret;
946
 
947
    p = pkt.data;
948
    ff_amf_write_string(&p, "FCSubscribe");
949
    ff_amf_write_number(&p, ++rt->nb_invokes);
950
    ff_amf_write_null(&p);
951
    ff_amf_write_string(&p, subscribe);
952
 
953
    return rtmp_send_packet(rt, &pkt, 1);
954
}
955
 
956
int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap,
957
                        const uint8_t *key, int keylen, uint8_t *dst)
958
{
959
    AVHMAC *hmac;
960
 
961
    hmac = av_hmac_alloc(AV_HMAC_SHA256);
962
    if (!hmac)
963
        return AVERROR(ENOMEM);
964
 
965
    av_hmac_init(hmac, key, keylen);
966
    if (gap <= 0) {
967
        av_hmac_update(hmac, src, len);
968
    } else { //skip 32 bytes used for storing digest
969
        av_hmac_update(hmac, src, gap);
970
        av_hmac_update(hmac, src + gap + 32, len - gap - 32);
971
    }
972
    av_hmac_final(hmac, dst, 32);
973
 
974
    av_hmac_free(hmac);
975
 
976
    return 0;
977
}
978
 
979
int ff_rtmp_calc_digest_pos(const uint8_t *buf, int off, int mod_val,
980
                            int add_val)
981
{
982
    int i, digest_pos = 0;
983
 
984
    for (i = 0; i < 4; i++)
985
        digest_pos += buf[i + off];
986
    digest_pos = digest_pos % mod_val + add_val;
987
 
988
    return digest_pos;
989
}
990
 
991
/**
992
 * Put HMAC-SHA2 digest of packet data (except for the bytes where this digest
993
 * will be stored) into that packet.
994
 *
995
 * @param buf handshake data (1536 bytes)
996
 * @param encrypted use an encrypted connection (RTMPE)
997
 * @return offset to the digest inside input data
998
 */
999
static int rtmp_handshake_imprint_with_digest(uint8_t *buf, int encrypted)
1000
{
1001
    int ret, digest_pos;
1002
 
1003
    if (encrypted)
1004
        digest_pos = ff_rtmp_calc_digest_pos(buf, 772, 728, 776);
1005
    else
1006
        digest_pos = ff_rtmp_calc_digest_pos(buf, 8, 728, 12);
1007
 
1008
    ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
1009
                              rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN,
1010
                              buf + digest_pos);
1011
    if (ret < 0)
1012
        return ret;
1013
 
1014
    return digest_pos;
1015
}
1016
 
1017
/**
1018
 * Verify that the received server response has the expected digest value.
1019
 *
1020
 * @param buf handshake data received from the server (1536 bytes)
1021
 * @param off position to search digest offset from
1022
 * @return 0 if digest is valid, digest position otherwise
1023
 */
1024
static int rtmp_validate_digest(uint8_t *buf, int off)
1025
{
1026
    uint8_t digest[32];
1027
    int ret, digest_pos;
1028
 
1029
    digest_pos = ff_rtmp_calc_digest_pos(buf, off, 728, off + 4);
1030
 
1031
    ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
1032
                              rtmp_server_key, SERVER_KEY_OPEN_PART_LEN,
1033
                              digest);
1034
    if (ret < 0)
1035
        return ret;
1036
 
1037
    if (!memcmp(digest, buf + digest_pos, 32))
1038
        return digest_pos;
1039
    return 0;
1040
}
1041
 
1042
static int rtmp_calc_swf_verification(URLContext *s, RTMPContext *rt,
1043
                                      uint8_t *buf)
1044
{
1045
    uint8_t *p;
1046
    int ret;
1047
 
1048
    if (rt->swfhash_len != 32) {
1049
        av_log(s, AV_LOG_ERROR,
1050
               "Hash of the decompressed SWF file is not 32 bytes long.\n");
1051
        return AVERROR(EINVAL);
1052
    }
1053
 
1054
    p = &rt->swfverification[0];
1055
    bytestream_put_byte(&p, 1);
1056
    bytestream_put_byte(&p, 1);
1057
    bytestream_put_be32(&p, rt->swfsize);
1058
    bytestream_put_be32(&p, rt->swfsize);
1059
 
1060
    if ((ret = ff_rtmp_calc_digest(rt->swfhash, 32, 0, buf, 32, p)) < 0)
1061
        return ret;
1062
 
1063
    return 0;
1064
}
1065
 
1066
#if CONFIG_ZLIB
1067
static int rtmp_uncompress_swfplayer(uint8_t *in_data, int64_t in_size,
1068
                                     uint8_t **out_data, int64_t *out_size)
1069
{
1070
    z_stream zs = { 0 };
1071
    void *ptr;
1072
    int size;
1073
    int ret = 0;
1074
 
1075
    zs.avail_in = in_size;
1076
    zs.next_in  = in_data;
1077
    ret = inflateInit(&zs);
1078
    if (ret != Z_OK)
1079
        return AVERROR_UNKNOWN;
1080
 
1081
    do {
1082
        uint8_t tmp_buf[16384];
1083
 
1084
        zs.avail_out = sizeof(tmp_buf);
1085
        zs.next_out  = tmp_buf;
1086
 
1087
        ret = inflate(&zs, Z_NO_FLUSH);
1088
        if (ret != Z_OK && ret != Z_STREAM_END) {
1089
            ret = AVERROR_UNKNOWN;
1090
            goto fail;
1091
        }
1092
 
1093
        size = sizeof(tmp_buf) - zs.avail_out;
1094
        if (!(ptr = av_realloc(*out_data, *out_size + size))) {
1095
            ret = AVERROR(ENOMEM);
1096
            goto fail;
1097
        }
1098
        *out_data = ptr;
1099
 
1100
        memcpy(*out_data + *out_size, tmp_buf, size);
1101
        *out_size += size;
1102
    } while (zs.avail_out == 0);
1103
 
1104
fail:
1105
    inflateEnd(&zs);
1106
    return ret;
1107
}
1108
#endif
1109
 
1110
static int rtmp_calc_swfhash(URLContext *s)
1111
{
1112
    RTMPContext *rt = s->priv_data;
1113
    uint8_t *in_data = NULL, *out_data = NULL, *swfdata;
1114
    int64_t in_size, out_size;
1115
    URLContext *stream;
1116
    char swfhash[32];
1117
    int swfsize;
1118
    int ret = 0;
1119
 
1120
    /* Get the SWF player file. */
1121
    if ((ret = ffurl_open(&stream, rt->swfverify, AVIO_FLAG_READ,
1122
                          &s->interrupt_callback, NULL)) < 0) {
1123
        av_log(s, AV_LOG_ERROR, "Cannot open connection %s.\n", rt->swfverify);
1124
        goto fail;
1125
    }
1126
 
1127
    if ((in_size = ffurl_seek(stream, 0, AVSEEK_SIZE)) < 0) {
1128
        ret = AVERROR(EIO);
1129
        goto fail;
1130
    }
1131
 
1132
    if (!(in_data = av_malloc(in_size))) {
1133
        ret = AVERROR(ENOMEM);
1134
        goto fail;
1135
    }
1136
 
1137
    if ((ret = ffurl_read_complete(stream, in_data, in_size)) < 0)
1138
        goto fail;
1139
 
1140
    if (in_size < 3) {
1141
        ret = AVERROR_INVALIDDATA;
1142
        goto fail;
1143
    }
1144
 
1145
    if (!memcmp(in_data, "CWS", 3)) {
1146
        /* Decompress the SWF player file using Zlib. */
1147
        if (!(out_data = av_malloc(8))) {
1148
            ret = AVERROR(ENOMEM);
1149
            goto fail;
1150
        }
1151
        *in_data = 'F'; // magic stuff
1152
        memcpy(out_data, in_data, 8);
1153
        out_size = 8;
1154
 
1155
#if CONFIG_ZLIB
1156
        if ((ret = rtmp_uncompress_swfplayer(in_data + 8, in_size - 8,
1157
                                             &out_data, &out_size)) < 0)
1158
            goto fail;
1159
#else
1160
        av_log(s, AV_LOG_ERROR,
1161
               "Zlib is required for decompressing the SWF player file.\n");
1162
        ret = AVERROR(EINVAL);
1163
        goto fail;
1164
#endif
1165
        swfsize = out_size;
1166
        swfdata = out_data;
1167
    } else {
1168
        swfsize = in_size;
1169
        swfdata = in_data;
1170
    }
1171
 
1172
    /* Compute the SHA256 hash of the SWF player file. */
1173
    if ((ret = ff_rtmp_calc_digest(swfdata, swfsize, 0,
1174
                                   "Genuine Adobe Flash Player 001", 30,
1175
                                   swfhash)) < 0)
1176
        goto fail;
1177
 
1178
    /* Set SWFVerification parameters. */
1179
    av_opt_set_bin(rt, "rtmp_swfhash", swfhash, 32, 0);
1180
    rt->swfsize = swfsize;
1181
 
1182
fail:
1183
    av_freep(&in_data);
1184
    av_freep(&out_data);
1185
    ffurl_close(stream);
1186
    return ret;
1187
}
1188
 
1189
/**
1190
 * Perform handshake with the server by means of exchanging pseudorandom data
1191
 * signed with HMAC-SHA2 digest.
1192
 *
1193
 * @return 0 if handshake succeeds, negative value otherwise
1194
 */
1195
static int rtmp_handshake(URLContext *s, RTMPContext *rt)
1196
{
1197
    AVLFG rnd;
1198
    uint8_t tosend    [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
1199
        3,                // unencrypted data
1200
        0, 0, 0, 0,       // client uptime
1201
        RTMP_CLIENT_VER1,
1202
        RTMP_CLIENT_VER2,
1203
        RTMP_CLIENT_VER3,
1204
        RTMP_CLIENT_VER4,
1205
    };
1206
    uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE];
1207
    uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1];
1208
    int i;
1209
    int server_pos, client_pos;
1210
    uint8_t digest[32], signature[32];
1211
    int ret, type = 0;
1212
 
1213
    av_log(s, AV_LOG_DEBUG, "Handshaking...\n");
1214
 
1215
    av_lfg_init(&rnd, 0xDEADC0DE);
1216
    // generate handshake packet - 1536 bytes of pseudorandom data
1217
    for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
1218
        tosend[i] = av_lfg_get(&rnd) >> 24;
1219
 
1220
    if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1221
        /* When the client wants to use RTMPE, we have to change the command
1222
         * byte to 0x06 which means to use encrypted data and we have to set
1223
         * the flash version to at least 9.0.115.0. */
1224
        tosend[0] = 6;
1225
        tosend[5] = 128;
1226
        tosend[6] = 0;
1227
        tosend[7] = 3;
1228
        tosend[8] = 2;
1229
 
1230
        /* Initialize the Diffie-Hellmann context and generate the public key
1231
         * to send to the server. */
1232
        if ((ret = ff_rtmpe_gen_pub_key(rt->stream, tosend + 1)) < 0)
1233
            return ret;
1234
    }
1235
 
1236
    client_pos = rtmp_handshake_imprint_with_digest(tosend + 1, rt->encrypted);
1237
    if (client_pos < 0)
1238
        return client_pos;
1239
 
1240
    if ((ret = ffurl_write(rt->stream, tosend,
1241
                           RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1242
        av_log(s, AV_LOG_ERROR, "Cannot write RTMP handshake request\n");
1243
        return ret;
1244
    }
1245
 
1246
    if ((ret = ffurl_read_complete(rt->stream, serverdata,
1247
                                   RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1248
        av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1249
        return ret;
1250
    }
1251
 
1252
    if ((ret = ffurl_read_complete(rt->stream, clientdata,
1253
                                   RTMP_HANDSHAKE_PACKET_SIZE)) < 0) {
1254
        av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1255
        return ret;
1256
    }
1257
 
1258
    av_log(s, AV_LOG_DEBUG, "Type answer %d\n", serverdata[0]);
1259
    av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
1260
           serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
1261
 
1262
    if (rt->is_input && serverdata[5] >= 3) {
1263
        server_pos = rtmp_validate_digest(serverdata + 1, 772);
1264
        if (server_pos < 0)
1265
            return server_pos;
1266
 
1267
        if (!server_pos) {
1268
            type = 1;
1269
            server_pos = rtmp_validate_digest(serverdata + 1, 8);
1270
            if (server_pos < 0)
1271
                return server_pos;
1272
 
1273
            if (!server_pos) {
1274
                av_log(s, AV_LOG_ERROR, "Server response validating failed\n");
1275
                return AVERROR(EIO);
1276
            }
1277
        }
1278
 
1279
        /* Generate SWFVerification token (SHA256 HMAC hash of decompressed SWF,
1280
         * key are the last 32 bytes of the server handshake. */
1281
        if (rt->swfsize) {
1282
            if ((ret = rtmp_calc_swf_verification(s, rt, serverdata + 1 +
1283
                                                  RTMP_HANDSHAKE_PACKET_SIZE - 32)) < 0)
1284
                return ret;
1285
        }
1286
 
1287
        ret = ff_rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
1288
                                  rtmp_server_key, sizeof(rtmp_server_key),
1289
                                  digest);
1290
        if (ret < 0)
1291
            return ret;
1292
 
1293
        ret = ff_rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE - 32,
1294
                                  0, digest, 32, signature);
1295
        if (ret < 0)
1296
            return ret;
1297
 
1298
        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1299
            /* Compute the shared secret key sent by the server and initialize
1300
             * the RC4 encryption. */
1301
            if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1302
                                                   tosend + 1, type)) < 0)
1303
                return ret;
1304
 
1305
            /* Encrypt the signature received by the server. */
1306
            ff_rtmpe_encrypt_sig(rt->stream, signature, digest, serverdata[0]);
1307
        }
1308
 
1309
        if (memcmp(signature, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
1310
            av_log(s, AV_LOG_ERROR, "Signature mismatch\n");
1311
            return AVERROR(EIO);
1312
        }
1313
 
1314
        for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
1315
            tosend[i] = av_lfg_get(&rnd) >> 24;
1316
        ret = ff_rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
1317
                                  rtmp_player_key, sizeof(rtmp_player_key),
1318
                                  digest);
1319
        if (ret < 0)
1320
            return ret;
1321
 
1322
        ret = ff_rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
1323
                                  digest, 32,
1324
                                  tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
1325
        if (ret < 0)
1326
            return ret;
1327
 
1328
        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1329
            /* Encrypt the signature to be send to the server. */
1330
            ff_rtmpe_encrypt_sig(rt->stream, tosend +
1331
                                 RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
1332
                                 serverdata[0]);
1333
        }
1334
 
1335
        // write reply back to the server
1336
        if ((ret = ffurl_write(rt->stream, tosend,
1337
                               RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1338
            return ret;
1339
 
1340
        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1341
            /* Set RC4 keys for encryption and update the keystreams. */
1342
            if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1343
                return ret;
1344
        }
1345
    } else {
1346
        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1347
            /* Compute the shared secret key sent by the server and initialize
1348
             * the RC4 encryption. */
1349
            if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1350
                            tosend + 1, 1)) < 0)
1351
                return ret;
1352
 
1353
            if (serverdata[0] == 9) {
1354
                /* Encrypt the signature received by the server. */
1355
                ff_rtmpe_encrypt_sig(rt->stream, signature, digest,
1356
                                     serverdata[0]);
1357
            }
1358
        }
1359
 
1360
        if ((ret = ffurl_write(rt->stream, serverdata + 1,
1361
                               RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1362
            return ret;
1363
 
1364
        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1365
            /* Set RC4 keys for encryption and update the keystreams. */
1366
            if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1367
                return ret;
1368
        }
1369
    }
1370
 
1371
    return 0;
1372
}
1373
 
1374
static int rtmp_receive_hs_packet(RTMPContext* rt, uint32_t *first_int,
1375
                                  uint32_t *second_int, char *arraydata,
1376
                                  int size)
1377
{
1378
    int inoutsize;
1379
 
1380
    inoutsize = ffurl_read_complete(rt->stream, arraydata,
1381
                                    RTMP_HANDSHAKE_PACKET_SIZE);
1382
    if (inoutsize <= 0)
1383
        return AVERROR(EIO);
1384
    if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1385
        av_log(rt, AV_LOG_ERROR, "Erroneous Message size %d"
1386
               " not following standard\n", (int)inoutsize);
1387
        return AVERROR(EINVAL);
1388
    }
1389
 
1390
    *first_int  = AV_RB32(arraydata);
1391
    *second_int = AV_RB32(arraydata + 4);
1392
    return 0;
1393
}
1394
 
1395
static int rtmp_send_hs_packet(RTMPContext* rt, uint32_t first_int,
1396
                               uint32_t second_int, char *arraydata, int size)
1397
{
1398
    int inoutsize;
1399
 
1400
    AV_WB32(arraydata, first_int);
1401
    AV_WB32(arraydata + 4, second_int);
1402
    inoutsize = ffurl_write(rt->stream, arraydata,
1403
                            RTMP_HANDSHAKE_PACKET_SIZE);
1404
    if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1405
        av_log(rt, AV_LOG_ERROR, "Unable to write answer\n");
1406
        return AVERROR(EIO);
1407
    }
1408
 
1409
    return 0;
1410
}
1411
 
1412
/**
1413
 * rtmp handshake server side
1414
 */
1415
static int rtmp_server_handshake(URLContext *s, RTMPContext *rt)
1416
{
1417
    uint8_t buffer[RTMP_HANDSHAKE_PACKET_SIZE];
1418
    uint32_t hs_epoch;
1419
    uint32_t hs_my_epoch;
1420
    uint8_t hs_c1[RTMP_HANDSHAKE_PACKET_SIZE];
1421
    uint8_t hs_s1[RTMP_HANDSHAKE_PACKET_SIZE];
1422
    uint32_t zeroes;
1423
    uint32_t temp       = 0;
1424
    int randomidx       = 0;
1425
    int inoutsize       = 0;
1426
    int ret;
1427
 
1428
    inoutsize = ffurl_read_complete(rt->stream, buffer, 1);       // Receive C0
1429
    if (inoutsize <= 0) {
1430
        av_log(s, AV_LOG_ERROR, "Unable to read handshake\n");
1431
        return AVERROR(EIO);
1432
    }
1433
    // Check Version
1434
    if (buffer[0] != 3) {
1435
        av_log(s, AV_LOG_ERROR, "RTMP protocol version mismatch\n");
1436
        return AVERROR(EIO);
1437
    }
1438
    if (ffurl_write(rt->stream, buffer, 1) <= 0) {                 // Send S0
1439
        av_log(s, AV_LOG_ERROR,
1440
               "Unable to write answer - RTMP S0\n");
1441
        return AVERROR(EIO);
1442
    }
1443
    /* Receive C1 */
1444
    ret = rtmp_receive_hs_packet(rt, &hs_epoch, &zeroes, hs_c1,
1445
                                 RTMP_HANDSHAKE_PACKET_SIZE);
1446
    if (ret) {
1447
        av_log(s, AV_LOG_ERROR, "RTMP Handshake C1 Error\n");
1448
        return ret;
1449
    }
1450
    /* Send S1 */
1451
    /* By now same epoch will be sent */
1452
    hs_my_epoch = hs_epoch;
1453
    /* Generate random */
1454
    for (randomidx = 8; randomidx < (RTMP_HANDSHAKE_PACKET_SIZE);
1455
         randomidx += 4)
1456
        AV_WB32(hs_s1 + randomidx, av_get_random_seed());
1457
 
1458
    ret = rtmp_send_hs_packet(rt, hs_my_epoch, 0, hs_s1,
1459
                              RTMP_HANDSHAKE_PACKET_SIZE);
1460
    if (ret) {
1461
        av_log(s, AV_LOG_ERROR, "RTMP Handshake S1 Error\n");
1462
        return ret;
1463
    }
1464
    /* Send S2 */
1465
    ret = rtmp_send_hs_packet(rt, hs_epoch, 0, hs_c1,
1466
                              RTMP_HANDSHAKE_PACKET_SIZE);
1467
    if (ret) {
1468
        av_log(s, AV_LOG_ERROR, "RTMP Handshake S2 Error\n");
1469
        return ret;
1470
    }
1471
    /* Receive C2 */
1472
    ret = rtmp_receive_hs_packet(rt, &temp, &zeroes, buffer,
1473
                                 RTMP_HANDSHAKE_PACKET_SIZE);
1474
    if (ret) {
1475
        av_log(s, AV_LOG_ERROR, "RTMP Handshake C2 Error\n");
1476
        return ret;
1477
    }
1478
    if (temp != hs_my_epoch)
1479
        av_log(s, AV_LOG_WARNING,
1480
               "Erroneous C2 Message epoch does not match up with C1 epoch\n");
1481
    if (memcmp(buffer + 8, hs_s1 + 8,
1482
               RTMP_HANDSHAKE_PACKET_SIZE - 8))
1483
        av_log(s, AV_LOG_WARNING,
1484
               "Erroneous C2 Message random does not match up\n");
1485
 
1486
    return 0;
1487
}
1488
 
1489
static int handle_chunk_size(URLContext *s, RTMPPacket *pkt)
1490
{
1491
    RTMPContext *rt = s->priv_data;
1492
    int ret;
1493
 
1494
    if (pkt->size < 4) {
1495
        av_log(s, AV_LOG_ERROR,
1496
               "Too short chunk size change packet (%d)\n",
1497
               pkt->size);
1498
        return AVERROR_INVALIDDATA;
1499
    }
1500
 
1501
    if (!rt->is_input) {
1502
        /* Send the same chunk size change packet back to the server,
1503
         * setting the outgoing chunk size to the same as the incoming one. */
1504
        if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
1505
                                        &rt->prev_pkt[1], &rt->nb_prev_pkt[1])) < 0)
1506
            return ret;
1507
        rt->out_chunk_size = AV_RB32(pkt->data);
1508
    }
1509
 
1510
    rt->in_chunk_size = AV_RB32(pkt->data);
1511
    if (rt->in_chunk_size <= 0) {
1512
        av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n",
1513
               rt->in_chunk_size);
1514
        return AVERROR_INVALIDDATA;
1515
    }
1516
    av_log(s, AV_LOG_DEBUG, "New incoming chunk size = %d\n",
1517
           rt->in_chunk_size);
1518
 
1519
    return 0;
1520
}
1521
 
1522
static int handle_ping(URLContext *s, RTMPPacket *pkt)
1523
{
1524
    RTMPContext *rt = s->priv_data;
1525
    int t, ret;
1526
 
1527
    if (pkt->size < 2) {
1528
        av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
1529
               pkt->size);
1530
        return AVERROR_INVALIDDATA;
1531
    }
1532
 
1533
    t = AV_RB16(pkt->data);
1534
    if (t == 6) {
1535
        if ((ret = gen_pong(s, rt, pkt)) < 0)
1536
            return ret;
1537
    } else if (t == 26) {
1538
        if (rt->swfsize) {
1539
            if ((ret = gen_swf_verification(s, rt)) < 0)
1540
                return ret;
1541
        } else {
1542
            av_log(s, AV_LOG_WARNING, "Ignoring SWFVerification request.\n");
1543
        }
1544
    }
1545
 
1546
    return 0;
1547
}
1548
 
1549
static int handle_client_bw(URLContext *s, RTMPPacket *pkt)
1550
{
1551
    RTMPContext *rt = s->priv_data;
1552
 
1553
    if (pkt->size < 4) {
1554
        av_log(s, AV_LOG_ERROR,
1555
               "Client bandwidth report packet is less than 4 bytes long (%d)\n",
1556
               pkt->size);
1557
        return AVERROR_INVALIDDATA;
1558
    }
1559
 
1560
    rt->client_report_size = AV_RB32(pkt->data);
1561
    if (rt->client_report_size <= 0) {
1562
        av_log(s, AV_LOG_ERROR, "Incorrect client bandwidth %d\n",
1563
                rt->client_report_size);
1564
        return AVERROR_INVALIDDATA;
1565
 
1566
    }
1567
    av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", rt->client_report_size);
1568
    rt->client_report_size >>= 1;
1569
 
1570
    return 0;
1571
}
1572
 
1573
static int handle_server_bw(URLContext *s, RTMPPacket *pkt)
1574
{
1575
    RTMPContext *rt = s->priv_data;
1576
 
1577
    if (pkt->size < 4) {
1578
        av_log(s, AV_LOG_ERROR,
1579
               "Too short server bandwidth report packet (%d)\n",
1580
               pkt->size);
1581
        return AVERROR_INVALIDDATA;
1582
    }
1583
 
1584
    rt->server_bw = AV_RB32(pkt->data);
1585
    if (rt->server_bw <= 0) {
1586
        av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n",
1587
               rt->server_bw);
1588
        return AVERROR_INVALIDDATA;
1589
    }
1590
    av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw);
1591
 
1592
    return 0;
1593
}
1594
 
1595
static int do_adobe_auth(RTMPContext *rt, const char *user, const char *salt,
1596
                         const char *opaque, const char *challenge)
1597
{
1598
    uint8_t hash[16];
1599
    char hashstr[AV_BASE64_SIZE(sizeof(hash))], challenge2[10];
1600
    struct AVMD5 *md5 = av_md5_alloc();
1601
    if (!md5)
1602
        return AVERROR(ENOMEM);
1603
 
1604
    snprintf(challenge2, sizeof(challenge2), "%08x", av_get_random_seed());
1605
 
1606
    av_md5_init(md5);
1607
    av_md5_update(md5, user, strlen(user));
1608
    av_md5_update(md5, salt, strlen(salt));
1609
    av_md5_update(md5, rt->password, strlen(rt->password));
1610
    av_md5_final(md5, hash);
1611
    av_base64_encode(hashstr, sizeof(hashstr), hash,
1612
                     sizeof(hash));
1613
    av_md5_init(md5);
1614
    av_md5_update(md5, hashstr, strlen(hashstr));
1615
    if (opaque)
1616
        av_md5_update(md5, opaque, strlen(opaque));
1617
    else if (challenge)
1618
        av_md5_update(md5, challenge, strlen(challenge));
1619
    av_md5_update(md5, challenge2, strlen(challenge2));
1620
    av_md5_final(md5, hash);
1621
    av_base64_encode(hashstr, sizeof(hashstr), hash,
1622
                     sizeof(hash));
1623
    snprintf(rt->auth_params, sizeof(rt->auth_params),
1624
             "?authmod=%s&user=%s&challenge=%s&response=%s",
1625
             "adobe", user, challenge2, hashstr);
1626
    if (opaque)
1627
        av_strlcatf(rt->auth_params, sizeof(rt->auth_params),
1628
                    "&opaque=%s", opaque);
1629
 
1630
    av_free(md5);
1631
    return 0;
1632
}
1633
 
1634
static int do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce)
1635
{
1636
    uint8_t hash[16];
1637
    char hashstr1[33], hashstr2[33];
1638
    const char *realm = "live";
1639
    const char *method = "publish";
1640
    const char *qop = "auth";
1641
    const char *nc = "00000001";
1642
    char cnonce[10];
1643
    struct AVMD5 *md5 = av_md5_alloc();
1644
    if (!md5)
1645
        return AVERROR(ENOMEM);
1646
 
1647
    snprintf(cnonce, sizeof(cnonce), "%08x", av_get_random_seed());
1648
 
1649
    av_md5_init(md5);
1650
    av_md5_update(md5, user, strlen(user));
1651
    av_md5_update(md5, ":", 1);
1652
    av_md5_update(md5, realm, strlen(realm));
1653
    av_md5_update(md5, ":", 1);
1654
    av_md5_update(md5, rt->password, strlen(rt->password));
1655
    av_md5_final(md5, hash);
1656
    ff_data_to_hex(hashstr1, hash, 16, 1);
1657
    hashstr1[32] = '\0';
1658
 
1659
    av_md5_init(md5);
1660
    av_md5_update(md5, method, strlen(method));
1661
    av_md5_update(md5, ":/", 2);
1662
    av_md5_update(md5, rt->app, strlen(rt->app));
1663
    if (!strchr(rt->app, '/'))
1664
        av_md5_update(md5, "/_definst_", strlen("/_definst_"));
1665
    av_md5_final(md5, hash);
1666
    ff_data_to_hex(hashstr2, hash, 16, 1);
1667
    hashstr2[32] = '\0';
1668
 
1669
    av_md5_init(md5);
1670
    av_md5_update(md5, hashstr1, strlen(hashstr1));
1671
    av_md5_update(md5, ":", 1);
1672
    if (nonce)
1673
        av_md5_update(md5, nonce, strlen(nonce));
1674
    av_md5_update(md5, ":", 1);
1675
    av_md5_update(md5, nc, strlen(nc));
1676
    av_md5_update(md5, ":", 1);
1677
    av_md5_update(md5, cnonce, strlen(cnonce));
1678
    av_md5_update(md5, ":", 1);
1679
    av_md5_update(md5, qop, strlen(qop));
1680
    av_md5_update(md5, ":", 1);
1681
    av_md5_update(md5, hashstr2, strlen(hashstr2));
1682
    av_md5_final(md5, hash);
1683
    ff_data_to_hex(hashstr1, hash, 16, 1);
1684
 
1685
    snprintf(rt->auth_params, sizeof(rt->auth_params),
1686
             "?authmod=%s&user=%s&nonce=%s&cnonce=%s&nc=%s&response=%s",
1687
             "llnw", user, nonce, cnonce, nc, hashstr1);
1688
 
1689
    av_free(md5);
1690
    return 0;
1691
}
1692
 
1693
static int handle_connect_error(URLContext *s, const char *desc)
1694
{
1695
    RTMPContext *rt = s->priv_data;
1696
    char buf[300], *ptr, authmod[15];
1697
    int i = 0, ret = 0;
1698
    const char *user = "", *salt = "", *opaque = NULL,
1699
               *challenge = NULL, *cptr = NULL, *nonce = NULL;
1700
 
1701
    if (!(cptr = strstr(desc, "authmod=adobe")) &&
1702
        !(cptr = strstr(desc, "authmod=llnw"))) {
1703
        av_log(s, AV_LOG_ERROR,
1704
               "Unknown connect error (unsupported authentication method?)\n");
1705
        return AVERROR_UNKNOWN;
1706
    }
1707
    cptr += strlen("authmod=");
1708
    while (*cptr && *cptr != ' ' && i < sizeof(authmod) - 1)
1709
        authmod[i++] = *cptr++;
1710
    authmod[i] = '\0';
1711
 
1712
    if (!rt->username[0] || !rt->password[0]) {
1713
        av_log(s, AV_LOG_ERROR, "No credentials set\n");
1714
        return AVERROR_UNKNOWN;
1715
    }
1716
 
1717
    if (strstr(desc, "?reason=authfailed")) {
1718
        av_log(s, AV_LOG_ERROR, "Incorrect username/password\n");
1719
        return AVERROR_UNKNOWN;
1720
    } else if (strstr(desc, "?reason=nosuchuser")) {
1721
        av_log(s, AV_LOG_ERROR, "Incorrect username\n");
1722
        return AVERROR_UNKNOWN;
1723
    }
1724
 
1725
    if (rt->auth_tried) {
1726
        av_log(s, AV_LOG_ERROR, "Authentication failed\n");
1727
        return AVERROR_UNKNOWN;
1728
    }
1729
 
1730
    rt->auth_params[0] = '\0';
1731
 
1732
    if (strstr(desc, "code=403 need auth")) {
1733
        snprintf(rt->auth_params, sizeof(rt->auth_params),
1734
                 "?authmod=%s&user=%s", authmod, rt->username);
1735
        return 0;
1736
    }
1737
 
1738
    if (!(cptr = strstr(desc, "?reason=needauth"))) {
1739
        av_log(s, AV_LOG_ERROR, "No auth parameters found\n");
1740
        return AVERROR_UNKNOWN;
1741
    }
1742
 
1743
    av_strlcpy(buf, cptr + 1, sizeof(buf));
1744
    ptr = buf;
1745
 
1746
    while (ptr) {
1747
        char *next  = strchr(ptr, '&');
1748
        char *value = strchr(ptr, '=');
1749
        if (next)
1750
            *next++ = '\0';
1751
        if (value) {
1752
            *value++ = '\0';
1753
            if (!strcmp(ptr, "user")) {
1754
                user = value;
1755
            } else if (!strcmp(ptr, "salt")) {
1756
                salt = value;
1757
            } else if (!strcmp(ptr, "opaque")) {
1758
                opaque = value;
1759
            } else if (!strcmp(ptr, "challenge")) {
1760
                challenge = value;
1761
            } else if (!strcmp(ptr, "nonce")) {
1762
                nonce = value;
1763
            } else {
1764
                av_log(s, AV_LOG_INFO, "Ignoring unsupported var %s\n", ptr);
1765
            }
1766
        } else {
1767
            av_log(s, AV_LOG_WARNING, "Variable %s has NULL value\n", ptr);
1768
        }
1769
        ptr = next;
1770
    }
1771
 
1772
    if (!strcmp(authmod, "adobe")) {
1773
        if ((ret = do_adobe_auth(rt, user, salt, opaque, challenge)) < 0)
1774
            return ret;
1775
    } else {
1776
        if ((ret = do_llnw_auth(rt, user, nonce)) < 0)
1777
            return ret;
1778
    }
1779
 
1780
    rt->auth_tried = 1;
1781
    return 0;
1782
}
1783
 
1784
static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
1785
{
1786
    RTMPContext *rt = s->priv_data;
1787
    const uint8_t *data_end = pkt->data + pkt->size;
1788
    char *tracked_method = NULL;
1789
    int level = AV_LOG_ERROR;
1790
    uint8_t tmpstr[256];
1791
    int ret;
1792
 
1793
    if ((ret = find_tracked_method(s, pkt, 9, &tracked_method)) < 0)
1794
        return ret;
1795
 
1796
    if (!ff_amf_get_field_value(pkt->data + 9, data_end,
1797
                                "description", tmpstr, sizeof(tmpstr))) {
1798
        if (tracked_method && (!strcmp(tracked_method, "_checkbw")      ||
1799
                               !strcmp(tracked_method, "releaseStream") ||
1800
                               !strcmp(tracked_method, "FCSubscribe")   ||
1801
                               !strcmp(tracked_method, "FCPublish"))) {
1802
            /* Gracefully ignore Adobe-specific historical artifact errors. */
1803
            level = AV_LOG_WARNING;
1804
            ret = 0;
1805
        } else if (tracked_method && !strcmp(tracked_method, "getStreamLength")) {
1806
            level = rt->live ? AV_LOG_DEBUG : AV_LOG_WARNING;
1807
            ret = 0;
1808
        } else if (tracked_method && !strcmp(tracked_method, "connect")) {
1809
            ret = handle_connect_error(s, tmpstr);
1810
            if (!ret) {
1811
                rt->do_reconnect = 1;
1812
                level = AV_LOG_VERBOSE;
1813
            }
1814
        } else
1815
            ret = AVERROR_UNKNOWN;
1816
        av_log(s, level, "Server error: %s\n", tmpstr);
1817
    }
1818
 
1819
    av_free(tracked_method);
1820
    return ret;
1821
}
1822
 
1823
static int write_begin(URLContext *s)
1824
{
1825
    RTMPContext *rt = s->priv_data;
1826
    PutByteContext pbc;
1827
    RTMPPacket spkt = { 0 };
1828
    int ret;
1829
 
1830
    // Send Stream Begin 1
1831
    if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
1832
                                     RTMP_PT_PING, 0, 6)) < 0) {
1833
        av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1834
        return ret;
1835
    }
1836
 
1837
    bytestream2_init_writer(&pbc, spkt.data, spkt.size);
1838
    bytestream2_put_be16(&pbc, 0);          // 0 -> Stream Begin
1839
    bytestream2_put_be32(&pbc, rt->nb_streamid);
1840
 
1841
    ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1842
                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1843
 
1844
    ff_rtmp_packet_destroy(&spkt);
1845
 
1846
    return ret;
1847
}
1848
 
1849
static int write_status(URLContext *s, RTMPPacket *pkt,
1850
                        const char *status, const char *filename)
1851
{
1852
    RTMPContext *rt = s->priv_data;
1853
    RTMPPacket spkt = { 0 };
1854
    char statusmsg[128];
1855
    uint8_t *pp;
1856
    int ret;
1857
 
1858
    if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1859
                                     RTMP_PT_INVOKE, 0,
1860
                                     RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1861
        av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1862
        return ret;
1863
    }
1864
 
1865
    pp = spkt.data;
1866
    spkt.extra = pkt->extra;
1867
    ff_amf_write_string(&pp, "onStatus");
1868
    ff_amf_write_number(&pp, 0);
1869
    ff_amf_write_null(&pp);
1870
 
1871
    ff_amf_write_object_start(&pp);
1872
    ff_amf_write_field_name(&pp, "level");
1873
    ff_amf_write_string(&pp, "status");
1874
    ff_amf_write_field_name(&pp, "code");
1875
    ff_amf_write_string(&pp, status);
1876
    ff_amf_write_field_name(&pp, "description");
1877
    snprintf(statusmsg, sizeof(statusmsg),
1878
             "%s is now published", filename);
1879
    ff_amf_write_string(&pp, statusmsg);
1880
    ff_amf_write_field_name(&pp, "details");
1881
    ff_amf_write_string(&pp, filename);
1882
    ff_amf_write_field_name(&pp, "clientid");
1883
    snprintf(statusmsg, sizeof(statusmsg), "%s", LIBAVFORMAT_IDENT);
1884
    ff_amf_write_string(&pp, statusmsg);
1885
    ff_amf_write_object_end(&pp);
1886
 
1887
    spkt.size = pp - spkt.data;
1888
    ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1889
                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1890
    ff_rtmp_packet_destroy(&spkt);
1891
 
1892
    return ret;
1893
}
1894
 
1895
static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
1896
{
1897
    RTMPContext *rt = s->priv_data;
1898
    double seqnum;
1899
    char filename[64];
1900
    char command[64];
1901
    int stringlen;
1902
    char *pchar;
1903
    const uint8_t *p = pkt->data;
1904
    uint8_t *pp      = NULL;
1905
    RTMPPacket spkt  = { 0 };
1906
    GetByteContext gbc;
1907
    int ret;
1908
 
1909
    bytestream2_init(&gbc, p, pkt->size);
1910
    if (ff_amf_read_string(&gbc, command, sizeof(command),
1911
                           &stringlen)) {
1912
        av_log(s, AV_LOG_ERROR, "Error in PT_INVOKE\n");
1913
        return AVERROR_INVALIDDATA;
1914
    }
1915
 
1916
    ret = ff_amf_read_number(&gbc, &seqnum);
1917
    if (ret)
1918
        return ret;
1919
    ret = ff_amf_read_null(&gbc);
1920
    if (ret)
1921
        return ret;
1922
    if (!strcmp(command, "FCPublish") ||
1923
        !strcmp(command, "publish")) {
1924
        ret = ff_amf_read_string(&gbc, filename,
1925
                                 sizeof(filename), &stringlen);
1926
        // check with url
1927
        if (s->filename) {
1928
            pchar = strrchr(s->filename, '/');
1929
            if (!pchar) {
1930
                av_log(s, AV_LOG_WARNING,
1931
                       "Unable to find / in url %s, bad format\n",
1932
                       s->filename);
1933
                pchar = s->filename;
1934
            }
1935
            pchar++;
1936
            if (strcmp(pchar, filename))
1937
                av_log(s, AV_LOG_WARNING, "Unexpected stream %s, expecting"
1938
                       " %s\n", filename, pchar);
1939
        }
1940
        rt->state = STATE_RECEIVING;
1941
    }
1942
 
1943
    if (!strcmp(command, "FCPublish")) {
1944
        if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1945
                                         RTMP_PT_INVOKE, 0,
1946
                                         RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1947
            av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1948
            return ret;
1949
        }
1950
        pp = spkt.data;
1951
        ff_amf_write_string(&pp, "onFCPublish");
1952
    } else if (!strcmp(command, "publish")) {
1953
        ret = write_begin(s);
1954
        if (ret < 0)
1955
            return ret;
1956
 
1957
        // Send onStatus(NetStream.Publish.Start)
1958
        return write_status(s, pkt, "NetStream.Publish.Start",
1959
                           filename);
1960
    } else if (!strcmp(command, "play")) {
1961
        ret = write_begin(s);
1962
        if (ret < 0)
1963
            return ret;
1964
        rt->state = STATE_SENDING;
1965
        return write_status(s, pkt, "NetStream.Play.Start",
1966
                            filename);
1967
    } else {
1968
        if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1969
                                         RTMP_PT_INVOKE, 0,
1970
                                         RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1971
            av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1972
            return ret;
1973
        }
1974
        pp = spkt.data;
1975
        ff_amf_write_string(&pp, "_result");
1976
        ff_amf_write_number(&pp, seqnum);
1977
        ff_amf_write_null(&pp);
1978
        if (!strcmp(command, "createStream")) {
1979
            rt->nb_streamid++;
1980
            if (rt->nb_streamid == 0 || rt->nb_streamid == 2)
1981
                rt->nb_streamid++; /* Values 0 and 2 are reserved */
1982
            ff_amf_write_number(&pp, rt->nb_streamid);
1983
            /* By now we don't control which streams are removed in
1984
             * deleteStream. There is no stream creation control
1985
             * if a client creates more than 2^32 - 2 streams. */
1986
        }
1987
    }
1988
    spkt.size = pp - spkt.data;
1989
    ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1990
                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1991
    ff_rtmp_packet_destroy(&spkt);
1992
    return ret;
1993
}
1994
 
1995
/**
1996
 * Read the AMF_NUMBER response ("_result") to a function call
1997
 * (e.g. createStream()). This response should be made up of the AMF_STRING
1998
 * "result", a NULL object and then the response encoded as AMF_NUMBER. On a
1999
 * successful response, we will return set the value to number (otherwise number
2000
 * will not be changed).
2001
 *
2002
 * @return 0 if reading the value succeeds, negative value otherwiss
2003
 */
2004
static int read_number_result(RTMPPacket *pkt, double *number)
2005
{
2006
    // We only need to fit "_result" in this.
2007
    uint8_t strbuffer[8];
2008
    int stringlen;
2009
    double numbuffer;
2010
    GetByteContext gbc;
2011
 
2012
    bytestream2_init(&gbc, pkt->data, pkt->size);
2013
 
2014
    // Value 1/4: "_result" as AMF_STRING
2015
    if (ff_amf_read_string(&gbc, strbuffer, sizeof(strbuffer), &stringlen))
2016
        return AVERROR_INVALIDDATA;
2017
    if (strcmp(strbuffer, "_result"))
2018
        return AVERROR_INVALIDDATA;
2019
    // Value 2/4: The callee reference number
2020
    if (ff_amf_read_number(&gbc, &numbuffer))
2021
        return AVERROR_INVALIDDATA;
2022
    // Value 3/4: Null
2023
    if (ff_amf_read_null(&gbc))
2024
        return AVERROR_INVALIDDATA;
2025
    // Value 4/4: The resonse as AMF_NUMBER
2026
    if (ff_amf_read_number(&gbc, &numbuffer))
2027
        return AVERROR_INVALIDDATA;
2028
    else
2029
        *number = numbuffer;
2030
 
2031
    return 0;
2032
}
2033
 
2034
static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
2035
{
2036
    RTMPContext *rt = s->priv_data;
2037
    char *tracked_method = NULL;
2038
    int ret = 0;
2039
 
2040
    if ((ret = find_tracked_method(s, pkt, 10, &tracked_method)) < 0)
2041
        return ret;
2042
 
2043
    if (!tracked_method) {
2044
        /* Ignore this reply when the current method is not tracked. */
2045
        return ret;
2046
    }
2047
 
2048
    if (!strcmp(tracked_method, "connect")) {
2049
        if (!rt->is_input) {
2050
            if ((ret = gen_release_stream(s, rt)) < 0)
2051
                goto fail;
2052
 
2053
            if ((ret = gen_fcpublish_stream(s, rt)) < 0)
2054
                goto fail;
2055
        } else {
2056
            if ((ret = gen_server_bw(s, rt)) < 0)
2057
                goto fail;
2058
        }
2059
 
2060
        if ((ret = gen_create_stream(s, rt)) < 0)
2061
            goto fail;
2062
 
2063
        if (rt->is_input) {
2064
            /* Send the FCSubscribe command when the name of live
2065
             * stream is defined by the user or if it's a live stream. */
2066
            if (rt->subscribe) {
2067
                if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0)
2068
                    goto fail;
2069
            } else if (rt->live == -1) {
2070
                if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0)
2071
                    goto fail;
2072
            }
2073
        }
2074
    } else if (!strcmp(tracked_method, "createStream")) {
2075
        double stream_id;
2076
        if (read_number_result(pkt, &stream_id)) {
2077
            av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
2078
        } else {
2079
            rt->stream_id = stream_id;
2080
        }
2081
 
2082
        if (!rt->is_input) {
2083
            if ((ret = gen_publish(s, rt)) < 0)
2084
                goto fail;
2085
        } else {
2086
            if (rt->live != -1) {
2087
                if ((ret = gen_get_stream_length(s, rt)) < 0)
2088
                    goto fail;
2089
            }
2090
            if ((ret = gen_play(s, rt)) < 0)
2091
                goto fail;
2092
            if ((ret = gen_buffer_time(s, rt)) < 0)
2093
                goto fail;
2094
        }
2095
    } else if (!strcmp(tracked_method, "getStreamLength")) {
2096
        if (read_number_result(pkt, &rt->duration)) {
2097
            av_log(s, AV_LOG_WARNING, "Unexpected reply on getStreamLength()\n");
2098
        }
2099
    }
2100
 
2101
fail:
2102
    av_free(tracked_method);
2103
    return ret;
2104
}
2105
 
2106
static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
2107
{
2108
    RTMPContext *rt = s->priv_data;
2109
    const uint8_t *data_end = pkt->data + pkt->size;
2110
    const uint8_t *ptr = pkt->data + RTMP_HEADER;
2111
    uint8_t tmpstr[256];
2112
    int i, t;
2113
 
2114
    for (i = 0; i < 2; i++) {
2115
        t = ff_amf_tag_size(ptr, data_end);
2116
        if (t < 0)
2117
            return 1;
2118
        ptr += t;
2119
    }
2120
 
2121
    t = ff_amf_get_field_value(ptr, data_end, "level", tmpstr, sizeof(tmpstr));
2122
    if (!t && !strcmp(tmpstr, "error")) {
2123
        t = ff_amf_get_field_value(ptr, data_end,
2124
                                   "description", tmpstr, sizeof(tmpstr));
2125
        if (t || !tmpstr[0])
2126
            t = ff_amf_get_field_value(ptr, data_end, "code",
2127
                                       tmpstr, sizeof(tmpstr));
2128
        if (!t)
2129
            av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
2130
        return -1;
2131
    }
2132
 
2133
    t = ff_amf_get_field_value(ptr, data_end, "code", tmpstr, sizeof(tmpstr));
2134
    if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
2135
    if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
2136
    if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
2137
    if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
2138
    if (!t && !strcmp(tmpstr, "NetStream.Seek.Notify")) rt->state = STATE_PLAYING;
2139
 
2140
    return 0;
2141
}
2142
 
2143
static int handle_invoke(URLContext *s, RTMPPacket *pkt)
2144
{
2145
    RTMPContext *rt = s->priv_data;
2146
    int ret = 0;
2147
 
2148
    //TODO: check for the messages sent for wrong state?
2149
    if (ff_amf_match_string(pkt->data, pkt->size, "_error")) {
2150
        if ((ret = handle_invoke_error(s, pkt)) < 0)
2151
            return ret;
2152
    } else if (ff_amf_match_string(pkt->data, pkt->size, "_result")) {
2153
        if ((ret = handle_invoke_result(s, pkt)) < 0)
2154
            return ret;
2155
    } else if (ff_amf_match_string(pkt->data, pkt->size, "onStatus")) {
2156
        if ((ret = handle_invoke_status(s, pkt)) < 0)
2157
            return ret;
2158
    } else if (ff_amf_match_string(pkt->data, pkt->size, "onBWDone")) {
2159
        if ((ret = gen_check_bw(s, rt)) < 0)
2160
            return ret;
2161
    } else if (ff_amf_match_string(pkt->data, pkt->size, "releaseStream") ||
2162
               ff_amf_match_string(pkt->data, pkt->size, "FCPublish")     ||
2163
               ff_amf_match_string(pkt->data, pkt->size, "publish")       ||
2164
               ff_amf_match_string(pkt->data, pkt->size, "play")          ||
2165
               ff_amf_match_string(pkt->data, pkt->size, "_checkbw")      ||
2166
               ff_amf_match_string(pkt->data, pkt->size, "createStream")) {
2167
        if ((ret = send_invoke_response(s, pkt)) < 0)
2168
            return ret;
2169
    }
2170
 
2171
    return ret;
2172
}
2173
 
2174
static int update_offset(RTMPContext *rt, int size)
2175
{
2176
    int old_flv_size;
2177
 
2178
    // generate packet header and put data into buffer for FLV demuxer
2179
    if (rt->flv_off < rt->flv_size) {
2180
        // There is old unread data in the buffer, thus append at the end
2181
        old_flv_size  = rt->flv_size;
2182
        rt->flv_size += size;
2183
    } else {
2184
        // All data has been read, write the new data at the start of the buffer
2185
        old_flv_size = 0;
2186
        rt->flv_size = size;
2187
        rt->flv_off  = 0;
2188
    }
2189
 
2190
    return old_flv_size;
2191
}
2192
 
2193
static int append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip)
2194
{
2195
    int old_flv_size, ret;
2196
    PutByteContext pbc;
2197
    const uint8_t *data = pkt->data + skip;
2198
    const int size      = pkt->size - skip;
2199
    uint32_t ts         = pkt->timestamp;
2200
 
2201
    if (pkt->type == RTMP_PT_AUDIO) {
2202
        rt->has_audio = 1;
2203
    } else if (pkt->type == RTMP_PT_VIDEO) {
2204
        rt->has_video = 1;
2205
    }
2206
 
2207
    old_flv_size = update_offset(rt, size + 15);
2208
 
2209
    if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
2210
        rt->flv_size = rt->flv_off = 0;
2211
        return ret;
2212
    }
2213
    bytestream2_init_writer(&pbc, rt->flv_data, rt->flv_size);
2214
    bytestream2_skip_p(&pbc, old_flv_size);
2215
    bytestream2_put_byte(&pbc, pkt->type);
2216
    bytestream2_put_be24(&pbc, size);
2217
    bytestream2_put_be24(&pbc, ts);
2218
    bytestream2_put_byte(&pbc, ts >> 24);
2219
    bytestream2_put_be24(&pbc, 0);
2220
    bytestream2_put_buffer(&pbc, data, size);
2221
    bytestream2_put_be32(&pbc, 0);
2222
 
2223
    return 0;
2224
}
2225
 
2226
static int handle_notify(URLContext *s, RTMPPacket *pkt)
2227
{
2228
    RTMPContext *rt  = s->priv_data;
2229
    uint8_t commandbuffer[64];
2230
    char statusmsg[128];
2231
    int stringlen, ret, skip = 0;
2232
    GetByteContext gbc;
2233
 
2234
    bytestream2_init(&gbc, pkt->data, pkt->size);
2235
    if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
2236
                           &stringlen))
2237
        return AVERROR_INVALIDDATA;
2238
 
2239
    if (!strcmp(commandbuffer, "onMetaData")) {
2240
        // metadata properties should be stored in a mixed array
2241
        if (bytestream2_get_byte(&gbc) == AMF_DATA_TYPE_MIXEDARRAY) {
2242
            // We have found a metaData Array so flv can determine the streams
2243
            // from this.
2244
            rt->received_metadata = 1;
2245
            // skip 32-bit max array index
2246
            bytestream2_skip(&gbc, 4);
2247
            while (bytestream2_get_bytes_left(&gbc) > 3) {
2248
                if (ff_amf_get_string(&gbc, statusmsg, sizeof(statusmsg),
2249
                                      &stringlen))
2250
                    return AVERROR_INVALIDDATA;
2251
                // We do not care about the content of the property (yet).
2252
                stringlen = ff_amf_tag_size(gbc.buffer, gbc.buffer_end);
2253
                if (stringlen < 0)
2254
                    return AVERROR_INVALIDDATA;
2255
                bytestream2_skip(&gbc, stringlen);
2256
 
2257
                // The presence of the following properties indicates that the
2258
                // respective streams are present.
2259
                if (!strcmp(statusmsg, "videocodecid")) {
2260
                    rt->has_video = 1;
2261
                }
2262
                if (!strcmp(statusmsg, "audiocodecid")) {
2263
                    rt->has_audio = 1;
2264
                }
2265
            }
2266
            if (bytestream2_get_be24(&gbc) != AMF_END_OF_OBJECT)
2267
                return AVERROR_INVALIDDATA;
2268
        }
2269
    }
2270
 
2271
    // Skip the @setDataFrame string and validate it is a notification
2272
    if (!strcmp(commandbuffer, "@setDataFrame")) {
2273
        skip = gbc.buffer - pkt->data;
2274
        ret = ff_amf_read_string(&gbc, statusmsg,
2275
                                 sizeof(statusmsg), &stringlen);
2276
        if (ret < 0)
2277
            return AVERROR_INVALIDDATA;
2278
    }
2279
 
2280
    return append_flv_data(rt, pkt, skip);
2281
}
2282
 
2283
/**
2284
 * Parse received packet and possibly perform some action depending on
2285
 * the packet contents.
2286
 * @return 0 for no errors, negative values for serious errors which prevent
2287
 *         further communications, positive values for uncritical errors
2288
 */
2289
static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
2290
{
2291
    int ret;
2292
 
2293
#ifdef DEBUG
2294
    ff_rtmp_packet_dump(s, pkt);
2295
#endif
2296
 
2297
    switch (pkt->type) {
2298
    case RTMP_PT_BYTES_READ:
2299
        av_log(s, AV_LOG_TRACE, "received bytes read report\n");
2300
        break;
2301
    case RTMP_PT_CHUNK_SIZE:
2302
        if ((ret = handle_chunk_size(s, pkt)) < 0)
2303
            return ret;
2304
        break;
2305
    case RTMP_PT_PING:
2306
        if ((ret = handle_ping(s, pkt)) < 0)
2307
            return ret;
2308
        break;
2309
    case RTMP_PT_CLIENT_BW:
2310
        if ((ret = handle_client_bw(s, pkt)) < 0)
2311
            return ret;
2312
        break;
2313
    case RTMP_PT_SERVER_BW:
2314
        if ((ret = handle_server_bw(s, pkt)) < 0)
2315
            return ret;
2316
        break;
2317
    case RTMP_PT_INVOKE:
2318
        if ((ret = handle_invoke(s, pkt)) < 0)
2319
            return ret;
2320
        break;
2321
    case RTMP_PT_VIDEO:
2322
    case RTMP_PT_AUDIO:
2323
    case RTMP_PT_METADATA:
2324
    case RTMP_PT_NOTIFY:
2325
        /* Audio, Video and Metadata packets are parsed in get_packet() */
2326
        break;
2327
    default:
2328
        av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
2329
        break;
2330
    }
2331
    return 0;
2332
}
2333
 
2334
static int handle_metadata(RTMPContext *rt, RTMPPacket *pkt)
2335
{
2336
    int ret, old_flv_size, type;
2337
    const uint8_t *next;
2338
    uint8_t *p;
2339
    uint32_t size;
2340
    uint32_t ts, cts, pts = 0;
2341
 
2342
    old_flv_size = update_offset(rt, pkt->size);
2343
 
2344
    if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
2345
        rt->flv_size = rt->flv_off = 0;
2346
        return ret;
2347
    }
2348
 
2349
    next = pkt->data;
2350
    p    = rt->flv_data + old_flv_size;
2351
 
2352
    /* copy data while rewriting timestamps */
2353
    ts = pkt->timestamp;
2354
 
2355
    while (next - pkt->data < pkt->size - RTMP_HEADER) {
2356
        type = bytestream_get_byte(&next);
2357
        size = bytestream_get_be24(&next);
2358
        cts  = bytestream_get_be24(&next);
2359
        cts |= bytestream_get_byte(&next) << 24;
2360
        if (!pts)
2361
            pts = cts;
2362
        ts += cts - pts;
2363
        pts = cts;
2364
        if (size + 3 + 4 > pkt->data + pkt->size - next)
2365
            break;
2366
        bytestream_put_byte(&p, type);
2367
        bytestream_put_be24(&p, size);
2368
        bytestream_put_be24(&p, ts);
2369
        bytestream_put_byte(&p, ts >> 24);
2370
        memcpy(p, next, size + 3 + 4);
2371
        next += size + 3 + 4;
2372
        p    += size + 3 + 4;
2373
    }
2374
    if (p != rt->flv_data + rt->flv_size) {
2375
        av_log(NULL, AV_LOG_WARNING, "Incomplete flv packets in "
2376
                                     "RTMP_PT_METADATA packet\n");
2377
        rt->flv_size = p - rt->flv_data;
2378
    }
2379
 
2380
    return 0;
2381
}
2382
 
2383
/**
2384
 * Interact with the server by receiving and sending RTMP packets until
2385
 * there is some significant data (media data or expected status notification).
2386
 *
2387
 * @param s          reading context
2388
 * @param for_header non-zero value tells function to work until it
2389
 * gets notification from the server that playing has been started,
2390
 * otherwise function will work until some media data is received (or
2391
 * an error happens)
2392
 * @return 0 for successful operation, negative value in case of error
2393
 */
2394
static int get_packet(URLContext *s, int for_header)
2395
{
2396
    RTMPContext *rt = s->priv_data;
2397
    int ret;
2398
 
2399
    if (rt->state == STATE_STOPPED)
2400
        return AVERROR_EOF;
2401
 
2402
    for (;;) {
2403
        RTMPPacket rpkt = { 0 };
2404
        if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
2405
                                       rt->in_chunk_size, &rt->prev_pkt[0],
2406
                                       &rt->nb_prev_pkt[0])) <= 0) {
2407
            if (ret == 0) {
2408
                return AVERROR(EAGAIN);
2409
            } else {
2410
                return AVERROR(EIO);
2411
            }
2412
        }
2413
 
2414
        // Track timestamp for later use
2415
        rt->last_timestamp = rpkt.timestamp;
2416
 
2417
        rt->bytes_read += ret;
2418
        if (rt->bytes_read - rt->last_bytes_read > rt->client_report_size) {
2419
            av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
2420
            if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
2421
                return ret;
2422
            rt->last_bytes_read = rt->bytes_read;
2423
        }
2424
 
2425
        ret = rtmp_parse_result(s, rt, &rpkt);
2426
 
2427
        // At this point we must check if we are in the seek state and continue
2428
        // with the next packet. handle_invoke will get us out of this state
2429
        // when the right message is encountered
2430
        if (rt->state == STATE_SEEKING) {
2431
            ff_rtmp_packet_destroy(&rpkt);
2432
            // We continue, let the natural flow of things happen:
2433
            // AVERROR(EAGAIN) or handle_invoke gets us out of here
2434
            continue;
2435
        }
2436
 
2437
        if (ret < 0) {//serious error in current packet
2438
            ff_rtmp_packet_destroy(&rpkt);
2439
            return ret;
2440
        }
2441
        if (rt->do_reconnect && for_header) {
2442
            ff_rtmp_packet_destroy(&rpkt);
2443
            return 0;
2444
        }
2445
        if (rt->state == STATE_STOPPED) {
2446
            ff_rtmp_packet_destroy(&rpkt);
2447
            return AVERROR_EOF;
2448
        }
2449
        if (for_header && (rt->state == STATE_PLAYING    ||
2450
                           rt->state == STATE_PUBLISHING ||
2451
                           rt->state == STATE_SENDING    ||
2452
                           rt->state == STATE_RECEIVING)) {
2453
            ff_rtmp_packet_destroy(&rpkt);
2454
            return 0;
2455
        }
2456
        if (!rpkt.size || !rt->is_input) {
2457
            ff_rtmp_packet_destroy(&rpkt);
2458
            continue;
2459
        }
2460
        if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO) {
2461
            ret = append_flv_data(rt, &rpkt, 0);
2462
            ff_rtmp_packet_destroy(&rpkt);
2463
            return ret;
2464
        } else if (rpkt.type == RTMP_PT_NOTIFY) {
2465
            ret = handle_notify(s, &rpkt);
2466
            ff_rtmp_packet_destroy(&rpkt);
2467
            return ret;
2468
        } else if (rpkt.type == RTMP_PT_METADATA) {
2469
            ret = handle_metadata(rt, &rpkt);
2470
            ff_rtmp_packet_destroy(&rpkt);
2471
            return 0;
2472
        }
2473
        ff_rtmp_packet_destroy(&rpkt);
2474
    }
2475
}
2476
 
2477
static int rtmp_close(URLContext *h)
2478
{
2479
    RTMPContext *rt = h->priv_data;
2480
    int ret = 0, i, j;
2481
 
2482
    if (!rt->is_input) {
2483
        rt->flv_data = NULL;
2484
        if (rt->out_pkt.size)
2485
            ff_rtmp_packet_destroy(&rt->out_pkt);
2486
        if (rt->state > STATE_FCPUBLISH)
2487
            ret = gen_fcunpublish_stream(h, rt);
2488
    }
2489
    if (rt->state > STATE_HANDSHAKED)
2490
        ret = gen_delete_stream(h, rt);
2491
    for (i = 0; i < 2; i++) {
2492
        for (j = 0; j < rt->nb_prev_pkt[i]; j++)
2493
            ff_rtmp_packet_destroy(&rt->prev_pkt[i][j]);
2494
        av_freep(&rt->prev_pkt[i]);
2495
    }
2496
 
2497
    free_tracked_methods(rt);
2498
    av_freep(&rt->flv_data);
2499
    ffurl_close(rt->stream);
2500
    return ret;
2501
}
2502
 
2503
/**
2504
 * Insert a fake onMetadata packet into the FLV stream to notify the FLV
2505
 * demuxer about the duration of the stream.
2506
 *
2507
 * This should only be done if there was no real onMetadata packet sent by the
2508
 * server at the start of the stream and if we were able to retrieve a valid
2509
 * duration via a getStreamLength call.
2510
 *
2511
 * @return 0 for successful operation, negative value in case of error
2512
 */
2513
static int inject_fake_duration_metadata(RTMPContext *rt)
2514
{
2515
    // We need to insert the metdata packet directly after the FLV
2516
    // header, i.e. we need to move all other already read data by the
2517
    // size of our fake metadata packet.
2518
 
2519
    uint8_t* p;
2520
    // Keep old flv_data pointer
2521
    uint8_t* old_flv_data = rt->flv_data;
2522
    // Allocate a new flv_data pointer with enough space for the additional package
2523
    if (!(rt->flv_data = av_malloc(rt->flv_size + 55))) {
2524
        rt->flv_data = old_flv_data;
2525
        return AVERROR(ENOMEM);
2526
    }
2527
 
2528
    // Copy FLV header
2529
    memcpy(rt->flv_data, old_flv_data, 13);
2530
    // Copy remaining packets
2531
    memcpy(rt->flv_data + 13 + 55, old_flv_data + 13, rt->flv_size - 13);
2532
    // Increase the size by the injected packet
2533
    rt->flv_size += 55;
2534
    // Delete the old FLV data
2535
    av_freep(&old_flv_data);
2536
 
2537
    p = rt->flv_data + 13;
2538
    bytestream_put_byte(&p, FLV_TAG_TYPE_META);
2539
    bytestream_put_be24(&p, 40); // size of data part (sum of all parts below)
2540
    bytestream_put_be24(&p, 0);  // timestamp
2541
    bytestream_put_be32(&p, 0);  // reserved
2542
 
2543
    // first event name as a string
2544
    bytestream_put_byte(&p, AMF_DATA_TYPE_STRING);
2545
    // "onMetaData" as AMF string
2546
    bytestream_put_be16(&p, 10);
2547
    bytestream_put_buffer(&p, "onMetaData", 10);
2548
 
2549
    // mixed array (hash) with size and string/type/data tuples
2550
    bytestream_put_byte(&p, AMF_DATA_TYPE_MIXEDARRAY);
2551
    bytestream_put_be32(&p, 1); // metadata_count
2552
 
2553
    // "duration" as AMF string
2554
    bytestream_put_be16(&p, 8);
2555
    bytestream_put_buffer(&p, "duration", 8);
2556
    bytestream_put_byte(&p, AMF_DATA_TYPE_NUMBER);
2557
    bytestream_put_be64(&p, av_double2int(rt->duration));
2558
 
2559
    // Finalise object
2560
    bytestream_put_be16(&p, 0); // Empty string
2561
    bytestream_put_byte(&p, AMF_END_OF_OBJECT);
2562
    bytestream_put_be32(&p, 40); // size of data part (sum of all parts below)
2563
 
2564
    return 0;
2565
}
2566
 
2567
/**
2568
 * Open RTMP connection and verify that the stream can be played.
2569
 *
2570
 * URL syntax: rtmp://server[:port][/app][/playpath]
2571
 *             where 'app' is first one or two directories in the path
2572
 *             (e.g. /ondemand/, /flash/live/, etc.)
2573
 *             and 'playpath' is a file name (the rest of the path,
2574
 *             may be prefixed with "mp4:")
2575
 */
2576
static int rtmp_open(URLContext *s, const char *uri, int flags)
2577
{
2578
    RTMPContext *rt = s->priv_data;
2579
    char proto[8], hostname[256], path[1024], auth[100], *fname;
2580
    char *old_app, *qmark, *n, fname_buffer[1024];
2581
    uint8_t buf[2048];
2582
    int port;
2583
    AVDictionary *opts = NULL;
2584
    int ret;
2585
 
2586
    if (rt->listen_timeout > 0)
2587
        rt->listen = 1;
2588
 
2589
    rt->is_input = !(flags & AVIO_FLAG_WRITE);
2590
 
2591
    av_url_split(proto, sizeof(proto), auth, sizeof(auth),
2592
                 hostname, sizeof(hostname), &port,
2593
                 path, sizeof(path), s->filename);
2594
 
2595
    n = strchr(path, ' ');
2596
    if (n) {
2597
        av_log(s, AV_LOG_WARNING,
2598
               "Detected librtmp style URL parameters, these aren't supported "
2599
               "by the libavformat internal RTMP handler currently enabled. "
2600
               "See the documentation for the correct way to pass parameters.\n");
2601
        *n = '\0'; // Trim not supported part
2602
    }
2603
 
2604
    if (auth[0]) {
2605
        char *ptr = strchr(auth, ':');
2606
        if (ptr) {
2607
            *ptr = '\0';
2608
            av_strlcpy(rt->username, auth, sizeof(rt->username));
2609
            av_strlcpy(rt->password, ptr + 1, sizeof(rt->password));
2610
        }
2611
    }
2612
 
2613
    if (rt->listen && strcmp(proto, "rtmp")) {
2614
        av_log(s, AV_LOG_ERROR, "rtmp_listen not available for %s\n",
2615
               proto);
2616
        return AVERROR(EINVAL);
2617
    }
2618
    if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
2619
        if (!strcmp(proto, "rtmpts"))
2620
            av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
2621
 
2622
        /* open the http tunneling connection */
2623
        ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
2624
    } else if (!strcmp(proto, "rtmps")) {
2625
        /* open the tls connection */
2626
        if (port < 0)
2627
            port = RTMPS_DEFAULT_PORT;
2628
        ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
2629
    } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
2630
        if (!strcmp(proto, "rtmpte"))
2631
            av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
2632
 
2633
        /* open the encrypted connection */
2634
        ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
2635
        rt->encrypted = 1;
2636
    } else {
2637
        /* open the tcp connection */
2638
        if (port < 0)
2639
            port = RTMP_DEFAULT_PORT;
2640
        if (rt->listen)
2641
            ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port,
2642
                        "?listen&listen_timeout=%d",
2643
                        rt->listen_timeout * 1000);
2644
        else
2645
            ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
2646
    }
2647
 
2648
reconnect:
2649
    if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
2650
                          &s->interrupt_callback, &opts)) < 0) {
2651
        av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
2652
        goto fail;
2653
    }
2654
 
2655
    if (rt->swfverify) {
2656
        if ((ret = rtmp_calc_swfhash(s)) < 0)
2657
            goto fail;
2658
    }
2659
 
2660
    rt->state = STATE_START;
2661
    if (!rt->listen && (ret = rtmp_handshake(s, rt)) < 0)
2662
        goto fail;
2663
    if (rt->listen && (ret = rtmp_server_handshake(s, rt)) < 0)
2664
        goto fail;
2665
 
2666
    rt->out_chunk_size = 128;
2667
    rt->in_chunk_size  = 128; // Probably overwritten later
2668
    rt->state = STATE_HANDSHAKED;
2669
 
2670
    // Keep the application name when it has been defined by the user.
2671
    old_app = rt->app;
2672
 
2673
    rt->app = av_malloc(APP_MAX_LENGTH);
2674
    if (!rt->app) {
2675
        ret = AVERROR(ENOMEM);
2676
        goto fail;
2677
    }
2678
 
2679
    //extract "app" part from path
2680
    qmark = strchr(path, '?');
2681
    if (qmark && strstr(qmark, "slist=")) {
2682
        char* amp;
2683
        // After slist we have the playpath, before the params, the app
2684
        av_strlcpy(rt->app, path + 1, FFMIN(qmark - path, APP_MAX_LENGTH));
2685
        fname = strstr(path, "slist=") + 6;
2686
        // Strip any further query parameters from fname
2687
        amp = strchr(fname, '&');
2688
        if (amp) {
2689
            av_strlcpy(fname_buffer, fname, FFMIN(amp - fname + 1,
2690
                                                  sizeof(fname_buffer)));
2691
            fname = fname_buffer;
2692
        }
2693
    } else if (!strncmp(path, "/ondemand/", 10)) {
2694
        fname = path + 10;
2695
        memcpy(rt->app, "ondemand", 9);
2696
    } else {
2697
        char *next = *path ? path + 1 : path;
2698
        char *p = strchr(next, '/');
2699
        if (!p) {
2700
            if (old_app) {
2701
                // If name of application has been defined by the user, assume that
2702
                // playpath is provided in the URL
2703
                fname = next;
2704
            } else {
2705
                fname = NULL;
2706
                av_strlcpy(rt->app, next, APP_MAX_LENGTH);
2707
            }
2708
        } else {
2709
            // make sure we do not mismatch a playpath for an application instance
2710
            char *c = strchr(p + 1, ':');
2711
            fname = strchr(p + 1, '/');
2712
            if (!fname || (c && c < fname)) {
2713
                fname = p + 1;
2714
                av_strlcpy(rt->app, path + 1, FFMIN(p - path, APP_MAX_LENGTH));
2715
            } else {
2716
                fname++;
2717
                av_strlcpy(rt->app, path + 1, FFMIN(fname - path - 1, APP_MAX_LENGTH));
2718
            }
2719
        }
2720
    }
2721
 
2722
    if (old_app) {
2723
        // The name of application has been defined by the user, override it.
2724
        if (strlen(old_app) >= APP_MAX_LENGTH) {
2725
            ret = AVERROR(EINVAL);
2726
            goto fail;
2727
        }
2728
        av_free(rt->app);
2729
        rt->app = old_app;
2730
    }
2731
 
2732
    if (!rt->playpath) {
2733
        rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
2734
        if (!rt->playpath) {
2735
            ret = AVERROR(ENOMEM);
2736
            goto fail;
2737
        }
2738
 
2739
        if (fname) {
2740
            int len = strlen(fname);
2741
            if (!strchr(fname, ':') && len >= 4 &&
2742
                (!strcmp(fname + len - 4, ".f4v") ||
2743
                 !strcmp(fname + len - 4, ".mp4"))) {
2744
                memcpy(rt->playpath, "mp4:", 5);
2745
            } else {
2746
                if (len >= 4 && !strcmp(fname + len - 4, ".flv"))
2747
                    fname[len - 4] = '\0';
2748
                rt->playpath[0] = 0;
2749
            }
2750
            av_strlcat(rt->playpath, fname, PLAYPATH_MAX_LENGTH);
2751
        } else {
2752
            rt->playpath[0] = '\0';
2753
        }
2754
    }
2755
 
2756
    if (!rt->tcurl) {
2757
        rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
2758
        if (!rt->tcurl) {
2759
            ret = AVERROR(ENOMEM);
2760
            goto fail;
2761
        }
2762
        ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
2763
                    port, "/%s", rt->app);
2764
    }
2765
 
2766
    if (!rt->flashver) {
2767
        rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
2768
        if (!rt->flashver) {
2769
            ret = AVERROR(ENOMEM);
2770
            goto fail;
2771
        }
2772
        if (rt->is_input) {
2773
            snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
2774
                    RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
2775
                    RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
2776
        } else {
2777
            snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
2778
                    "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
2779
        }
2780
    }
2781
 
2782
    rt->client_report_size = 1048576;
2783
    rt->bytes_read = 0;
2784
    rt->has_audio = 0;
2785
    rt->has_video = 0;
2786
    rt->received_metadata = 0;
2787
    rt->last_bytes_read = 0;
2788
    rt->server_bw = 2500000;
2789
    rt->duration = 0;
2790
 
2791
    av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
2792
           proto, path, rt->app, rt->playpath);
2793
    if (!rt->listen) {
2794
        if ((ret = gen_connect(s, rt)) < 0)
2795
            goto fail;
2796
    } else {
2797
        if ((ret = read_connect(s, s->priv_data)) < 0)
2798
            goto fail;
2799
    }
2800
 
2801
    do {
2802
        ret = get_packet(s, 1);
2803
    } while (ret == AVERROR(EAGAIN));
2804
    if (ret < 0)
2805
        goto fail;
2806
 
2807
    if (rt->do_reconnect) {
2808
        int i;
2809
        ffurl_close(rt->stream);
2810
        rt->stream       = NULL;
2811
        rt->do_reconnect = 0;
2812
        rt->nb_invokes   = 0;
2813
        for (i = 0; i < 2; i++)
2814
            memset(rt->prev_pkt[i], 0,
2815
                   sizeof(**rt->prev_pkt) * rt->nb_prev_pkt[i]);
2816
        free_tracked_methods(rt);
2817
        goto reconnect;
2818
    }
2819
 
2820
    if (rt->is_input) {
2821
        // generate FLV header for demuxer
2822
        rt->flv_size = 13;
2823
        if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
2824
            goto fail;
2825
        rt->flv_off  = 0;
2826
        memcpy(rt->flv_data, "FLV\1\0\0\0\0\011\0\0\0\0", rt->flv_size);
2827
 
2828
        // Read packets until we reach the first A/V packet or read metadata.
2829
        // If there was a metadata package in front of the A/V packets, we can
2830
        // build the FLV header from this. If we do not receive any metadata,
2831
        // the FLV decoder will allocate the needed streams when their first
2832
        // audio or video packet arrives.
2833
        while (!rt->has_audio && !rt->has_video && !rt->received_metadata) {
2834
            if ((ret = get_packet(s, 0)) < 0)
2835
               goto fail;
2836
        }
2837
 
2838
        // Either after we have read the metadata or (if there is none) the
2839
        // first packet of an A/V stream, we have a better knowledge about the
2840
        // streams, so set the FLV header accordingly.
2841
        if (rt->has_audio) {
2842
            rt->flv_data[4] |= FLV_HEADER_FLAG_HASAUDIO;
2843
        }
2844
        if (rt->has_video) {
2845
            rt->flv_data[4] |= FLV_HEADER_FLAG_HASVIDEO;
2846
        }
2847
 
2848
        // If we received the first packet of an A/V stream and no metadata but
2849
        // the server returned a valid duration, create a fake metadata packet
2850
        // to inform the FLV decoder about the duration.
2851
        if (!rt->received_metadata && rt->duration > 0) {
2852
            if ((ret = inject_fake_duration_metadata(rt)) < 0)
2853
                goto fail;
2854
        }
2855
    } else {
2856
        rt->flv_size = 0;
2857
        rt->flv_data = NULL;
2858
        rt->flv_off  = 0;
2859
        rt->skip_bytes = 13;
2860
    }
2861
 
2862
    s->max_packet_size = rt->stream->max_packet_size;
2863
    s->is_streamed     = 1;
2864
    return 0;
2865
 
2866
fail:
2867
    av_dict_free(&opts);
2868
    rtmp_close(s);
2869
    return ret;
2870
}
2871
 
2872
static int rtmp_read(URLContext *s, uint8_t *buf, int size)
2873
{
2874
    RTMPContext *rt = s->priv_data;
2875
    int orig_size = size;
2876
    int ret;
2877
 
2878
    while (size > 0) {
2879
        int data_left = rt->flv_size - rt->flv_off;
2880
 
2881
        if (data_left >= size) {
2882
            memcpy(buf, rt->flv_data + rt->flv_off, size);
2883
            rt->flv_off += size;
2884
            return orig_size;
2885
        }
2886
        if (data_left > 0) {
2887
            memcpy(buf, rt->flv_data + rt->flv_off, data_left);
2888
            buf  += data_left;
2889
            size -= data_left;
2890
            rt->flv_off = rt->flv_size;
2891
            return data_left;
2892
        }
2893
        if ((ret = get_packet(s, 0)) < 0)
2894
           return ret;
2895
    }
2896
    return orig_size;
2897
}
2898
 
2899
static int64_t rtmp_seek(URLContext *s, int stream_index, int64_t timestamp,
2900
                         int flags)
2901
{
2902
    RTMPContext *rt = s->priv_data;
2903
    int ret;
2904
    av_log(s, AV_LOG_DEBUG,
2905
           "Seek on stream index %d at timestamp %"PRId64" with flags %08x\n",
2906
           stream_index, timestamp, flags);
2907
    if ((ret = gen_seek(s, rt, timestamp)) < 0) {
2908
        av_log(s, AV_LOG_ERROR,
2909
               "Unable to send seek command on stream index %d at timestamp "
2910
               "%"PRId64" with flags %08x\n",
2911
               stream_index, timestamp, flags);
2912
        return ret;
2913
    }
2914
    rt->flv_off = rt->flv_size;
2915
    rt->state = STATE_SEEKING;
2916
    return timestamp;
2917
}
2918
 
2919
static int rtmp_pause(URLContext *s, int pause)
2920
{
2921
    RTMPContext *rt = s->priv_data;
2922
    int ret;
2923
    av_log(s, AV_LOG_DEBUG, "Pause at timestamp %d\n",
2924
           rt->last_timestamp);
2925
    if ((ret = gen_pause(s, rt, pause, rt->last_timestamp)) < 0) {
2926
        av_log(s, AV_LOG_ERROR, "Unable to send pause command at timestamp %d\n",
2927
               rt->last_timestamp);
2928
        return ret;
2929
    }
2930
    return 0;
2931
}
2932
 
2933
static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
2934
{
2935
    RTMPContext *rt = s->priv_data;
2936
    int size_temp = size;
2937
    int pktsize, pkttype, copy;
2938
    uint32_t ts;
2939
    const uint8_t *buf_temp = buf;
2940
    uint8_t c;
2941
    int ret;
2942
 
2943
    do {
2944
        if (rt->skip_bytes) {
2945
            int skip = FFMIN(rt->skip_bytes, size_temp);
2946
            buf_temp       += skip;
2947
            size_temp      -= skip;
2948
            rt->skip_bytes -= skip;
2949
            continue;
2950
        }
2951
 
2952
        if (rt->flv_header_bytes < RTMP_HEADER) {
2953
            const uint8_t *header = rt->flv_header;
2954
            int channel = RTMP_AUDIO_CHANNEL;
2955
 
2956
            copy = FFMIN(RTMP_HEADER - rt->flv_header_bytes, size_temp);
2957
            bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
2958
            rt->flv_header_bytes += copy;
2959
            size_temp            -= copy;
2960
            if (rt->flv_header_bytes < RTMP_HEADER)
2961
                break;
2962
 
2963
            pkttype = bytestream_get_byte(&header);
2964
            pktsize = bytestream_get_be24(&header);
2965
            ts = bytestream_get_be24(&header);
2966
            ts |= bytestream_get_byte(&header) << 24;
2967
            bytestream_get_be24(&header);
2968
            rt->flv_size = pktsize;
2969
 
2970
            if (pkttype == RTMP_PT_VIDEO)
2971
                channel = RTMP_VIDEO_CHANNEL;
2972
 
2973
            if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
2974
                pkttype == RTMP_PT_NOTIFY) {
2975
                if ((ret = ff_rtmp_check_alloc_array(&rt->prev_pkt[1],
2976
                                                     &rt->nb_prev_pkt[1],
2977
                                                     channel)) < 0)
2978
                    return ret;
2979
                // Force sending a full 12 bytes header by clearing the
2980
                // channel id, to make it not match a potential earlier
2981
                // packet in the same channel.
2982
                rt->prev_pkt[1][channel].channel_id = 0;
2983
            }
2984
 
2985
            //this can be a big packet, it's better to send it right here
2986
            if ((ret = ff_rtmp_packet_create(&rt->out_pkt, channel,
2987
                                             pkttype, ts, pktsize)) < 0)
2988
                return ret;
2989
 
2990
            rt->out_pkt.extra = rt->stream_id;
2991
            rt->flv_data = rt->out_pkt.data;
2992
        }
2993
 
2994
        copy = FFMIN(rt->flv_size - rt->flv_off, size_temp);
2995
        bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, copy);
2996
        rt->flv_off += copy;
2997
        size_temp   -= copy;
2998
 
2999
        if (rt->flv_off == rt->flv_size) {
3000
            rt->skip_bytes = 4;
3001
 
3002
            if (rt->out_pkt.type == RTMP_PT_NOTIFY) {
3003
                // For onMetaData and |RtmpSampleAccess packets, we want
3004
                // @setDataFrame prepended to the packet before it gets sent.
3005
                // However, not all RTMP_PT_NOTIFY packets (e.g., onTextData
3006
                // and onCuePoint).
3007
                uint8_t commandbuffer[64];
3008
                int stringlen = 0;
3009
                GetByteContext gbc;
3010
 
3011
                bytestream2_init(&gbc, rt->flv_data, rt->flv_size);
3012
                if (!ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
3013
                                        &stringlen)) {
3014
                    if (!strcmp(commandbuffer, "onMetaData") ||
3015
                        !strcmp(commandbuffer, "|RtmpSampleAccess")) {
3016
                        uint8_t *ptr;
3017
                        if ((ret = av_reallocp(&rt->out_pkt.data, rt->out_pkt.size + 16)) < 0) {
3018
                            rt->flv_size = rt->flv_off = rt->flv_header_bytes = 0;
3019
                            return ret;
3020
                        }
3021
                        memmove(rt->out_pkt.data + 16, rt->out_pkt.data, rt->out_pkt.size);
3022
                        rt->out_pkt.size += 16;
3023
                        ptr = rt->out_pkt.data;
3024
                        ff_amf_write_string(&ptr, "@setDataFrame");
3025
                    }
3026
                }
3027
            }
3028
 
3029
            if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
3030
                return ret;
3031
            rt->flv_size = 0;
3032
            rt->flv_off = 0;
3033
            rt->flv_header_bytes = 0;
3034
            rt->flv_nb_packets++;
3035
        }
3036
    } while (buf_temp - buf < size);
3037
 
3038
    if (rt->flv_nb_packets < rt->flush_interval)
3039
        return size;
3040
    rt->flv_nb_packets = 0;
3041
 
3042
    /* set stream into nonblocking mode */
3043
    rt->stream->flags |= AVIO_FLAG_NONBLOCK;
3044
 
3045
    /* try to read one byte from the stream */
3046
    ret = ffurl_read(rt->stream, &c, 1);
3047
 
3048
    /* switch the stream back into blocking mode */
3049
    rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
3050
 
3051
    if (ret == AVERROR(EAGAIN)) {
3052
        /* no incoming data to handle */
3053
        return size;
3054
    } else if (ret < 0) {
3055
        return ret;
3056
    } else if (ret == 1) {
3057
        RTMPPacket rpkt = { 0 };
3058
 
3059
        if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
3060
                                                rt->in_chunk_size,
3061
                                                &rt->prev_pkt[0],
3062
                                                &rt->nb_prev_pkt[0], c)) <= 0)
3063
             return ret;
3064
 
3065
        if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
3066
            return ret;
3067
 
3068
        ff_rtmp_packet_destroy(&rpkt);
3069
    }
3070
 
3071
    return size;
3072
}
3073
 
3074
#define OFFSET(x) offsetof(RTMPContext, x)
3075
#define DEC AV_OPT_FLAG_DECODING_PARAM
3076
#define ENC AV_OPT_FLAG_ENCODING_PARAM
3077
 
3078
static const AVOption rtmp_options[] = {
3079
    {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3080
    {"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {.i64 = 3000}, 0, INT_MAX, DEC|ENC},
3081
    {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3082
    {"rtmp_flashver", "Version of the Flash plugin used to run the SWF player.", OFFSET(flashver), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3083
    {"rtmp_flush_interval", "Number of packets flushed in the same request (RTMPT only).", OFFSET(flush_interval), AV_OPT_TYPE_INT, {.i64 = 10}, 0, INT_MAX, ENC},
3084
    {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {.i64 = -2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
3085
    {"any", "both", 0, AV_OPT_TYPE_CONST, {.i64 = -2}, 0, 0, DEC, "rtmp_live"},
3086
    {"live", "live stream", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, DEC, "rtmp_live"},
3087
    {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, DEC, "rtmp_live"},
3088
    {"rtmp_pageurl", "URL of the web page in which the media was embedded. By default no value will be sent.", OFFSET(pageurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
3089
    {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3090
    {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
3091
    {"rtmp_swfhash", "SHA256 hash of the decompressed SWF file (32 bytes).", OFFSET(swfhash), AV_OPT_TYPE_BINARY, .flags = DEC},
3092
    {"rtmp_swfsize", "Size of the decompressed SWF file, required for SWFVerification.", OFFSET(swfsize), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC},
3093
    {"rtmp_swfurl", "URL of the SWF player. By default no value will be sent", OFFSET(swfurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3094
    {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically.", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
3095
    {"rtmp_tcurl", "URL of the target stream. Defaults to proto://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3096
    {"rtmp_listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
3097
    {"listen",      "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
3098
    {"timeout", "Maximum timeout (in seconds) to wait for incoming connections. -1 is infinite. Implies -rtmp_listen 1",  OFFSET(listen_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
3099
    { NULL },
3100
};
3101
 
3102
#define RTMP_PROTOCOL(flavor)                    \
3103
static const AVClass flavor##_class = {          \
3104
    .class_name = #flavor,                       \
3105
    .item_name  = av_default_item_name,          \
3106
    .option     = rtmp_options,                  \
3107
    .version    = LIBAVUTIL_VERSION_INT,         \
3108
};                                               \
3109
                                                 \
3110
URLProtocol ff_##flavor##_protocol = {           \
3111
    .name           = #flavor,                   \
3112
    .url_open       = rtmp_open,                 \
3113
    .url_read       = rtmp_read,                 \
3114
    .url_read_seek  = rtmp_seek,                 \
3115
    .url_read_pause = rtmp_pause,                \
3116
    .url_write      = rtmp_write,                \
3117
    .url_close      = rtmp_close,                \
3118
    .priv_data_size = sizeof(RTMPContext),       \
3119
    .flags          = URL_PROTOCOL_FLAG_NETWORK, \
3120
    .priv_data_class= &flavor##_class,           \
3121
};
3122
 
3123
 
3124
RTMP_PROTOCOL(rtmp)
3125
RTMP_PROTOCOL(rtmpe)
3126
RTMP_PROTOCOL(rtmps)
3127
RTMP_PROTOCOL(rtmpt)
3128
RTMP_PROTOCOL(rtmpte)
3129
RTMP_PROTOCOL(rtmpts)