mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
refine flv codec, rename fast encoder to flv vod stream decoder
This commit is contained in:
parent
032118581a
commit
8271bd657b
4 changed files with 290 additions and 277 deletions
|
@ -304,7 +304,7 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsFlvFastDecoder ffd;
|
SrsFlvVodStreamDecoder ffd;
|
||||||
|
|
||||||
// open fast decoder
|
// open fast decoder
|
||||||
if ((ret = ffd.initialize(&fs)) != ERROR_SUCCESS) {
|
if ((ret = ffd.initialize(&fs)) != ERROR_SUCCESS) {
|
||||||
|
|
|
@ -225,167 +225,6 @@ int SrsFlvEncoder::write_tag(char* header, int header_size, char* tag, int tag_s
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsFlvFastDecoder::SrsFlvFastDecoder()
|
|
||||||
{
|
|
||||||
_fs = NULL;
|
|
||||||
tag_stream = new SrsStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsFlvFastDecoder::~SrsFlvFastDecoder()
|
|
||||||
{
|
|
||||||
srs_freep(tag_stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsFlvFastDecoder::initialize(SrsFileReader* fs)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
_fs = fs;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsFlvFastDecoder::read_header(char** pdata, int* psize)
|
|
||||||
{
|
|
||||||
*pdata = NULL;
|
|
||||||
*psize = 0;
|
|
||||||
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
srs_assert(_fs);
|
|
||||||
|
|
||||||
// 9bytes header and 4bytes first previous-tag-size
|
|
||||||
int size = 13;
|
|
||||||
char* buf = new char[size];
|
|
||||||
|
|
||||||
if ((ret = _fs->read(buf, size, NULL)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pdata = buf;
|
|
||||||
*psize = size;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsFlvFastDecoder::read_sequence_header(int64_t* pstart, int* psize)
|
|
||||||
{
|
|
||||||
*pstart = 0;
|
|
||||||
*psize = 0;
|
|
||||||
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
srs_assert(_fs);
|
|
||||||
|
|
||||||
// simply, the first video/audio must be the sequence header.
|
|
||||||
// and must be a sequence video and audio.
|
|
||||||
|
|
||||||
// 11bytes tag header
|
|
||||||
static char tag_header[] = {
|
|
||||||
(char)0x00, // TagType UB [5], 9 = video, 8 = audio, 18 = script data
|
|
||||||
(char)0x00, (char)0x00, (char)0x00, // 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.
|
|
||||||
};
|
|
||||||
|
|
||||||
// discovery the sequence header video and audio.
|
|
||||||
// @remark, maybe no video or no audio.
|
|
||||||
bool got_video = false;
|
|
||||||
bool got_audio = false;
|
|
||||||
// audio/video sequence and data offset.
|
|
||||||
int64_t av_sequence_offset_start = -1;
|
|
||||||
int64_t av_sequence_offset_end = -1;
|
|
||||||
for (;;) {
|
|
||||||
if ((ret = _fs->read(tag_header, SRS_FLV_TAG_HEADER_SIZE, NULL)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = tag_stream->initialize(tag_header, SRS_FLV_TAG_HEADER_SIZE)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t tag_type = tag_stream->read_1bytes();
|
|
||||||
int32_t data_size = tag_stream->read_3bytes();
|
|
||||||
|
|
||||||
bool is_video = tag_type == 0x09;
|
|
||||||
bool is_audio = tag_type == 0x08;
|
|
||||||
bool is_not_av = !is_video && !is_audio;
|
|
||||||
if (is_not_av) {
|
|
||||||
// skip body and tag size.
|
|
||||||
_fs->skip(data_size + SRS_FLV_PREVIOUS_TAG_SIZE);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if video duplicated, no audio
|
|
||||||
if (is_video && got_video) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// if audio duplicated, no video
|
|
||||||
if (is_audio && got_audio) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// video
|
|
||||||
if (is_video) {
|
|
||||||
srs_assert(!got_video);
|
|
||||||
got_video = true;
|
|
||||||
|
|
||||||
if (av_sequence_offset_start < 0) {
|
|
||||||
av_sequence_offset_start = _fs->tellg() - SRS_FLV_TAG_HEADER_SIZE;
|
|
||||||
}
|
|
||||||
av_sequence_offset_end = _fs->tellg() + data_size + SRS_FLV_PREVIOUS_TAG_SIZE;
|
|
||||||
_fs->skip(data_size + SRS_FLV_PREVIOUS_TAG_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// audio
|
|
||||||
if (is_audio) {
|
|
||||||
srs_assert(!got_audio);
|
|
||||||
got_audio = true;
|
|
||||||
|
|
||||||
if (av_sequence_offset_start < 0) {
|
|
||||||
av_sequence_offset_start = _fs->tellg() - SRS_FLV_TAG_HEADER_SIZE;
|
|
||||||
}
|
|
||||||
av_sequence_offset_end = _fs->tellg() + data_size + SRS_FLV_PREVIOUS_TAG_SIZE;
|
|
||||||
_fs->skip(data_size + SRS_FLV_PREVIOUS_TAG_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// seek to the sequence header start offset.
|
|
||||||
if (av_sequence_offset_start > 0) {
|
|
||||||
_fs->lseek(av_sequence_offset_start);
|
|
||||||
*pstart = av_sequence_offset_start;
|
|
||||||
*psize = (int)(av_sequence_offset_end - av_sequence_offset_start);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsFlvFastDecoder::lseek(int64_t offset)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
srs_assert(_fs);
|
|
||||||
|
|
||||||
if (offset >= _fs->filesize()) {
|
|
||||||
ret = ERROR_SYSTEM_FILE_EOF;
|
|
||||||
srs_warn("flv fast decoder seek overflow file, "
|
|
||||||
"size=%"PRId64", offset=%"PRId64", ret=%d",
|
|
||||||
_fs->filesize(), offset, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_fs->lseek(offset) < 0) {
|
|
||||||
ret = ERROR_SYSTEM_FILE_SEEK;
|
|
||||||
srs_warn("flv fast decoder seek error, "
|
|
||||||
"size=%"PRId64", offset=%"PRId64", ret=%d",
|
|
||||||
_fs->filesize(), offset, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsFlvDecoder::SrsFlvDecoder()
|
SrsFlvDecoder::SrsFlvDecoder()
|
||||||
{
|
{
|
||||||
_fs = NULL;
|
_fs = NULL;
|
||||||
|
@ -491,3 +330,164 @@ int SrsFlvDecoder::read_previous_tag_size(char ts[4])
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsFlvVodStreamDecoder::SrsFlvVodStreamDecoder()
|
||||||
|
{
|
||||||
|
_fs = NULL;
|
||||||
|
tag_stream = new SrsStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsFlvVodStreamDecoder::~SrsFlvVodStreamDecoder()
|
||||||
|
{
|
||||||
|
srs_freep(tag_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsFlvVodStreamDecoder::initialize(SrsFileReader* fs)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
_fs = fs;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsFlvVodStreamDecoder::read_header(char** pdata, int* psize)
|
||||||
|
{
|
||||||
|
*pdata = NULL;
|
||||||
|
*psize = 0;
|
||||||
|
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
srs_assert(_fs);
|
||||||
|
|
||||||
|
// 9bytes header and 4bytes first previous-tag-size
|
||||||
|
int size = 13;
|
||||||
|
char* buf = new char[size];
|
||||||
|
|
||||||
|
if ((ret = _fs->read(buf, size, NULL)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pdata = buf;
|
||||||
|
*psize = size;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsFlvVodStreamDecoder::read_sequence_header(int64_t* pstart, int* psize)
|
||||||
|
{
|
||||||
|
*pstart = 0;
|
||||||
|
*psize = 0;
|
||||||
|
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
srs_assert(_fs);
|
||||||
|
|
||||||
|
// simply, the first video/audio must be the sequence header.
|
||||||
|
// and must be a sequence video and audio.
|
||||||
|
|
||||||
|
// 11bytes tag header
|
||||||
|
static char tag_header[] = {
|
||||||
|
(char)0x00, // TagType UB [5], 9 = video, 8 = audio, 18 = script data
|
||||||
|
(char)0x00, (char)0x00, (char)0x00, // 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.
|
||||||
|
};
|
||||||
|
|
||||||
|
// discovery the sequence header video and audio.
|
||||||
|
// @remark, maybe no video or no audio.
|
||||||
|
bool got_video = false;
|
||||||
|
bool got_audio = false;
|
||||||
|
// audio/video sequence and data offset.
|
||||||
|
int64_t av_sequence_offset_start = -1;
|
||||||
|
int64_t av_sequence_offset_end = -1;
|
||||||
|
for (;;) {
|
||||||
|
if ((ret = _fs->read(tag_header, SRS_FLV_TAG_HEADER_SIZE, NULL)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = tag_stream->initialize(tag_header, SRS_FLV_TAG_HEADER_SIZE)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t tag_type = tag_stream->read_1bytes();
|
||||||
|
int32_t data_size = tag_stream->read_3bytes();
|
||||||
|
|
||||||
|
bool is_video = tag_type == 0x09;
|
||||||
|
bool is_audio = tag_type == 0x08;
|
||||||
|
bool is_not_av = !is_video && !is_audio;
|
||||||
|
if (is_not_av) {
|
||||||
|
// skip body and tag size.
|
||||||
|
_fs->skip(data_size + SRS_FLV_PREVIOUS_TAG_SIZE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if video duplicated, no audio
|
||||||
|
if (is_video && got_video) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// if audio duplicated, no video
|
||||||
|
if (is_audio && got_audio) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// video
|
||||||
|
if (is_video) {
|
||||||
|
srs_assert(!got_video);
|
||||||
|
got_video = true;
|
||||||
|
|
||||||
|
if (av_sequence_offset_start < 0) {
|
||||||
|
av_sequence_offset_start = _fs->tellg() - SRS_FLV_TAG_HEADER_SIZE;
|
||||||
|
}
|
||||||
|
av_sequence_offset_end = _fs->tellg() + data_size + SRS_FLV_PREVIOUS_TAG_SIZE;
|
||||||
|
_fs->skip(data_size + SRS_FLV_PREVIOUS_TAG_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// audio
|
||||||
|
if (is_audio) {
|
||||||
|
srs_assert(!got_audio);
|
||||||
|
got_audio = true;
|
||||||
|
|
||||||
|
if (av_sequence_offset_start < 0) {
|
||||||
|
av_sequence_offset_start = _fs->tellg() - SRS_FLV_TAG_HEADER_SIZE;
|
||||||
|
}
|
||||||
|
av_sequence_offset_end = _fs->tellg() + data_size + SRS_FLV_PREVIOUS_TAG_SIZE;
|
||||||
|
_fs->skip(data_size + SRS_FLV_PREVIOUS_TAG_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// seek to the sequence header start offset.
|
||||||
|
if (av_sequence_offset_start > 0) {
|
||||||
|
_fs->lseek(av_sequence_offset_start);
|
||||||
|
*pstart = av_sequence_offset_start;
|
||||||
|
*psize = (int)(av_sequence_offset_end - av_sequence_offset_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsFlvVodStreamDecoder::lseek(int64_t offset)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
srs_assert(_fs);
|
||||||
|
|
||||||
|
if (offset >= _fs->filesize()) {
|
||||||
|
ret = ERROR_SYSTEM_FILE_EOF;
|
||||||
|
srs_warn("flv fast decoder seek overflow file, "
|
||||||
|
"size=%"PRId64", offset=%"PRId64", ret=%d",
|
||||||
|
_fs->filesize(), offset, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_fs->lseek(offset) < 0) {
|
||||||
|
ret = ERROR_SYSTEM_FILE_SEEK;
|
||||||
|
srs_warn("flv fast decoder seek error, "
|
||||||
|
"size=%"PRId64", offset=%"PRId64", ret=%d",
|
||||||
|
_fs->filesize(), offset, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,9 @@ public:
|
||||||
virtual ~SrsFlvEncoder();
|
virtual ~SrsFlvEncoder();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* initialize the underlayer file stream,
|
* initialize the underlayer file stream.
|
||||||
* user can initialize multiple times to encode multiple flv files.
|
* @remark user can initialize multiple times to encode multiple flv files.
|
||||||
|
* @remark, user must free the fs, flv encoder never close/free it.
|
||||||
*/
|
*/
|
||||||
virtual int initialize(SrsFileWriter* fs);
|
virtual int initialize(SrsFileWriter* fs);
|
||||||
public:
|
public:
|
||||||
|
@ -85,21 +86,50 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* decode flv fast by only decoding the header and tag.
|
* decode flv file.
|
||||||
*/
|
*/
|
||||||
class SrsFlvFastDecoder
|
class SrsFlvDecoder
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SrsFileReader* _fs;
|
SrsFileReader* _fs;
|
||||||
private:
|
private:
|
||||||
SrsStream* tag_stream;
|
SrsStream* tag_stream;
|
||||||
public:
|
public:
|
||||||
SrsFlvFastDecoder();
|
SrsFlvDecoder();
|
||||||
virtual ~SrsFlvFastDecoder();
|
virtual ~SrsFlvDecoder();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* initialize the underlayer file stream,
|
* initialize the underlayer file stream
|
||||||
* user can initialize multiple times to encode multiple flv files.
|
* @remark user can initialize multiple times to decode multiple flv files.
|
||||||
|
* @remark, user must free the fs, flv decoder never close/free it.
|
||||||
|
*/
|
||||||
|
virtual int initialize(SrsFileReader* fs);
|
||||||
|
public:
|
||||||
|
virtual int read_header(char header[9]);
|
||||||
|
virtual int read_tag_header(char* ptype, int32_t* pdata_size, u_int32_t* ptime);
|
||||||
|
virtual int read_tag_data(char* data, int32_t size);
|
||||||
|
virtual int read_previous_tag_size(char ts[4]);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* decode flv fast by only decoding the header and tag.
|
||||||
|
* used for vod flv stream to read the header and sequence header,
|
||||||
|
* then seek to specified offset.
|
||||||
|
*/
|
||||||
|
class SrsFlvVodStreamDecoder
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SrsFileReader* _fs;
|
||||||
|
private:
|
||||||
|
SrsStream* tag_stream;
|
||||||
|
public:
|
||||||
|
SrsFlvVodStreamDecoder();
|
||||||
|
virtual ~SrsFlvVodStreamDecoder();
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* initialize the underlayer file stream
|
||||||
|
* @remark user can initialize multiple times to decode multiple flv files.
|
||||||
|
* @remark, user must free the fs, flv decoder never close/free it.
|
||||||
*/
|
*/
|
||||||
virtual int initialize(SrsFileReader* fs);
|
virtual int initialize(SrsFileReader* fs);
|
||||||
public:
|
public:
|
||||||
|
@ -118,29 +148,4 @@ public:
|
||||||
virtual int lseek(int64_t offset);
|
virtual int lseek(int64_t offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* decode flv file.
|
|
||||||
*/
|
|
||||||
class SrsFlvDecoder
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
SrsFileReader* _fs;
|
|
||||||
private:
|
|
||||||
SrsStream* tag_stream;
|
|
||||||
public:
|
|
||||||
SrsFlvDecoder();
|
|
||||||
virtual ~SrsFlvDecoder();
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* initialize the underlayer file stream,
|
|
||||||
* user can initialize multiple times to decode multiple flv files.
|
|
||||||
*/
|
|
||||||
virtual int initialize(SrsFileReader* fs);
|
|
||||||
public:
|
|
||||||
virtual int read_header(char header[9]);
|
|
||||||
virtual int read_tag_header(char* ptype, int32_t* pdata_size, u_int32_t* ptime);
|
|
||||||
virtual int read_tag_data(char* data, int32_t size);
|
|
||||||
virtual int read_previous_tag_size(char ts[4]);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,88 +26,7 @@ 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>
|
||||||
VOID TEST(KernelCodecTest, IsKeyFrame)
|
|
||||||
{
|
|
||||||
int8_t data;
|
|
||||||
|
|
||||||
data = 0x10;
|
|
||||||
EXPECT_TRUE(SrsFlvCodec::video_is_keyframe(&data, 1));
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::video_is_keyframe(&data, 0));
|
|
||||||
|
|
||||||
data = 0x20;
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::video_is_keyframe(&data, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TEST(KernelCodecTest, IsH264)
|
|
||||||
{
|
|
||||||
int8_t data;
|
|
||||||
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::video_is_h264(&data, 0));
|
|
||||||
|
|
||||||
data = 0x17;
|
|
||||||
EXPECT_TRUE(SrsFlvCodec::video_is_h264(&data, 1));
|
|
||||||
|
|
||||||
data = 0x07;
|
|
||||||
EXPECT_TRUE(SrsFlvCodec::video_is_h264(&data, 1));
|
|
||||||
|
|
||||||
data = 0x08;
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::video_is_h264(&data, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TEST(KernelCodecTest, IsSequenceHeader)
|
|
||||||
{
|
|
||||||
int16_t data;
|
|
||||||
char* pp = (char*)&data;
|
|
||||||
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 0));
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 1));
|
|
||||||
|
|
||||||
pp[0] = 0x17;
|
|
||||||
pp[1] = 0x00;
|
|
||||||
EXPECT_TRUE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
|
|
||||||
pp[0] = 0x18;
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
|
|
||||||
pp[0] = 0x27;
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
|
|
||||||
pp[0] = 0x17;
|
|
||||||
pp[1] = 0x01;
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TEST(KernelCodecTest, IsAAC)
|
|
||||||
{
|
|
||||||
int8_t data;
|
|
||||||
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::audio_is_aac(&data, 0));
|
|
||||||
|
|
||||||
data = 0xa0;
|
|
||||||
EXPECT_TRUE(SrsFlvCodec::audio_is_aac(&data, 1));
|
|
||||||
|
|
||||||
data = 0xa7;
|
|
||||||
EXPECT_TRUE(SrsFlvCodec::audio_is_aac(&data, 1));
|
|
||||||
|
|
||||||
data = 0x00;
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::audio_is_aac(&data, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TEST(KernelCodecTest, IsAudioSequenceHeader)
|
|
||||||
{
|
|
||||||
int16_t data;
|
|
||||||
char* pp = (char*)&data;
|
|
||||||
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::audio_is_sequence_header((int8_t*)pp, 0));
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::audio_is_sequence_header((int8_t*)pp, 1));
|
|
||||||
|
|
||||||
pp[0] = 0xa0;
|
|
||||||
pp[1] = 0x00;
|
|
||||||
EXPECT_TRUE(SrsFlvCodec::audio_is_sequence_header((int8_t*)pp, 2));
|
|
||||||
pp[0] = 0x00;
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
|
|
||||||
pp[0] = 0xa0;
|
|
||||||
pp[1] = 0x01;
|
|
||||||
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
MockSrsFileWriter::MockSrsFileWriter()
|
MockSrsFileWriter::MockSrsFileWriter()
|
||||||
{
|
{
|
||||||
|
@ -194,3 +113,92 @@ int MockSrsFileReader::read(void* buf, size_t count, ssize_t* pnread)
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID TEST(KernelCodecTest, IsKeyFrame)
|
||||||
|
{
|
||||||
|
int8_t data;
|
||||||
|
|
||||||
|
data = 0x10;
|
||||||
|
EXPECT_TRUE(SrsFlvCodec::video_is_keyframe(&data, 1));
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::video_is_keyframe(&data, 0));
|
||||||
|
|
||||||
|
data = 0x20;
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::video_is_keyframe(&data, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID TEST(KernelCodecTest, IsH264)
|
||||||
|
{
|
||||||
|
int8_t data;
|
||||||
|
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::video_is_h264(&data, 0));
|
||||||
|
|
||||||
|
data = 0x17;
|
||||||
|
EXPECT_TRUE(SrsFlvCodec::video_is_h264(&data, 1));
|
||||||
|
|
||||||
|
data = 0x07;
|
||||||
|
EXPECT_TRUE(SrsFlvCodec::video_is_h264(&data, 1));
|
||||||
|
|
||||||
|
data = 0x08;
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::video_is_h264(&data, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID TEST(KernelCodecTest, IsSequenceHeader)
|
||||||
|
{
|
||||||
|
int16_t data;
|
||||||
|
char* pp = (char*)&data;
|
||||||
|
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 0));
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 1));
|
||||||
|
|
||||||
|
pp[0] = 0x17;
|
||||||
|
pp[1] = 0x00;
|
||||||
|
EXPECT_TRUE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
|
||||||
|
pp[0] = 0x18;
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
|
||||||
|
pp[0] = 0x27;
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
|
||||||
|
pp[0] = 0x17;
|
||||||
|
pp[1] = 0x01;
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID TEST(KernelCodecTest, IsAAC)
|
||||||
|
{
|
||||||
|
int8_t data;
|
||||||
|
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::audio_is_aac(&data, 0));
|
||||||
|
|
||||||
|
data = 0xa0;
|
||||||
|
EXPECT_TRUE(SrsFlvCodec::audio_is_aac(&data, 1));
|
||||||
|
|
||||||
|
data = 0xa7;
|
||||||
|
EXPECT_TRUE(SrsFlvCodec::audio_is_aac(&data, 1));
|
||||||
|
|
||||||
|
data = 0x00;
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::audio_is_aac(&data, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID TEST(KernelCodecTest, IsAudioSequenceHeader)
|
||||||
|
{
|
||||||
|
int16_t data;
|
||||||
|
char* pp = (char*)&data;
|
||||||
|
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::audio_is_sequence_header((int8_t*)pp, 0));
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::audio_is_sequence_header((int8_t*)pp, 1));
|
||||||
|
|
||||||
|
pp[0] = 0xa0;
|
||||||
|
pp[1] = 0x00;
|
||||||
|
EXPECT_TRUE(SrsFlvCodec::audio_is_sequence_header((int8_t*)pp, 2));
|
||||||
|
pp[0] = 0x00;
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
|
||||||
|
pp[0] = 0xa0;
|
||||||
|
pp[1] = 0x01;
|
||||||
|
EXPECT_FALSE(SrsFlvCodec::video_is_sequence_header((int8_t*)pp, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID TEST(KernelFlvTest, IsAudioSequenceHeader)
|
||||||
|
{
|
||||||
|
MockSrsFileWriter fs;
|
||||||
|
SrsFlvEncoder enc;
|
||||||
|
ASSERT_TRUE(ERROR_SUCCESS == enc.initialize(&fs));
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue