Commit f3a02f4b authored by Michael Niedermayer's avatar Michael Niedermayer

Merge commit '32a414f3'

* commit '32a414f3':
  rtmp: Support AMF_DATA_TYPE_MIXEDARRAY
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents 3cfd4df8 32a414f3
...@@ -370,28 +370,35 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt) ...@@ -370,28 +370,35 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt)
int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end) int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
{ {
const uint8_t *base = data; const uint8_t *base = data;
AMFDataType type;
unsigned nb = -1;
int parse_key = 1;
if (data >= data_end) if (data >= data_end)
return -1; return -1;
switch (*data++) { switch ((type = *data++)) {
case AMF_DATA_TYPE_NUMBER: return 9; case AMF_DATA_TYPE_NUMBER: return 9;
case AMF_DATA_TYPE_BOOL: return 2; case AMF_DATA_TYPE_BOOL: return 2;
case AMF_DATA_TYPE_STRING: return 3 + AV_RB16(data); case AMF_DATA_TYPE_STRING: return 3 + AV_RB16(data);
case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data); case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data);
case AMF_DATA_TYPE_NULL: return 1; case AMF_DATA_TYPE_NULL: return 1;
case AMF_DATA_TYPE_ARRAY: case AMF_DATA_TYPE_ARRAY:
data += 4; parse_key = 0;
case AMF_DATA_TYPE_MIXEDARRAY:
nb = bytestream_get_be32(&data);
case AMF_DATA_TYPE_OBJECT: case AMF_DATA_TYPE_OBJECT:
for (;;) { while (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY) {
int size = bytestream_get_be16(&data);
int t; int t;
if (!size) { if (parse_key) {
data++; int size = bytestream_get_be16(&data);
break; if (!size) {
data++;
break;
}
if (size < 0 || size >= data_end - data)
return -1;
data += size;
} }
if (size < 0 || size >= data_end - data)
return -1;
data += size;
t = ff_amf_tag_size(data, data_end); t = ff_amf_tag_size(data, data_end);
if (t < 0 || t >= data_end - data) if (t < 0 || t >= data_end - data)
return -1; return -1;
...@@ -474,12 +481,14 @@ static const char* rtmp_packet_type(int type) ...@@ -474,12 +481,14 @@ static const char* rtmp_packet_type(int type)
static void amf_tag_contents(void *ctx, const uint8_t *data, static void amf_tag_contents(void *ctx, const uint8_t *data,
const uint8_t *data_end) const uint8_t *data_end)
{ {
unsigned int size; unsigned int size, nb = -1;
char buf[1024]; char buf[1024];
AMFDataType type;
int parse_key = 1;
if (data >= data_end) if (data >= data_end)
return; return;
switch (*data++) { switch ((type = *data++)) {
case AMF_DATA_TYPE_NUMBER: case AMF_DATA_TYPE_NUMBER:
av_log(ctx, AV_LOG_DEBUG, " number %g\n", av_int2double(AV_RB64(data))); av_log(ctx, AV_LOG_DEBUG, " number %g\n", av_int2double(AV_RB64(data)));
return; return;
...@@ -488,7 +497,7 @@ static void amf_tag_contents(void *ctx, const uint8_t *data, ...@@ -488,7 +497,7 @@ static void amf_tag_contents(void *ctx, const uint8_t *data,
return; return;
case AMF_DATA_TYPE_STRING: case AMF_DATA_TYPE_STRING:
case AMF_DATA_TYPE_LONG_STRING: case AMF_DATA_TYPE_LONG_STRING:
if (data[-1] == AMF_DATA_TYPE_STRING) { if (type == AMF_DATA_TYPE_STRING) {
size = bytestream_get_be16(&data); size = bytestream_get_be16(&data);
} else { } else {
size = bytestream_get_be32(&data); size = bytestream_get_be32(&data);
...@@ -502,22 +511,28 @@ static void amf_tag_contents(void *ctx, const uint8_t *data, ...@@ -502,22 +511,28 @@ static void amf_tag_contents(void *ctx, const uint8_t *data,
av_log(ctx, AV_LOG_DEBUG, " NULL\n"); av_log(ctx, AV_LOG_DEBUG, " NULL\n");
return; return;
case AMF_DATA_TYPE_ARRAY: case AMF_DATA_TYPE_ARRAY:
data += 4; parse_key = 0;
case AMF_DATA_TYPE_MIXEDARRAY:
nb = bytestream_get_be32(&data);
case AMF_DATA_TYPE_OBJECT: case AMF_DATA_TYPE_OBJECT:
av_log(ctx, AV_LOG_DEBUG, " {\n"); av_log(ctx, AV_LOG_DEBUG, " {\n");
for (;;) { while (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY) {
int t; int t;
size = bytestream_get_be16(&data); if (parse_key) {
av_strlcpy(buf, data, FFMIN(sizeof(buf), size + 1)); size = bytestream_get_be16(&data);
if (!size) { size = FFMIN(size, sizeof(buf) - 1);
av_log(ctx, AV_LOG_DEBUG, " }\n"); if (!size) {
data++; av_log(ctx, AV_LOG_DEBUG, " }\n");
break; data++;
break;
}
memcpy(buf, data, size);
buf[size] = 0;
if (size >= data_end - data)
return;
data += size;
av_log(ctx, AV_LOG_DEBUG, " %s: ", buf);
} }
if (size >= data_end - data)
return;
data += size;
av_log(ctx, AV_LOG_DEBUG, " %s: ", buf);
amf_tag_contents(ctx, data, data_end); amf_tag_contents(ctx, data, data_end);
t = ff_amf_tag_size(data, data_end); t = ff_amf_tag_size(data, data_end);
if (t < 0 || t >= data_end - data) if (t < 0 || t >= data_end - data)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment