mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 03:41:55 +00:00
fix #185, AMF0 support 0x0B the date type codec. 2.0.5.
This commit is contained in:
parent
05cce97140
commit
6a3418cd45
6 changed files with 220 additions and 4 deletions
|
@ -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
|
||||
|
|
Binary file not shown.
|
@ -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…
Reference in a new issue