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
2013-11-24 12:39:47 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
ba234e87417b5d1dc06ab39ed3b8abc3fee74dd0
ba234e87
1 parent
b87318de
add avc format doc. decode the flv codec info
隐藏空白字符变更
内嵌
并排对比
正在显示
10 个修改的文件
包含
387 行增加
和
97 行删除
trunk/doc/H.264-AVC-ISO_IEC_14496-15.pdf
trunk/src/core/srs_core_client.cpp
trunk/src/core/srs_core_codec.cpp
trunk/src/core/srs_core_codec.hpp
trunk/src/core/srs_core_hls.cpp
trunk/src/core/srs_core_hls.hpp
trunk/src/core/srs_core_source.cpp
trunk/src/core/srs_core_source.hpp
trunk/src/core/srs_core_stream.cpp
trunk/src/core/srs_core_stream.hpp
trunk/doc/H.264-AVC-ISO_IEC_14496-15.pdf
0 → 100644
查看文件 @
ba234e8
不能预览此文件类型
trunk/src/core/srs_core_client.cpp
查看文件 @
ba234e8
...
...
@@ -151,6 +151,7 @@ int SrsClient::do_cycle()
// find a source to publish.
SrsSource
*
source
=
SrsSource
::
find
(
req
->
get_stream_url
());
srs_assert
(
source
!=
NULL
);
SrsHLS
*
hls
=
source
->
get_hls
();
bool
enabled_cache
=
true
;
conf
=
config
->
get_gop_cache
(
req
->
vhost
);
...
...
@@ -181,6 +182,7 @@ int SrsClient::do_cycle()
}
srs_info
(
"start to publish stream %s success"
,
req
->
stream
.
c_str
());
ret
=
publish
(
source
,
true
);
hls
->
on_unpublish
();
source
->
on_unpublish
();
return
ret
;
}
...
...
@@ -193,6 +195,7 @@ int SrsClient::do_cycle()
}
srs_info
(
"flash start to publish stream %s success"
,
req
->
stream
.
c_str
());
ret
=
publish
(
source
,
false
);
hls
->
on_unpublish
();
source
->
on_unpublish
();
return
ret
;
}
...
...
@@ -330,8 +333,15 @@ int SrsClient::publish(SrsSource* source, bool is_fmle)
srs_verbose
(
"check publish_refer success."
);
SrsPithyPrint
pithy_print
(
SRS_STAGE_PUBLISH_USER
);
SrsHLS
*
hls
=
source
->
get_hls
();
// notify the hls to prepare when publish start.
if
((
ret
=
hls
->
on_publish
())
!=
ERROR_SUCCESS
)
{
srs_error
(
"hls on_publish failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"hls on_publish success."
);
while
(
true
)
{
// switch to other st-threads.
st_usleep
(
0
);
...
...
@@ -366,14 +376,26 @@ int SrsClient::process_publish_message(SrsSource* source, SrsHLS* hls, SrsCommon
int
ret
=
ERROR_SUCCESS
;
// process audio packet
if
(
msg
->
header
.
is_audio
()
&&
((
ret
=
source
->
on_audio
(
msg
))
!=
ERROR_SUCCESS
))
{
srs_error
(
"process audio message failed. ret=%d"
,
ret
);
return
ret
;
if
(
msg
->
header
.
is_audio
())
{
if
((
ret
=
hls
->
on_audio
(
msg
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"hls process audio message failed. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
source
->
on_audio
(
msg
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"source process audio message failed. ret=%d"
,
ret
);
return
ret
;
}
}
// process video packet
if
(
msg
->
header
.
is_video
()
&&
((
ret
=
source
->
on_video
(
msg
))
!=
ERROR_SUCCESS
))
{
srs_error
(
"process video message failed. ret=%d"
,
ret
);
return
ret
;
if
(
msg
->
header
.
is_video
())
{
if
((
ret
=
hls
->
on_video
(
msg
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"hls process video message failed. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
source
->
on_video
(
msg
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"source process video message failed. ret=%d"
,
ret
);
return
ret
;
}
}
// process onMetaData
...
...
@@ -386,8 +408,12 @@ int SrsClient::process_publish_message(SrsSource* source, SrsHLS* hls, SrsCommon
SrsPacket
*
pkt
=
msg
->
get_packet
();
if
(
dynamic_cast
<
SrsOnMetaDataPacket
*>
(
pkt
))
{
SrsOnMetaDataPacket
*
metadata
=
dynamic_cast
<
SrsOnMetaDataPacket
*>
(
pkt
);
if
((
ret
=
hls
->
on_meta_data
(
metadata
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"hls process onMetaData message failed. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
source
->
on_meta_data
(
msg
,
metadata
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"process onMetaData message failed. ret=%d"
,
ret
);
srs_error
(
"
source
process onMetaData message failed. ret=%d"
,
ret
);
return
ret
;
}
srs_trace
(
"process onMetaData message success."
);
...
...
trunk/src/core/srs_core_codec.cpp
查看文件 @
ba234e8
...
...
@@ -23,32 +23,84 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core_codec.hpp>
#include <srs_core_error.hpp>
#include <srs_core_stream.hpp>
SrsCodec
::
SrsCodec
()
{
width
=
0
;
height
=
0
;
duration
=
0
;
frame_rate
=
0
;
video_data_rate
=
0
;
video_codec_id
=
0
;
audio_data_rate
=
0
;
audio_codec_id
=
0
;
aac_sample_rate
=
0
;
sample_rate
=
0
;
sample_size
=
0
;
audio_channels
=
0
;
profile
=
0
;
level
=
0
;
avc_extra_size
=
0
;
avc_extra_data
=
NULL
;
aac_extra_size
=
0
;
aac_extra_data
=
NULL
;
stream
=
new
SrsStream
();
}
SrsCodec
::~
SrsCodec
()
{
srs_freepa
(
avc_extra_data
);
srs_freepa
(
aac_extra_data
);
srs_freep
(
stream
);
}
bool
SrsCodec
::
video_is_keyframe
(
int8_t
*
data
,
int
size
)
int
SrsCodec
::
parse_av_codec
(
bool
is_video
,
int8_t
*
data
,
int
size
)
{
// E.4.3.1 VIDEODATA
// Frame Type UB [4]
// Type of video frame. The following values are defined:
// 1 = key frame (for AVC, a seekable frame)
// 2 = inter frame (for AVC, a non-seekable frame)
// 3 = disposable inter frame (H.263 only)
// 4 = generated key frame (reserved for server use only)
// 5 = video info/command frame
//
// AVCPacketType IF CodecID == 7 UI8
// The following values are defined:
// 0 = AVC sequence header
// 1 = AVC NALU
// 2 = AVC end of sequence (lower level NALU sequence ender is
// not required or supported)
int
ret
=
ERROR_SUCCESS
;
if
(
!
data
||
size
<=
0
)
{
return
ret
;
}
if
((
ret
=
stream
->
initialize
((
char
*
)
data
,
size
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
is_video
)
{
if
(
!
stream
->
require
(
1
))
{
return
ret
;
}
int8_t
frame_type
=
stream
->
read_1bytes
();
int8_t
codec_id
=
frame_type
&
0x0f
;
frame_type
=
(
frame_type
>>
4
)
&
0x0f
;
video_codec_id
=
codec_id
;
if
(
codec_id
!=
SrsCodecVideoAVC
)
{
return
ret
;
}
if
(
!
stream
->
require
(
4
))
{
return
ret
;
}
int8_t
avc_packet_type
=
stream
->
read_1bytes
();
int32_t
composition_time
=
stream
->
read_3bytes
();
// 5.2.4.1.1 Syntax
if
(
avc_packet_type
==
SrsCodecVideoAVCTypeSequenceHeader
)
{
}
}
else
{
}
return
ret
;
}
bool
SrsCodec
::
video_is_keyframe
(
int8_t
*
data
,
int
size
)
{
// 2bytes required.
if
(
size
<
1
)
{
return
false
;
...
...
@@ -57,27 +109,11 @@ bool SrsCodec::video_is_keyframe(int8_t* data, int size)
char
frame_type
=
*
(
char
*
)
data
;
frame_type
=
(
frame_type
>>
4
)
&
0x0F
;
return
frame_type
==
1
;
return
frame_type
==
SrsCodecVideoAVCFrameKeyFrame
;
}
bool
SrsCodec
::
video_is_sequence_header
(
int8_t
*
data
,
int
size
)
{
// E.4.3.1 VIDEODATA
// Frame Type UB [4]
// Type of video frame. The following values are defined:
// 1 = key frame (for AVC, a seekable frame)
// 2 = inter frame (for AVC, a non-seekable frame)
// 3 = disposable inter frame (H.263 only)
// 4 = generated key frame (reserved for server use only)
// 5 = video info/command frame
//
// AVCPacketType IF CodecID == 7 UI8
// The following values are defined:
// 0 = AVC sequence header
// 1 = AVC NALU
// 2 = AVC end of sequence (lower level NALU sequence ender is
// not required or supported)
// sequence header only for h264
if
(
!
video_is_h264
(
data
,
size
))
{
return
false
;
...
...
@@ -93,16 +129,12 @@ bool SrsCodec::video_is_sequence_header(int8_t* data, int size)
char
avc_packet_type
=
*
(
char
*
)(
data
+
1
);
return
frame_type
==
1
&&
avc_packet_type
==
0
;
return
frame_type
==
SrsCodecVideoAVCFrameKeyFrame
&&
avc_packet_type
==
SrsCodecVideoAVCTypeSequenceHeader
;
}
bool
SrsCodec
::
audio_is_sequence_header
(
int8_t
*
data
,
int
size
)
{
// AACPacketType IF SoundFormat == 10 UI8
// The following values are defined:
// 0 = AAC sequence header
// 1 = AAC raw
// sequence header only for aac
if
(
!
audio_is_aac
(
data
,
size
))
{
return
false
;
...
...
@@ -115,21 +147,11 @@ bool SrsCodec::audio_is_sequence_header(int8_t* data, int size)
char
aac_packet_type
=
*
(
char
*
)(
data
+
1
);
return
aac_packet_type
==
0
;
return
aac_packet_type
==
SrsCodecAudioTypeSequenceHeader
;
}
bool
SrsCodec
::
video_is_h264
(
int8_t
*
data
,
int
size
)
{
// E.4.3.1 VIDEODATA
// CodecID UB [4]
// Codec Identifier. The following values are defined:
// 2 = Sorenson H.263
// 3 = Screen video
// 4 = On2 VP6
// 5 = On2 VP6 with alpha channel
// 6 = Screen video version 2
// 7 = AVC
// 1bytes required.
if
(
size
<
1
)
{
return
false
;
...
...
@@ -138,31 +160,11 @@ bool SrsCodec::video_is_h264(int8_t* data, int size)
char
codec_id
=
*
(
char
*
)
data
;
codec_id
=
codec_id
&
0x0F
;
return
codec_id
==
7
;
return
codec_id
==
SrsCodecVideoAVC
;
}
bool
SrsCodec
::
audio_is_aac
(
int8_t
*
data
,
int
size
)
{
// SoundFormat UB [4]
// Format of SoundData. The following values are defined:
// 0 = Linear PCM, platform endian
// 1 = ADPCM
// 2 = MP3
// 3 = Linear PCM, little endian
// 4 = Nellymoser 16 kHz mono
// 5 = Nellymoser 8 kHz mono
// 6 = Nellymoser
// 7 = G.711 A-law logarithmic PCM
// 8 = G.711 mu-law logarithmic PCM
// 9 = reserved
// 10 = AAC
// 11 = Speex
// 14 = MP3 8 kHz
// 15 = Device-specific sound
// Formats 7, 8, 14, and 15 are reserved.
// AAC is supported in Flash Player 9,0,115,0 and higher.
// Speex is supported in Flash Player 10 and higher.
// 1bytes required.
if
(
size
<
1
)
{
return
false
;
...
...
@@ -171,5 +173,5 @@ bool SrsCodec::audio_is_aac(int8_t* data, int size)
char
sound_format
=
*
(
char
*
)
data
;
sound_format
=
(
sound_format
>>
4
)
&
0x0F
;
return
sound_format
==
10
;
return
sound_format
==
SrsCodecAudioAAC
;
}
...
...
trunk/src/core/srs_core_codec.hpp
查看文件 @
ba234e8
...
...
@@ -30,36 +30,170 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core.hpp>
class
SrsStream
;
// E.4.3.1 VIDEODATA
// CodecID UB [4]
// Codec Identifier. The following values are defined:
// 2 = Sorenson H.263
// 3 = Screen video
// 4 = On2 VP6
// 5 = On2 VP6 with alpha channel
// 6 = Screen video version 2
// 7 = AVC
enum
SrsCodecVideo
{
SrsCodecVideoSorensonH263
=
2
,
SrsCodecVideoScreenVideo
=
3
,
SrsCodecVideoOn2VP6
=
4
,
SrsCodecVideoOn2VP6WithAlphaChannel
=
5
,
SrsCodecVideoScreenVideoVersion2
=
6
,
SrsCodecVideoAVC
=
7
,
};
// E.4.3.1 VIDEODATA
// Frame Type UB [4]
// Type of video frame. The following values are defined:
// 1 = key frame (for AVC, a seekable frame)
// 2 = inter frame (for AVC, a non-seekable frame)
// 3 = disposable inter frame (H.263 only)
// 4 = generated key frame (reserved for server use only)
// 5 = video info/command frame
enum
SrsCodecVideoAVCFrame
{
SrsCodecVideoAVCFrameKeyFrame
=
1
,
SrsCodecVideoAVCFrameInterFrame
=
2
,
SrsCodecVideoAVCFrameDisposableInterFrame
=
3
,
SrsCodecVideoAVCFrameGeneratedKeyFrame
=
4
,
SrsCodecVideoAVCFrameVideoInfoFrame
=
5
,
};
// AVCPacketType IF CodecID == 7 UI8
// The following values are defined:
// 0 = AVC sequence header
// 1 = AVC NALU
// 2 = AVC end of sequence (lower level NALU sequence ender is
// not required or supported)
enum
SrsCodecVideoAVCType
{
SrsCodecVideoAVCTypeSequenceHeader
=
0
,
SrsCodecVideoAVCTypeNALU
=
1
,
SrsCodecVideoAVCTypeSequenceHeaderEOF
=
2
,
};
// SoundFormat UB [4]
// Format of SoundData. The following values are defined:
// 0 = Linear PCM, platform endian
// 1 = ADPCM
// 2 = MP3
// 3 = Linear PCM, little endian
// 4 = Nellymoser 16 kHz mono
// 5 = Nellymoser 8 kHz mono
// 6 = Nellymoser
// 7 = G.711 A-law logarithmic PCM
// 8 = G.711 mu-law logarithmic PCM
// 9 = reserved
// 10 = AAC
// 11 = Speex
// 14 = MP3 8 kHz
// 15 = Device-specific sound
// Formats 7, 8, 14, and 15 are reserved.
// AAC is supported in Flash Player 9,0,115,0 and higher.
// Speex is supported in Flash Player 10 and higher.
enum
SrsCodecAudio
{
SrsCodecAudioLinearPCMPlatformEndian
=
0
,
SrsCodecAudioADPCM
=
1
,
SrsCodecAudioMP3
=
2
,
SrsCodecAudioLinearPCMLittleEndian
=
3
,
SrsCodecAudioNellymoser16kHzMono
=
4
,
SrsCodecAudioNellymoser8kHzMono
=
5
,
SrsCodecAudioNellymoser
=
6
,
SrsCodecAudioReservedG711AlawLogarithmicPCM
=
7
,
SrsCodecAudioReservedG711MuLawLogarithmicPCM
=
8
,
SrsCodecAudioReserved
=
9
,
SrsCodecAudioAAC
=
10
,
SrsCodecAudioSpeex
=
11
,
SrsCodecAudioReservedMP3_8kHz
=
14
,
SrsCodecAudioReservedDeviceSpecificSound
=
15
,
};
// AACPacketType IF SoundFormat == 10 UI8
// The following values are defined:
// 0 = AAC sequence header
// 1 = AAC raw
enum
SrsCodecAudioType
{
SrsCodecAudioTypeSequenceHeader
=
0
,
SrsCodecAudioTypeRawData
=
1
,
};
/**
* Annex E. The FLV File Format
*/
class
SrsCodec
{
private
:
SrsStream
*
stream
;
public
:
/**
* video specified
*/
int
width
;
int
height
;
int
duration
;
int
frame_rate
;
// @see: SrsCodecVideo
int
video_codec_id
;
int
video_data_rate
;
// in bps
u_int8_t
profile
;
// profile_idc, page 45.
u_int8_t
level
;
// level_idc, page 45.
/**
* audio specified
*/
int
audio_codec_id
;
int
audio_data_rate
;
// in bps
int
aac_sample_rate
;
int
sample_rate
;
/* 5512, 11025, 22050, 44100 */
int
sample_size
;
/* 1=8bit, 2=16bit */
int
audio_channels
;
/* 1, 2 */
// the avc extra data, the AVC sequence header,
// without the flv codec header
int
avc_extra_size
;
char
*
avc_extra_data
;
// the aac extra data, the AAC sequence header,
// without the flv codec header
int
aac_extra_size
;
char
*
aac_extra_data
;
public
:
SrsCodec
();
virtual
~
SrsCodec
();
// the following function used for hls to build the codec info.
public:
virtual
int
parse_av_codec
(
bool
is_video
,
int8_t
*
data
,
int
size
);
// the following function used to finger out the flv/rtmp packet detail.
public:
/**
* only check the frame_type, not check the codec type.
*/
virtual
bool
video_is_keyframe
(
int8_t
*
data
,
int
size
);
static
bool
video_is_keyframe
(
int8_t
*
data
,
int
size
);
/**
* check codec h264, keyframe, sequence header
*/
virtual
bool
video_is_sequence_header
(
int8_t
*
data
,
int
size
);
static
bool
video_is_sequence_header
(
int8_t
*
data
,
int
size
);
/**
* check codec aac, sequence header
*/
virtual
bool
audio_is_sequence_header
(
int8_t
*
data
,
int
size
);
static
bool
audio_is_sequence_header
(
int8_t
*
data
,
int
size
);
/**
* check codec h264.
*/
virtual
bool
video_is_h264
(
int8_t
*
data
,
int
size
);
static
bool
video_is_h264
(
int8_t
*
data
,
int
size
);
private
:
/**
* check codec aac.
*/
virtual
bool
audio_is_aac
(
int8_t
*
data
,
int
size
);
static
bool
audio_is_aac
(
int8_t
*
data
,
int
size
);
};
#endif
\ No newline at end of file
...
...
trunk/src/core/srs_core_hls.cpp
查看文件 @
ba234e8
...
...
@@ -23,11 +23,117 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core_hls.hpp>
#include <srs_core_error.hpp>
#include <srs_core_codec.hpp>
#include <srs_core_amf0.hpp>
#include <srs_core_protocol.hpp>
SrsHLS
::
SrsHLS
()
{
codec
=
new
SrsCodec
();
}
SrsHLS
::~
SrsHLS
()
{
srs_freep
(
codec
);
}
int
SrsHLS
::
on_publish
()
{
int
ret
=
ERROR_SUCCESS
;
return
ret
;
}
void
SrsHLS
::
on_unpublish
()
{
}
int
SrsHLS
::
on_meta_data
(
SrsOnMetaDataPacket
*
metadata
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
!
metadata
||
!
metadata
->
metadata
)
{
return
ret
;
}
SrsAmf0Object
*
obj
=
metadata
->
metadata
;
if
(
obj
->
size
()
<=
0
)
{
return
ret
;
}
// finger out the codec info from metadata if possible.
SrsAmf0Any
*
prop
=
NULL
;
if
((
prop
=
obj
->
get_property
(
"duration"
))
!=
NULL
&&
prop
->
is_number
())
{
codec
->
duration
=
(
int
)
srs_amf0_convert
<
SrsAmf0Number
>
(
prop
)
->
value
;
}
if
((
prop
=
obj
->
get_property
(
"width"
))
!=
NULL
&&
prop
->
is_number
())
{
codec
->
width
=
(
int
)
srs_amf0_convert
<
SrsAmf0Number
>
(
prop
)
->
value
;
}
if
((
prop
=
obj
->
get_property
(
"height"
))
!=
NULL
&&
prop
->
is_number
())
{
codec
->
height
=
(
int
)
srs_amf0_convert
<
SrsAmf0Number
>
(
prop
)
->
value
;
}
if
((
prop
=
obj
->
get_property
(
"framerate"
))
!=
NULL
&&
prop
->
is_number
())
{
codec
->
frame_rate
=
(
int
)
srs_amf0_convert
<
SrsAmf0Number
>
(
prop
)
->
value
;
}
if
((
prop
=
obj
->
get_property
(
"videocodecid"
))
!=
NULL
&&
prop
->
is_number
())
{
codec
->
video_codec_id
=
(
int
)
srs_amf0_convert
<
SrsAmf0Number
>
(
prop
)
->
value
;
}
if
((
prop
=
obj
->
get_property
(
"videodatarate"
))
!=
NULL
&&
prop
->
is_number
())
{
codec
->
video_data_rate
=
(
int
)(
1000
*
srs_amf0_convert
<
SrsAmf0Number
>
(
prop
)
->
value
);
}
if
((
prop
=
obj
->
get_property
(
"audiocodecid"
))
!=
NULL
&&
prop
->
is_number
())
{
codec
->
audio_codec_id
=
(
int
)
srs_amf0_convert
<
SrsAmf0Number
>
(
prop
)
->
value
;
}
if
((
prop
=
obj
->
get_property
(
"audiodatarate"
))
!=
NULL
&&
prop
->
is_number
())
{
codec
->
audio_data_rate
=
(
int
)(
1000
*
srs_amf0_convert
<
SrsAmf0Number
>
(
prop
)
->
value
);
}
if
((
prop
=
obj
->
get_property
(
"audiosamplerate"
))
!=
NULL
&&
prop
->
is_number
())
{
codec
->
sample_rate
=
(
int
)
srs_amf0_convert
<
SrsAmf0Number
>
(
prop
)
->
value
;
}
if
((
prop
=
obj
->
get_property
(
"audiosamplesize"
))
!=
NULL
&&
prop
->
is_number
())
{
codec
->
sample_size
=
(
int
)
srs_amf0_convert
<
SrsAmf0Number
>
(
prop
)
->
value
;
if
(
codec
->
sample_size
==
16
)
{
codec
->
sample_size
=
2
;
}
else
{
codec
->
sample_size
=
1
;
}
}
if
((
prop
=
obj
->
get_property
(
"stereo"
))
!=
NULL
&&
prop
->
is_number
())
{
if
(
srs_amf0_convert
<
SrsAmf0Boolean
>
(
prop
)
->
value
)
{
codec
->
audio_channels
=
2
;
}
else
{
codec
->
audio_channels
=
1
;
}
}
return
ret
;
}
int
SrsHLS
::
on_audio
(
SrsCommonMessage
*
audio
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
codec
->
parse_av_codec
(
false
,
audio
->
payload
,
audio
->
size
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
int
SrsHLS
::
on_video
(
SrsCommonMessage
*
video
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
codec
->
parse_av_codec
(
true
,
video
->
payload
,
video
->
size
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
codec
->
video_codec_id
!=
SrsCodecVideoAVC
)
{
return
ret
;
}
return
ret
;
}
...
...
trunk/src/core/srs_core_hls.hpp
查看文件 @
ba234e8
...
...
@@ -29,11 +29,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <srs_core.hpp>
class
SrsOnMetaDataPacket
;
class
SrsCommonMessage
;
class
SrsCodec
;
class
SrsHLS
{
private
:
SrsCodec
*
codec
;
public
:
SrsHLS
();
virtual
~
SrsHLS
();
public
:
virtual
int
on_publish
();
virtual
void
on_unpublish
();
virtual
int
on_meta_data
(
SrsOnMetaDataPacket
*
metadata
);
virtual
int
on_audio
(
SrsCommonMessage
*
audio
);
virtual
int
on_video
(
SrsCommonMessage
*
video
);
};
#endif
\ No newline at end of file
...
...
trunk/src/core/srs_core_source.cpp
查看文件 @
ba234e8
...
...
@@ -53,13 +53,11 @@ SrsConsumer::SrsConsumer(SrsSource* _source)
source
=
_source
;
last_pkt_correct_time
=
last_pkt_time
=
0
;
paused
=
false
;
codec
=
new
SrsCodec
();
}
SrsConsumer
::~
SrsConsumer
()
{
clear
();
srs_freep
(
codec
);
clear
();
source
->
on_consumer_destroy
(
this
);
}
...
...
@@ -141,7 +139,7 @@ void SrsConsumer::shrink()
SrsSharedPtrMessage
*
msg
=
*
it
;
if
(
msg
->
header
.
is_video
())
{
has_video
=
true
;
if
(
codec
->
video_is_keyframe
(
msg
->
payload
,
msg
->
size
))
{
if
(
SrsCodec
::
video_is_keyframe
(
msg
->
payload
,
msg
->
size
))
{
iframe
=
it
;
frame_to_remove
=
i
+
1
;
}
...
...
@@ -240,7 +238,6 @@ void SrsConsumer::clear()
SrsSource
::
SrsSource
(
std
::
string
_stream_url
)
{
stream_url
=
_stream_url
;
codec
=
new
SrsCodec
();
hls
=
new
SrsHLS
();
cache_metadata
=
cache_sh_video
=
cache_sh_audio
=
NULL
;
...
...
@@ -266,7 +263,6 @@ SrsSource::~SrsSource()
srs_freep
(
cache_sh_video
);
srs_freep
(
cache_sh_audio
);
srs_freep
(
codec
);
srs_freep
(
hls
);
}
...
...
@@ -364,7 +360,7 @@ int SrsSource::on_audio(SrsCommonMessage* audio)
srs_info
(
"dispatch audio success."
);
// cache the sequence header if h264
if
(
codec
->
audio_is_sequence_header
(
msg
->
payload
,
msg
->
size
))
{
if
(
SrsCodec
::
audio_is_sequence_header
(
msg
->
payload
,
msg
->
size
))
{
srs_freep
(
cache_sh_audio
);
cache_sh_audio
=
msg
->
copy
();
srs_trace
(
"update audio sequence header success. size=%d"
,
msg
->
header
.
payload_length
);
...
...
@@ -409,7 +405,7 @@ int SrsSource::on_video(SrsCommonMessage* video)
srs_info
(
"dispatch video success."
);
// cache the sequence header if h264
if
(
codec
->
video_is_sequence_header
(
msg
->
payload
,
msg
->
size
))
{
if
(
SrsCodec
::
video_is_sequence_header
(
msg
->
payload
,
msg
->
size
))
{
srs_freep
(
cache_sh_video
);
cache_sh_video
=
msg
->
copy
();
srs_trace
(
"update video sequence header success. size=%d"
,
msg
->
header
.
payload_length
);
...
...
@@ -521,7 +517,7 @@ int SrsSource::cache_last_gop(SrsSharedPtrMessage* msg)
}
// clear gop cache when got key frame
if
(
msg
->
header
.
is_video
()
&&
codec
->
video_is_keyframe
(
msg
->
payload
,
msg
->
size
))
{
if
(
msg
->
header
.
is_video
()
&&
SrsCodec
::
video_is_keyframe
(
msg
->
payload
,
msg
->
size
))
{
srs_info
(
"clear gop cache when got keyframe. vcount=%d, count=%d"
,
cached_video_count
,
(
int
)
gop_cache
.
size
());
...
...
trunk/src/core/srs_core_source.hpp
查看文件 @
ba234e8
...
...
@@ -34,7 +34,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <vector>
#include <string>
class
SrsCodec
;
class
SrsSource
;
class
SrsCommonMessage
;
class
SrsOnMetaDataPacket
;
...
...
@@ -52,7 +51,6 @@ private:
SrsSource
*
source
;
std
::
vector
<
SrsSharedPtrMessage
*>
msgs
;
bool
paused
;
SrsCodec
*
codec
;
public
:
SrsConsumer
(
SrsSource
*
_source
);
virtual
~
SrsConsumer
();
...
...
@@ -108,7 +106,6 @@ public:
static
SrsSource
*
find
(
std
::
string
stream_url
);
private
:
SrsHLS
*
hls
;
SrsCodec
*
codec
;
std
::
string
stream_url
;
std
::
vector
<
SrsConsumer
*>
consumers
;
// gop cache for client fast startup.
...
...
trunk/src/core/srs_core_stream.cpp
查看文件 @
ba234e8
...
...
@@ -106,6 +106,19 @@ int16_t SrsStream::read_2bytes()
return
value
;
}
int32_t
SrsStream
::
read_3bytes
()
{
srs_assert
(
require
(
3
));
int32_t
value
=
0x00
;
pp
=
(
char
*
)
&
value
;
pp
[
2
]
=
*
p
++
;
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
return
value
;
}
int32_t
SrsStream
::
read_4bytes
()
{
srs_assert
(
require
(
4
));
...
...
trunk/src/core/srs_core_stream.hpp
查看文件 @
ba234e8
...
...
@@ -84,6 +84,10 @@ public:
*/
virtual
int16_t
read_2bytes
();
/**
* get 3bytes int from stream.
*/
virtual
int32_t
read_3bytes
();
/**
* get 4bytes int from stream.
*/
virtual
int32_t
read_4bytes
();
...
...
请
注册
或
登录
后发表评论