mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
connect vhost/app packet decoded.
This commit is contained in:
parent
2886672347
commit
df400ef1c5
6 changed files with 324 additions and 59 deletions
|
@ -24,6 +24,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <srs_core_amf0.hpp>
|
#include <srs_core_amf0.hpp>
|
||||||
|
|
||||||
#include <srs_core_log.hpp>
|
#include <srs_core_log.hpp>
|
||||||
|
#include <srs_core_error.hpp>
|
||||||
#include <srs_core_stream.hpp>
|
#include <srs_core_stream.hpp>
|
||||||
|
|
||||||
// AMF0 marker
|
// AMF0 marker
|
||||||
|
@ -49,30 +50,34 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// origin array whos data takes the same form as LengthValueBytes
|
// origin array whos data takes the same form as LengthValueBytes
|
||||||
#define RTMP_AMF0_OriginStrictArray 0x20
|
#define RTMP_AMF0_OriginStrictArray 0x20
|
||||||
|
|
||||||
std::string srs_amf0_read_utf8(SrsStream* stream)
|
int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&);
|
||||||
|
|
||||||
|
int srs_amf0_read_utf8(SrsStream* stream, std::string& value)
|
||||||
{
|
{
|
||||||
std::string str;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// len
|
// len
|
||||||
if (!stream->require(2)) {
|
if (!stream->require(2)) {
|
||||||
srs_warn("amf0 read string length failed");
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
return str;
|
srs_error("amf0 read string length failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
int16_t len = stream->read_2bytes();
|
int16_t len = stream->read_2bytes();
|
||||||
srs_verbose("amf0 read string length success. len=%d", len);
|
srs_verbose("amf0 read string length success. len=%d", len);
|
||||||
|
|
||||||
// empty string
|
// empty string
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
srs_verbose("amf0 read empty string.");
|
srs_verbose("amf0 read empty string. ret=%d", ret);
|
||||||
return str;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// data
|
// data
|
||||||
if (!stream->require(len)) {
|
if (!stream->require(len)) {
|
||||||
srs_warn("amf0 read string data failed");
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
return str;
|
srs_error("amf0 read string data failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
str = stream->read_string(len);
|
std::string str = stream->read_string(len);
|
||||||
|
|
||||||
// support utf8-1 only
|
// support utf8-1 only
|
||||||
// 1.3.1 Strings and UTF-8
|
// 1.3.1 Strings and UTF-8
|
||||||
|
@ -80,54 +85,104 @@ std::string srs_amf0_read_utf8(SrsStream* stream)
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
char ch = *(str.data() + i);
|
char ch = *(str.data() + i);
|
||||||
if ((ch & 0x80) != 0) {
|
if ((ch & 0x80) != 0) {
|
||||||
srs_warn("only support utf8-1, 0x00-0x7F, actual is %#x", (int)ch);
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
return "";
|
srs_error("only support utf8-1, 0x00-0x7F, actual is %#x. ret=%d", (int)ch, ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value = str;
|
||||||
srs_verbose("amf0 read string data success. str=%s", str.c_str());
|
srs_verbose("amf0 read string data success. str=%s", str.c_str());
|
||||||
|
|
||||||
return str;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string srs_amf0_read_string(SrsStream* stream)
|
int srs_amf0_read_string(SrsStream* stream, std::string& value)
|
||||||
{
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// marker
|
// marker
|
||||||
if (!stream->require(1)) {
|
if (!stream->require(1)) {
|
||||||
srs_warn("amf0 read string marker failed");
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
return "";
|
srs_error("amf0 read string marker failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
char marker = stream->read_char();
|
char marker = stream->read_char();
|
||||||
if (marker != RTMP_AMF0_String) {
|
if (marker != RTMP_AMF0_String) {
|
||||||
srs_warn("amf0 check string marker failed. marker=%#x, required=%#x", marker, RTMP_AMF0_String);
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
return "";
|
srs_error("amf0 check string marker failed. "
|
||||||
|
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_String, ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
srs_verbose("amf0 read string marker success");
|
srs_verbose("amf0 read string marker success");
|
||||||
|
|
||||||
return srs_amf0_read_utf8(stream);
|
return srs_amf0_read_utf8(stream, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
double srs_amf0_read_number(SrsStream* stream)
|
int srs_amf0_read_boolean(SrsStream* stream, bool& value)
|
||||||
{
|
{
|
||||||
double value = 0;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// marker
|
// marker
|
||||||
if (!stream->require(1)) {
|
if (!stream->require(1)) {
|
||||||
srs_warn("amf0 read number marker failed");
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
return value;
|
srs_error("amf0 read bool marker failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char marker = stream->read_char();
|
||||||
|
if (marker != RTMP_AMF0_Boolean) {
|
||||||
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
|
srs_error("amf0 check bool marker failed. "
|
||||||
|
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Boolean, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_verbose("amf0 read bool marker success");
|
||||||
|
|
||||||
|
// value
|
||||||
|
if (!stream->require(1)) {
|
||||||
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
|
srs_error("amf0 read bool value failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream->read_char() == 0) {
|
||||||
|
value = false;
|
||||||
|
} else {
|
||||||
|
value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
srs_verbose("amf0 read bool value success. value=%d", value);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srs_amf0_read_number(SrsStream* stream, double& value)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// marker
|
||||||
|
if (!stream->require(1)) {
|
||||||
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
|
srs_error("amf0 read number marker failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
char marker = stream->read_char();
|
char marker = stream->read_char();
|
||||||
if (marker != RTMP_AMF0_Number) {
|
if (marker != RTMP_AMF0_Number) {
|
||||||
srs_warn("amf0 check number marker failed. marker=%#x, required=%#x", marker, RTMP_AMF0_Number);
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
return value;
|
srs_error("amf0 check number marker failed. "
|
||||||
|
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Number, ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
srs_verbose("amf0 read number marker success");
|
srs_verbose("amf0 read number marker success");
|
||||||
|
|
||||||
// value
|
// value
|
||||||
if (!stream->require(8)) {
|
if (!stream->require(8)) {
|
||||||
srs_warn("amf0 read number value failed");
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
return value;
|
srs_error("amf0 read number value failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t temp = stream->read_8bytes();
|
int64_t temp = stream->read_8bytes();
|
||||||
|
@ -135,13 +190,158 @@ double srs_amf0_read_number(SrsStream* stream)
|
||||||
|
|
||||||
srs_verbose("amf0 read number value success. value=%.2f", value);
|
srs_verbose("amf0 read number value success. value=%.2f", value);
|
||||||
|
|
||||||
return value;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsAmf0Object* srs_amf0_read_object(SrsStream* stream)
|
int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
|
||||||
{
|
{
|
||||||
SrsAmf0Object* value = NULL;
|
int ret = ERROR_SUCCESS;
|
||||||
return value;
|
|
||||||
|
// marker
|
||||||
|
if (!stream->require(1)) {
|
||||||
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
|
srs_error("amf0 read any marker failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char marker = stream->read_char();
|
||||||
|
srs_verbose("amf0 any marker success");
|
||||||
|
|
||||||
|
// backward the 1byte marker.
|
||||||
|
stream->skip(-1);
|
||||||
|
|
||||||
|
switch (marker) {
|
||||||
|
case RTMP_AMF0_String: {
|
||||||
|
std::string data;
|
||||||
|
if ((ret = srs_amf0_read_string(stream, data)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
value = new SrsAmf0String();
|
||||||
|
srs_amf0_convert<SrsAmf0String>(value)->value = data;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case RTMP_AMF0_Boolean: {
|
||||||
|
bool data;
|
||||||
|
if ((ret = srs_amf0_read_boolean(stream, data)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
value = new SrsAmf0Boolean();
|
||||||
|
srs_amf0_convert<SrsAmf0Boolean>(value)->value = data;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case RTMP_AMF0_Number: {
|
||||||
|
double data;
|
||||||
|
if ((ret = srs_amf0_read_number(stream, data)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
value = new SrsAmf0Number();
|
||||||
|
srs_amf0_convert<SrsAmf0Number>(value)->value = data;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case RTMP_AMF0_ObjectEnd: {
|
||||||
|
SrsAmf0ObjectEOF* p = NULL;
|
||||||
|
if ((ret = srs_amf0_read_object_eof(stream, p)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
value = p;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case RTMP_AMF0_Object: {
|
||||||
|
SrsAmf0Object* p = NULL;
|
||||||
|
if ((ret = srs_amf0_read_object(stream, p)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
value = p;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
value = new SrsAmf0Any();
|
||||||
|
value->marker = stream->read_char();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// marker
|
||||||
|
if (!stream->require(1)) {
|
||||||
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
|
srs_error("amf0 read object eof marker failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char marker = stream->read_char();
|
||||||
|
if (marker != RTMP_AMF0_ObjectEnd) {
|
||||||
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
|
srs_error("amf0 check object eof marker failed. "
|
||||||
|
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_ObjectEnd, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_verbose("amf0 read object eof marker success");
|
||||||
|
|
||||||
|
// value
|
||||||
|
value = new SrsAmf0ObjectEOF();
|
||||||
|
srs_verbose("amf0 read object eof marker success");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// marker
|
||||||
|
if (!stream->require(1)) {
|
||||||
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
|
srs_error("amf0 read object marker failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char marker = stream->read_char();
|
||||||
|
if (marker != RTMP_AMF0_Object) {
|
||||||
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
|
srs_error("amf0 check object marker failed. "
|
||||||
|
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_verbose("amf0 read object marker success");
|
||||||
|
|
||||||
|
// value
|
||||||
|
value = new SrsAmf0Object();
|
||||||
|
|
||||||
|
while (!stream->empty()) {
|
||||||
|
// property-name: utf8 string
|
||||||
|
std::string property_name;
|
||||||
|
if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("amf0 object read property name failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// property-value: any
|
||||||
|
SrsAmf0Any* property_value = NULL;
|
||||||
|
if ((ret = srs_amf0_read_any(stream, property_value)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("amf0 object read property_value failed. "
|
||||||
|
"name=%s, ret=%d", property_name.c_str(), ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AMF0 Object EOF.
|
||||||
|
if (property_name.empty() || !property_value || property_value->is_object_eof()) {
|
||||||
|
if (property_value) {
|
||||||
|
delete property_value;
|
||||||
|
}
|
||||||
|
srs_info("amf0 read object EOF.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add property
|
||||||
|
value->properties[property_name] = property_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsAmf0Any::SrsAmf0Any()
|
SrsAmf0Any::SrsAmf0Any()
|
||||||
|
@ -158,6 +358,11 @@ bool SrsAmf0Any::is_string()
|
||||||
return marker == RTMP_AMF0_String;
|
return marker == RTMP_AMF0_String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsAmf0Any::is_boolean()
|
||||||
|
{
|
||||||
|
return marker == RTMP_AMF0_Boolean;
|
||||||
|
}
|
||||||
|
|
||||||
bool SrsAmf0Any::is_number()
|
bool SrsAmf0Any::is_number()
|
||||||
{
|
{
|
||||||
return marker == RTMP_AMF0_Number;
|
return marker == RTMP_AMF0_Number;
|
||||||
|
@ -168,6 +373,11 @@ bool SrsAmf0Any::is_object()
|
||||||
return marker == RTMP_AMF0_Object;
|
return marker == RTMP_AMF0_Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsAmf0Any::is_object_eof()
|
||||||
|
{
|
||||||
|
return marker == RTMP_AMF0_ObjectEnd;
|
||||||
|
}
|
||||||
|
|
||||||
SrsAmf0String::SrsAmf0String()
|
SrsAmf0String::SrsAmf0String()
|
||||||
{
|
{
|
||||||
marker = RTMP_AMF0_String;
|
marker = RTMP_AMF0_String;
|
||||||
|
@ -177,6 +387,16 @@ SrsAmf0String::~SrsAmf0String()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsAmf0Boolean::SrsAmf0Boolean()
|
||||||
|
{
|
||||||
|
marker = RTMP_AMF0_Boolean;
|
||||||
|
value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsAmf0Boolean::~SrsAmf0Boolean()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
SrsAmf0Number::SrsAmf0Number()
|
SrsAmf0Number::SrsAmf0Number()
|
||||||
{
|
{
|
||||||
marker = RTMP_AMF0_Number;
|
marker = RTMP_AMF0_Number;
|
||||||
|
@ -185,12 +405,12 @@ SrsAmf0Number::SrsAmf0Number()
|
||||||
|
|
||||||
SrsAmf0Number::~SrsAmf0Number()
|
SrsAmf0Number::~SrsAmf0Number()
|
||||||
{
|
{
|
||||||
|
marker = RTMP_AMF0_ObjectEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsAmf0ObjectEOF::SrsAmf0ObjectEOF()
|
SrsAmf0ObjectEOF::SrsAmf0ObjectEOF()
|
||||||
{
|
{
|
||||||
utf8_empty = 0x00;
|
utf8_empty = 0x00;
|
||||||
object_end_marker = RTMP_AMF0_ObjectEnd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsAmf0ObjectEOF::~SrsAmf0ObjectEOF()
|
SrsAmf0ObjectEOF::~SrsAmf0ObjectEOF()
|
||||||
|
|
|
@ -43,25 +43,30 @@ class SrsAmf0Object;
|
||||||
* UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4
|
* UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4
|
||||||
* UTF8-1 = %x00-7F
|
* UTF8-1 = %x00-7F
|
||||||
* @remark only support UTF8-1 char.
|
* @remark only support UTF8-1 char.
|
||||||
* @return default value is empty string.
|
|
||||||
*/
|
*/
|
||||||
extern std::string srs_amf0_read_utf8(SrsStream* stream);
|
extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read amf0 string from stream.
|
* read amf0 string from stream.
|
||||||
* 2.4 String Type
|
* 2.4 String Type
|
||||||
* string-type = string-marker UTF-8
|
* string-type = string-marker UTF-8
|
||||||
* @return default value is empty string.
|
|
||||||
*/
|
*/
|
||||||
extern std::string srs_amf0_read_string(SrsStream* stream);
|
extern int srs_amf0_read_string(SrsStream* stream, std::string& value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read amf0 boolean from stream.
|
||||||
|
* 2.4 String Type
|
||||||
|
* boolean-type = boolean-marker U8
|
||||||
|
* 0 is false, <> 0 is true
|
||||||
|
*/
|
||||||
|
extern int srs_amf0_read_boolean(SrsStream* stream, bool& value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read amf0 number from stream.
|
* read amf0 number from stream.
|
||||||
* 2.2 Number Type
|
* 2.2 Number Type
|
||||||
* number-type = number-marker DOUBLE
|
* number-type = number-marker DOUBLE
|
||||||
* @return default value is 0.
|
|
||||||
*/
|
*/
|
||||||
extern double srs_amf0_read_number(SrsStream* stream);
|
extern int srs_amf0_read_number(SrsStream* stream, double& value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read amf0 object from stream.
|
* read amf0 object from stream.
|
||||||
|
@ -69,7 +74,7 @@ extern double srs_amf0_read_number(SrsStream* stream);
|
||||||
* anonymous-object-type = object-marker *(object-property)
|
* anonymous-object-type = object-marker *(object-property)
|
||||||
* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
|
* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
|
||||||
*/
|
*/
|
||||||
extern SrsAmf0Object* srs_amf0_read_object(SrsStream* stream);
|
extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* any amf0 value.
|
* any amf0 value.
|
||||||
|
@ -87,22 +92,10 @@ struct SrsAmf0Any
|
||||||
virtual ~SrsAmf0Any();
|
virtual ~SrsAmf0Any();
|
||||||
|
|
||||||
virtual bool is_string();
|
virtual bool is_string();
|
||||||
|
virtual bool is_boolean();
|
||||||
virtual bool is_number();
|
virtual bool is_number();
|
||||||
virtual bool is_object();
|
virtual bool is_object();
|
||||||
|
virtual bool is_object_eof();
|
||||||
/**
|
|
||||||
* convert the any to specified object.
|
|
||||||
* @return T*, the converted object. never NULL.
|
|
||||||
* @remark, user must ensure the current object type,
|
|
||||||
* or the covert will cause assert failed.
|
|
||||||
*/
|
|
||||||
template<class T>
|
|
||||||
T* convert()
|
|
||||||
{
|
|
||||||
T* p = dynamic_cast<T>(this);
|
|
||||||
srs_assert(p != NULL);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,6 +112,21 @@ struct SrsAmf0String : public SrsAmf0Any
|
||||||
virtual ~SrsAmf0String();
|
virtual ~SrsAmf0String();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read amf0 boolean from stream.
|
||||||
|
* 2.4 String Type
|
||||||
|
* boolean-type = boolean-marker U8
|
||||||
|
* 0 is false, <> 0 is true
|
||||||
|
* @return default value is false.
|
||||||
|
*/
|
||||||
|
struct SrsAmf0Boolean : public SrsAmf0Any
|
||||||
|
{
|
||||||
|
bool value;
|
||||||
|
|
||||||
|
SrsAmf0Boolean();
|
||||||
|
virtual ~SrsAmf0Boolean();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read amf0 number from stream.
|
* read amf0 number from stream.
|
||||||
* 2.2 Number Type
|
* 2.2 Number Type
|
||||||
|
@ -138,10 +146,9 @@ struct SrsAmf0Number : public SrsAmf0Any
|
||||||
* object-end-type = UTF-8-empty object-end-marker
|
* object-end-type = UTF-8-empty object-end-marker
|
||||||
* 0x00 0x00 0x09
|
* 0x00 0x00 0x09
|
||||||
*/
|
*/
|
||||||
struct SrsAmf0ObjectEOF
|
struct SrsAmf0ObjectEOF : public SrsAmf0Any
|
||||||
{
|
{
|
||||||
int16_t utf8_empty;
|
int16_t utf8_empty;
|
||||||
char object_end_marker;
|
|
||||||
|
|
||||||
SrsAmf0ObjectEOF();
|
SrsAmf0ObjectEOF();
|
||||||
virtual ~SrsAmf0ObjectEOF();
|
virtual ~SrsAmf0ObjectEOF();
|
||||||
|
@ -160,5 +167,19 @@ struct SrsAmf0Object : public SrsAmf0Any
|
||||||
SrsAmf0Object();
|
SrsAmf0Object();
|
||||||
virtual ~SrsAmf0Object();
|
virtual ~SrsAmf0Object();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert the any to specified object.
|
||||||
|
* @return T*, the converted object. never NULL.
|
||||||
|
* @remark, user must ensure the current object type,
|
||||||
|
* or the covert will cause assert failed.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
T* srs_amf0_convert(SrsAmf0Any* any)
|
||||||
|
{
|
||||||
|
T* p = dynamic_cast<T*>(any);
|
||||||
|
srs_assert(p != NULL);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -281,7 +281,11 @@ int SrsMessage::decode_packet()
|
||||||
}
|
}
|
||||||
srs_verbose("decode stream initialized success");
|
srs_verbose("decode stream initialized success");
|
||||||
|
|
||||||
std::string command = srs_amf0_read_string(stream);
|
std::string command;
|
||||||
|
if ((ret = srs_amf0_read_string(stream, command)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("decode AMF0 command name failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
srs_verbose("AMF0 command message, command_name=%s", command.c_str());
|
srs_verbose("AMF0 command message, command_name=%s", command.c_str());
|
||||||
|
|
||||||
stream->reset();
|
stream->reset();
|
||||||
|
@ -337,7 +341,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
command_name = srs_amf0_read_string(stream);
|
if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("amf0 decode connect command_name failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_CONNECT) {
|
if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_CONNECT) {
|
||||||
ret = ERROR_RTMP_AMF0_DECODE;
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
srs_error("amf0 decode connect command_name failed. "
|
srs_error("amf0 decode connect command_name failed. "
|
||||||
|
@ -345,7 +352,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction_id = srs_amf0_read_number(stream);
|
if ((ret = srs_amf0_read_number(stream, transaction_id)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("amf0 decode connect transaction_id failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
if (transaction_id != 1.0) {
|
if (transaction_id != 1.0) {
|
||||||
ret = ERROR_RTMP_AMF0_DECODE;
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
srs_error("amf0 decode connect transaction_id failed. "
|
srs_error("amf0 decode connect transaction_id failed. "
|
||||||
|
@ -353,7 +363,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
command_object = srs_amf0_read_object(stream);
|
if ((ret = srs_amf0_read_object(stream, command_object)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("amf0 decode connect command_object failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
if (command_object == NULL) {
|
if (command_object == NULL) {
|
||||||
ret = ERROR_RTMP_AMF0_DECODE;
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
srs_error("amf0 decode connect command_object failed. ret=%d", ret);
|
srs_error("amf0 decode connect command_object failed. ret=%d", ret);
|
||||||
|
|
|
@ -238,6 +238,7 @@ public:
|
||||||
|
|
||||||
*pmsg = msg;
|
*pmsg = msg;
|
||||||
*ppacket = pkt;
|
*ppacket = pkt;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -70,7 +70,12 @@ bool SrsStream::empty()
|
||||||
|
|
||||||
bool SrsStream::require(int required_size)
|
bool SrsStream::require(int required_size)
|
||||||
{
|
{
|
||||||
return !empty() && (required_size < bytes + size - p);
|
return !empty() && (required_size <= bytes + size - p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsStream::skip(int size)
|
||||||
|
{
|
||||||
|
p += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
char SrsStream::read_char()
|
char SrsStream::read_char()
|
||||||
|
|
|
@ -65,6 +65,11 @@ public:
|
||||||
* @return true if stream can read/write specified required_size bytes.
|
* @return true if stream can read/write specified required_size bytes.
|
||||||
*/
|
*/
|
||||||
virtual bool require(int required_size);
|
virtual bool require(int required_size);
|
||||||
|
/**
|
||||||
|
* to skip some size.
|
||||||
|
* @size can be any value. positive to forward; nagetive to backward.
|
||||||
|
*/
|
||||||
|
virtual void skip(int size);
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* get 1bytes char from stream.
|
* get 1bytes char from stream.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue