mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 03:41:55 +00:00
Cover FLV transmux.
This commit is contained in:
parent
f760c04340
commit
7aa5fbee85
4 changed files with 111 additions and 58 deletions
|
@ -420,10 +420,8 @@ srs_error_t SrsFlvTransmuxer::write_metadata(char type, char* data, int size)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
srs_assert(data);
|
if (size > 0) {
|
||||||
|
cache_metadata(type, data, size, tag_header);
|
||||||
if ((err = write_metadata_to_cache(type, data, size, tag_header)) != srs_success) {
|
|
||||||
return srs_error_wrap(err, "cache metadata");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = write_tag(tag_header, sizeof(tag_header), data, size)) != srs_success) {
|
if ((err = write_tag(tag_header, sizeof(tag_header), data, size)) != srs_success) {
|
||||||
|
@ -437,10 +435,8 @@ srs_error_t SrsFlvTransmuxer::write_audio(int64_t timestamp, char* data, int siz
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
srs_assert(data);
|
if (size > 0) {
|
||||||
|
cache_audio(timestamp, data, size, tag_header);
|
||||||
if ((err = write_audio_to_cache(timestamp, data, size, tag_header)) != srs_success) {
|
|
||||||
return srs_error_wrap(err, "cache audio");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = write_tag(tag_header, sizeof(tag_header), data, size)) != srs_success) {
|
if ((err = write_tag(tag_header, sizeof(tag_header), data, size)) != srs_success) {
|
||||||
|
@ -454,10 +450,8 @@ srs_error_t SrsFlvTransmuxer::write_video(int64_t timestamp, char* data, int siz
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
srs_assert(data);
|
if (size > 0) {
|
||||||
|
cache_video(timestamp, data, size, tag_header);
|
||||||
if ((err = write_video_to_cache(timestamp, data, size, tag_header)) != srs_success) {
|
|
||||||
return srs_error_wrap(err, "cache video");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = write_tag(tag_header, sizeof(tag_header), data, size)) != srs_success) {
|
if ((err = write_tag(tag_header, sizeof(tag_header), data, size)) != srs_success) {
|
||||||
|
@ -513,23 +507,15 @@ srs_error_t SrsFlvTransmuxer::write_tags(SrsSharedPtrMessage** msgs, int count)
|
||||||
|
|
||||||
// cache all flv header.
|
// cache all flv header.
|
||||||
if (msg->is_audio()) {
|
if (msg->is_audio()) {
|
||||||
if ((err = write_audio_to_cache(msg->timestamp, msg->payload, msg->size, cache)) != srs_success) {
|
cache_audio(msg->timestamp, msg->payload, msg->size, cache);
|
||||||
return srs_error_wrap(err, "cache audio");
|
|
||||||
}
|
|
||||||
} else if (msg->is_video()) {
|
} else if (msg->is_video()) {
|
||||||
if ((err = write_video_to_cache(msg->timestamp, msg->payload, msg->size, cache)) != srs_success) {
|
cache_video(msg->timestamp, msg->payload, msg->size, cache);
|
||||||
return srs_error_wrap(err, "cache video");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if ((err = write_metadata_to_cache(SrsFrameTypeScript, msg->payload, msg->size, cache)) != srs_success) {
|
cache_metadata(SrsFrameTypeScript, msg->payload, msg->size, cache);
|
||||||
return srs_error_wrap(err, "cache metadata");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// cache all pts.
|
// cache all pts.
|
||||||
if ((err = write_pts_to_cache(SRS_FLV_TAG_HEADER_SIZE + msg->size, pts)) != srs_success) {
|
cache_pts(SRS_FLV_TAG_HEADER_SIZE + msg->size, pts);
|
||||||
return srs_error_wrap(err, "cache pts");
|
|
||||||
}
|
|
||||||
|
|
||||||
// all ioves.
|
// all ioves.
|
||||||
iovs[0].iov_base = cache;
|
iovs[0].iov_base = cache;
|
||||||
|
@ -553,10 +539,8 @@ srs_error_t SrsFlvTransmuxer::write_tags(SrsSharedPtrMessage** msgs, int count)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
srs_error_t SrsFlvTransmuxer::write_metadata_to_cache(char type, char* data, int size, char* cache)
|
void SrsFlvTransmuxer::cache_metadata(char type, char* data, int size, char* cache)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
|
||||||
|
|
||||||
srs_assert(data);
|
srs_assert(data);
|
||||||
|
|
||||||
// 11 bytes tag header
|
// 11 bytes tag header
|
||||||
|
@ -577,14 +561,10 @@ srs_error_t SrsFlvTransmuxer::write_metadata_to_cache(char type, char* data, int
|
||||||
tag_stream->write_3bytes(0x00);
|
tag_stream->write_3bytes(0x00);
|
||||||
tag_stream->write_1bytes(0x00);
|
tag_stream->write_1bytes(0x00);
|
||||||
tag_stream->write_3bytes(0x00);
|
tag_stream->write_3bytes(0x00);
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsFlvTransmuxer::write_audio_to_cache(int64_t timestamp, char* data, int size, char* cache)
|
void SrsFlvTransmuxer::cache_audio(int64_t timestamp, char* data, int size, char* cache)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
|
||||||
|
|
||||||
srs_assert(data);
|
srs_assert(data);
|
||||||
|
|
||||||
timestamp &= 0x7fffffff;
|
timestamp &= 0x7fffffff;
|
||||||
|
@ -608,14 +588,10 @@ srs_error_t SrsFlvTransmuxer::write_audio_to_cache(int64_t timestamp, char* data
|
||||||
// default to little-endian
|
// default to little-endian
|
||||||
tag_stream->write_1bytes((timestamp >> 24) & 0xFF);
|
tag_stream->write_1bytes((timestamp >> 24) & 0xFF);
|
||||||
tag_stream->write_3bytes(0x00);
|
tag_stream->write_3bytes(0x00);
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsFlvTransmuxer::write_video_to_cache(int64_t timestamp, char* data, int size, char* cache)
|
void SrsFlvTransmuxer::cache_video(int64_t timestamp, char* data, int size, char* cache)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
|
||||||
|
|
||||||
srs_assert(data);
|
srs_assert(data);
|
||||||
|
|
||||||
timestamp &= 0x7fffffff;
|
timestamp &= 0x7fffffff;
|
||||||
|
@ -639,20 +615,13 @@ srs_error_t SrsFlvTransmuxer::write_video_to_cache(int64_t timestamp, char* data
|
||||||
// default to little-endian
|
// default to little-endian
|
||||||
tag_stream->write_1bytes((timestamp >> 24) & 0xFF);
|
tag_stream->write_1bytes((timestamp >> 24) & 0xFF);
|
||||||
tag_stream->write_3bytes(0x00);
|
tag_stream->write_3bytes(0x00);
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsFlvTransmuxer::write_pts_to_cache(int size, char* cache)
|
void SrsFlvTransmuxer::cache_pts(int size, char* cache)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
|
||||||
|
|
||||||
SrsBuffer* tag_stream = new SrsBuffer(cache, 11);
|
SrsBuffer* tag_stream = new SrsBuffer(cache, 11);
|
||||||
SrsAutoFree(SrsBuffer, tag_stream);
|
SrsAutoFree(SrsBuffer, tag_stream);
|
||||||
|
|
||||||
tag_stream->write_4bytes(size);
|
tag_stream->write_4bytes(size);
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsFlvTransmuxer::write_tag(char* header, int header_size, char* tag, int tag_size)
|
srs_error_t SrsFlvTransmuxer::write_tag(char* header, int header_size, char* tag, int tag_size)
|
||||||
|
@ -661,9 +630,7 @@ srs_error_t SrsFlvTransmuxer::write_tag(char* header, int header_size, char* tag
|
||||||
|
|
||||||
// PreviousTagSizeN UI32 Size of last tag, including its header, in bytes.
|
// PreviousTagSizeN UI32 Size of last tag, including its header, in bytes.
|
||||||
char pre_size[SRS_FLV_PREVIOUS_TAG_SIZE];
|
char pre_size[SRS_FLV_PREVIOUS_TAG_SIZE];
|
||||||
if ((err = write_pts_to_cache(tag_size + header_size, pre_size)) != srs_success) {
|
cache_pts(tag_size + header_size, pre_size);
|
||||||
return srs_error_wrap(err, "cache pts");
|
|
||||||
}
|
|
||||||
|
|
||||||
iovec iovs[3];
|
iovec iovs[3];
|
||||||
iovs[0].iov_base = header;
|
iovs[0].iov_base = header;
|
||||||
|
|
|
@ -394,10 +394,10 @@ public:
|
||||||
virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count);
|
virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count);
|
||||||
#endif
|
#endif
|
||||||
private:
|
private:
|
||||||
virtual srs_error_t write_metadata_to_cache(char type, char* data, int size, char* cache);
|
virtual void cache_metadata(char type, char* data, int size, char* cache);
|
||||||
virtual srs_error_t write_audio_to_cache(int64_t timestamp, char* data, int size, char* cache);
|
virtual void cache_audio(int64_t timestamp, char* data, int size, char* cache);
|
||||||
virtual srs_error_t write_video_to_cache(int64_t timestamp, char* data, int size, char* cache);
|
virtual void cache_video(int64_t timestamp, char* data, int size, char* cache);
|
||||||
virtual srs_error_t write_pts_to_cache(int size, char* cache);
|
virtual void cache_pts(int size, char* cache);
|
||||||
virtual srs_error_t write_tag(char* header, int header_size, char* tag, int tag_size);
|
virtual srs_error_t write_tag(char* header, int header_size, char* tag, int tag_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ MockSrsFileWriter::MockSrsFileWriter()
|
||||||
data = new char[size];
|
data = new char[size];
|
||||||
offset = 0;
|
offset = 0;
|
||||||
err = srs_success;
|
err = srs_success;
|
||||||
error_offset = 0;
|
error_offset = -1;
|
||||||
opened = false;
|
opened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,8 +95,9 @@ srs_error_t MockSrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
|
||||||
}
|
}
|
||||||
|
|
||||||
int nwriten = srs_min(MAX_MOCK_DATA_SIZE - offset, (int)count);
|
int nwriten = srs_min(MAX_MOCK_DATA_SIZE - offset, (int)count);
|
||||||
|
if (nwriten > 0) {
|
||||||
memcpy(data + offset, buf, nwriten);
|
memcpy(data + offset, buf, nwriten);
|
||||||
|
}
|
||||||
|
|
||||||
if (pnwrite) {
|
if (pnwrite) {
|
||||||
*pnwrite = nwriten;
|
*pnwrite = nwriten;
|
||||||
|
@ -105,7 +106,7 @@ srs_error_t MockSrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
|
||||||
offset += nwriten;
|
offset += nwriten;
|
||||||
size = srs_max(size, offset);
|
size = srs_max(size, offset);
|
||||||
|
|
||||||
if (error_offset > 0 && offset >= error_offset) {
|
if (error_offset >= 0 && offset > error_offset) {
|
||||||
return srs_error_new(-1, "exceed offset");
|
return srs_error_new(-1, "exceed offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,6 +659,89 @@ VOID TEST(KernelFlvTest, FlvEncoderSizeTag)
|
||||||
EXPECT_EQ(11+4+0, SrsFlvTransmuxer::size_tag(0));
|
EXPECT_EQ(11+4+0, SrsFlvTransmuxer::size_tag(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID TEST(KernelFLVTest, CoverErrorCase)
|
||||||
|
{
|
||||||
|
srs_error_t err;
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockSrsFileWriter w;
|
||||||
|
HELPER_EXPECT_SUCCESS(w.open(""));
|
||||||
|
|
||||||
|
SrsFlvTransmuxer m;
|
||||||
|
HELPER_EXPECT_SUCCESS(m.initialize(&w));
|
||||||
|
HELPER_EXPECT_SUCCESS(m.write_header());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockSrsFileWriter w;
|
||||||
|
HELPER_EXPECT_SUCCESS(w.open(""));
|
||||||
|
w.error_offset = 0;
|
||||||
|
|
||||||
|
SrsFlvTransmuxer m;
|
||||||
|
HELPER_EXPECT_SUCCESS(m.initialize(&w));
|
||||||
|
HELPER_EXPECT_FAILED(m.write_header());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockSrsFileWriter w;
|
||||||
|
HELPER_EXPECT_SUCCESS(w.open(""));
|
||||||
|
w.error_offset = 9;
|
||||||
|
|
||||||
|
SrsFlvTransmuxer m;
|
||||||
|
HELPER_EXPECT_SUCCESS(m.initialize(&w));
|
||||||
|
HELPER_EXPECT_FAILED(m.write_header());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockSrsFileWriter w;
|
||||||
|
HELPER_EXPECT_SUCCESS(w.open(""));
|
||||||
|
w.error_offset = 0;
|
||||||
|
|
||||||
|
SrsFlvTransmuxer m;
|
||||||
|
HELPER_EXPECT_SUCCESS(m.initialize(&w));
|
||||||
|
HELPER_EXPECT_FAILED(m.write_metadata(0, NULL, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockSrsFileWriter w;
|
||||||
|
HELPER_EXPECT_SUCCESS(w.open(""));
|
||||||
|
w.error_offset = 0;
|
||||||
|
|
||||||
|
SrsFlvTransmuxer m;
|
||||||
|
HELPER_EXPECT_SUCCESS(m.initialize(&w));
|
||||||
|
HELPER_EXPECT_FAILED(m.write_audio(0, NULL, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockSrsFileWriter w;
|
||||||
|
HELPER_EXPECT_SUCCESS(w.open(""));
|
||||||
|
w.error_offset = 0;
|
||||||
|
|
||||||
|
SrsFlvTransmuxer m;
|
||||||
|
HELPER_EXPECT_SUCCESS(m.initialize(&w));
|
||||||
|
HELPER_EXPECT_FAILED(m.write_video(0, NULL, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SRS_PERF_FAST_FLV_ENCODER
|
||||||
|
if (true) {
|
||||||
|
MockSrsFileWriter w;
|
||||||
|
HELPER_EXPECT_SUCCESS(w.open(""));
|
||||||
|
w.error_offset = 0;
|
||||||
|
|
||||||
|
SrsFlvTransmuxer m;
|
||||||
|
HELPER_EXPECT_SUCCESS(m.initialize(&w));
|
||||||
|
|
||||||
|
SrsMessageHeader h;
|
||||||
|
h.initialize_video(10, 30, 20);
|
||||||
|
SrsSharedPtrMessage msg;
|
||||||
|
HELPER_EXPECT_SUCCESS(msg.create(&h, new char[1], 1));
|
||||||
|
|
||||||
|
SrsSharedPtrMessage* msgs = &msg;
|
||||||
|
HELPER_EXPECT_FAILED(m.write_tags(&msgs, 1));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test the flv decoder,
|
* test the flv decoder,
|
||||||
* exception: file stream not open.
|
* exception: file stream not open.
|
||||||
|
@ -2403,7 +2487,7 @@ VOID TEST(KernelAACTest, TransmaxRTMP2AAC)
|
||||||
EXPECT_EQ(44100, srs_aac_srates[m.aac_sample_rate]);
|
EXPECT_EQ(44100, srs_aac_srates[m.aac_sample_rate]);
|
||||||
EXPECT_EQ(2, m.aac_channels);
|
EXPECT_EQ(2, m.aac_channels);
|
||||||
|
|
||||||
f.error_offset = 7;
|
f.error_offset = 6;
|
||||||
|
|
||||||
err = m.write_audio(0, (char*)"\xaf\x01\x00", 3);
|
err = m.write_audio(0, (char*)"\xaf\x01\x00", 3);
|
||||||
EXPECT_TRUE(srs_success != err);
|
EXPECT_TRUE(srs_success != err);
|
||||||
|
@ -2427,7 +2511,7 @@ VOID TEST(KernelAACTest, TransmaxRTMP2AAC)
|
||||||
EXPECT_EQ(44100, srs_aac_srates[m.aac_sample_rate]);
|
EXPECT_EQ(44100, srs_aac_srates[m.aac_sample_rate]);
|
||||||
EXPECT_EQ(2, m.aac_channels);
|
EXPECT_EQ(2, m.aac_channels);
|
||||||
|
|
||||||
f.error_offset = 8;
|
f.error_offset = 7;
|
||||||
|
|
||||||
err = m.write_audio(0, (char*)"\xaf\x01\x00", 3);
|
err = m.write_audio(0, (char*)"\xaf\x01\x00", 3);
|
||||||
EXPECT_TRUE(srs_success != err);
|
EXPECT_TRUE(srs_success != err);
|
||||||
|
|
|
@ -53,7 +53,9 @@ public:
|
||||||
int size;
|
int size;
|
||||||
int offset;
|
int offset;
|
||||||
srs_error_t err;
|
srs_error_t err;
|
||||||
|
// Error if exceed this offset.
|
||||||
int error_offset;
|
int error_offset;
|
||||||
|
// Whether opened.
|
||||||
bool opened;
|
bool opened;
|
||||||
public:
|
public:
|
||||||
MockSrsFileWriter();
|
MockSrsFileWriter();
|
||||||
|
|
Loading…
Reference in a new issue