47
47
bytestream_put_buffer(dst, str, strlen(str));
50
void ff_amf_write_string2(uint8_t **dst, const char *str1, const char *str2)
52
int len1 = 0, len2 = 0;
57
bytestream_put_byte(dst, AMF_DATA_TYPE_STRING);
58
bytestream_put_be16(dst, len1 + len2);
59
bytestream_put_buffer(dst, str1, len1);
60
bytestream_put_buffer(dst, str2, len2);
50
63
void ff_amf_write_null(uint8_t **dst)
52
65
bytestream_put_byte(dst, AMF_DATA_TYPE_NULL);
71
84
bytestream_put_be24(dst, AMF_DATA_TYPE_OBJECT_END);
87
int ff_amf_read_bool(GetByteContext *bc, int *val)
89
if (bytestream2_get_byte(bc) != AMF_DATA_TYPE_BOOL)
90
return AVERROR_INVALIDDATA;
91
*val = bytestream2_get_byte(bc);
95
int ff_amf_read_number(GetByteContext *bc, double *val)
98
if (bytestream2_get_byte(bc) != AMF_DATA_TYPE_NUMBER)
99
return AVERROR_INVALIDDATA;
100
read = bytestream2_get_be64(bc);
101
*val = av_int2double(read);
105
int ff_amf_read_string(GetByteContext *bc, uint8_t *str,
106
int strsize, int *length)
110
if (bytestream2_get_byte(bc) != AMF_DATA_TYPE_STRING)
111
return AVERROR_INVALIDDATA;
112
stringlen = bytestream2_get_be16(bc);
113
if (stringlen + 1 > strsize)
114
return AVERROR(EINVAL);
115
readsize = bytestream2_get_buffer(bc, str, stringlen);
116
if (readsize != stringlen) {
117
av_log(NULL, AV_LOG_WARNING,
118
"Unable to read as many bytes as AMF string signaled\n");
120
str[readsize] = '\0';
121
*length = FFMIN(stringlen, readsize);
125
int ff_amf_read_null(GetByteContext *bc)
127
if (bytestream2_get_byte(bc) != AMF_DATA_TYPE_NULL)
128
return AVERROR_INVALIDDATA;
74
132
int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
75
133
int chunk_size, RTMPPacket *prev_pkt)
77
uint8_t hdr, t, buf[16];
78
int channel_id, timestamp, data_size, offset = 0;
137
if (ffurl_read(h, &hdr, 1) != 1)
140
return ff_rtmp_packet_read_internal(h, p, chunk_size, prev_pkt, hdr);
143
int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
144
RTMPPacket *prev_pkt, uint8_t hdr)
148
int channel_id, timestamp, size, offset = 0;
79
149
uint32_t extra = 0;
80
150
enum RTMPPacketType type;
83
if (ffurl_read(h, &hdr, 1) != 1)
86
155
channel_id = hdr & 0x3F;
88
157
if (channel_id < 2) { //special case for channel number >= 64
90
159
if (ffurl_read_complete(h, buf, channel_id + 1) != channel_id + 1)
91
160
return AVERROR(EIO);
92
size += channel_id + 1;
161
written += channel_id + 1;
93
162
channel_id = AV_RL16(buf) + 64;
95
data_size = prev_pkt[channel_id].data_size;
96
type = prev_pkt[channel_id].type;
97
extra = prev_pkt[channel_id].extra;
164
size = prev_pkt[channel_id].size;
165
type = prev_pkt[channel_id].type;
166
extra = prev_pkt[channel_id].extra;
100
169
if (hdr == RTMP_PS_ONEBYTE) {
103
172
if (ffurl_read_complete(h, buf, 3) != 3)
104
173
return AVERROR(EIO);
106
175
timestamp = AV_RB24(buf);
107
176
if (hdr != RTMP_PS_FOURBYTES) {
108
177
if (ffurl_read_complete(h, buf, 3) != 3)
109
178
return AVERROR(EIO);
111
data_size = AV_RB24(buf);
112
181
if (ffurl_read_complete(h, buf, 1) != 1)
113
182
return AVERROR(EIO);
116
185
if (hdr == RTMP_PS_TWELVEBYTES) {
117
186
if (ffurl_read_complete(h, buf, 4) != 4)
118
187
return AVERROR(EIO);
120
189
extra = AV_RL32(buf);
129
198
if (hdr != RTMP_PS_TWELVEBYTES)
130
199
timestamp += prev_pkt[channel_id].timestamp;
132
if (ff_rtmp_packet_create(p, channel_id, type, timestamp, data_size))
201
if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp,
134
204
p->extra = extra;
136
206
prev_pkt[channel_id].channel_id = channel_id;
137
207
prev_pkt[channel_id].type = type;
138
prev_pkt[channel_id].data_size = data_size;
208
prev_pkt[channel_id].size = size;
139
209
prev_pkt[channel_id].ts_delta = timestamp - prev_pkt[channel_id].timestamp;
140
210
prev_pkt[channel_id].timestamp = timestamp;
141
211
prev_pkt[channel_id].extra = extra;
142
while (data_size > 0) {
143
int toread = FFMIN(data_size, chunk_size);
213
int toread = FFMIN(size, chunk_size);
144
214
if (ffurl_read_complete(h, p->data + offset, toread) != toread) {
145
215
ff_rtmp_packet_destroy(p);
146
216
return AVERROR(EIO);
148
data_size -= chunk_size;
149
offset += chunk_size;
152
ffurl_read_complete(h, &t, 1); //marker
219
offset += chunk_size;
220
written += chunk_size;
222
if ((ret = ffurl_read_complete(h, &t, 1)) < 0) { // marker
223
ff_rtmp_packet_destroy(p);
154
227
if (t != (0xC0 + channel_id))
161
234
int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
196
270
timestamp = pkt->ts_delta;
197
271
bytestream_put_be24(&p, timestamp >= 0xFFFFFF ? 0xFFFFFF : timestamp);
198
272
if (mode != RTMP_PS_FOURBYTES) {
199
bytestream_put_be24(&p, pkt->data_size);
273
bytestream_put_be24(&p, pkt->size);
200
274
bytestream_put_byte(&p, pkt->type);
201
275
if (mode == RTMP_PS_TWELVEBYTES)
202
276
bytestream_put_le32(&p, pkt->extra);
217
291
prev_pkt[pkt->channel_id].extra = pkt->extra;
219
ffurl_write(h, pkt_hdr, p-pkt_hdr);
220
size = p - pkt_hdr + pkt->data_size;
221
while (off < pkt->data_size) {
222
int towrite = FFMIN(chunk_size, pkt->data_size - off);
223
ffurl_write(h, pkt->data + off, towrite);
293
if ((ret = ffurl_write(h, pkt_hdr, p - pkt_hdr)) < 0)
295
written = p - pkt_hdr + pkt->size;
296
while (off < pkt->size) {
297
int towrite = FFMIN(chunk_size, pkt->size - off);
298
if ((ret = ffurl_write(h, pkt->data + off, towrite)) < 0)
225
if (off < pkt->data_size) {
301
if (off < pkt->size) {
226
302
uint8_t marker = 0xC0 | pkt->channel_id;
227
ffurl_write(h, &marker, 1);
303
if ((ret = ffurl_write(h, &marker, 1)) < 0)
234
311
int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type,
426
503
void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p)
428
505
av_log(ctx, AV_LOG_DEBUG, "RTMP packet type '%s'(%d) for channel %d, timestamp %d, extra field %d size %d\n",
429
rtmp_packet_type(p->type), p->type, p->channel_id, p->timestamp, p->extra, p->data_size);
506
rtmp_packet_type(p->type), p->type, p->channel_id, p->timestamp, p->extra, p->size);
430
507
if (p->type == RTMP_PT_INVOKE || p->type == RTMP_PT_NOTIFY) {
431
uint8_t *src = p->data, *src_end = p->data + p->data_size;
508
uint8_t *src = p->data, *src_end = p->data + p->size;
432
509
while (src < src_end) {
434
511
ff_amf_tag_contents(ctx, src, src_end);
443
520
av_log(ctx, AV_LOG_DEBUG, "Client BW = %d\n", AV_RB32(p->data));
444
521
} else if (p->type != RTMP_PT_AUDIO && p->type != RTMP_PT_VIDEO && p->type != RTMP_PT_METADATA) {
446
for (i = 0; i < p->data_size; i++)
523
for (i = 0; i < p->size; i++)
447
524
av_log(ctx, AV_LOG_DEBUG, " %02X", p->data[i]);
448
525
av_log(ctx, AV_LOG_DEBUG, "\n");
529
int ff_amf_match_string(const uint8_t *data, int size, const char *str)
531
int len = strlen(str);
539
if (type != AMF_DATA_TYPE_LONG_STRING &&
540
type != AMF_DATA_TYPE_STRING)
543
if (type == AMF_DATA_TYPE_LONG_STRING) {
544
if ((size -= 4 + 1) < 0)
546
amf_len = bytestream_get_be32(&data);
548
if ((size -= 2 + 1) < 0)
550
amf_len = bytestream_get_be16(&data);
559
return !memcmp(data, str, len);