Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2014-07-05 07:40:55 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
8271bd657b8cf64dbb8f133a72f67e5ad6c03a07
8271bd65
1 parent
03211858
refine flv codec, rename fast encoder to flv vod stream decoder
显示空白字符变更
内嵌
并排对比
正在显示
4 个修改的文件
包含
238 行增加
和
225 行删除
trunk/src/app/srs_app_http_conn.cpp
trunk/src/kernel/srs_kernel_flv.cpp
trunk/src/kernel/srs_kernel_flv.hpp
trunk/src/utest/srs_utest_kernel.cpp
trunk/src/app/srs_app_http_conn.cpp
查看文件 @
8271bd6
...
...
@@ -304,7 +304,7 @@ int SrsHttpVhost::response_flv_file2(SrsSocket* skt, SrsHttpMessage* req, string
return
ret
;
}
SrsFlv
Fast
Decoder
ffd
;
SrsFlv
VodStream
Decoder
ffd
;
// open fast decoder
if
((
ret
=
ffd
.
initialize
(
&
fs
))
!=
ERROR_SUCCESS
)
{
...
...
trunk/src/kernel/srs_kernel_flv.cpp
查看文件 @
8271bd6
...
...
@@ -225,18 +225,123 @@ int SrsFlvEncoder::write_tag(char* header, int header_size, char* tag, int tag_s
return
ret
;
}
SrsFlvFastDecoder
::
SrsFlvFastDecoder
()
SrsFlvDecoder
::
SrsFlvDecoder
()
{
_fs
=
NULL
;
tag_stream
=
new
SrsStream
();
}
SrsFlvDecoder
::~
SrsFlvDecoder
()
{
srs_freep
(
tag_stream
);
}
int
SrsFlvDecoder
::
initialize
(
SrsFileReader
*
fs
)
{
int
ret
=
ERROR_SUCCESS
;
_fs
=
fs
;
return
ret
;
}
int
SrsFlvDecoder
::
read_header
(
char
header
[
9
])
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
_fs
->
read
(
header
,
9
,
NULL
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
char
*
h
=
header
;
if
(
h
[
0
]
!=
'F'
||
h
[
1
]
!=
'L'
||
h
[
2
]
!=
'V'
)
{
ret
=
ERROR_SYSTEM_FLV_HEADER
;
srs_warn
(
"flv header must start with FLV. ret=%d"
,
ret
);
return
ret
;
}
return
ret
;
}
int
SrsFlvDecoder
::
read_tag_header
(
char
*
ptype
,
int32_t
*
pdata_size
,
u_int32_t
*
ptime
)
{
int
ret
=
ERROR_SUCCESS
;
char
th
[
11
];
// tag header
// read tag header
if
((
ret
=
_fs
->
read
(
th
,
11
,
NULL
))
!=
ERROR_SUCCESS
)
{
if
(
ret
!=
ERROR_SYSTEM_FILE_EOF
)
{
srs_error
(
"read flv tag header failed. ret=%d"
,
ret
);
}
return
ret
;
}
// Reserved UB [2]
// Filter UB [1]
// TagType UB [5]
*
ptype
=
(
int
)(
th
[
0
]
&
0x1F
);
// DataSize UI24
char
*
pp
=
(
char
*
)
pdata_size
;
pp
[
2
]
=
th
[
1
];
pp
[
1
]
=
th
[
2
];
pp
[
0
]
=
th
[
3
];
// Timestamp UI24
pp
=
(
char
*
)
ptime
;
pp
[
2
]
=
th
[
4
];
pp
[
1
]
=
th
[
5
];
pp
[
0
]
=
th
[
6
];
// TimestampExtended UI8
pp
[
3
]
=
th
[
7
];
return
ret
;
}
int
SrsFlvDecoder
::
read_tag_data
(
char
*
data
,
int32_t
size
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
_fs
->
read
(
data
,
size
,
NULL
))
!=
ERROR_SUCCESS
)
{
if
(
ret
!=
ERROR_SYSTEM_FILE_EOF
)
{
srs_error
(
"read flv tag header failed. ret=%d"
,
ret
);
}
return
ret
;
}
return
ret
;
}
int
SrsFlvDecoder
::
read_previous_tag_size
(
char
ts
[
4
])
{
int
ret
=
ERROR_SUCCESS
;
// ignore 4bytes tag size.
if
((
ret
=
_fs
->
read
(
ts
,
4
,
NULL
))
!=
ERROR_SUCCESS
)
{
if
(
ret
!=
ERROR_SYSTEM_FILE_EOF
)
{
srs_error
(
"read flv previous tag size failed. ret=%d"
,
ret
);
}
return
ret
;
}
return
ret
;
}
SrsFlvVodStreamDecoder
::
SrsFlvVodStreamDecoder
()
{
_fs
=
NULL
;
tag_stream
=
new
SrsStream
();
}
SrsFlv
FastDecoder
::~
SrsFlvFast
Decoder
()
SrsFlv
VodStreamDecoder
::~
SrsFlvVodStream
Decoder
()
{
srs_freep
(
tag_stream
);
}
int
SrsFlv
Fast
Decoder
::
initialize
(
SrsFileReader
*
fs
)
int
SrsFlv
VodStream
Decoder
::
initialize
(
SrsFileReader
*
fs
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -245,7 +350,7 @@ int SrsFlvFastDecoder::initialize(SrsFileReader* fs)
return
ret
;
}
int
SrsFlv
Fast
Decoder
::
read_header
(
char
**
pdata
,
int
*
psize
)
int
SrsFlv
VodStream
Decoder
::
read_header
(
char
**
pdata
,
int
*
psize
)
{
*
pdata
=
NULL
;
*
psize
=
0
;
...
...
@@ -268,7 +373,7 @@ int SrsFlvFastDecoder::read_header(char** pdata, int* psize)
return
ret
;
}
int
SrsFlv
Fast
Decoder
::
read_sequence_header
(
int64_t
*
pstart
,
int
*
psize
)
int
SrsFlv
VodStream
Decoder
::
read_sequence_header
(
int64_t
*
pstart
,
int
*
psize
)
{
*
pstart
=
0
;
*
psize
=
0
;
...
...
@@ -361,7 +466,7 @@ int SrsFlvFastDecoder::read_sequence_header(int64_t* pstart, int* psize)
return
ret
;
}
int
SrsFlv
Fast
Decoder
::
lseek
(
int64_t
offset
)
int
SrsFlv
VodStream
Decoder
::
lseek
(
int64_t
offset
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -386,108 +491,3 @@ int SrsFlvFastDecoder::lseek(int64_t offset)
return
ret
;
}
SrsFlvDecoder
::
SrsFlvDecoder
()
{
_fs
=
NULL
;
tag_stream
=
new
SrsStream
();
}
SrsFlvDecoder
::~
SrsFlvDecoder
()
{
srs_freep
(
tag_stream
);
}
int
SrsFlvDecoder
::
initialize
(
SrsFileReader
*
fs
)
{
int
ret
=
ERROR_SUCCESS
;
_fs
=
fs
;
return
ret
;
}
int
SrsFlvDecoder
::
read_header
(
char
header
[
9
])
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
_fs
->
read
(
header
,
9
,
NULL
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
char
*
h
=
header
;
if
(
h
[
0
]
!=
'F'
||
h
[
1
]
!=
'L'
||
h
[
2
]
!=
'V'
)
{
ret
=
ERROR_SYSTEM_FLV_HEADER
;
srs_warn
(
"flv header must start with FLV. ret=%d"
,
ret
);
return
ret
;
}
return
ret
;
}
int
SrsFlvDecoder
::
read_tag_header
(
char
*
ptype
,
int32_t
*
pdata_size
,
u_int32_t
*
ptime
)
{
int
ret
=
ERROR_SUCCESS
;
char
th
[
11
];
// tag header
// read tag header
if
((
ret
=
_fs
->
read
(
th
,
11
,
NULL
))
!=
ERROR_SUCCESS
)
{
if
(
ret
!=
ERROR_SYSTEM_FILE_EOF
)
{
srs_error
(
"read flv tag header failed. ret=%d"
,
ret
);
}
return
ret
;
}
// Reserved UB [2]
// Filter UB [1]
// TagType UB [5]
*
ptype
=
(
int
)(
th
[
0
]
&
0x1F
);
// DataSize UI24
char
*
pp
=
(
char
*
)
pdata_size
;
pp
[
2
]
=
th
[
1
];
pp
[
1
]
=
th
[
2
];
pp
[
0
]
=
th
[
3
];
// Timestamp UI24
pp
=
(
char
*
)
ptime
;
pp
[
2
]
=
th
[
4
];
pp
[
1
]
=
th
[
5
];
pp
[
0
]
=
th
[
6
];
// TimestampExtended UI8
pp
[
3
]
=
th
[
7
];
return
ret
;
}
int
SrsFlvDecoder
::
read_tag_data
(
char
*
data
,
int32_t
size
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
_fs
->
read
(
data
,
size
,
NULL
))
!=
ERROR_SUCCESS
)
{
if
(
ret
!=
ERROR_SYSTEM_FILE_EOF
)
{
srs_error
(
"read flv tag header failed. ret=%d"
,
ret
);
}
return
ret
;
}
return
ret
;
}
int
SrsFlvDecoder
::
read_previous_tag_size
(
char
ts
[
4
])
{
int
ret
=
ERROR_SUCCESS
;
// ignore 4bytes tag size.
if
((
ret
=
_fs
->
read
(
ts
,
4
,
NULL
))
!=
ERROR_SUCCESS
)
{
if
(
ret
!=
ERROR_SYSTEM_FILE_EOF
)
{
srs_error
(
"read flv previous tag size failed. ret=%d"
,
ret
);
}
return
ret
;
}
return
ret
;
}
...
...
trunk/src/kernel/srs_kernel_flv.hpp
查看文件 @
8271bd6
...
...
@@ -49,8 +49,9 @@ public:
virtual
~
SrsFlvEncoder
();
public
:
/**
* initialize the underlayer file stream,
* user can initialize multiple times to encode multiple flv files.
* initialize the underlayer file stream.
* @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
);
public
:
...
...
@@ -85,62 +86,66 @@ private:
};
/**
* decode flv f
ast by only decoding the header and tag
.
* decode flv f
ile
.
*/
class
SrsFlv
Fast
Decoder
class
SrsFlvDecoder
{
private
:
SrsFileReader
*
_fs
;
private
:
SrsStream
*
tag_stream
;
public
:
SrsFlvFastDecoder
();
virtual
~
SrsFlvFastDecoder
();
SrsFlvDecoder
();
virtual
~
SrsFlvDecoder
();
public
:
/**
* initialize the underlayer file stream,
* user can initialize multiple times to encode multiple flv files.
* 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
);
public
:
/**
* read the flv header and size.
*/
virtual
int
read_header
(
char
**
pdata
,
int
*
psize
);
/**
* read the sequence header and size.
*/
virtual
int
read_sequence_header
(
int64_t
*
pstart
,
int
*
psize
);
public
:
/**
* for start offset, seed to this position and response flv stream.
*/
virtual
int
lseek
(
int64_t
offset
);
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 file.
* 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
SrsFlvDecoder
class
SrsFlv
VodStream
Decoder
{
private
:
SrsFileReader
*
_fs
;
private
:
SrsStream
*
tag_stream
;
public
:
SrsFlvDecoder
();
virtual
~
SrsFlvDecoder
();
SrsFlvVodStreamDecoder
();
virtual
~
SrsFlvVodStreamDecoder
();
public
:
/**
* initialize the underlayer file stream,
* user can initialize multiple times to decode multiple flv files.
* 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
);
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
]);
/**
* read the flv header and size.
*/
virtual
int
read_header
(
char
**
pdata
,
int
*
psize
);
/**
* read the sequence header and size.
*/
virtual
int
read_sequence_header
(
int64_t
*
pstart
,
int
*
psize
);
public
:
/**
* for start offset, seed to this position and response flv stream.
*/
virtual
int
lseek
(
int64_t
offset
);
};
#endif
...
...
trunk/src/utest/srs_utest_kernel.cpp
查看文件 @
8271bd6
...
...
@@ -26,88 +26,7 @@ using namespace std;
#include <srs_kernel_error.hpp>
#include <srs_kernel_codec.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
));
}
#include <srs_kernel_flv.hpp>
MockSrsFileWriter
::
MockSrsFileWriter
()
{
...
...
@@ -194,3 +113,92 @@ int MockSrsFileReader::read(void* buf, size_t count, ssize_t* pnread)
int
ret
=
ERROR_SUCCESS
;
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
));
}
...
...
请
注册
或
登录
后发表评论