1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-13 11:51:57 +00:00

complete the normal kernel flv utest. 0.9.147

This commit is contained in:
winlin 2014-07-05 11:10:42 +08:00
parent 010eb09a30
commit d219a7b67e
11 changed files with 691 additions and 172 deletions

View file

@ -312,14 +312,12 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string
} }
// save header, send later. // save header, send later.
char* flv_header = NULL; char flv_header[13];
int flv_size = 0;
// send flv header // send flv header
if ((ret = ffd.read_header(&flv_header, &flv_size)) != ERROR_SUCCESS) { if ((ret = ffd.read_header_ext(flv_header)) != ERROR_SUCCESS) {
return ret; return ret;
} }
SrsAutoFree(char, flv_header);
// save sequence header, send later // save sequence header, send later
char* sh_data = NULL; char* sh_data = NULL;
@ -328,7 +326,7 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string
if (true) { if (true) {
// send sequence header // send sequence header
int64_t start = 0; int64_t start = 0;
if ((ret = ffd.read_sequence_header(&start, &sh_size)) != ERROR_SUCCESS) { if ((ret = ffd.read_sequence_header_summary(&start, &sh_size)) != ERROR_SUCCESS) {
return ret; return ret;
} }
if (sh_size <= 0) { if (sh_size <= 0) {
@ -350,7 +348,7 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string
std::stringstream ss; std::stringstream ss;
res_status_line(ss)->res_content_type_flv(ss) res_status_line(ss)->res_content_type_flv(ss)
->res_content_length(ss, (int)(flv_size + sh_size + left)); ->res_content_length(ss, (int)(sizeof(flv_header) + sh_size + left));
if (req->requires_crossdomain()) { if (req->requires_crossdomain()) {
res_enable_crossdomain(ss); res_enable_crossdomain(ss);
@ -363,7 +361,7 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string
return ret; return ret;
} }
if (flv_size > 0 && (ret = skt->write(flv_header, flv_size, NULL)) != ERROR_SUCCESS) { if ((ret = skt->write(flv_header, sizeof(flv_header), NULL)) != ERROR_SUCCESS) {
return ret; return ret;
} }
if (sh_size > 0 && (ret = skt->write(sh_data, sh_size, NULL)) != ERROR_SUCCESS) { if (sh_size > 0 && (ret = skt->write(sh_data, sh_size, NULL)) != ERROR_SUCCESS) {

2
trunk/src/core/srs_core.hpp Executable file → Normal file
View file

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

View file

@ -119,8 +119,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_SYSTEM_FILE_RENAME 429 #define ERROR_SYSTEM_FILE_RENAME 429
#define ERROR_SYSTEM_CREATE_PIPE 430 #define ERROR_SYSTEM_CREATE_PIPE 430
#define ERROR_SYSTEM_FILE_SEEK 431 #define ERROR_SYSTEM_FILE_SEEK 431
#define ERROR_SYSTEM_FLV_HEADER 432 #define ERROR_SYSTEM_IO_INVALID 432
#define ERROR_SYSTEM_IO_INVALID 433
// see librtmp. // see librtmp.
// failed when open ssl create the dh // failed when open ssl create the dh
@ -189,12 +188,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_HTTP_FLV_SEQUENCE_HEADER 806 #define ERROR_HTTP_FLV_SEQUENCE_HEADER 806
#define ERROR_HTTP_FLV_OFFSET_OVERFLOW 807 #define ERROR_HTTP_FLV_OFFSET_OVERFLOW 807
#define ERROR_KERNEL_FLV_HEADER 900
#define ERROR_KERNEL_FLV_STREAM_CLOSED 901
// system control message, // system control message,
// not an error, but special control logic. // not an error, but special control logic.
// sys ctl: rtmp close stream, support replay. // sys ctl: rtmp close stream, support replay.
#define ERROR_CONTROL_RTMP_CLOSE 900 #define ERROR_CONTROL_RTMP_CLOSE 2000
// FMLE stop publish and republish. // FMLE stop publish and republish.
#define ERROR_CONTROL_REPUBLISH 901 #define ERROR_CONTROL_REPUBLISH 2001
/** /**
* whether the error code is an system control error. * whether the error code is an system control error.

View file

@ -53,6 +53,12 @@ int SrsFlvEncoder::initialize(SrsFileWriter* fs)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (!fs->is_open()) {
ret = ERROR_KERNEL_FLV_STREAM_CLOSED;
srs_warn("stream is not open for decoder. ret=%d", ret);
return ret;
}
_fs = fs; _fs = fs;
return ret; return ret;
@ -92,7 +98,7 @@ int SrsFlvEncoder::write_header(char flv_header[9])
return ret; return ret;
} }
char pts[] = { 0x00, 0x00, 0x00, 0x00 }; char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)0x00 };
if ((ret = _fs->write(pts, 4, NULL)) != ERROR_SUCCESS) { if ((ret = _fs->write(pts, 4, NULL)) != ERROR_SUCCESS) {
return ret; return ret;
} }
@ -104,6 +110,7 @@ int SrsFlvEncoder::write_metadata(char* data, int size)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// 11 bytes tag header
static char tag_header[] = { static char tag_header[] = {
(char)18, // TagType UB [5], 18 = script data (char)18, // TagType UB [5], 18 = script data
(char)0x00, (char)0x00, (char)0x00, // DataSize UI24 Length of the message. (char)0x00, (char)0x00, (char)0x00, // DataSize UI24 Length of the message.
@ -240,6 +247,12 @@ int SrsFlvDecoder::initialize(SrsFileReader* fs)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (!fs->is_open()) {
ret = ERROR_KERNEL_FLV_STREAM_CLOSED;
srs_warn("stream is not open for decoder. ret=%d", ret);
return ret;
}
_fs = fs; _fs = fs;
return ret; return ret;
@ -255,7 +268,7 @@ int SrsFlvDecoder::read_header(char header[9])
char* h = header; char* h = header;
if (h[0] != 'F' || h[1] != 'L' || h[2] != 'V') { if (h[0] != 'F' || h[1] != 'L' || h[2] != 'V') {
ret = ERROR_SYSTEM_FLV_HEADER; ret = ERROR_KERNEL_FLV_HEADER;
srs_warn("flv header must start with FLV. ret=%d", ret); srs_warn("flv header must start with FLV. ret=%d", ret);
return ret; return ret;
} }
@ -345,35 +358,37 @@ int SrsFlvVodStreamDecoder::initialize(SrsFileReader* fs)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if (!fs->is_open()) {
ret = ERROR_KERNEL_FLV_STREAM_CLOSED;
srs_warn("stream is not open for decoder. ret=%d", ret);
return ret;
}
_fs = fs; _fs = fs;
return ret; return ret;
} }
int SrsFlvVodStreamDecoder::read_header(char** pdata, int* psize) int SrsFlvVodStreamDecoder::read_header_ext(char header[13])
{ {
*pdata = NULL;
*psize = 0;
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
srs_assert(_fs); srs_assert(_fs);
// @remark, always false, for sizeof(char[13]) equals to sizeof(char*)
//srs_assert(13 == sizeof(header));
// 9bytes header and 4bytes first previous-tag-size // 9bytes header and 4bytes first previous-tag-size
int size = 13; int size = 13;
char* buf = new char[size];
if ((ret = _fs->read(buf, size, NULL)) != ERROR_SUCCESS) { if ((ret = _fs->read(header, size, NULL)) != ERROR_SUCCESS) {
return ret; return ret;
} }
*pdata = buf;
*psize = size;
return ret; return ret;
} }
int SrsFlvVodStreamDecoder::read_sequence_header(int64_t* pstart, int* psize) int SrsFlvVodStreamDecoder::read_sequence_header_summary(int64_t* pstart, int* psize)
{ {
*pstart = 0; *pstart = 0;
*psize = 0; *psize = 0;

View file

@ -66,7 +66,7 @@ public:
virtual int write_header(char flv_header[9]); virtual int write_header(char flv_header[9]);
/** /**
* write flv metadata. * write flv metadata.
* serialize from: * @param data, the amf0 metadata which serialize from:
* AMF0 string: onMetaData, * AMF0 string: onMetaData,
* AMF0 object: the metadata object. * AMF0 object: the metadata object.
*/ */
@ -76,6 +76,7 @@ public:
*/ */
virtual int write_audio(int64_t timestamp, char* data, int size); virtual int write_audio(int64_t timestamp, char* data, int size);
virtual int write_video(int64_t timestamp, char* data, int size); virtual int write_video(int64_t timestamp, char* data, int size);
public:
/** /**
* get the tag size, * get the tag size,
* including the tag header, body, and 4bytes previous tag size. * including the tag header, body, and 4bytes previous tag size.
@ -134,13 +135,17 @@ public:
virtual int initialize(SrsFileReader* fs); virtual int initialize(SrsFileReader* fs);
public: public:
/** /**
* read the flv header and size. * read the flv header and its size.
* @param header, fill it 13bytes(9bytes header, 4bytes previous tag size).
*/ */
virtual int read_header(char** pdata, int* psize); virtual int read_header_ext(char header[13]);
/** /**
* read the sequence header and size. * read the sequence header tags offset and its size.
* @param pstart, the start offset of sequence header.
* @param psize, output the size, (tag header)+(tag body)+(4bytes previous tag size).
* @remark we think the first audio/video is sequence header.
*/ */
virtual int read_sequence_header(int64_t* pstart, int* psize); virtual int read_sequence_header_summary(int64_t* pstart, int* psize);
public: public:
/** /**
* for start offset, seed to this position and response flv stream. * for start offset, seed to this position and response flv stream.

View file

@ -557,31 +557,6 @@ namespace srs
return bytes; return bytes;
} }
/**
* compare the memory in bytes.
*/
bool srs_bytes_equals(void* pa, void* pb, int size)
{
u_int8_t* a = (u_int8_t*)pa;
u_int8_t* b = (u_int8_t*)pb;
if (!a && !b) {
return true;
}
if (!a || !b) {
return false;
}
for(int i = 0; i < size; i++){
if(a[i] != b[i]){
return false;
}
}
return true;
}
c2s2::c2s2() c2s2::c2s2()
{ {
srs_random_generate(random, 1504); srs_random_generate(random, 1504);

View file

@ -167,11 +167,6 @@ namespace srs
*/ */
char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key); char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key);
/**
* compare the memory in bytes.
*/
bool srs_bytes_equals(void* pa, void* pb, int size);
/** /**
* c1s1 schema0 * c1s1 schema0
* time: 4bytes * time: 4bytes

View file

@ -126,3 +126,28 @@ string srs_generate_tc_url(string ip, string vhost, string app, string port)
return tcUrl; return tcUrl;
} }
/**
* compare the memory in bytes.
*/
bool srs_bytes_equals(void* pa, void* pb, int size)
{
u_int8_t* a = (u_int8_t*)pa;
u_int8_t* b = (u_int8_t*)pb;
if (!a && !b) {
return true;
}
if (!a || !b) {
return false;
}
for(int i = 0; i < size; i++){
if(a[i] != b[i]){
return false;
}
}
return true;
}

View file

@ -58,4 +58,9 @@ extern void srs_random_generate(char* bytes, int size);
// generate the tcUrl. // generate the tcUrl.
extern std::string srs_generate_tc_url(std::string ip, std::string vhost, std::string app, std::string port); extern std::string srs_generate_tc_url(std::string ip, std::string vhost, std::string app, std::string port);
/**
* compare the memory in bytes.
*/
extern bool srs_bytes_equals(void* pa, void* pb, int size);
#endif #endif

View file

@ -27,93 +27,155 @@ using namespace std;
#include <srs_kernel_error.hpp> #include <srs_kernel_error.hpp>
#include <srs_kernel_codec.hpp> #include <srs_kernel_codec.hpp>
#include <srs_kernel_flv.hpp> #include <srs_kernel_flv.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_protocol_utility.hpp>
#define MAX_MOCK_DATA_SIZE 1024 * 1024
MockSrsFileWriter::MockSrsFileWriter() MockSrsFileWriter::MockSrsFileWriter()
{ {
data = new char[MAX_MOCK_DATA_SIZE];
offset = -1;
} }
MockSrsFileWriter::~MockSrsFileWriter() MockSrsFileWriter::~MockSrsFileWriter()
{ {
srs_freep(data);
} }
int MockSrsFileWriter::open(string file) int MockSrsFileWriter::open(string /*file*/)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
offset = 0;
return ret; return ret;
} }
void MockSrsFileWriter::close() void MockSrsFileWriter::close()
{ {
int ret = ERROR_SUCCESS; offset = 0;
return;
} }
bool MockSrsFileWriter::is_open() bool MockSrsFileWriter::is_open()
{ {
return true; return offset >= 0;
} }
int64_t MockSrsFileWriter::tellg() int64_t MockSrsFileWriter::tellg()
{ {
return 0; return offset;
} }
int MockSrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite) int MockSrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
int size = srs_min(MAX_MOCK_DATA_SIZE - offset, count);
memcpy(data + offset, buf, size);
if (pnwrite) {
*pnwrite = size;
}
offset += size;
return ret; return ret;
} }
void MockSrsFileWriter::mock_reset_offset()
{
offset = 0;
}
MockSrsFileReader::MockSrsFileReader() MockSrsFileReader::MockSrsFileReader()
{ {
data = new char[MAX_MOCK_DATA_SIZE];
size = 0;
offset = -1;
} }
MockSrsFileReader::~MockSrsFileReader() MockSrsFileReader::~MockSrsFileReader()
{ {
srs_freep(data);
} }
int MockSrsFileReader::open(string file) int MockSrsFileReader::open(string /*file*/)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
offset = 0;
return ret; return ret;
} }
void MockSrsFileReader::close() void MockSrsFileReader::close()
{ {
int ret = ERROR_SUCCESS; offset = 0;
return;
} }
bool MockSrsFileReader::is_open() bool MockSrsFileReader::is_open()
{ {
return true; return offset >= 0;
} }
int64_t MockSrsFileReader::tellg() int64_t MockSrsFileReader::tellg()
{ {
return 0; return offset;
} }
void MockSrsFileReader::skip(int64_t size) void MockSrsFileReader::skip(int64_t _size)
{ {
offset += _size;
} }
int64_t MockSrsFileReader::lseek(int64_t offset) int64_t MockSrsFileReader::lseek(int64_t _offset)
{ {
offset = (int)_offset;
return offset; return offset;
} }
int64_t MockSrsFileReader::filesize() int64_t MockSrsFileReader::filesize()
{ {
return 0; return size;
} }
int MockSrsFileReader::read(void* buf, size_t count, ssize_t* pnread) int MockSrsFileReader::read(void* buf, size_t count, ssize_t* pnread)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
int s = srs_min(size - offset, (int)count);
if (s <= 0) {
return ret;
}
memcpy(buf, data + offset, s);
if (pnread) {
*pnread = s;
}
offset += s;
return ret; return ret;
} }
void MockSrsFileReader::mock_append_data(const char* _data, int _size)
{
int s = srs_min(MAX_MOCK_DATA_SIZE - offset, _size);
memcpy(data + offset, _data, s);
offset += s;
size += s;
}
void MockSrsFileReader::mock_reset_offset()
{
offset = 0;
}
VOID TEST(KernelCodecTest, IsKeyFrame) VOID TEST(KernelCodecTest, IsKeyFrame)
{ {
int8_t data; int8_t data;
@ -196,9 +258,431 @@ VOID TEST(KernelCodecTest, IsAudioSequenceHeader)
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2)); EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
} }
VOID TEST(KernelFlvTest, IsAudioSequenceHeader) VOID TEST(KernelFlvTest, FlvEncoderStreamClosed)
{ {
MockSrsFileWriter fs; MockSrsFileWriter fs;
SrsFlvEncoder enc; SrsFlvEncoder enc;
ASSERT_TRUE(ERROR_SUCCESS == enc.initialize(&fs)); ASSERT_TRUE(ERROR_SUCCESS != enc.initialize(&fs));
}
VOID TEST(KernelFlvTest, FlvEncoderWriteHeader)
{
MockSrsFileWriter fs;
SrsFlvEncoder enc;
ASSERT_TRUE(ERROR_SUCCESS == fs.open(""));
ASSERT_TRUE(ERROR_SUCCESS == enc.initialize(&fs));
// write header, 9bytes
char flv_header[] = {
'F', 'L', 'V', // Signatures "FLV"
(char)0x01, // File version (for example, 0x01 for FLV version 1)
(char)0x00, // 4, audio; 1, video; 5 audio+video.
(char)0x00, (char)0x00, (char)0x00, (char)0x09 // DataOffset UI32 The length of this header in bytes
};
char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)0x00 };
EXPECT_TRUE(ERROR_SUCCESS == enc.write_header());
ASSERT_TRUE(9 + 4 == fs.offset);
EXPECT_TRUE(srs_bytes_equals(flv_header, fs.data, 9));
EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 9, 4));
// customer header
flv_header[3] = 0xF0;
flv_header[4] = 0xF1;
flv_header[5] = 0x01;
fs.mock_reset_offset();
EXPECT_TRUE(ERROR_SUCCESS == enc.write_header(flv_header));
ASSERT_TRUE(9 + 4 == fs.offset);
EXPECT_TRUE(srs_bytes_equals(flv_header, fs.data, 9));
EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 9, 4));
}
VOID TEST(KernelFlvTest, FlvEncoderWriteMetadata)
{
MockSrsFileWriter fs;
EXPECT_TRUE(ERROR_SUCCESS == fs.open(""));
SrsFlvEncoder enc;
ASSERT_TRUE(ERROR_SUCCESS == enc.initialize(&fs));
// 11 bytes tag header
char tag_header[] = {
(char)18, // TagType UB [5], 18 = script data
(char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message.
(char)0x00, (char)0x00, (char)0x00, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};
char md[] = {
(char)0x01, (char)0x02, (char)0x03, (char)0x04,
(char)0x04, (char)0x03, (char)0x02, (char)0x01
};
char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 };
ASSERT_TRUE(ERROR_SUCCESS == enc.write_metadata(md, 8));
ASSERT_TRUE(11 + 8 + 4 == fs.offset);
EXPECT_TRUE(srs_bytes_equals(tag_header, fs.data, 11));
EXPECT_TRUE(srs_bytes_equals(md, fs.data + 11, 8));
EXPECT_TRUE(true); // donot know why, if not add it, the print is disabled.
EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 19, 4));
}
VOID TEST(KernelFlvTest, FlvEncoderWriteAudio)
{
MockSrsFileWriter fs;
SrsFlvEncoder enc;
ASSERT_TRUE(ERROR_SUCCESS == fs.open(""));
ASSERT_TRUE(ERROR_SUCCESS == enc.initialize(&fs));
// 11bytes tag header
char tag_header[] = {
(char)8, // TagType UB [5], 8 = audio
(char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message.
(char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};
char audio[] = {
(char)0x01, (char)0x02, (char)0x03, (char)0x04,
(char)0x04, (char)0x03, (char)0x02, (char)0x01
};
char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 };
ASSERT_TRUE(ERROR_SUCCESS == enc.write_audio(0x30, audio, 8));
ASSERT_TRUE(11 + 8 + 4 == fs.offset);
EXPECT_TRUE(srs_bytes_equals(tag_header, fs.data, 11));
EXPECT_TRUE(srs_bytes_equals(audio, fs.data + 11, 8));
EXPECT_TRUE(true); // donot know why, if not add it, the print is disabled.
EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 11 + 8, 4));
}
VOID TEST(KernelFlvTest, FlvEncoderWriteVideo)
{
MockSrsFileWriter fs;
SrsFlvEncoder enc;
ASSERT_TRUE(ERROR_SUCCESS == fs.open(""));
ASSERT_TRUE(ERROR_SUCCESS == enc.initialize(&fs));
// 11bytes tag header
char tag_header[] = {
(char)9, // TagType UB [5], 9 = video
(char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message.
(char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};
char video[] = {
(char)0x01, (char)0x02, (char)0x03, (char)0x04,
(char)0x04, (char)0x03, (char)0x02, (char)0x01
};
char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 };
ASSERT_TRUE(ERROR_SUCCESS == enc.write_video(0x30, video, 8));
ASSERT_TRUE(11 + 8 + 4 == fs.offset);
EXPECT_TRUE(srs_bytes_equals(tag_header, fs.data, 11));
EXPECT_TRUE(srs_bytes_equals(video, fs.data + 11, 8));
EXPECT_TRUE(true); // donot know why, if not add it, the print is disabled.
EXPECT_TRUE(srs_bytes_equals(pts, fs.data + 11 + 8, 4));
}
VOID TEST(KernelFlvTest, FlvEncoderSizeTag)
{
EXPECT_EQ(11+4+10, SrsFlvEncoder::size_tag(10));
EXPECT_EQ(11+4+0, SrsFlvEncoder::size_tag(0));
}
VOID TEST(KernelFlvTest, FlvDecoderStreamClosed)
{
MockSrsFileReader fs;
SrsFlvDecoder dec;
ASSERT_TRUE(ERROR_SUCCESS != dec.initialize(&fs));
}
VOID TEST(KernelFlvTest, FlvDecoderHeader)
{
MockSrsFileReader fs;
SrsFlvDecoder dec;
ASSERT_TRUE(ERROR_SUCCESS == fs.open(""));
ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs));
// 9bytes
char flv_header[] = {
'F', 'L', 'V', // Signatures "FLV"
(char)0x01, // File version (for example, 0x01 for FLV version 1)
(char)0x00, // 4, audio; 1, video; 5 audio+video.
(char)0x00, (char)0x00, (char)0x00, (char)0x09 // DataOffset UI32 The length of this header in bytes
};
char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)0x00 };
fs.mock_append_data(flv_header, 9);
fs.mock_append_data(pts, 4);
char data[1024];
fs.mock_reset_offset();
EXPECT_TRUE(ERROR_SUCCESS == dec.read_header(data));
EXPECT_TRUE(srs_bytes_equals(flv_header, data, 9));
EXPECT_TRUE(ERROR_SUCCESS == dec.read_previous_tag_size(data));
EXPECT_TRUE(srs_bytes_equals(pts, data, 4));
}
VOID TEST(KernelFlvTest, FlvDecoderMetadata)
{
MockSrsFileReader fs;
SrsFlvDecoder dec;
ASSERT_TRUE(ERROR_SUCCESS == fs.open(""));
ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs));
// 11 bytes tag header
char tag_header[] = {
(char)18, // TagType UB [5], 18 = script data
(char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message.
(char)0x00, (char)0x00, (char)0x00, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};
char md[] = {
(char)0x01, (char)0x02, (char)0x03, (char)0x04,
(char)0x04, (char)0x03, (char)0x02, (char)0x01
};
char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 };
fs.mock_append_data(tag_header, 11);
fs.mock_append_data(md, 8);
fs.mock_append_data(pts, 4);
char type = 0;
int32_t size = 0;
u_int32_t time = 0;
char data[1024];
fs.mock_reset_offset();
EXPECT_TRUE(ERROR_SUCCESS == dec.read_tag_header(&type, &size, &time));
EXPECT_TRUE(18 == type);
EXPECT_TRUE(8 == size);
EXPECT_TRUE(0 == time);
EXPECT_TRUE(ERROR_SUCCESS == dec.read_tag_data(data, size));
EXPECT_TRUE(srs_bytes_equals(md, data, 8));
EXPECT_TRUE(ERROR_SUCCESS == dec.read_previous_tag_size(data));
EXPECT_TRUE(srs_bytes_equals(pts, data, 4));
}
VOID TEST(KernelFlvTest, FlvDecoderAudio)
{
MockSrsFileReader fs;
SrsFlvDecoder dec;
ASSERT_TRUE(ERROR_SUCCESS == fs.open(""));
ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs));
// 11bytes tag header
char tag_header[] = {
(char)8, // TagType UB [5], 8 = audio
(char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message.
(char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};
char audio[] = {
(char)0x01, (char)0x02, (char)0x03, (char)0x04,
(char)0x04, (char)0x03, (char)0x02, (char)0x01
};
char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 };
fs.mock_append_data(tag_header, 11);
fs.mock_append_data(audio, 8);
fs.mock_append_data(pts, 4);
char type = 0;
int32_t size = 0;
u_int32_t time = 0;
char data[1024];
fs.mock_reset_offset();
EXPECT_TRUE(ERROR_SUCCESS == dec.read_tag_header(&type, &size, &time));
EXPECT_TRUE(8 == type);
EXPECT_TRUE(8 == size);
EXPECT_TRUE(0x30 == time);
EXPECT_TRUE(ERROR_SUCCESS == dec.read_tag_data(data, size));
EXPECT_TRUE(srs_bytes_equals(audio, data, 8));
EXPECT_TRUE(ERROR_SUCCESS == dec.read_previous_tag_size(data));
EXPECT_TRUE(srs_bytes_equals(pts, data, 4));
}
VOID TEST(KernelFlvTest, FlvDecoderVideo)
{
MockSrsFileReader fs;
SrsFlvDecoder dec;
ASSERT_TRUE(ERROR_SUCCESS == fs.open(""));
ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs));
// 11bytes tag header
char tag_header[] = {
(char)9, // TagType UB [5], 9 = video
(char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message.
(char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};
char video[] = {
(char)0x01, (char)0x02, (char)0x03, (char)0x04,
(char)0x04, (char)0x03, (char)0x02, (char)0x01
};
char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 };
fs.mock_append_data(tag_header, 11);
fs.mock_append_data(video, 8);
fs.mock_append_data(pts, 4);
char type = 0;
int32_t size = 0;
u_int32_t time = 0;
char data[1024];
fs.mock_reset_offset();
EXPECT_TRUE(ERROR_SUCCESS == dec.read_tag_header(&type, &size, &time));
EXPECT_TRUE(9 == type);
EXPECT_TRUE(8 == size);
EXPECT_TRUE(0x30 == time);
EXPECT_TRUE(ERROR_SUCCESS == dec.read_tag_data(data, size));
EXPECT_TRUE(srs_bytes_equals(video, data, 8));
EXPECT_TRUE(ERROR_SUCCESS == dec.read_previous_tag_size(data));
EXPECT_TRUE(srs_bytes_equals(pts, data, 4));
}
VOID TEST(KernelFlvTest, FlvVSDecoderStreamClosed)
{
MockSrsFileReader fs;
SrsFlvVodStreamDecoder dec;
ASSERT_TRUE(ERROR_SUCCESS != dec.initialize(&fs));
}
VOID TEST(KernelFlvTest, FlvVSDecoderHeader)
{
MockSrsFileReader fs;
SrsFlvVodStreamDecoder dec;
ASSERT_TRUE(ERROR_SUCCESS == fs.open(""));
ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs));
// 9bytes
char flv_header[] = {
'F', 'L', 'V', // Signatures "FLV"
(char)0x01, // File version (for example, 0x01 for FLV version 1)
(char)0x00, // 4, audio; 1, video; 5 audio+video.
(char)0x00, (char)0x00, (char)0x00, (char)0x09 // DataOffset UI32 The length of this header in bytes
};
char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)0x00 };
fs.mock_append_data(flv_header, 9);
fs.mock_append_data(pts, 4);
char data[1024];
fs.mock_reset_offset();
EXPECT_TRUE(ERROR_SUCCESS == dec.read_header_ext(data));
EXPECT_TRUE(srs_bytes_equals(flv_header, data, 9));
}
VOID TEST(KernelFlvTest, FlvVSDecoderSequenceHeader)
{
MockSrsFileReader fs;
SrsFlvVodStreamDecoder dec;
ASSERT_TRUE(ERROR_SUCCESS == fs.open(""));
ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs));
if (true) {
// 11 bytes tag header
char tag_header[] = {
(char)18, // TagType UB [5], 18 = script data
(char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message.
(char)0x00, (char)0x00, (char)0x00, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};
char md[] = {
(char)0x01, (char)0x02, (char)0x03, (char)0x04,
(char)0x04, (char)0x03, (char)0x02, (char)0x01
};
char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 };
fs.mock_append_data(tag_header, 11);
fs.mock_append_data(md, 8);
fs.mock_append_data(pts, 4);
}
if (true) {
// 11bytes tag header
char tag_header[] = {
(char)8, // TagType UB [5], 8 = audio
(char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message.
(char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};
char audio[] = {
(char)0x01, (char)0x02, (char)0x03, (char)0x04,
(char)0x04, (char)0x03, (char)0x02, (char)0x01
};
char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 };
fs.mock_append_data(tag_header, 11);
fs.mock_append_data(audio, 8);
fs.mock_append_data(pts, 4);
}
if (true) {
// 11bytes tag header
char tag_header[] = {
(char)9, // TagType UB [5], 9 = video
(char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message.
(char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};
char video[] = {
(char)0x01, (char)0x02, (char)0x03, (char)0x04,
(char)0x04, (char)0x03, (char)0x02, (char)0x01
};
char pts[] = { (char)0x00, (char)0x00, (char)0x00, (char)19 };
fs.mock_append_data(tag_header, 11);
fs.mock_append_data(video, 8);
fs.mock_append_data(pts, 4);
}
fs.mock_reset_offset();
int64_t start = 0;
int size = 0;
EXPECT_TRUE(ERROR_SUCCESS == dec.read_sequence_header_summary(&start, &size));
EXPECT_TRUE(23 == start);
EXPECT_TRUE(46 == size);
}
VOID TEST(KernelFlvTest, FlvVSDecoderSeek)
{
MockSrsFileReader fs;
SrsFlvVodStreamDecoder dec;
ASSERT_TRUE(ERROR_SUCCESS == fs.open(""));
ASSERT_TRUE(ERROR_SUCCESS == dec.initialize(&fs));
// 11bytes tag header
char tag_header[] = {
(char)8, // TagType UB [5], 8 = audio
(char)0x00, (char)0x00, (char)0x08, // DataSize UI24 Length of the message.
(char)0x00, (char)0x00, (char)0x30, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};
fs.mock_append_data(tag_header, 11);
EXPECT_TRUE(11 == fs.offset);
EXPECT_TRUE(ERROR_SUCCESS == dec.lseek(0));
EXPECT_TRUE(0 == fs.offset);
EXPECT_TRUE(ERROR_SUCCESS == dec.lseek(5));
EXPECT_TRUE(5 == fs.offset);
} }

View file

@ -34,6 +34,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class MockSrsFileWriter : public SrsFileWriter class MockSrsFileWriter : public SrsFileWriter
{ {
public:
char* data;
int offset;
public: public:
MockSrsFileWriter(); MockSrsFileWriter();
virtual ~MockSrsFileWriter(); virtual ~MockSrsFileWriter();
@ -45,10 +48,17 @@ public:
virtual int64_t tellg(); virtual int64_t tellg();
public: public:
virtual int write(void* buf, size_t count, ssize_t* pnwrite); virtual int write(void* buf, size_t count, ssize_t* pnwrite);
// for mock
public:
void mock_reset_offset();
}; };
class MockSrsFileReader : public SrsFileReader class MockSrsFileReader : public SrsFileReader
{ {
public:
char* data;
int size;
int offset;
public: public:
MockSrsFileReader(); MockSrsFileReader();
virtual ~MockSrsFileReader(); virtual ~MockSrsFileReader();
@ -63,6 +73,11 @@ public:
virtual int64_t filesize(); virtual int64_t filesize();
public: public:
virtual int read(void* buf, size_t count, ssize_t* pnread); virtual int read(void* buf, size_t count, ssize_t* pnread);
// for mock
public:
// append data to current offset, modify the offset and size.
void mock_append_data(const char* _data, int _size);
void mock_reset_offset();
}; };
#endif #endif