int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)

{

    const uint8_t *base = data;



    if (data >= data_end)

        return -1;

    switch (*data++) {

    case AMF_DATA_TYPE_NUMBER:      return 9;

    case AMF_DATA_TYPE_BOOL:        return 2;

    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_NULL:        return 1;

    case AMF_DATA_TYPE_ARRAY:

        data += 4;

    case AMF_DATA_TYPE_OBJECT:

        for (;;) {

            int size = bytestream_get_be16(&data);

            int t;

            if (!size) {

                data++;

                break;

            }

            if (data + size >= data_end || data + size < data)

                return -1;

            data += size;

            t = ff_amf_tag_size(data, data_end);

            if (t < 0 || data + t >= data_end)

                return -1;

            data += t;

        }

        return data - base;

    case AMF_DATA_TYPE_OBJECT_END:  return 1;

    default:                        return -1;

    }

}
