static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *data_end) { int size; char buf[1024]; if (data >= data_end) return; switch (*data++) { case AMF_DATA_TYPE_NUMBER: av_log(ctx, AV_LOG_DEBUG, " number %g\n", av_int2double(AV_RB64(data))); return; case AMF_DATA_TYPE_BOOL: av_log(ctx, AV_LOG_DEBUG, " bool %d\n", *data); return; case AMF_DATA_TYPE_STRING: case AMF_DATA_TYPE_LONG_STRING: if (data[-1] == AMF_DATA_TYPE_STRING) { size = bytestream_get_be16(&data); } else { size = bytestream_get_be32(&data); } size = FFMIN(size, 1023); memcpy(buf, data, size); buf[size] = 0; av_log(ctx, AV_LOG_DEBUG, " string '%s'\n", buf); return; case AMF_DATA_TYPE_NULL: av_log(ctx, AV_LOG_DEBUG, " NULL\n"); return; case AMF_DATA_TYPE_ARRAY: data += 4; case AMF_DATA_TYPE_OBJECT: av_log(ctx, AV_LOG_DEBUG, " {\n"); for (;;) { int size = bytestream_get_be16(&data); int t; memcpy(buf, data, size); buf[size] = 0; if (!size) { av_log(ctx, AV_LOG_DEBUG, " }\n"); data++; break; } if (size < 0 || size >= data_end - data) return; data += size; av_log(ctx, AV_LOG_DEBUG, " %s: ", buf); ff_amf_tag_contents(ctx, data, data_end); t = ff_amf_tag_size(data, data_end); if (t < 0 || t >= data_end - data) return; data += t; } return; case AMF_DATA_TYPE_OBJECT_END: av_log(ctx, AV_LOG_DEBUG, " }\n"); return; default: return; } }