mirror of
https://github.com/ossrs/srs.git
synced 2025-02-14 12:21:55 +00:00
support flv inject and flv http streaming with start=bytes. 0.9.122
This commit is contained in:
parent
d56f445076
commit
7ec202ee41
10 changed files with 241 additions and 29 deletions
|
@ -231,6 +231,7 @@ Supported operating systems and hardware:
|
|||
* 2013-10-17, Created.<br/>
|
||||
|
||||
## History
|
||||
* v1.0, 2014-05-29, support flv inject and flv http streaming with start=bytes. 0.9.122
|
||||
* <strong>v1.0, 2014-05-28, [1.0 mainline4(0.9.120)](https://github.com/winlinvip/simple-rtmp-server/releases/tag/1.0.mainline4) released. 39200 lines.</strong>
|
||||
* v1.0, 2014-05-27, fix [#87](https://github.com/winlinvip/simple-rtmp-server/issues/87), add source id for full trackable log. 0.9.120
|
||||
* v1.0, 2014-05-27, fix [#84](https://github.com/winlinvip/simple-rtmp-server/issues/84), unpublish when edge disconnect. 0.9.119
|
||||
|
|
|
@ -38,7 +38,6 @@ gcc srs_flv_injecter.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_flv_i
|
|||
#define ERROR_INJECTED 10000
|
||||
|
||||
int process(const char* in_flv_file, const char* out_flv_file, srs_flv_t* pic, srs_flv_t* poc);
|
||||
int inject_flv(srs_flv_t ic, srs_flv_t oc);
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -108,22 +107,52 @@ int process(const char* in_flv_file, const char* out_flv_file, srs_flv_t* pic, s
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((*pic = srs_flv_open_read(in_flv_file)) == NULL) {
|
||||
srs_flv_t ic;
|
||||
srs_flv_t oc;
|
||||
|
||||
// to adjust metadata.
|
||||
// the ic metadata end offset, the next tag start offset.
|
||||
// all oc metadata must adjust according to:
|
||||
// adjust = new_metadata_end_offset - metadata_end_offset
|
||||
int64_t metadata_end_offset = 0;
|
||||
|
||||
// metadata
|
||||
srs_amf0_t amf0_name = NULL;
|
||||
srs_amf0_t amf0_data = NULL;
|
||||
srs_amf0_t filepositions = NULL;
|
||||
|
||||
if ((ic = srs_flv_open_read(in_flv_file)) == NULL) {
|
||||
ret = 2;
|
||||
trace("open input flv file failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
*pic = ic;
|
||||
|
||||
if ((*poc = srs_flv_open_write(out_flv_file)) == NULL) {
|
||||
if ((oc = srs_flv_open_write(out_flv_file)) == NULL) {
|
||||
ret = 2;
|
||||
trace("open output flv file failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
*poc = oc;
|
||||
|
||||
if ((ret = inject_flv(*pic, *poc)) != 0) {
|
||||
/**
|
||||
* we use two roundtrip to avoid the paddings of metadata,
|
||||
* to support large keyframes videos without padding fields.
|
||||
*/
|
||||
// build keyframes offset to metadata.
|
||||
if ((ret = build_keyframes(ic, &amf0_name, &amf0_data, &filepositions, &metadata_end_offset)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// inject the metadata to oc.
|
||||
if ((ret = do_inject_flv(ic, oc, amf0_name, amf0_data, filepositions, metadata_end_offset)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: FIXME: mem leak when error.
|
||||
srs_amf0_free(amf0_name);
|
||||
srs_amf0_free(amf0_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -148,12 +177,13 @@ int parse_metadata(char* data, int size, srs_amf0_t* pname, srs_amf0_t* pdata)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int inject_flv(srs_flv_t ic, srs_flv_t oc)
|
||||
int build_keyframes(srs_flv_t ic, srs_amf0_t *pname, srs_amf0_t* pdata, srs_amf0_t* pfilepositions, int64_t* pmetadata_end_offset)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// flv header
|
||||
char header[13];
|
||||
|
||||
// packet data
|
||||
char type;
|
||||
u_int32_t timestamp = 0;
|
||||
|
@ -163,8 +193,8 @@ int inject_flv(srs_flv_t ic, srs_flv_t oc)
|
|||
|
||||
// metadata
|
||||
srs_amf0_t amf0_name = NULL;
|
||||
int amf0_name_size = 0;
|
||||
srs_amf0_t amf0_data = NULL;
|
||||
|
||||
srs_amf0_t keyframes = NULL;
|
||||
srs_amf0_t filepositions = NULL;
|
||||
srs_amf0_t times = NULL;
|
||||
|
@ -184,7 +214,7 @@ int inject_flv(srs_flv_t ic, srs_flv_t oc)
|
|||
if ((ret = srs_flv_read_tag_header(ic, &type, &size, ×tamp)) != 0) {
|
||||
if (srs_flv_is_eof(ret)) {
|
||||
trace("parse completed.");
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
trace("flv get packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
|
@ -192,7 +222,7 @@ int inject_flv(srs_flv_t ic, srs_flv_t oc)
|
|||
|
||||
if (size <= 0) {
|
||||
trace("invalid size=%d", size);
|
||||
break;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: FIXME: mem leak when error.
|
||||
|
@ -208,30 +238,40 @@ int inject_flv(srs_flv_t ic, srs_flv_t oc)
|
|||
srs_amf0_strict_array_append(times, srs_amf0_create_number(((double)timestamp)/ 1000));
|
||||
}
|
||||
} else if (type == SRS_RTMP_TYPE_SCRIPT) {
|
||||
*pmetadata_end_offset = srs_flv_tellg(ic);
|
||||
if ((ret = parse_metadata(data, size, &amf0_name, &amf0_data)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*pname = amf0_name;
|
||||
*pdata = amf0_data;
|
||||
|
||||
if (srs_amf0_is_object(amf0_data)) {
|
||||
keyframes = srs_amf0_object_property(amf0_data, "keyframes");
|
||||
if (keyframes != NULL) {
|
||||
return 0;
|
||||
if (keyframes == NULL) {
|
||||
keyframes = srs_amf0_create_ecma_array();
|
||||
}
|
||||
keyframes = srs_amf0_create_ecma_array();
|
||||
srs_amf0_object_property_set(amf0_data, "keyframes", keyframes);
|
||||
filepositions = srs_amf0_create_strict_array();
|
||||
// always clear the old keyframes.
|
||||
srs_amf0_ecma_array_clear(keyframes);
|
||||
|
||||
*pfilepositions = filepositions = srs_amf0_create_strict_array();
|
||||
srs_amf0_object_property_set(keyframes, "filepositions", filepositions);
|
||||
|
||||
times = srs_amf0_create_strict_array();
|
||||
srs_amf0_object_property_set(keyframes, "times", times);
|
||||
} else if (srs_amf0_is_ecma_array(amf0_data)) {
|
||||
keyframes = srs_amf0_ecma_array_property(amf0_data, "keyframes");
|
||||
if (keyframes != NULL) {
|
||||
return 0;
|
||||
if (keyframes == NULL) {
|
||||
keyframes = srs_amf0_create_ecma_array();
|
||||
}
|
||||
keyframes = srs_amf0_create_ecma_array();
|
||||
srs_amf0_ecma_array_property_set(amf0_data, "keyframes", keyframes);
|
||||
filepositions = srs_amf0_create_strict_array();
|
||||
// always clear the old keyframes.
|
||||
srs_amf0_ecma_array_clear(keyframes);
|
||||
|
||||
*pfilepositions = filepositions = srs_amf0_create_strict_array();
|
||||
srs_amf0_ecma_array_property_set(keyframes, "filepositions", filepositions);
|
||||
|
||||
times = srs_amf0_create_strict_array();
|
||||
srs_amf0_ecma_array_property_set(keyframes, "times", times);
|
||||
}
|
||||
|
@ -240,6 +280,30 @@ int inject_flv(srs_flv_t ic, srs_flv_t oc)
|
|||
free(data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int do_inject_flv(srs_flv_t ic, srs_flv_t oc, srs_amf0_t amf0_name, srs_amf0_t amf0_data, srs_amf0_t filepositions, int64_t metadata_end_offset)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// flv header
|
||||
char header[13];
|
||||
// packet data
|
||||
char type;
|
||||
u_int32_t timestamp = 0;
|
||||
char* data = NULL;
|
||||
int32_t size;
|
||||
|
||||
// metadata
|
||||
srs_amf0_t fileposition = NULL;
|
||||
int amf0_name_size = 0;
|
||||
int i;
|
||||
|
||||
// the metadata end offset, the next tag start offset.
|
||||
int64_t new_metadata_end_offset = 0;
|
||||
int offset_adjust = 0;
|
||||
|
||||
// reset to write injected file
|
||||
srs_flv_lseek(ic, 0);
|
||||
|
||||
|
@ -255,7 +319,18 @@ int inject_flv(srs_flv_t ic, srs_flv_t oc)
|
|||
if (amf0_name != NULL && amf0_data != NULL) {
|
||||
amf0_name_size = srs_amf0_size(amf0_name);
|
||||
size = amf0_name_size + srs_amf0_size(amf0_data);
|
||||
|
||||
// adjust all offset of keyframes.
|
||||
new_metadata_end_offset = srs_flv_tellg(oc) + srs_flv_size_tag(size);
|
||||
// the adjust is new offset sub the old offset of metadata end.
|
||||
offset_adjust = new_metadata_end_offset - metadata_end_offset;
|
||||
for (i = 0; i < srs_amf0_strict_array_property_count(filepositions); i++) {
|
||||
fileposition = srs_amf0_strict_array_property_at(filepositions, i);
|
||||
srs_amf0_set_number(fileposition, srs_amf0_to_number(fileposition) + offset_adjust);
|
||||
}
|
||||
|
||||
data = (char*)malloc(size);
|
||||
memset(data, 0, size);
|
||||
if ((ret = srs_amf0_serialize(amf0_name, data, amf0_name_size)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -267,6 +342,7 @@ int inject_flv(srs_flv_t ic, srs_flv_t oc)
|
|||
}
|
||||
free(data);
|
||||
}
|
||||
|
||||
trace("build keyframe infos from flv");
|
||||
for (;;) {
|
||||
// tag header
|
||||
|
@ -303,8 +379,5 @@ int inject_flv(srs_flv_t ic, srs_flv_t oc)
|
|||
free(data);
|
||||
}
|
||||
|
||||
srs_amf0_free(amf0_name);
|
||||
srs_amf0_free(amf0_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
// current release version
|
||||
#define VERSION_MAJOR "0"
|
||||
#define VERSION_MINOR "9"
|
||||
#define VERSION_REVISION "121"
|
||||
#define VERSION_REVISION "122"
|
||||
#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
|
||||
// server info.
|
||||
#define RTMP_SIG_SRS_KEY "SRS"
|
||||
|
|
|
@ -330,6 +330,11 @@ int SrsFlvEncoder::write_video(int64_t timestamp, char* data, int size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsFlvEncoder::size_tag(int data_size)
|
||||
{
|
||||
return SRS_FLV_TAG_HEADER_SIZE + data_size + SRS_FLV_PREVIOUS_TAG_SIZE;
|
||||
}
|
||||
|
||||
int SrsFlvEncoder::write_tag(char* header, int header_size, char* tag, int tag_size)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
|
|
@ -105,6 +105,11 @@ public:
|
|||
*/
|
||||
virtual int write_audio(int64_t timestamp, char* data, int size);
|
||||
virtual int write_video(int64_t timestamp, char* data, int size);
|
||||
/**
|
||||
* get the tag size,
|
||||
* including the tag header, body, and 4bytes previous tag size.
|
||||
*/
|
||||
static int size_tag(int data_size);
|
||||
private:
|
||||
virtual int write_tag(char* header, int header_size, char* tag, int tag_size);
|
||||
};
|
||||
|
|
|
@ -519,6 +519,11 @@ int srs_flv_write_tag(srs_flv_t flv, char type, int32_t time, char* data, int si
|
|||
return ret;
|
||||
}
|
||||
|
||||
int srs_flv_size_tag(int data_size)
|
||||
{
|
||||
return SrsFlvEncoder::size_tag(data_size);
|
||||
}
|
||||
|
||||
int64_t srs_flv_tellg(srs_flv_t flv)
|
||||
{
|
||||
FlvContext* context = (FlvContext*)flv;
|
||||
|
@ -684,6 +689,12 @@ amf0_number srs_amf0_to_number(srs_amf0_t amf0)
|
|||
return any->to_number();
|
||||
}
|
||||
|
||||
void srs_amf0_set_number(srs_amf0_t amf0, amf0_number value)
|
||||
{
|
||||
SrsAmf0Any* any = (SrsAmf0Any*)amf0;
|
||||
any->set_number(value);
|
||||
}
|
||||
|
||||
int srs_amf0_object_property_count(srs_amf0_t amf0)
|
||||
{
|
||||
SrsAmf0Object* obj = (SrsAmf0Object*)amf0;
|
||||
|
@ -746,6 +757,12 @@ void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name, srs_amf
|
|||
obj->set(name, any);
|
||||
}
|
||||
|
||||
void srs_amf0_ecma_array_clear(srs_amf0_t amf0)
|
||||
{
|
||||
SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0;
|
||||
obj->clear();
|
||||
}
|
||||
|
||||
int srs_amf0_strict_array_property_count(srs_amf0_t amf0)
|
||||
{
|
||||
SrsAmf0StrictArray * obj = (SrsAmf0StrictArray*)amf0;
|
||||
|
|
|
@ -169,6 +169,8 @@ int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size);
|
|||
int srs_flv_write_header(srs_flv_t flv, char header[9]);
|
||||
/* write flv tag to file, auto write the 4bytes previous tag size */
|
||||
int srs_flv_write_tag(srs_flv_t flv, char type, int32_t time, char* data, int size);
|
||||
/* get the tag size, for flv injecter to adjust offset, size=tag_header+data+previous_tag */
|
||||
int srs_flv_size_tag(int data_size);
|
||||
/* file stream */
|
||||
/* file stream tellg to get offset */
|
||||
int64_t srs_flv_tellg(srs_flv_t flv);
|
||||
|
@ -211,6 +213,8 @@ amf0_bool srs_amf0_is_strict_array(srs_amf0_t amf0);
|
|||
const char* srs_amf0_to_string(srs_amf0_t amf0);
|
||||
amf0_bool srs_amf0_to_boolean(srs_amf0_t amf0);
|
||||
amf0_number srs_amf0_to_number(srs_amf0_t amf0);
|
||||
/* value setter */
|
||||
void srs_amf0_set_number(srs_amf0_t amf0, amf0_number value);
|
||||
/* object value converter */
|
||||
int srs_amf0_object_property_count(srs_amf0_t amf0);
|
||||
const char* srs_amf0_object_property_name_at(srs_amf0_t amf0, int index);
|
||||
|
@ -223,6 +227,7 @@ const char* srs_amf0_ecma_array_property_name_at(srs_amf0_t amf0, int index);
|
|||
srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index);
|
||||
srs_amf0_t srs_amf0_ecma_array_property(srs_amf0_t amf0, const char* name);
|
||||
void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value);
|
||||
void srs_amf0_ecma_array_clear(srs_amf0_t amf0);
|
||||
/* strict array value converter */
|
||||
int srs_amf0_strict_array_property_count(srs_amf0_t amf0);
|
||||
srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index);
|
||||
|
|
|
@ -75,6 +75,7 @@ public:
|
|||
virtual int total_size();
|
||||
virtual int read(SrsStream* stream);
|
||||
virtual int write(SrsStream* stream);
|
||||
virtual SrsAmf0Any* copy();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -95,6 +96,7 @@ public:
|
|||
virtual int total_size();
|
||||
virtual int read(SrsStream* stream);
|
||||
virtual int write(SrsStream* stream);
|
||||
virtual SrsAmf0Any* copy();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -114,6 +116,7 @@ public:
|
|||
virtual int total_size();
|
||||
virtual int read(SrsStream* stream);
|
||||
virtual int write(SrsStream* stream);
|
||||
virtual SrsAmf0Any* copy();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -130,6 +133,7 @@ public:
|
|||
virtual int total_size();
|
||||
virtual int read(SrsStream* stream);
|
||||
virtual int write(SrsStream* stream);
|
||||
virtual SrsAmf0Any* copy();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -146,6 +150,7 @@ public:
|
|||
virtual int total_size();
|
||||
virtual int read(SrsStream* stream);
|
||||
virtual int write(SrsStream* stream);
|
||||
virtual SrsAmf0Any* copy();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -173,6 +178,8 @@ public:
|
|||
virtual SrsAmf0Any* get_property(std::string name);
|
||||
virtual SrsAmf0Any* ensure_property_string(std::string name);
|
||||
virtual SrsAmf0Any* ensure_property_number(std::string name);
|
||||
|
||||
virtual void copy(__SrsUnSortedHashtable* src);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -191,6 +198,7 @@ public:
|
|||
virtual int total_size();
|
||||
virtual int read(SrsStream* stream);
|
||||
virtual int write(SrsStream* stream);
|
||||
virtual SrsAmf0Any* copy();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -310,6 +318,13 @@ SrsAmf0StrictArray* SrsAmf0Any::to_strict_array()
|
|||
return p;
|
||||
}
|
||||
|
||||
void SrsAmf0Any::set_number(double value)
|
||||
{
|
||||
__SrsAmf0Number* p = dynamic_cast<__SrsAmf0Number*>(this);
|
||||
srs_assert(p != NULL);
|
||||
p->value = value;
|
||||
}
|
||||
|
||||
bool SrsAmf0Any::is_object_eof()
|
||||
{
|
||||
return marker == RTMP_AMF0_ObjectEnd;
|
||||
|
@ -433,13 +448,7 @@ __SrsUnSortedHashtable::__SrsUnSortedHashtable()
|
|||
|
||||
__SrsUnSortedHashtable::~__SrsUnSortedHashtable()
|
||||
{
|
||||
std::vector<SrsAmf0ObjectPropertyType>::iterator it;
|
||||
for (it = properties.begin(); it != properties.end(); ++it) {
|
||||
SrsAmf0ObjectPropertyType& elem = *it;
|
||||
SrsAmf0Any* any = elem.second;
|
||||
srs_freep(any);
|
||||
}
|
||||
properties.clear();
|
||||
clear();
|
||||
}
|
||||
|
||||
int __SrsUnSortedHashtable::count()
|
||||
|
@ -449,6 +458,12 @@ int __SrsUnSortedHashtable::count()
|
|||
|
||||
void __SrsUnSortedHashtable::clear()
|
||||
{
|
||||
std::vector<SrsAmf0ObjectPropertyType>::iterator it;
|
||||
for (it = properties.begin(); it != properties.end(); ++it) {
|
||||
SrsAmf0ObjectPropertyType& elem = *it;
|
||||
SrsAmf0Any* any = elem.second;
|
||||
srs_freep(any);
|
||||
}
|
||||
properties.clear();
|
||||
}
|
||||
|
||||
|
@ -543,6 +558,17 @@ SrsAmf0Any* __SrsUnSortedHashtable::ensure_property_number(string name)
|
|||
return prop;
|
||||
}
|
||||
|
||||
void __SrsUnSortedHashtable::copy(__SrsUnSortedHashtable* src)
|
||||
{
|
||||
std::vector<SrsAmf0ObjectPropertyType>::iterator it;
|
||||
for (it = src->properties.begin(); it != src->properties.end(); ++it) {
|
||||
SrsAmf0ObjectPropertyType& elem = *it;
|
||||
std::string key = elem.first;
|
||||
SrsAmf0Any* any = elem.second;
|
||||
set(key, any->copy());
|
||||
}
|
||||
}
|
||||
|
||||
__SrsAmf0ObjectEOF::__SrsAmf0ObjectEOF()
|
||||
{
|
||||
marker = RTMP_AMF0_ObjectEnd;
|
||||
|
@ -623,6 +649,11 @@ int __SrsAmf0ObjectEOF::write(SrsStream* stream)
|
|||
return ret;
|
||||
}
|
||||
|
||||
SrsAmf0Any* __SrsAmf0ObjectEOF::copy()
|
||||
{
|
||||
return new __SrsAmf0ObjectEOF();
|
||||
}
|
||||
|
||||
SrsAmf0Object::SrsAmf0Object()
|
||||
{
|
||||
properties = new __SrsUnSortedHashtable();
|
||||
|
@ -750,6 +781,13 @@ int SrsAmf0Object::write(SrsStream* stream)
|
|||
return ret;
|
||||
}
|
||||
|
||||
SrsAmf0Any* SrsAmf0Object::copy()
|
||||
{
|
||||
SrsAmf0Object* copy = new SrsAmf0Object();
|
||||
copy->properties->copy(properties);
|
||||
return copy;
|
||||
}
|
||||
|
||||
int SrsAmf0Object::count()
|
||||
{
|
||||
return properties->count();
|
||||
|
@ -792,6 +830,7 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_number(string name)
|
|||
|
||||
SrsAmf0EcmaArray::SrsAmf0EcmaArray()
|
||||
{
|
||||
_count = 0;
|
||||
properties = new __SrsUnSortedHashtable();
|
||||
eof = new __SrsAmf0ObjectEOF();
|
||||
marker = RTMP_AMF0_EcmaArray;
|
||||
|
@ -937,6 +976,14 @@ int SrsAmf0EcmaArray::write(SrsStream* stream)
|
|||
return ret;
|
||||
}
|
||||
|
||||
SrsAmf0Any* SrsAmf0EcmaArray::copy()
|
||||
{
|
||||
SrsAmf0EcmaArray* copy = new SrsAmf0EcmaArray();
|
||||
copy->properties->copy(properties);
|
||||
copy->_count = _count;
|
||||
return copy;
|
||||
}
|
||||
|
||||
void SrsAmf0EcmaArray::clear()
|
||||
{
|
||||
properties->clear();
|
||||
|
@ -1097,6 +1144,20 @@ int SrsAmf0StrictArray::write(SrsStream* stream)
|
|||
return ret;
|
||||
}
|
||||
|
||||
SrsAmf0Any* SrsAmf0StrictArray::copy()
|
||||
{
|
||||
SrsAmf0StrictArray* copy = new SrsAmf0StrictArray();
|
||||
|
||||
std::vector<SrsAmf0Any*>::iterator it;
|
||||
for (it = properties.begin(); it != properties.end(); ++it) {
|
||||
SrsAmf0Any* any = *it;
|
||||
copy->append(any->copy());
|
||||
}
|
||||
|
||||
copy->_count = _count;
|
||||
return copy;
|
||||
}
|
||||
|
||||
void SrsAmf0StrictArray::clear()
|
||||
{
|
||||
properties.clear();
|
||||
|
@ -1116,6 +1177,7 @@ SrsAmf0Any* SrsAmf0StrictArray::at(int index)
|
|||
void SrsAmf0StrictArray::append(SrsAmf0Any* any)
|
||||
{
|
||||
properties.push_back(any);
|
||||
_count = (int32_t)properties.size();
|
||||
}
|
||||
|
||||
int SrsAmf0Size::utf8(string value)
|
||||
|
@ -1216,6 +1278,12 @@ int __SrsAmf0String::write(SrsStream* stream)
|
|||
return srs_amf0_write_string(stream, value);
|
||||
}
|
||||
|
||||
SrsAmf0Any* __SrsAmf0String::copy()
|
||||
{
|
||||
__SrsAmf0String* copy = new __SrsAmf0String(value.c_str());
|
||||
return copy;
|
||||
}
|
||||
|
||||
__SrsAmf0Boolean::__SrsAmf0Boolean(bool _value)
|
||||
{
|
||||
marker = RTMP_AMF0_Boolean;
|
||||
|
@ -1241,6 +1309,12 @@ int __SrsAmf0Boolean::write(SrsStream* stream)
|
|||
return srs_amf0_write_boolean(stream, value);
|
||||
}
|
||||
|
||||
SrsAmf0Any* __SrsAmf0Boolean::copy()
|
||||
{
|
||||
__SrsAmf0Boolean* copy = new __SrsAmf0Boolean(value);
|
||||
return copy;
|
||||
}
|
||||
|
||||
__SrsAmf0Number::__SrsAmf0Number(double _value)
|
||||
{
|
||||
marker = RTMP_AMF0_Number;
|
||||
|
@ -1266,6 +1340,12 @@ int __SrsAmf0Number::write(SrsStream* stream)
|
|||
return srs_amf0_write_number(stream, value);
|
||||
}
|
||||
|
||||
SrsAmf0Any* __SrsAmf0Number::copy()
|
||||
{
|
||||
__SrsAmf0Number* copy = new __SrsAmf0Number(value);
|
||||
return copy;
|
||||
}
|
||||
|
||||
__SrsAmf0Null::__SrsAmf0Null()
|
||||
{
|
||||
marker = RTMP_AMF0_Null;
|
||||
|
@ -1290,6 +1370,12 @@ int __SrsAmf0Null::write(SrsStream* stream)
|
|||
return srs_amf0_write_null(stream);
|
||||
}
|
||||
|
||||
SrsAmf0Any* __SrsAmf0Null::copy()
|
||||
{
|
||||
__SrsAmf0Null* copy = new __SrsAmf0Null();
|
||||
return copy;
|
||||
}
|
||||
|
||||
__SrsAmf0Undefined::__SrsAmf0Undefined()
|
||||
{
|
||||
marker = RTMP_AMF0_Undefined;
|
||||
|
@ -1314,6 +1400,12 @@ int __SrsAmf0Undefined::write(SrsStream* stream)
|
|||
return srs_amf0_write_undefined(stream);
|
||||
}
|
||||
|
||||
SrsAmf0Any* __SrsAmf0Undefined::copy()
|
||||
{
|
||||
__SrsAmf0Undefined* copy = new __SrsAmf0Undefined();
|
||||
return copy;
|
||||
}
|
||||
|
||||
int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any** ppvalue)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
|
|
@ -63,6 +63,11 @@ class __SrsAmf0ObjectEOF;
|
|||
// SrsAmf0Object* obj = SrsAmf0Any::object();
|
||||
// 5. SrsAmf0EcmaArray: create the amf0 ecma array.
|
||||
// SrsAmf0EcmaArray* arr = SrsAmf0Any::ecma_array();
|
||||
// 6. SrsAmf0Any: set basic type value
|
||||
// SrsAmf0Any* pany = ...
|
||||
// if (pany->is_number()) {
|
||||
// pany->set_number(100.1);
|
||||
// }
|
||||
//
|
||||
// please carefully the size and count of amf0 any:
|
||||
// 1. total_size(): the total memory size the object wrote to buffer.
|
||||
|
@ -129,6 +134,12 @@ public:
|
|||
*/
|
||||
virtual SrsAmf0EcmaArray* to_ecma_array();
|
||||
virtual SrsAmf0StrictArray* to_strict_array();
|
||||
public:
|
||||
/**
|
||||
* set the number of any when is_number() indicates true.
|
||||
* user must ensure the type is a number, or assert failed.
|
||||
*/
|
||||
virtual void set_number(double value);
|
||||
public:
|
||||
/**
|
||||
* get the size of amf0 any, including the marker size.
|
||||
|
@ -139,6 +150,7 @@ public:
|
|||
*/
|
||||
virtual int read(SrsStream* stream) = 0;
|
||||
virtual int write(SrsStream* stream) = 0;
|
||||
virtual SrsAmf0Any* copy() = 0;
|
||||
public:
|
||||
static SrsAmf0Any* str(const char* value = NULL);
|
||||
static SrsAmf0Any* boolean(bool value = false);
|
||||
|
@ -175,6 +187,7 @@ public:
|
|||
virtual int total_size();
|
||||
virtual int read(SrsStream* stream);
|
||||
virtual int write(SrsStream* stream);
|
||||
virtual SrsAmf0Any* copy();
|
||||
|
||||
public:
|
||||
virtual int count();
|
||||
|
@ -215,6 +228,7 @@ public:
|
|||
virtual int total_size();
|
||||
virtual int read(SrsStream* stream);
|
||||
virtual int write(SrsStream* stream);
|
||||
virtual SrsAmf0Any* copy();
|
||||
|
||||
public:
|
||||
virtual void clear();
|
||||
|
@ -254,6 +268,7 @@ public:
|
|||
virtual int total_size();
|
||||
virtual int read(SrsStream* stream);
|
||||
virtual int write(SrsStream* stream);
|
||||
virtual SrsAmf0Any* copy();
|
||||
|
||||
public:
|
||||
virtual void clear();
|
||||
|
|
|
@ -3173,10 +3173,9 @@ int SrsOnMetaDataPacket::decode(SrsStream* stream)
|
|||
|
||||
// if ecma array, copy to object.
|
||||
for (int i = 0; i < arr->count(); i++) {
|
||||
metadata->set(arr->key_at(i), arr->value_at(i));
|
||||
metadata->set(arr->key_at(i), arr->value_at(i)->copy());
|
||||
}
|
||||
|
||||
arr->clear();
|
||||
srs_info("decode metadata array success");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue