34 bytestream_put_byte(dst, val);
46 bytestream_put_be16(dst, strlen(str));
52 int len1 = 0, len2 = 0;
58 bytestream_put_be16(dst, len1 + len2);
75 bytestream_put_be16(dst, strlen(str));
92 read = bytestream2_get_be64(bc);
102 stringlen = bytestream2_get_be16(bc);
103 if (stringlen + 1 > strsize)
106 if (readsize != stringlen) {
108 "Unable to read as many bytes as AMF string signaled\n");
110 str[readsize] =
'\0';
111 *length =
FFMIN(stringlen, readsize);
135 if (channel < *nb_prev_pkt)
138 nb_alloc = channel + 16;
145 memset(ptr + *nb_prev_pkt, 0, (nb_alloc - *nb_prev_pkt) *
sizeof(*ptr));
147 *nb_prev_pkt = nb_alloc;
152 int chunk_size,
RTMPPacket **prev_pkt,
int *nb_prev_pkt)
169 int channel_id, timestamp,
size;
178 channel_id = hdr & 0x3F;
180 if (channel_id < 2) {
184 written += channel_id + 1;
185 channel_id =
AV_RL16(buf) + 64;
190 prev_pkt = *prev_pkt_ptr;
191 size = prev_pkt[channel_id].
size;
192 type = prev_pkt[channel_id].
type;
193 extra = prev_pkt[channel_id].
extra;
197 ts_field = prev_pkt[channel_id].
ts_field;
220 if (ts_field == 0xFFFFFF) {
225 timestamp = ts_field;
228 timestamp += prev_pkt[channel_id].
timestamp;
230 if (prev_pkt[channel_id].read && size != prev_pkt[channel_id].size) {
232 size, prev_pkt[channel_id].size);
234 prev_pkt[channel_id].
read = 0;
238 if (!prev_pkt[channel_id].read) {
244 prev_pkt[channel_id].
ts_field = ts_field;
245 prev_pkt[channel_id].
timestamp = timestamp;
265 prev_pkt[channel_id].
extra = extra;
268 toread =
FFMIN(size, chunk_size);
286 prev_pkt[channel_id].
read = 0;
297 if (ret > 0 || ret !=
AVERROR(EAGAIN))
309 uint8_t pkt_hdr[16], *p = pkt_hdr;
321 prev_pkt = *prev_pkt_ptr;
332 if (timestamp >= 0xFFFFFF) {
350 bytestream_put_byte(&p, pkt->
channel_id | (mode << 6));
352 bytestream_put_byte(&p, 0 | (mode << 6));
353 bytestream_put_byte(&p, pkt->
channel_id - 64);
355 bytestream_put_byte(&p, 1 | (mode << 6));
356 bytestream_put_le16(&p, pkt->
channel_id - 64);
359 bytestream_put_be24(&p, pkt->
ts_field);
361 bytestream_put_be24(&p, pkt->
size);
362 bytestream_put_byte(&p, pkt->
type);
364 bytestream_put_le32(&p, pkt->
extra);
368 bytestream_put_be32(&p, timestamp);
377 if ((ret =
ffurl_write(h, pkt_hdr, p - pkt_hdr)) < 0)
379 written = p - pkt_hdr + pkt->
size;
380 while (off < pkt->
size) {
381 int towrite =
FFMIN(chunk_size, pkt->
size - off);
385 if (off < pkt->size) {
403 int timestamp,
int size)
437 type = bytestream2_get_byte(gb);
440 bytestream2_get_be64(gb);
443 bytestream2_get_byte(gb);
459 nb = bytestream2_get_be32(gb);
464 int size = bytestream2_get_be16(gb);
466 bytestream2_get_byte(gb);
488 if (data >= data_end)
503 int namelen = strlen(name);
513 bytestream2_get_byte(gb);
516 int size = bytestream2_get_be16(gb);
522 if (size == namelen && !memcmp(gb->
buffer-size, name, namelen)) {
523 switch (bytestream2_get_byte(gb)) {
528 snprintf(dst, dst_size,
"%s", bytestream2_get_byte(gb) ?
"true" :
"false");
531 len = bytestream2_get_be16(gb);
534 if (dst_size < len + 1)
556 if (data >= data_end)
565 static const char* rtmp_packet_type(
int type)
582 default:
return "unknown";
589 unsigned int size, nb = -1;
594 if (
data >= data_end)
596 switch ((type = *
data++)) {
606 size = bytestream_get_be16(&
data);
608 size = bytestream_get_be32(&
data);
610 size =
FFMIN(size,
sizeof(buf) - 1);
611 memcpy(buf,
data, size);
621 nb = bytestream_get_be32(&
data);
627 size = bytestream_get_be16(&
data);
628 size =
FFMIN(size,
sizeof(buf) - 1);
634 memcpy(buf,
data, size);
636 if (size >= data_end -
data)
641 amf_tag_contents(
ctx,
data, data_end);
643 if (t < 0 || t >= data_end -
data)
658 av_log(
ctx,
AV_LOG_DEBUG,
"RTMP packet type '%s'(%d) for channel %d, timestamp %d, extra field %d size %d\n",
662 while (src < src_end) {
664 amf_tag_contents(
ctx, src, src_end);
676 for (i = 0; i < p->
size; i++)
685 int len = strlen(str);
698 if ((size -= 4 + 1) < 0)
700 amf_len = bytestream_get_be32(&data);
702 if ((size -= 2 + 1) < 0)
704 amf_len = bytestream_get_be16(&data);
713 return !memcmp(data, str, len);
int ff_amf_match_string(const uint8_t *data, int size, const char *str)
Match AMF string with a NULL-terminated string.
int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size, RTMPPacket **prev_pkt, int *nb_prev_pkt, uint8_t hdr)
Read internal RTMP packet sent by the server.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
int ff_amf_read_null(GetByteContext *bc)
Read AMF NULL value.
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
ptrdiff_t const GLvoid * data
int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p, int chunk_size, RTMPPacket **prev_pkt, int *nb_prev_pkt)
Read RTMP packet sent by the server.
#define AV_LOG_WARNING
Something somehow does not look correct.
int ffurl_write(URLContext *h, const unsigned char *buf, int size)
Write size bytes from buf to the resource accessed by h.
void ff_amf_write_field_name(uint8_t **dst, const char *str)
Write string used as field name in AMF object to buffer.
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.
static av_always_inline uint64_t av_double2int(double f)
Reinterpret a double as a 64-bit integer.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
RTMPPacketType type
packet payload type
#define av_assert0(cond)
assert() equivalent, that is always enabled.
static av_always_inline double av_int2double(uint64_t i)
Reinterpret a 64-bit integer as a double.
int read
amount read, including headers
uint32_t extra
probably an additional channel ID used during streaming data
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
void ff_amf_write_string(uint8_t **dst, const char *str)
Write string in AMF format to buffer.
void ff_amf_write_object_end(uint8_t **dst)
Write marker for end of AMF object to buffer.
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
int size
packet payload size
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
void ff_amf_write_bool(uint8_t **dst, int val)
Write boolean value in AMF format to buffer.
static int parse_key(DBEContext *s)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
int ff_amf_get_string(GetByteContext *bc, uint8_t *str, int strsize, int *length)
Get AMF string value.
packet has 12-byte header
static int amf_get_field_value2(GetByteContext *gb, const uint8_t *name, uint8_t *dst, int dst_size)
static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p, int chunk_size, RTMPPacket **prev_pkt_ptr, int *nb_prev_pkt, uint8_t hdr)
void ff_rtmp_packet_destroy(RTMPPacket *pkt)
Free RTMP packet.
RTMPPacketType
known RTMP packet types
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.
static int amf_tag_skip(GetByteContext *gb)
int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt, int chunk_size, RTMPPacket **prev_pkt_ptr, int *nb_prev_pkt)
Send RTMP packet to the server.
static av_always_inline int bytestream2_tell(GetByteContext *g)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
uint32_t ts_field
24-bit timestamp or increment to the previous one, in milliseconds (latter only for media packets)...
void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p)
Print information and contents of RTMP packet.
int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type, int timestamp, int size)
Create new RTMP packet with given attributes.
int ff_amf_read_number(GetByteContext *bc, double *val)
Read AMF number value.
int channel_id
RTMP channel ID (nothing to do with audio/video channels though)
void ff_amf_write_null(uint8_t **dst)
Write AMF NULL value to buffer.
uint32_t timestamp
packet full timestamp
uint8_t * data
packet payload
int offset
amount of data read so far
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
channel
Use these values when setting the channel map with ebur128_set_channel().
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...
int ff_rtmp_check_alloc_array(RTMPPacket **prev_pkt, int *nb_prev_pkt, int channel)
Enlarge the prev_pkt array to fit the given channel.
int ff_amf_read_string(GetByteContext *bc, uint8_t *str, int strsize, int *length)
Read AMF string value.
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
packet is really a next chunk of a packet
void ff_amf_write_number(uint8_t **dst, double val)
Write number in AMF format to buffer.
void ff_amf_write_object_start(uint8_t **dst)
Write marker for AMF object to buffer.
structure for holding RTMP packets
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.
unbuffered private I/O API
invoke some stream action
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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.Frame references ownership and permissions
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
static double val(void *priv, double ch)
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...
mode
Use these values in ebur128_init (or'ed).
window acknowledgement size