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 14:28:58 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
fcfd51ee208eb3fe57a42e9f35fa771b3b700e29
fcfd51ee
1 parent
ba234e87
decoded audio and video. add avc file format doc
隐藏空白字符变更
内嵌
并排对比
正在显示
6 个修改的文件
包含
199 行增加
和
47 行删除
trunk/doc/H.264-AVC-ISO_IEC_14496-15.pdf
trunk/doc/aac-mp4a-format-ISO_IEC_14496-3+2001.pdf
trunk/src/core/srs_core_codec.cpp
trunk/src/core/srs_core_codec.hpp
trunk/src/core/srs_core_error.hpp
trunk/src/core/srs_core_hls.cpp
trunk/doc/H.264-AVC-ISO_IEC_14496-15.pdf
查看文件 @
fcfd51e
不能预览此文件类型
trunk/doc/aac-mp4a-format-ISO_IEC_14496-3+2001.pdf
0 → 100644
查看文件 @
fcfd51e
此 diff 太大无法显示。
trunk/src/core/srs_core_codec.cpp
查看文件 @
fcfd51e
...
...
@@ -23,8 +23,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core_codec.hpp>
#include <string.h>
#include <srs_core_error.hpp>
#include <srs_core_stream.hpp>
#include <srs_core_log.hpp>
SrsCodec
::
SrsCodec
()
{
...
...
@@ -36,10 +39,9 @@ SrsCodec::SrsCodec()
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
;
sound_rate
=
0
;
sound_size
=
0
;
sound_type
=
0
;
profile
=
0
;
level
=
0
;
avc_extra_size
=
0
;
...
...
@@ -58,44 +60,133 @@ SrsCodec::~SrsCodec()
srs_freep
(
stream
);
}
int
SrsCodec
::
parse_a
v_codec
(
bool
is_video
,
int8_t
*
data
,
int
size
)
int
SrsCodec
::
parse_a
udio_codec
(
int8_t
*
data
,
int
size
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
!
data
||
size
<=
0
)
{
srs_trace
(
"no audio present, hls ignore it."
);
return
ret
;
}
if
((
ret
=
stream
->
initialize
((
char
*
)
data
,
size
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// audio decode
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"hls decode audio sound_format failed. ret=%d"
,
ret
);
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
sound_format
=
stream
->
read_1bytes
();
sound_type
=
sound_format
&
0x01
;
sound_size
=
(
sound_format
>>
1
)
&
0x01
;
sound_rate
=
(
sound_format
>>
2
)
&
0x01
;
sound_format
=
(
sound_format
>>
4
)
&
0x0f
;
audio_codec_id
=
sound_format
;
// only support aac
if
(
audio_codec_id
!=
SrsCodecAudioAAC
)
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"hls only support audio aac codec. ret=%d"
,
ret
);
return
ret
;
}
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"hls decode audio aac_packet_type failed. ret=%d"
,
ret
);
return
ret
;
}
int8_t
aac_packet_type
=
stream
->
read_1bytes
();
if
(
aac_packet_type
==
SrsCodecAudioTypeSequenceHeader
)
{
// AudioSpecificConfig
// 1.6.2.1 AudioSpecificConfig, in aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 33.
aac_extra_size
=
size
-
stream
->
pos
();
if
(
aac_extra_size
>
0
)
{
srs_freepa
(
aac_extra_data
);
aac_extra_data
=
new
char
[
aac_extra_size
];
memcpy
(
aac_extra_data
,
data
+
stream
->
pos
(),
aac_extra_size
);
}
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
if
(
aac_packet_type
==
SrsCodecAudioTypeRawData
)
{
// Raw AAC frame data in UI8 []
}
else
{
// ignored.
}
srs_info
(
"audio decoded, type=%d, codec=%d, asize=%d, rate=%d, format=%d, size=%d"
,
sound_type
,
audio_codec_id
,
sound_size
,
sound_rate
,
sound_format
,
size
);
return
ret
;
}
int
SrsCodec
::
parse_video_codec
(
int8_t
*
data
,
int
size
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
!
data
||
size
<=
0
)
{
srs_trace
(
"no video present, hls ignore it."
);
return
ret
;
}
if
((
ret
=
stream
->
initialize
((
char
*
)
data
,
size
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// video decode
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"hls decode video frame_type failed. ret=%d"
,
ret
);
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
;
// only support h.264/avc
if
(
codec_id
!=
SrsCodecVideoAVC
)
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"hls only support video h.264/avc codec. ret=%d"
,
ret
);
return
ret
;
}
if
(
!
stream
->
require
(
4
))
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"hls decode video avc_packet_type failed. ret=%d"
,
ret
);
return
ret
;
}
int8_t
avc_packet_type
=
stream
->
read_1bytes
();
int32_t
composition_time
=
stream
->
read_3bytes
();
// avoid warning, used it future.
(
void
)
composition_time
;
if
(
avc_packet_type
==
SrsCodecVideoAVCTypeSequenceHeader
)
{
// AVCDecoderConfigurationRecord
// 5.2.4.1.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
avc_extra_size
=
size
-
stream
->
pos
();
if
(
avc_extra_size
>
0
)
{
srs_freepa
(
avc_extra_data
);
avc_extra_data
=
new
char
[
avc_extra_size
];
memcpy
(
avc_extra_data
,
data
+
stream
->
pos
(),
avc_extra_size
);
}
}
else
if
(
avc_packet_type
==
SrsCodecVideoAVCTypeNALU
){
// One or more NALUs (Full frames are required)
// 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 20
}
else
{
// ignored.
}
srs_info
(
"video decoded, type=%d, codec=%d, avc=%d, time=%d, size=%d"
,
frame_type
,
video_codec_id
,
avc_packet_type
,
composition_time
,
size
);
return
ret
;
}
...
...
trunk/src/core/srs_core_codec.hpp
查看文件 @
fcfd51e
...
...
@@ -128,6 +128,39 @@ enum SrsCodecAudioType
SrsCodecAudioTypeRawData
=
1
,
};
// Sampling rate. The following values are defined:
// 0 = 5.5 kHz = 5512 Hz
// 1 = 11 kHz = 11025 Hz
// 2 = 22 kHz = 22050 Hz
// 3 = 44 kHz = 44100 Hz
enum
SrsCodecAudioSampleRate
{
SrsCodecAudioSampleRate5512
=
0
,
SrsCodecAudioSampleRate11025
=
1
,
SrsCodecAudioSampleRate22050
=
2
,
SrsCodecAudioSampleRate44100
=
3
,
};
// Size of each audio sample. This parameter only pertains to
// uncompressed formats. Compressed formats always decode
// to 16 bits internally.
// 0 = 8-bit samples
// 1 = 16-bit samples
enum
SrsCodecAudioSampleSize
{
SrsCodecAudioSampleSize8bit
=
0
,
SrsCodecAudioSampleSize16bit
=
1
,
};
// Mono or stereo sound
// 0 = Mono sound
// 1 = Stereo sound
enum
SrsCodecAudioSoundType
{
SrsCodecAudioSoundTypeMono
=
0
,
SrsCodecAudioSoundTypeStereo
=
1
,
};
/**
* Annex E. The FLV File Format
*/
...
...
@@ -139,30 +172,35 @@ 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.
int
width
;
int
height
;
int
video_data_rate
;
// in bps
int
frame_rate
;
int
duration
;
/**
* audio specified
*/
// @see: SrsCodecAudioType
int
audio_codec_id
;
// @see: SrsCodecAudioSampleRate
int
sound_rate
;
// @see: SrsCodecAudioSampleSize
int
sound_size
;
// @see: SrsCodecAudioSoundType
int
sound_type
;
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
// without the flv codec header,
// @see: ffmpeg, AVCodecContext::extradata
int
avc_extra_size
;
char
*
avc_extra_data
;
// the aac extra data, the AAC sequence header,
// without the flv codec header
// without the flv codec header,
// @see: ffmpeg, AVCodecContext::extradata
int
aac_extra_size
;
char
*
aac_extra_data
;
public
:
...
...
@@ -170,7 +208,8 @@ public:
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
);
virtual
int
parse_audio_codec
(
int8_t
*
data
,
int
size
);
virtual
int
parse_video_codec
(
int8_t
*
data
,
int
size
);
// the following function used to finger out the flv/rtmp packet detail.
public:
/**
...
...
trunk/src/core/srs_core_error.hpp
查看文件 @
fcfd51e
...
...
@@ -107,4 +107,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// when open ssl sha256 digest key invalid size.
#define ERROR_OpenSslSha256DigestSize 512
#define ERROR_HLS_METADATA 600
#define ERROR_HLS_DECODE_ERROR 601
#endif
\ No newline at end of file
...
...
trunk/src/core/srs_core_hls.cpp
查看文件 @
fcfd51e
...
...
@@ -53,11 +53,13 @@ int SrsHLS::on_meta_data(SrsOnMetaDataPacket* metadata)
int
ret
=
ERROR_SUCCESS
;
if
(
!
metadata
||
!
metadata
->
metadata
)
{
srs_trace
(
"no metadata persent, hls ignored it."
);
return
ret
;
}
SrsAmf0Object
*
obj
=
metadata
->
metadata
;
if
(
obj
->
size
()
<=
0
)
{
srs_trace
(
"no metadata persent, hls ignored it."
);
return
ret
;
}
...
...
@@ -90,21 +92,38 @@ int SrsHLS::on_meta_data(SrsOnMetaDataPacket* metadata)
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
;
int
sound_rate
=
(
int
)
srs_amf0_convert
<
SrsAmf0Number
>
(
prop
)
->
value
;
if
(
sound_rate
==
5512
)
{
codec
->
sound_rate
=
SrsCodecAudioSampleRate5512
;
}
else
if
(
sound_rate
==
11025
)
{
codec
->
sound_rate
=
SrsCodecAudioSampleRate11025
;
}
else
if
(
sound_rate
==
22050
)
{
codec
->
sound_rate
=
SrsCodecAudioSampleRate22050
;
}
else
if
(
sound_rate
==
44100
)
{
codec
->
sound_rate
=
SrsCodecAudioSampleRate44100
;
}
else
{
ret
=
ERROR_HLS_METADATA
;
srs_error
(
"invalid sound_rate of metadata: %d, ret=%d"
,
sound_rate
,
ret
);
return
ret
;
}
}
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
;
int
sound_size
=
(
int
)
srs_amf0_convert
<
SrsAmf0Number
>
(
prop
)
->
value
;
if
(
sound_size
==
16
)
{
codec
->
sound_size
=
SrsCodecAudioSampleSize16bit
;
}
else
if
(
sound_size
==
8
)
{
codec
->
sound_size
=
SrsCodecAudioSampleSize8bit
;
}
else
{
codec
->
sample_size
=
1
;
ret
=
ERROR_HLS_METADATA
;
srs_error
(
"invalid sound_size of metadata: %d, ret=%d"
,
sound_size
,
ret
);
return
ret
;
}
}
if
((
prop
=
obj
->
get_property
(
"stereo"
))
!=
NULL
&&
prop
->
is_number
())
{
if
(
srs_amf0_convert
<
SrsAmf0Boolean
>
(
prop
)
->
value
)
{
codec
->
audio_channels
=
2
;
codec
->
sound_type
=
SrsCodecAudioSoundTypeStereo
;
}
else
{
codec
->
audio_channels
=
1
;
codec
->
sound_type
=
SrsCodecAudioSoundTypeMono
;
}
}
...
...
@@ -115,7 +134,7 @@ int SrsHLS::on_audio(SrsCommonMessage* audio)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
codec
->
parse_a
v_codec
(
false
,
audio
->
payload
,
audio
->
size
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
codec
->
parse_a
udio_codec
(
audio
->
payload
,
audio
->
size
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
...
...
@@ -126,7 +145,7 @@ int SrsHLS::on_video(SrsCommonMessage* video)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
codec
->
parse_
av_codec
(
true
,
video
->
payload
,
video
->
size
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
codec
->
parse_
video_codec
(
video
->
payload
,
video
->
size
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
...
...
请
注册
或
登录
后发表评论