rtmppkt.c
Go to the documentation of this file.
1 /*
2  * RTMP input format
3  * Copyright (c) 2009 Kostya 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 #include "libavcodec/bytestream.h"
23 #include "libavutil/avstring.h"
24 #include "libavutil/intfloat.h"
25 #include "avformat.h"
26 
27 #include "rtmppkt.h"
28 #include "flv.h"
29 #include "url.h"
30 
32 {
33  bytestream_put_byte(dst, AMF_DATA_TYPE_BOOL);
34  bytestream_put_byte(dst, val);
35 }
36 
38 {
39  bytestream_put_byte(dst, AMF_DATA_TYPE_NUMBER);
40  bytestream_put_be64(dst, av_double2int(val));
41 }
42 
43 void ff_amf_write_string(uint8_t **dst, const char *str)
44 {
45  bytestream_put_byte(dst, AMF_DATA_TYPE_STRING);
46  bytestream_put_be16(dst, strlen(str));
47  bytestream_put_buffer(dst, str, strlen(str));
48 }
49 
50 void ff_amf_write_string2(uint8_t **dst, const char *str1, const char *str2)
51 {
52  int len1 = 0, len2 = 0;
53  if (str1)
54  len1 = strlen(str1);
55  if (str2)
56  len2 = strlen(str2);
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);
61 }
62 
64 {
65  bytestream_put_byte(dst, AMF_DATA_TYPE_NULL);
66 }
67 
69 {
70  bytestream_put_byte(dst, AMF_DATA_TYPE_OBJECT);
71 }
72 
73 void ff_amf_write_field_name(uint8_t **dst, const char *str)
74 {
75  bytestream_put_be16(dst, strlen(str));
76  bytestream_put_buffer(dst, str, strlen(str));
77 }
78 
80 {
81  /* first two bytes are field name length = 0,
82  * AMF object should end with it and end marker
83  */
84  bytestream_put_be24(dst, AMF_DATA_TYPE_OBJECT_END);
85 }
86 
88 {
89  if (bytestream2_get_byte(bc) != AMF_DATA_TYPE_BOOL)
90  return AVERROR_INVALIDDATA;
91  *val = bytestream2_get_byte(bc);
92  return 0;
93 }
94 
96 {
97  uint64_t read;
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);
102  return 0;
103 }
104 
106  int strsize, int *length)
107 {
108  int stringlen = 0;
109  int readsize;
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) {
118  "Unable to read as many bytes as AMF string signaled\n");
119  }
120  str[readsize] = '\0';
121  *length = FFMIN(stringlen, readsize);
122  return 0;
123 }
124 
126 {
127  if (bytestream2_get_byte(bc) != AMF_DATA_TYPE_NULL)
128  return AVERROR_INVALIDDATA;
129  return 0;
130 }
131 
133  int chunk_size, RTMPPacket *prev_pkt)
134 {
135  uint8_t hdr;
136 
137  if (ffurl_read(h, &hdr, 1) != 1)
138  return AVERROR(EIO);
139 
140  return ff_rtmp_packet_read_internal(h, p, chunk_size, prev_pkt, hdr);
141 }
142 
144  RTMPPacket *prev_pkt, uint8_t hdr)
145 {
146 
147  uint8_t t, buf[16];
148  int channel_id, timestamp, data_size, offset = 0;
149  uint32_t extra = 0;
150  enum RTMPPacketType type;
151  int size = 0;
152  int ret;
153 
154  size++;
155  channel_id = hdr & 0x3F;
156 
157  if (channel_id < 2) { //special case for channel number >= 64
158  buf[1] = 0;
159  if (ffurl_read_complete(h, buf, channel_id + 1) != channel_id + 1)
160  return AVERROR(EIO);
161  size += channel_id + 1;
162  channel_id = AV_RL16(buf) + 64;
163  }
164  data_size = prev_pkt[channel_id].data_size;
165  type = prev_pkt[channel_id].type;
166  extra = prev_pkt[channel_id].extra;
167 
168  hdr >>= 6;
169  if (hdr == RTMP_PS_ONEBYTE) {
170  timestamp = prev_pkt[channel_id].ts_delta;
171  } else {
172  if (ffurl_read_complete(h, buf, 3) != 3)
173  return AVERROR(EIO);
174  size += 3;
175  timestamp = AV_RB24(buf);
176  if (hdr != RTMP_PS_FOURBYTES) {
177  if (ffurl_read_complete(h, buf, 3) != 3)
178  return AVERROR(EIO);
179  size += 3;
180  data_size = AV_RB24(buf);
181  if (ffurl_read_complete(h, buf, 1) != 1)
182  return AVERROR(EIO);
183  size++;
184  type = buf[0];
185  if (hdr == RTMP_PS_TWELVEBYTES) {
186  if (ffurl_read_complete(h, buf, 4) != 4)
187  return AVERROR(EIO);
188  size += 4;
189  extra = AV_RL32(buf);
190  }
191  }
192  if (timestamp == 0xFFFFFF) {
193  if (ffurl_read_complete(h, buf, 4) != 4)
194  return AVERROR(EIO);
195  timestamp = AV_RB32(buf);
196  }
197  }
198  if (hdr != RTMP_PS_TWELVEBYTES)
199  timestamp += prev_pkt[channel_id].timestamp;
200 
201  if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp,
202  data_size)) < 0)
203  return ret;
204  p->extra = extra;
205  // save history
206  prev_pkt[channel_id].channel_id = channel_id;
207  prev_pkt[channel_id].type = type;
208  prev_pkt[channel_id].data_size = data_size;
209  prev_pkt[channel_id].ts_delta = timestamp - prev_pkt[channel_id].timestamp;
210  prev_pkt[channel_id].timestamp = timestamp;
211  prev_pkt[channel_id].extra = extra;
212  while (data_size > 0) {
213  int toread = FFMIN(data_size, chunk_size);
214  if (ffurl_read_complete(h, p->data + offset, toread) != toread) {
216  return AVERROR(EIO);
217  }
218  data_size -= chunk_size;
219  offset += chunk_size;
220  size += chunk_size;
221  if (data_size > 0) {
222  if ((ret = ffurl_read_complete(h, &t, 1)) < 0) { // marker
224  return ret;
225  }
226  size++;
227  if (t != (0xC0 + channel_id))
228  return -1;
229  }
230  }
231  return size;
232 }
233 
235  int chunk_size, RTMPPacket *prev_pkt)
236 {
237  uint8_t pkt_hdr[16], *p = pkt_hdr;
239  int off = 0;
240  int size = 0;
241  int ret;
242 
243  pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp;
244 
245  //if channel_id = 0, this is first presentation of prev_pkt, send full hdr.
246  if (prev_pkt[pkt->channel_id].channel_id &&
247  pkt->extra == prev_pkt[pkt->channel_id].extra) {
248  if (pkt->type == prev_pkt[pkt->channel_id].type &&
249  pkt->data_size == prev_pkt[pkt->channel_id].data_size) {
250  mode = RTMP_PS_FOURBYTES;
251  if (pkt->ts_delta == prev_pkt[pkt->channel_id].ts_delta)
252  mode = RTMP_PS_ONEBYTE;
253  } else {
254  mode = RTMP_PS_EIGHTBYTES;
255  }
256  }
257 
258  if (pkt->channel_id < 64) {
259  bytestream_put_byte(&p, pkt->channel_id | (mode << 6));
260  } else if (pkt->channel_id < 64 + 256) {
261  bytestream_put_byte(&p, 0 | (mode << 6));
262  bytestream_put_byte(&p, pkt->channel_id - 64);
263  } else {
264  bytestream_put_byte(&p, 1 | (mode << 6));
265  bytestream_put_le16(&p, pkt->channel_id - 64);
266  }
267  if (mode != RTMP_PS_ONEBYTE) {
268  uint32_t timestamp = pkt->timestamp;
269  if (mode != RTMP_PS_TWELVEBYTES)
270  timestamp = pkt->ts_delta;
271  bytestream_put_be24(&p, timestamp >= 0xFFFFFF ? 0xFFFFFF : timestamp);
272  if (mode != RTMP_PS_FOURBYTES) {
273  bytestream_put_be24(&p, pkt->data_size);
274  bytestream_put_byte(&p, pkt->type);
275  if (mode == RTMP_PS_TWELVEBYTES)
276  bytestream_put_le32(&p, pkt->extra);
277  }
278  if (timestamp >= 0xFFFFFF)
279  bytestream_put_be32(&p, timestamp);
280  }
281  // save history
282  prev_pkt[pkt->channel_id].channel_id = pkt->channel_id;
283  prev_pkt[pkt->channel_id].type = pkt->type;
284  prev_pkt[pkt->channel_id].data_size = pkt->data_size;
285  prev_pkt[pkt->channel_id].timestamp = pkt->timestamp;
286  if (mode != RTMP_PS_TWELVEBYTES) {
287  prev_pkt[pkt->channel_id].ts_delta = pkt->ts_delta;
288  } else {
289  prev_pkt[pkt->channel_id].ts_delta = pkt->timestamp;
290  }
291  prev_pkt[pkt->channel_id].extra = pkt->extra;
292 
293  if ((ret = ffurl_write(h, pkt_hdr, p - pkt_hdr)) < 0)
294  return ret;
295  size = p - pkt_hdr + pkt->data_size;
296  while (off < pkt->data_size) {
297  int towrite = FFMIN(chunk_size, pkt->data_size - off);
298  if ((ret = ffurl_write(h, pkt->data + off, towrite)) < 0)
299  return ret;
300  off += towrite;
301  if (off < pkt->data_size) {
302  uint8_t marker = 0xC0 | pkt->channel_id;
303  if ((ret = ffurl_write(h, &marker, 1)) < 0)
304  return ret;
305  size++;
306  }
307  }
308  return size;
309 }
310 
312  int timestamp, int size)
313 {
314  if (size) {
315  pkt->data = av_malloc(size);
316  if (!pkt->data)
317  return AVERROR(ENOMEM);
318  }
319  pkt->data_size = size;
320  pkt->channel_id = channel_id;
321  pkt->type = type;
322  pkt->timestamp = timestamp;
323  pkt->extra = 0;
324  pkt->ts_delta = 0;
325 
326  return 0;
327 }
328 
330 {
331  if (!pkt)
332  return;
333  av_freep(&pkt->data);
334  pkt->data_size = 0;
335 }
336 
337 int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
338 {
339  const uint8_t *base = data;
340 
341  if (data >= data_end)
342  return -1;
343  switch (*data++) {
344  case AMF_DATA_TYPE_NUMBER: return 9;
345  case AMF_DATA_TYPE_BOOL: return 2;
346  case AMF_DATA_TYPE_STRING: return 3 + AV_RB16(data);
347  case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data);
348  case AMF_DATA_TYPE_NULL: return 1;
349  case AMF_DATA_TYPE_ARRAY:
350  data += 4;
352  for (;;) {
353  int size = bytestream_get_be16(&data);
354  int t;
355  if (!size) {
356  data++;
357  break;
358  }
359  if (size < 0 || size >= data_end - data)
360  return -1;
361  data += size;
362  t = ff_amf_tag_size(data, data_end);
363  if (t < 0 || t >= data_end - data)
364  return -1;
365  data += t;
366  }
367  return data - base;
368  case AMF_DATA_TYPE_OBJECT_END: return 1;
369  default: return -1;
370  }
371 }
372 
373 int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end,
374  const uint8_t *name, uint8_t *dst, int dst_size)
375 {
376  int namelen = strlen(name);
377  int len;
378 
379  while (*data != AMF_DATA_TYPE_OBJECT && data < data_end) {
380  len = ff_amf_tag_size(data, data_end);
381  if (len < 0)
382  len = data_end - data;
383  data += len;
384  }
385  if (data_end - data < 3)
386  return -1;
387  data++;
388  for (;;) {
389  int size = bytestream_get_be16(&data);
390  if (!size)
391  break;
392  if (size < 0 || size >= data_end - data)
393  return -1;
394  data += size;
395  if (size == namelen && !memcmp(data-size, name, namelen)) {
396  switch (*data++) {
398  snprintf(dst, dst_size, "%g", av_int2double(AV_RB64(data)));
399  break;
400  case AMF_DATA_TYPE_BOOL:
401  snprintf(dst, dst_size, "%s", *data ? "true" : "false");
402  break;
404  len = bytestream_get_be16(&data);
405  av_strlcpy(dst, data, FFMIN(len+1, dst_size));
406  break;
407  default:
408  return -1;
409  }
410  return 0;
411  }
412  len = ff_amf_tag_size(data, data_end);
413  if (len < 0 || len >= data_end - data)
414  return -1;
415  data += len;
416  }
417  return -1;
418 }
419 
420 static const char* rtmp_packet_type(int type)
421 {
422  switch (type) {
423  case RTMP_PT_CHUNK_SIZE: return "chunk size";
424  case RTMP_PT_BYTES_READ: return "bytes read";
425  case RTMP_PT_PING: return "ping";
426  case RTMP_PT_SERVER_BW: return "server bandwidth";
427  case RTMP_PT_CLIENT_BW: return "client bandwidth";
428  case RTMP_PT_AUDIO: return "audio packet";
429  case RTMP_PT_VIDEO: return "video packet";
430  case RTMP_PT_FLEX_STREAM: return "Flex shared stream";
431  case RTMP_PT_FLEX_OBJECT: return "Flex shared object";
432  case RTMP_PT_FLEX_MESSAGE: return "Flex shared message";
433  case RTMP_PT_NOTIFY: return "notification";
434  case RTMP_PT_SHARED_OBJ: return "shared object";
435  case RTMP_PT_INVOKE: return "invoke";
436  case RTMP_PT_METADATA: return "metadata";
437  default: return "unknown";
438  }
439 }
440 
441 static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *data_end)
442 {
443  unsigned int size;
444  char buf[1024];
445 
446  if (data >= data_end)
447  return;
448  switch (*data++) {
450  av_log(ctx, AV_LOG_DEBUG, " number %g\n", av_int2double(AV_RB64(data)));
451  return;
452  case AMF_DATA_TYPE_BOOL:
453  av_log(ctx, AV_LOG_DEBUG, " bool %d\n", *data);
454  return;
457  if (data[-1] == AMF_DATA_TYPE_STRING) {
458  size = bytestream_get_be16(&data);
459  } else {
460  size = bytestream_get_be32(&data);
461  }
462  size = FFMIN(size, sizeof(buf) - 1);
463  memcpy(buf, data, size);
464  buf[size] = 0;
465  av_log(ctx, AV_LOG_DEBUG, " string '%s'\n", buf);
466  return;
467  case AMF_DATA_TYPE_NULL:
468  av_log(ctx, AV_LOG_DEBUG, " NULL\n");
469  return;
470  case AMF_DATA_TYPE_ARRAY:
471  data += 4;
473  av_log(ctx, AV_LOG_DEBUG, " {\n");
474  for (;;) {
475  int t;
476  size = bytestream_get_be16(&data);
477  av_strlcpy(buf, data, FFMIN(sizeof(buf), size + 1));
478  if (!size) {
479  av_log(ctx, AV_LOG_DEBUG, " }\n");
480  data++;
481  break;
482  }
483  if (size >= data_end - data)
484  return;
485  data += size;
486  av_log(ctx, AV_LOG_DEBUG, " %s: ", buf);
487  ff_amf_tag_contents(ctx, data, data_end);
488  t = ff_amf_tag_size(data, data_end);
489  if (t < 0 || t >= data_end - data)
490  return;
491  data += t;
492  }
493  return;
495  av_log(ctx, AV_LOG_DEBUG, " }\n");
496  return;
497  default:
498  return;
499  }
500 }
501 
502 void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p)
503 {
504  av_log(ctx, AV_LOG_DEBUG, "RTMP packet type '%s'(%d) for channel %d, timestamp %d, extra field %d size %d\n",
505  rtmp_packet_type(p->type), p->type, p->channel_id, p->timestamp, p->extra, p->data_size);
506  if (p->type == RTMP_PT_INVOKE || p->type == RTMP_PT_NOTIFY) {
507  uint8_t *src = p->data, *src_end = p->data + p->data_size;
508  while (src < src_end) {
509  int sz;
510  ff_amf_tag_contents(ctx, src, src_end);
511  sz = ff_amf_tag_size(src, src_end);
512  if (sz < 0)
513  break;
514  src += sz;
515  }
516  } else if (p->type == RTMP_PT_SERVER_BW){
517  av_log(ctx, AV_LOG_DEBUG, "Server BW = %d\n", AV_RB32(p->data));
518  } else if (p->type == RTMP_PT_CLIENT_BW){
519  av_log(ctx, AV_LOG_DEBUG, "Client BW = %d\n", AV_RB32(p->data));
520  } else if (p->type != RTMP_PT_AUDIO && p->type != RTMP_PT_VIDEO && p->type != RTMP_PT_METADATA) {
521  int i;
522  for (i = 0; i < p->data_size; i++)
523  av_log(ctx, AV_LOG_DEBUG, " %02X", p->data[i]);
524  av_log(ctx, AV_LOG_DEBUG, "\n");
525  }
526 }
const char * name
Definition: avisynth_c.h:675
video packet
Definition: rtmppkt.h:54
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int ff_amf_read_null(GetByteContext *bc)
Read AMF NULL value.
Definition: rtmppkt.c:125
client bandwidth
Definition: rtmppkt.h:52
#define AV_RB64
int data_size
packet payload size
Definition: rtmppkt.h:84
int ffurl_write(URLContext *h, const unsigned char *buf, int size)
Write size bytes from buf to the resource accessed by h.
Definition: avio.c:317
void ff_amf_write_field_name(uint8_t **dst, const char *str)
Write string used as field name in AMF object to buffer.
Definition: rtmppkt.c:73
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
#define AV_RB24
int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
Calculate number of bytes taken by first AMF entry in data.
Definition: rtmppkt.c:337
static av_always_inline uint64_t av_double2int(double f)
Reinterpret a double as a 64-bit integer.
Definition: intfloat.h:70
#define AV_RL16
int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p, int chunk_size, RTMPPacket *prev_pkt)
Read RTMP packet sent by the server.
Definition: rtmppkt.c:132
RTMPPacketType type
packet payload type
Definition: rtmppkt.h:79
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
ping
Definition: rtmppkt.h:50
static av_always_inline double av_int2double(uint64_t i)
Reinterpret a 64-bit integer as a double.
Definition: intfloat.h:60
uint8_t
mode
Definition: f_perms.c:27
static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *data_end)
Definition: rtmppkt.c:441
uint32_t extra
probably an additional channel ID used during streaming data
Definition: rtmppkt.h:82
#define AV_RB32
static AVPacket pkt
Definition: demuxing.c:56
uint32_t ts_delta
timestamp increment to the previous one in milliseconds (latter only for media packets) ...
Definition: rtmppkt.h:81
void ff_amf_write_string(uint8_t **dst, const char *str)
Write string in AMF format to buffer.
Definition: rtmppkt.c:43
void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p)
Print information and contents of RTMP packet.
Definition: rtmppkt.c:502
void ff_amf_write_object_end(uint8_t **dst)
Write marker for end of AMF object to buffer.
Definition: rtmppkt.c:79
void ff_amf_write_bool(uint8_t **dst, int val)
Write boolean value in AMF format to buffer.
Definition: rtmppkt.c:31
number of bytes read
Definition: rtmppkt.h:49
packet has 4-byte header
Definition: rtmppkt.h:70
#define AV_RB16
Spectrum Plot time data
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:258
audio packet
Definition: rtmppkt.h:53
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
static const uint8_t offset[127][2]
Definition: vf_spp.c:70
packet has 12-byte header
Definition: rtmppkt.h:68
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:82
int size
server bandwidth
Definition: rtmppkt.h:51
#define FFMIN(a, b)
Definition: common.h:58
void ff_rtmp_packet_destroy(RTMPPacket *pkt)
Free RTMP packet.
Definition: rtmppkt.c:329
ret
Definition: avfilter.c:821
RTMPPacketType
known RTMP packet types
Definition: rtmppkt.h:47
t
Definition: genspecsines3.m:6
int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end, const uint8_t *name, uint8_t *dst, int dst_size)
Retrieve value of given AMF object field in string form.
Definition: rtmppkt.c:373
#define AV_RL32
shared object
Definition: rtmppkt.h:59
Flex shared message.
Definition: rtmppkt.h:57
NULL
Definition: eval.c:55
chunk size change
Definition: rtmppkt.h:48
FLV common header.
int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt, int chunk_size, RTMPPacket *prev_pkt)
Send RTMP packet to the server.
Definition: rtmppkt.c:234
AVS_Value src
Definition: avisynth_c.h:523
void * buf
Definition: avisynth_c.h:594
Definition: url.h:41
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
synthesis window for stochastic i
int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type, int timestamp, int size)
Create new RTMP packet with given attributes.
Definition: rtmppkt.c:311
int ff_amf_read_number(GetByteContext *bc, double *val)
Read AMF number value.
Definition: rtmppkt.c:95
int channel_id
RTMP channel ID (nothing to do with audio/video channels though)
Definition: rtmppkt.h:78
packet has 8-byte header
Definition: rtmppkt.h:69
#define snprintf
Definition: snprintf.h:34
int ff_amf_read_bool(GetByteContext *bc, int *val)
Read AMF boolean value.
Definition: rtmppkt.c:87
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
#define type
some notification
Definition: rtmppkt.h:58
void ff_amf_write_null(uint8_t **dst)
Write AMF NULL value to buffer.
Definition: rtmppkt.c:63
uint32_t timestamp
packet full timestamp
Definition: rtmppkt.h:80
uint8_t * data
packet payload
Definition: rtmppkt.h:83
static const char * rtmp_packet_type(int type)
Definition: rtmppkt.c:420
Main libavformat public API header.
Flex shared stream.
Definition: rtmppkt.h:55
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
int ffurl_read_complete(URLContext *h, unsigned char *buf, int size)
Read as many bytes as possible (up to size), calling the read function multiple times if necessary...
Definition: avio.c:310
int ff_amf_read_string(GetByteContext *bc, uint8_t *str, int strsize, int *length)
Read AMF string value.
Definition: rtmppkt.c:105
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:337
int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size, RTMPPacket *prev_pkt, uint8_t hdr)
Read internal RTMP packet sent by the server.
Definition: rtmppkt.c:143
packet is really a next chunk of a packet
Definition: rtmppkt.h:71
void ff_amf_write_number(uint8_t **dst, double val)
Write number in AMF format to buffer.
Definition: rtmppkt.c:37
Flex shared object.
Definition: rtmppkt.h:56
int len
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
void ff_amf_write_object_start(uint8_t **dst)
Write marker for AMF object to buffer.
Definition: rtmppkt.c:68
structure for holding RTMP packets
Definition: rtmppkt.h:77
void ff_amf_write_string2(uint8_t **dst, const char *str1, const char *str2)
Write a string consisting of two parts in AMF format to a buffer.
Definition: rtmppkt.c:50
unbuffered private I/O API
invoke some stream action
Definition: rtmppkt.h:60
const char int length
Definition: avisynth_c.h:668
int ffurl_read(URLContext *h, unsigned char *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf...
Definition: avio.c:303
FLV metadata.
Definition: rtmppkt.h:61