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
2015-01-19 00:05:12 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
3244c083c7e1efd46efdb3a9db85d4efef63975c
3244c083
1 parent
7674524c
for bug #293, support http aac stream
隐藏空白字符变更
内嵌
并排对比
正在显示
4 个修改的文件
包含
148 行增加
和
10 行删除
trunk/src/app/srs_app_http_conn.cpp
trunk/src/kernel/srs_kernel_aac.cpp
trunk/src/kernel/srs_kernel_aac.hpp
trunk/src/kernel/srs_kernel_error.hpp
trunk/src/app/srs_app_http_conn.cpp
查看文件 @
3244c08
...
...
@@ -214,9 +214,10 @@ int SrsAacStreamEncoder::write_audio(int64_t timestamp, char* data, int size)
return
enc
->
write_audio
(
timestamp
,
data
,
size
);
}
int
SrsAacStreamEncoder
::
write_video
(
int64_t
timestamp
,
char
*
data
,
int
size
)
int
SrsAacStreamEncoder
::
write_video
(
int64_t
/*timestamp*/
,
char
*
/*data*/
,
int
/*size*/
)
{
return
enc
->
write_video
(
timestamp
,
data
,
size
);
// aac ignore any flv video.
return
ERROR_SUCCESS
;
}
int
SrsAacStreamEncoder
::
write_metadata
(
int64_t
/*timestamp*/
,
char
*
/*data*/
,
int
/*size*/
)
...
...
@@ -318,6 +319,9 @@ int SrsLiveStream::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
if
(
serve_flv_streaming
)
{
enc
=
new
SrsFlvStreamEncoder
();
}
if
(
serve_aac_streaming
)
{
enc
=
new
SrsAacStreamEncoder
();
}
SrsAutoFree
(
ISrsStreamEncoder
,
enc
);
if
((
ret
=
enc
->
initialize
(
&
writer
))
!=
ERROR_SUCCESS
)
{
...
...
trunk/src/kernel/srs_kernel_aac.cpp
查看文件 @
3244c08
...
...
@@ -36,6 +36,7 @@ using namespace std;
#include <srs_kernel_error.hpp>
#include <srs_kernel_stream.hpp>
#include <srs_kernel_file.hpp>
#include <srs_kernel_codec.hpp>
#define SRS_FLV_TAG_HEADER_SIZE 11
#define SRS_FLV_PREVIOUS_TAG_SIZE 4
...
...
@@ -43,6 +44,7 @@ using namespace std;
SrsAacEncoder
::
SrsAacEncoder
()
{
_fs
=
NULL
;
got_sequence_header
=
false
;
tag_stream
=
new
SrsStream
();
}
...
...
@@ -76,16 +78,143 @@ int SrsAacEncoder::write_audio(int64_t timestamp, char* data, int size)
timestamp
&=
0x7fffffff
;
return
ret
;
}
SrsStream
*
stream
=
tag_stream
;
if
((
ret
=
stream
->
initialize
(
data
,
size
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int
SrsAacEncoder
::
write_video
(
int64_t
timestamp
,
char
*
data
,
int
size
)
{
int
ret
=
ERROR_SUCCESS
;
// audio decode
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_AAC_DECODE_ERROR
;
srs_error
(
"aac decode audio sound_format failed. ret=%d"
,
ret
);
return
ret
;
}
srs_assert
(
data
);
// @see: E.4.2 Audio Tags, video_file_format_spec_v10_1.pdf, page 76
int8_t
sound_format
=
stream
->
read_1bytes
();
timestamp
&=
0x7fffffff
;
// @see: SrsAvcAacCodec::audio_aac_demux
//int8_t sound_type = sound_format & 0x01;
//int8_t sound_size = (sound_format >> 1) & 0x01;
//int8_t sound_rate = (sound_format >> 2) & 0x03;
sound_format
=
(
sound_format
>>
4
)
&
0x0f
;
if
((
SrsCodecAudio
)
sound_format
!=
SrsCodecAudioAAC
)
{
ret
=
ERROR_AAC_DECODE_ERROR
;
srs_error
(
"aac required, format=%d. ret=%d"
,
sound_format
,
ret
);
return
ret
;
}
if
(
!
stream
->
require
(
1
))
{
ret
=
ERROR_AAC_DECODE_ERROR
;
srs_error
(
"aac decode aac_packet_type failed. ret=%d"
,
ret
);
return
ret
;
}
SrsCodecAudioType
aac_packet_type
=
(
SrsCodecAudioType
)
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.
//
// only need to decode the first 2bytes:
// audioObjectType, aac_profile, 5bits.
// samplingFrequencyIndex, aac_sample_rate, 4bits.
// channelConfiguration, aac_channels, 4bits
if
(
!
stream
->
require
(
2
))
{
ret
=
ERROR_AAC_DECODE_ERROR
;
srs_error
(
"aac decode sequence header failed. ret=%d"
,
ret
);
return
ret
;
}
aac_profile
=
stream
->
read_1bytes
();
aac_sample_rate
=
stream
->
read_1bytes
();
aac_channels
=
(
aac_sample_rate
>>
3
)
&
0x0f
;
aac_sample_rate
=
((
aac_profile
<<
1
)
&
0x0e
)
|
((
aac_sample_rate
>>
7
)
&
0x01
);
aac_profile
=
(
aac_profile
>>
3
)
&
0x1f
;
got_sequence_header
=
true
;
return
ret
;
}
if
(
!
got_sequence_header
)
{
ret
=
ERROR_AAC_DECODE_ERROR
;
srs_error
(
"aac no sequence header. ret=%d"
,
ret
);
return
ret
;
}
// the left is the aac raw frame data.
int16_t
aac_frame_length
=
stream
->
size
()
-
stream
->
pos
();
// write the ADTS header.
// @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 75,
// 1.A.2.2 Audio_Data_Transport_Stream frame, ADTS
// @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64145885
// byte_alignment()
// adts_fixed_header:
// 12bits syncword,
// 16bits left.
// adts_variable_header:
// 28bits
// 12+16+28=56bits
// adts_error_check:
// 16bits if protection_absent
// 56+16=72bits
// if protection_absent:
// require(7bytes)=56bits
// else
// require(9bytes)=72bits
char
aac_fixed_header
[
7
];
if
(
true
)
{
char
*
pp
=
aac_fixed_header
;
// Syncword 12 bslbf
*
pp
++
=
0xff
;
// 4bits left.
// adts_fixed_header(), 1.A.2.2.1 Fixed Header of ADTS
// ID 1 bslbf
// Layer 2 uimsbf
// protection_absent 1 bslbf
*
pp
++
=
0xf1
;
// Profile_ObjectType 2 uimsbf
// sampling_frequency_index 4 uimsbf
// private_bit 1 bslbf
// channel_configuration 3 uimsbf
// original/copy 1 bslbf
// home 1 bslbf
int8_t
fh_Profile_ObjectType
=
aac_profile
-
1
;
*
pp
++
=
((
fh_Profile_ObjectType
<<
6
)
&
0xc0
)
|
((
aac_sample_rate
<<
2
)
&
0x3c
)
|
((
aac_channels
>>
2
)
&
0x01
);
// @remark, Emphasis is removed,
// @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64154736
// 4bits left.
// adts_variable_header(), 1.A.2.2.2 Variable Header of ADTS
// copyright_identification_bit 1 bslbf
// copyright_identification_start 1 bslbf
*
pp
++
=
((
aac_channels
<<
6
)
&
0xc0
)
|
((
aac_frame_length
>>
11
)
&
0x03
);
// aac_frame_length 13 bslbf: Length of the frame including headers and error_check in bytes.
// use the left 2bits as the 13 and 12 bit,
// the aac_frame_length is 13bits, so we move 13-2=11.
*
pp
++
=
aac_frame_length
>>
3
;
// adts_buffer_fullness 11 bslbf
*
pp
++
=
(
aac_frame_length
<<
5
)
&
0xe0
;
// no_raw_data_blocks_in_frame 2 uimsbf
*
pp
++
=
0xfc
;
}
// write 7bytes fixed header.
if
((
ret
=
_fs
->
write
(
aac_fixed_header
,
7
,
NULL
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// write aac frame body.
if
((
ret
=
_fs
->
write
(
data
+
stream
->
pos
(),
aac_frame_length
,
NULL
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
...
...
trunk/src/kernel/srs_kernel_aac.hpp
查看文件 @
3244c08
...
...
@@ -43,6 +43,11 @@ class SrsAacEncoder
private
:
SrsFileWriter
*
_fs
;
private
:
int8_t
aac_profile
;
int8_t
aac_sample_rate
;
int8_t
aac_channels
;
bool
got_sequence_header
;
private
:
SrsStream
*
tag_stream
;
public
:
SrsAacEncoder
();
...
...
@@ -60,7 +65,6 @@ public:
* @remark assert data is not NULL.
*/
virtual
int
write_audio
(
int64_t
timestamp
,
char
*
data
,
int
size
);
virtual
int
write_video
(
int64_t
timestamp
,
char
*
data
,
int
size
);
};
#endif
...
...
trunk/src/kernel/srs_kernel_error.hpp
查看文件 @
3244c08
...
...
@@ -204,6 +204,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_AAC_DATA_INVALID 3048
#define ERROR_HTTP_STATUS_INVLIAD 3049
#define ERROR_KERNEL_AAC_STREAM_CLOSED 3050
#define ERROR_AAC_DECODE_ERROR 3051
///////////////////////////////////////////////////////
// HTTP protocol error.
...
...
请
注册
或
登录
后发表评论