fix #185, AMF0 support 0x0B the date type codec. 2.0.5.

pull/133/head
winlin 10 years ago
parent 05cce97140
commit 6a3418cd45

@ -220,6 +220,7 @@ Supported operating systems and hardware:
* 2013-10-17, Created.<br/>
## History
* v2.0, 2014-10-25, fix [#185](https://github.com/winlinvip/simple-rtmp-server/issues/185), AMF0 support 0x0B the date type codec. 2.0.5.
* v2.0, 2014-10-24, fix [#186](https://github.com/winlinvip/simple-rtmp-server/issues/186), hotfix for bug #186, drop connect args when not object. 2.0.4.
* v2.0, 2014-10-24, rename wiki/xxx to wiki/v1_CN_xxx. 2.0.3.
* v2.0, 2014-10-19, fix [#184](https://github.com/winlinvip/simple-rtmp-server/issues/184), support AnnexB in RTMP body for HLS. 2.0.2

@ -377,7 +377,7 @@ package
this.media_conn.connect(null);
} else {
var tcUrl:String = this.user_url.substr(0, this.user_url.lastIndexOf("/"));
this.media_conn.connect(tcUrl);
this.media_conn.connect(tcUrl, new Date());
}
}

@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR "2"
#define VERSION_MINOR "0"
#define VERSION_REVISION "6"
#define VERSION_REVISION "7"
#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
// server info.
#define RTMP_SIG_SRS_KEY "SRS"

@ -109,6 +109,11 @@ bool SrsAmf0Any::is_strict_array()
return marker == RTMP_AMF0_StrictArray;
}
bool SrsAmf0Any::is_date()
{
return marker == RTMP_AMF0_Date;
}
bool SrsAmf0Any::is_complex_object()
{
return is_object() || is_object_eof() || is_ecma_array() || is_strict_array();
@ -142,6 +147,20 @@ double SrsAmf0Any::to_number()
return p->value;
}
int64_t SrsAmf0Any::to_date()
{
SrsAmf0Date* p = dynamic_cast<SrsAmf0Date*>(this);
srs_assert(p != NULL);
return p->date();
}
int16_t SrsAmf0Any::to_date_time_zone()
{
SrsAmf0Date* p = dynamic_cast<SrsAmf0Date*>(this);
srs_assert(p != NULL);
return p->time_zone();
}
SrsAmf0Object* SrsAmf0Any::to_object()
{
SrsAmf0Object* p = dynamic_cast<SrsAmf0Object*>(this);
@ -189,6 +208,9 @@ void __srs_amf0_do_print(SrsAmf0Any* any, stringstream& ss, int level)
ss << "Number " << std::fixed << any->to_number() << endl;
} else if (any->is_string()) {
ss << "String " << any->to_str() << endl;
} else if (any->is_date()) {
ss << "Date " << std::hex << any->to_date()
<< "/" << std::hex << any->to_date_time_zone() << endl;
} else if (any->is_null()) {
ss << "Null" << endl;
} else if (any->is_ecma_array()) {
@ -304,6 +326,11 @@ SrsAmf0StrictArray* SrsAmf0Any::strict_array()
return new SrsAmf0StrictArray();
}
SrsAmf0Any* SrsAmf0Any::date(int64_t value)
{
return new SrsAmf0Date(value);
}
int SrsAmf0Any::discovery(SrsStream* stream, SrsAmf0Any** ppvalue)
{
int ret = ERROR_SUCCESS;
@ -360,6 +387,10 @@ int SrsAmf0Any::discovery(SrsStream* stream, SrsAmf0Any** ppvalue)
*ppvalue = SrsAmf0Any::strict_array();
return ret;
}
case RTMP_AMF0_Date: {
*ppvalue = SrsAmf0Any::date();
return ret;
}
case RTMP_AMF0_Invalid:
default: {
ret = ERROR_RTMP_AMF0_INVALID;
@ -805,7 +836,7 @@ int SrsAmf0EcmaArray::read(SrsStream* stream)
if (marker != RTMP_AMF0_EcmaArray) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 check ecma_array marker failed. "
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_EcmaArray, ret);
return ret;
}
srs_verbose("amf0 read ecma_array marker success");
@ -1003,7 +1034,7 @@ int SrsAmf0StrictArray::read(SrsStream* stream)
if (marker != RTMP_AMF0_StrictArray) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 check strict_array marker failed. "
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_StrictArray, ret);
return ret;
}
srs_verbose("amf0 read strict_array marker success");
@ -1127,6 +1158,11 @@ int SrsAmf0Size::number()
return 1 + 8;
}
int SrsAmf0Size::date()
{
return 1 + 8 + 2;
}
int SrsAmf0Size::null()
{
return 1;
@ -1278,6 +1314,130 @@ SrsAmf0Any* SrsAmf0Number::copy()
return copy;
}
SrsAmf0Date::SrsAmf0Date(int64_t value)
{
marker = RTMP_AMF0_Date;
_date_value = value;
_time_zone = 0;
}
SrsAmf0Date::~SrsAmf0Date()
{
}
int SrsAmf0Date::total_size()
{
return SrsAmf0Size::date();
}
int SrsAmf0Date::read(SrsStream* stream)
{
int ret = ERROR_SUCCESS;
// marker
if (!stream->require(1)) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 read date marker failed. ret=%d", ret);
return ret;
}
char marker = stream->read_1bytes();
if (marker != RTMP_AMF0_Date) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 check date marker failed. "
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Date, ret);
return ret;
}
srs_verbose("amf0 read date marker success");
// date value
// An ActionScript Date is serialized as the number of milliseconds
// elapsed since the epoch of midnight on 1st Jan 1970 in the UTC
// time zone.
if (!stream->require(8)) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 read date failed. ret=%d", ret);
return ret;
}
_date_value = stream->read_8bytes();
srs_verbose("amf0 read date success. date=%"PRId64, _date_value);
// time zone
// While the design of this type reserves room for time zone offset
// information, it should not be filled in, nor used, as it is unconventional
// to change time zones when serializing dates on a network. It is suggested
// that the time zone be queried independently as needed.
if (!stream->require(2)) {
ret = ERROR_RTMP_AMF0_DECODE;
srs_error("amf0 read time zone failed. ret=%d", ret);
return ret;
}
_time_zone = stream->read_2bytes();
srs_verbose("amf0 read time zone success. zone=%d", _time_zone);
return ret;
}
int SrsAmf0Date::write(SrsStream* stream)
{
int ret = ERROR_SUCCESS;
// marker
if (!stream->require(1)) {
ret = ERROR_RTMP_AMF0_ENCODE;
srs_error("amf0 write date marker failed. ret=%d", ret);
return ret;
}
stream->write_1bytes(RTMP_AMF0_Date);
srs_verbose("amf0 write date marker success");
// date value
if (!stream->require(8)) {
ret = ERROR_RTMP_AMF0_ENCODE;
srs_error("amf0 write date failed. ret=%d", ret);
return ret;
}
stream->write_8bytes(_date_value);
srs_verbose("amf0 write date success. date=%"PRId64, _date_value);
// time zone
if (!stream->require(2)) {
ret = ERROR_RTMP_AMF0_ENCODE;
srs_error("amf0 write time zone failed. ret=%d", ret);
return ret;
}
stream->write_2bytes(_time_zone);
srs_verbose("amf0 write time zone success. date=%d", _time_zone);
srs_verbose("write date object success.");
return ret;
}
SrsAmf0Any* SrsAmf0Date::copy()
{
SrsAmf0Date* copy = new SrsAmf0Date(0);
copy->_date_value = _date_value;
copy->_time_zone = _time_zone;
return copy;
}
int64_t SrsAmf0Date::date()
{
return _date_value;
}
int16_t SrsAmf0Date::time_zone()
{
return _time_zone;
}
SrsAmf0Null::SrsAmf0Null()
{
marker = RTMP_AMF0_Null;

@ -43,6 +43,7 @@ namespace _srs_internal
{
class SrsUnSortedHashtable;
class SrsAmf0ObjectEOF;
class SrsAmf0Date;
}
/*
@ -185,6 +186,12 @@ public:
*/
virtual bool is_strict_array();
/**
* whether current instance is an AMF0 date.
* @return true if instance is an AMF0 date; otherwise, false.
* @remark, if true, use to_date() to get its value.
*/
virtual bool is_date();
/**
* whether current instance is an AMF0 object, object-EOF, ecma-array or strict-array.
*/
virtual bool is_complex_object();
@ -212,6 +219,12 @@ public:
*/
virtual double to_number();
/**
* convert instance to date,
* @remark assert is_date(), user must ensure the type then convert.
*/
virtual int64_t to_date();
virtual int16_t to_date_time_zone();
/**
* convert instance to amf0 object,
* @remark assert is_object(), user must ensure the type then convert.
*/
@ -274,6 +287,10 @@ public:
*/
static SrsAmf0Any* number(double value = 0.0);
/**
* create an AMF0 date instance
*/
static SrsAmf0Any* date(int64_t value = 0);
/**
* create an AMF0 null instance
*/
static SrsAmf0Any* null();
@ -532,6 +549,7 @@ public:
static int utf8(std::string value);
static int str(std::string value);
static int number();
static int date();
static int null();
static int undefined();
static int boolean();
@ -673,6 +691,43 @@ namespace _srs_internal
virtual SrsAmf0Any* copy();
};
/**
* 2.13 Date Type
* time-zone = S16 ; reserved, not supported should be set to 0x0000
* date-type = date-marker DOUBLE time-zone
* @see: https://github.com/winlinvip/simple-rtmp-server/issues/185
*/
class SrsAmf0Date : public SrsAmf0Any
{
private:
int64_t _date_value;
int16_t _time_zone;
private:
friend class SrsAmf0Any;
/**
* make amf0 date to private,
* use should never declare it, use SrsAmf0Any::date() to create it.
*/
SrsAmf0Date(int64_t value);
public:
virtual ~SrsAmf0Date();
// serialize/deserialize to/from stream.
public:
virtual int total_size();
virtual int read(SrsStream* stream);
virtual int write(SrsStream* stream);
virtual SrsAmf0Any* copy();
public:
/**
* get the date value.
*/
virtual int64_t date();
/**
* get the time_zone.
*/
virtual int16_t time_zone();
};
/**
* read amf0 null from stream.
* 2.7 null Type

Loading…
Cancel
Save