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) {

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

@ -1,99 +1,99 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2013-2014 winlin Copyright (c) 2013-2014 winlin
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SRS_CORE_HPP #ifndef SRS_CORE_HPP
#define SRS_CORE_HPP #define SRS_CORE_HPP
/* /*
#include <srs_core.hpp> #include <srs_core.hpp>
*/ */
// 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"
#define RTMP_SIG_SRS_ROLE "origin/edge server" #define RTMP_SIG_SRS_ROLE "origin/edge server"
#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(Simple RTMP Server)" #define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(Simple RTMP Server)"
#define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server" #define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server"
#define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT #define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT
#define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin" #define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin"
#define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com" #define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com"
#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" #define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)"
#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2014 winlin" #define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2014 winlin"
#define RTMP_SIG_SRS_PRIMARY_AUTHROS "winlin,wenjie.zhao" #define RTMP_SIG_SRS_PRIMARY_AUTHROS "winlin,wenjie.zhao"
#define RTMP_SIG_SRS_CONTRIBUTORS_URL RTMP_SIG_SRS_URL"/blob/master/AUTHORS.txt" #define RTMP_SIG_SRS_CONTRIBUTORS_URL RTMP_SIG_SRS_URL"/blob/master/AUTHORS.txt"
/** /**
* the core provides the common defined macros, utilities, * the core provides the common defined macros, utilities,
* user must include the srs_core.hpp before any header, or maybe * user must include the srs_core.hpp before any header, or maybe
* build failed. * build failed.
*/ */
// for 32bit os, 2G big file limit for unistd io, // for 32bit os, 2G big file limit for unistd io,
// ie. read/write/lseek to use 64bits size for huge file. // ie. read/write/lseek to use 64bits size for huge file.
#ifndef _FILE_OFFSET_BITS #ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#endif #endif
// for int64_t print using PRId64 format. // for int64_t print using PRId64 format.
#ifndef __STDC_FORMAT_MACROS #ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS
#endif #endif
#include <inttypes.h> #include <inttypes.h>
#include <assert.h> #include <assert.h>
#define srs_assert(expression) assert(expression) #define srs_assert(expression) assert(expression)
#include <stddef.h> #include <stddef.h>
#include <sys/types.h> #include <sys/types.h>
// generated by configure. // generated by configure.
#include <srs_auto_headers.hpp> #include <srs_auto_headers.hpp>
// free the p and set to NULL. // free the p and set to NULL.
// p must be a T*. // p must be a T*.
#define srs_freep(p) \ #define srs_freep(p) \
if (p) { \ if (p) { \
delete p; \ delete p; \
p = NULL; \ p = NULL; \
} \ } \
(void)0 (void)0
// sometimes, the freepa is useless, // sometimes, the freepa is useless,
// it's recomments to free each elem explicit. // it's recomments to free each elem explicit.
// so we remove the srs_freepa utility. // so we remove the srs_freepa utility.
/** /**
* disable copy constructor of class * disable copy constructor of class
*/ */
#define disable_default_copy(className)\ #define disable_default_copy(className)\
private:\ private:\
/** \ /** \
* disable the copy constructor and operator=, donot allow directly copy. \ * disable the copy constructor and operator=, donot allow directly copy. \
*/ \ */ \
className(const className&); \ className(const className&); \
className& operator= (const className&) className& operator= (const className&)
#endif #endif

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