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-15 10:44:06 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
a4d3283cdd4c37d24299ac50f5bb3421d1af2089
a4d3283c
1 parent
f020690e
refine hls codec sample info. 0.9.161
隐藏空白字符变更
内嵌
并排对比
正在显示
5 个修改的文件
包含
105 行增加
和
83 行删除
trunk/src/app/srs_app_avc_aac.cpp
trunk/src/app/srs_app_avc_aac.hpp
trunk/src/app/srs_app_hls.cpp
trunk/src/app/srs_app_hls.hpp
trunk/src/core/srs_core.hpp
trunk/src/app/srs_app_avc_aac.cpp
查看文件 @
a4d3283
...
...
@@ -30,26 +30,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_kernel_codec.hpp>
#include <srs_kernel_stream.hpp>
SrsCodec
Buffer
::
SrsCodecBuffer
()
SrsCodec
SampleUnit
::
SrsCodecSampleUnit
()
{
size
=
0
;
bytes
=
NULL
;
}
void
SrsCodecBuffer
::
append
(
void
*
data
,
int
len
)
SrsCodecSampleUnit
::~
SrsCodecSampleUnit
(
)
{
srs_assert
(
data
);
srs_assert
(
len
>
0
);
bytes
=
(
char
*
)
realloc
(
bytes
,
size
+
len
);
memcpy
(
bytes
+
size
,
data
,
len
);
size
+=
len
;
}
void
SrsCodecBuffer
::
free
()
{
size
=
0
;
srs_freep
(
bytes
);
}
SrsCodecSample
::
SrsCodecSample
()
...
...
@@ -64,7 +52,7 @@ SrsCodecSample::~SrsCodecSample()
void
SrsCodecSample
::
clear
()
{
is_video
=
false
;
nb_
buffer
s
=
0
;
nb_
sample_unit
s
=
0
;
cts
=
0
;
frame_type
=
SrsCodecVideoAVCFrameReserved
;
...
...
@@ -76,20 +64,20 @@ void SrsCodecSample::clear()
aac_packet_type
=
SrsCodecAudioTypeReserved
;
}
int
SrsCodecSample
::
add_sample
(
char
*
bytes
,
int
size
)
int
SrsCodecSample
::
add_sample
_unit
(
char
*
bytes
,
int
size
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
nb_
buffer
s
>=
SRS_MAX_CODEC_SAMPLE
)
{
if
(
nb_
sample_unit
s
>=
SRS_MAX_CODEC_SAMPLE
)
{
ret
=
ERROR_HLS_DECODE_ERROR
;
srs_error
(
"hls decode samples error, "
"exceed the max count: %d, ret=%d"
,
SRS_MAX_CODEC_SAMPLE
,
ret
);
return
ret
;
}
SrsCodecBuffer
*
buf
=
&
buffers
[
nb_buffers
++
];
buf
->
bytes
=
bytes
;
buf
->
size
=
size
;
SrsCodecSampleUnit
*
sample_unit
=
&
sample_units
[
nb_sample_units
++
];
sample_unit
->
bytes
=
bytes
;
sample_unit
->
size
=
size
;
return
ret
;
}
...
...
@@ -239,7 +227,7 @@ int SrsAvcAacCodec::audio_aac_demux(char* data, int size, SrsCodecSample* sample
// Raw AAC frame data in UI8 []
// 6.3 Raw Data, aac-iso-13818-7.pdf, page 28
if
((
ret
=
sample
->
add_sample
(
stream
->
data
()
+
stream
->
pos
(),
stream
->
size
()
-
stream
->
pos
()))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
sample
->
add_sample
_unit
(
stream
->
data
()
+
stream
->
pos
(),
stream
->
size
()
-
stream
->
pos
()))
!=
ERROR_SUCCESS
)
{
srs_error
(
"hls add audio sample failed. ret=%d"
,
ret
);
return
ret
;
}
...
...
@@ -445,7 +433,7 @@ int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample
return
ret
;
}
// 7.3.1 NAL unit syntax, H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
if
((
ret
=
sample
->
add_sample
(
stream
->
data
()
+
stream
->
pos
(),
NALUnitLength
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
sample
->
add_sample
_unit
(
stream
->
data
()
+
stream
->
pos
(),
NALUnitLength
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"hls add video sample failed. ret=%d"
,
ret
);
return
ret
;
}
...
...
trunk/src/app/srs_app_avc_aac.hpp
查看文件 @
a4d3283
...
...
@@ -89,30 +89,38 @@ enum SrsCodecAudioSoundType
};
/**
* buffer indicates the position and size.
* the codec sample unit.
* for h.264 video packet, a NALU is a sample unit.
* for aac raw audio packet, a NALU is the entire aac raw data.
* for sequence header, it's not a sample unit.
*/
class
SrsCodec
Buffer
class
SrsCodec
SampleUnit
{
public
:
/**
* @remark user must manage the bytes.
* the sample bytes is directly ptr to packet bytes,
* user should never use it when packet destroyed.
*/
int
size
;
char
*
bytes
;
public
:
SrsCodecBuffer
();
void
append
(
void
*
data
,
int
len
);
public
:
/**
* free the bytes,
* user can invoke it to free the bytes,
* the SrsCodecBuffer never free automatically.
*/
void
free
();
SrsCodecSampleUnit
();
virtual
~
SrsCodecSampleUnit
();
};
/**
* the samples in the flv audio/video packet.
* the sample used to analysis a video/audio packet,
* split the h.264 NALUs to buffers, or aac raw data to a buffer,
* and decode the video/audio specified infos.
*
* the sample unit:
* a video packet codec in h.264 contains many NALUs, each is a sample unit.
* a audio packet codec in aac is a sample unit.
* @remark, the video/audio sequence header is not sample unit,
* all sequence header stores as extra data,
* @see SrsAvcAacCodec.avc_extra_data and SrsAvcAacCodec.aac_extra_data
* @remark, user must clear all samples before decode a new video/audio packet.
*/
class
SrsCodecSample
{
...
...
@@ -123,12 +131,14 @@ public:
* generally, aac audio packet corresponding to one buffer,
* where avc/h264 video packet may contains multiple buffer.
*/
int
nb_buffers
;
SrsCodecBuffer
buffers
[
SRS_MAX_CODEC_SAMPLE
];
int
nb_sample_units
;
SrsCodecSampleUnit
sample_units
[
SRS_MAX_CODEC_SAMPLE
];
public
:
bool
is_video
;
// CompositionTime, video_file_format_spec_v10_1.pdf, page 78.
// cts = pts - dts, where dts = flvheader->timestamp.
/**
* CompositionTime, video_file_format_spec_v10_1.pdf, page 78.
* cts = pts - dts, where dts = flvheader->timestamp.
*/
int32_t
cts
;
public
:
// video specified
...
...
@@ -143,13 +153,37 @@ public:
public
:
SrsCodecSample
();
virtual
~
SrsCodecSample
();
public
:
/**
* clear all samples.
* the sample units never copy the bytes, it directly use the ptr,
* so when video/audio packet is destroyed, the sample must be clear.
* in a word, user must clear sample before demux it.
* @remark demux sample use SrsAvcAacCodec.audio_aac_demux or video_avc_demux.
*/
void
clear
();
int
add_sample
(
char
*
bytes
,
int
size
);
/**
* add the a sample unit, it's a h.264 NALU or aac raw data.
* the sample unit directly use the ptr of packet bytes,
* so user must never use sample unit when packet is destroyed.
* in a word, user must clear sample before demux it.
*/
int
add_sample_unit
(
char
*
bytes
,
int
size
);
};
/**
* the h264/avc and aac codec, for media stream.
* to decode the stream of avc/aac for hls.
*
* to demux the FLV/RTMP video/audio packet to sample,
* add each NALUs of h.264 as a sample unit to sample,
* while the entire aac raw data as a sample unit.
*
* for sequence header,
* demux it and save it in the avc_extra_data and aac_extra_data,
*
* for the codec info, such as audio sample rate,
* decode from FLV/RTMP header, then use codec info in sequence
* header to override it.
*/
class
SrsAvcAacCodec
{
...
...
trunk/src/app/srs_app_hls.cpp
查看文件 @
a4d3283
...
...
@@ -68,6 +68,7 @@ using namespace std;
#include <srs_kernel_utility.hpp>
#include <srs_app_avc_aac.hpp>
#include <srs_kernel_file.hpp>
#include <srs_kernel_buffer.hpp>
// max PES packets size to flush the video.
#define SRS_AUTO_HLS_AUDIO_CACHE_SIZE 1024 * 1024
...
...
@@ -195,16 +196,16 @@ public:
return
ret
;
}
static
int
write_frame
(
SrsFileWriter
*
writer
,
SrsMpegtsFrame
*
frame
,
Srs
Codec
Buffer
*
buffer
)
static
int
write_frame
(
SrsFileWriter
*
writer
,
SrsMpegtsFrame
*
frame
,
SrsBuffer
*
buffer
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
!
buffer
->
bytes
||
buffer
->
size
<=
0
)
{
if
(
!
buffer
->
bytes
()
||
buffer
->
length
()
<=
0
)
{
return
ret
;
}
char
*
last
=
buffer
->
bytes
+
buffer
->
size
;
char
*
pos
=
buffer
->
bytes
;
char
*
last
=
buffer
->
bytes
()
+
buffer
->
length
();
char
*
pos
=
buffer
->
bytes
();
bool
first
=
true
;
while
(
pos
<
last
)
{
...
...
@@ -478,7 +479,7 @@ int SrsTSMuxer::open(string _path)
return
ret
;
}
int
SrsTSMuxer
::
write_audio
(
SrsMpegtsFrame
*
af
,
Srs
Codec
Buffer
*
ab
)
int
SrsTSMuxer
::
write_audio
(
SrsMpegtsFrame
*
af
,
SrsBuffer
*
ab
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -489,7 +490,7 @@ int SrsTSMuxer::write_audio(SrsMpegtsFrame* af, SrsCodecBuffer* ab)
return
ret
;
}
int
SrsTSMuxer
::
write_video
(
SrsMpegtsFrame
*
vf
,
Srs
Codec
Buffer
*
vb
)
int
SrsTSMuxer
::
write_video
(
SrsMpegtsFrame
*
vf
,
SrsBuffer
*
vb
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -651,7 +652,7 @@ bool SrsHlsMuxer::is_segment_overflow()
return
current
->
duration
>=
hls_fragment
;
}
int
SrsHlsMuxer
::
flush_audio
(
SrsMpegtsFrame
*
af
,
Srs
Codec
Buffer
*
ab
)
int
SrsHlsMuxer
::
flush_audio
(
SrsMpegtsFrame
*
af
,
SrsBuffer
*
ab
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -661,7 +662,7 @@ int SrsHlsMuxer::flush_audio(SrsMpegtsFrame* af, SrsCodecBuffer* ab)
return
ret
;
}
if
(
ab
->
size
<=
0
)
{
if
(
ab
->
length
()
<=
0
)
{
return
ret
;
}
...
...
@@ -673,13 +674,12 @@ int SrsHlsMuxer::flush_audio(SrsMpegtsFrame* af, SrsCodecBuffer* ab)
}
// write success, clear and free the buffer
ab
->
free
(
);
ab
->
erase
(
ab
->
length
()
);
return
ret
;
}
int
SrsHlsMuxer
::
flush_video
(
SrsMpegtsFrame
*
af
,
SrsCodecBuffer
*
ab
,
SrsMpegtsFrame
*
vf
,
SrsCodecBuffer
*
vb
)
int
SrsHlsMuxer
::
flush_video
(
SrsMpegtsFrame
*
af
,
SrsBuffer
*
ab
,
SrsMpegtsFrame
*
vf
,
SrsBuffer
*
vb
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -699,7 +699,7 @@ int SrsHlsMuxer::flush_video(
}
// write success, clear and free the buffer
vb
->
free
(
);
vb
->
erase
(
vb
->
length
()
);
return
ret
;
}
...
...
@@ -962,8 +962,8 @@ SrsHlsCache::SrsHlsCache()
{
aac_jitter
=
new
SrsHlsAacJitter
();
ab
=
new
SrsCodecBuffer
();
vb
=
new
SrsCodecBuffer
();
ab
=
new
SrsBuffer
();
vb
=
new
SrsBuffer
();
af
=
new
SrsMpegtsFrame
();
vf
=
new
SrsMpegtsFrame
();
...
...
@@ -975,8 +975,8 @@ SrsHlsCache::~SrsHlsCache()
{
srs_freep
(
aac_jitter
);
ab
->
free
();
vb
->
free
();
ab
->
erase
(
ab
->
length
());
vb
->
erase
(
vb
->
length
());
srs_freep
(
ab
);
srs_freep
(
vb
);
...
...
@@ -1051,7 +1051,7 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
int
ret
=
ERROR_SUCCESS
;
// start buffer, set the af
if
(
ab
->
size
==
0
)
{
if
(
ab
->
length
()
==
0
)
{
pts
=
aac_jitter
->
on_buffer_start
(
pts
,
sample
->
sound_rate
,
codec
->
aac_sample_rate
);
af
->
dts
=
af
->
pts
=
audio_buffer_start_pts
=
pts
;
...
...
@@ -1067,7 +1067,7 @@ int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
}
// flush if buffer exceed max size.
if
(
ab
->
size
>
SRS_AUTO_HLS_AUDIO_CACHE_SIZE
)
{
if
(
ab
->
length
()
>
SRS_AUTO_HLS_AUDIO_CACHE_SIZE
)
{
if
((
ret
=
muxer
->
flush_audio
(
af
,
ab
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
...
...
@@ -1159,11 +1159,11 @@ int SrsHlsCache::cache_audio(SrsAvcAacCodec* codec, SrsCodecSample* sample)
{
int
ret
=
ERROR_SUCCESS
;
for
(
int
i
=
0
;
i
<
sample
->
nb_buffers
;
i
++
)
{
SrsCodecBuffer
*
buf
=
&
sample
->
buffers
[
i
];
int32_t
size
=
buf
->
size
;
for
(
int
i
=
0
;
i
<
sample
->
nb_sample_units
;
i
++
)
{
SrsCodecSampleUnit
*
sample_unit
=
&
sample
->
sample_units
[
i
];
int32_t
size
=
sample_unit
->
size
;
if
(
!
buf
->
bytes
||
size
<=
0
||
size
>
0x1fff
)
{
if
(
!
sample_unit
->
bytes
||
size
<=
0
||
size
>
0x1fff
)
{
ret
=
ERROR_HLS_AAC_FRAME_LENGTH
;
srs_error
(
"invalid aac frame length=%d, ret=%d"
,
size
,
ret
);
return
ret
;
...
...
@@ -1215,8 +1215,8 @@ int SrsHlsCache::cache_audio(SrsAvcAacCodec* codec, SrsCodecSample* sample)
adts_header
[
5
]
|=
0x1f
;
// copy to audio buffer
ab
->
append
(
adts_header
,
sizeof
(
adts_header
));
ab
->
append
(
buf
->
bytes
,
buf
->
size
);
ab
->
append
((
const
char
*
)
adts_header
,
sizeof
(
adts_header
));
ab
->
append
(
sample_unit
->
bytes
,
sample_unit
->
size
);
}
return
ret
;
...
...
@@ -1239,11 +1239,11 @@ int SrsHlsCache::cache_video(SrsAvcAacCodec* codec, SrsCodecSample* sample)
* xxxxxxx // data bytes.
* so, for each sample, we append header in aud_nal, then appends the bytes in sample.
*/
for
(
int
i
=
0
;
i
<
sample
->
nb_buffers
;
i
++
)
{
SrsCodecBuffer
*
buf
=
&
sample
->
buffers
[
i
];
int32_t
size
=
buf
->
size
;
for
(
int
i
=
0
;
i
<
sample
->
nb_sample_units
;
i
++
)
{
SrsCodecSampleUnit
*
sample_unit
=
&
sample
->
sample_units
[
i
];
int32_t
size
=
sample_unit
->
size
;
if
(
!
buf
->
bytes
||
size
<=
0
)
{
if
(
!
sample_unit
->
bytes
||
size
<=
0
)
{
ret
=
ERROR_HLS_AVC_SAMPLE_SIZE
;
srs_error
(
"invalid avc sample length=%d, ret=%d"
,
size
,
ret
);
return
ret
;
...
...
@@ -1259,7 +1259,7 @@ int SrsHlsCache::cache_video(SrsAvcAacCodec* codec, SrsCodecSample* sample)
// 5bits, 7.3.1 NAL unit syntax,
// H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
u_int8_t
nal_unit_type
;
nal_unit_type
=
*
buf
->
bytes
;
nal_unit_type
=
*
sample_unit
->
bytes
;
nal_unit_type
&=
0x1f
;
// @see: ngx_rtmp_hls_video
...
...
@@ -1277,7 +1277,7 @@ int SrsHlsCache::cache_video(SrsAvcAacCodec* codec, SrsCodecSample* sample)
}
if
(
nal_unit_type
==
1
||
nal_unit_type
==
5
||
nal_unit_type
==
6
)
{
// for type 6, append a aud with type 9.
vb
->
append
(
aud_nal
,
sizeof
(
aud_nal
));
vb
->
append
(
(
const
char
*
)
aud_nal
,
sizeof
(
aud_nal
));
aud_sent
=
true
;
}
}
...
...
@@ -1290,13 +1290,13 @@ int SrsHlsCache::cache_video(SrsAvcAacCodec* codec, SrsCodecSample* sample)
// @see: ngx_rtmp_hls_append_sps_pps
if
(
codec
->
sequenceParameterSetLength
>
0
)
{
// AnnexB prefix, for sps always 4 bytes header
vb
->
append
(
aud_nal
,
4
);
vb
->
append
(
(
const
char
*
)
aud_nal
,
4
);
// sps
vb
->
append
(
codec
->
sequenceParameterSetNALUnit
,
codec
->
sequenceParameterSetLength
);
}
if
(
codec
->
pictureParameterSetLength
>
0
)
{
// AnnexB prefix, for pps always 4 bytes header
vb
->
append
(
aud_nal
,
4
);
vb
->
append
(
(
const
char
*
)
aud_nal
,
4
);
// pps
vb
->
append
(
codec
->
pictureParameterSetNALUnit
,
codec
->
pictureParameterSetLength
);
}
...
...
@@ -1318,13 +1318,13 @@ int SrsHlsCache::cache_video(SrsAvcAacCodec* codec, SrsCodecSample* sample)
u_int8_t
*
end
=
p
+
3
;
// first AnnexB prefix is long (4 bytes)
if
(
vb
->
size
==
0
)
{
if
(
vb
->
length
()
==
0
)
{
p
=
aud_nal
;
}
vb
->
append
(
p
,
end
-
p
);
vb
->
append
(
(
const
char
*
)
p
,
end
-
p
);
// sample data
vb
->
append
(
buf
->
bytes
,
buf
->
size
);
vb
->
append
(
sample_unit
->
bytes
,
sample_unit
->
size
);
}
return
ret
;
...
...
trunk/src/app/srs_app_hls.hpp
查看文件 @
a4d3283
...
...
@@ -50,9 +50,9 @@ extern int aac_sample_rates[];
#include <string>
#include <vector>
class
SrsBuffer
;
class
SrsSharedPtrMessage
;
class
SrsCodecSample
;
class
SrsCodecBuffer
;
class
SrsMpegtsFrame
;
class
SrsAmf0Object
;
class
SrsRtmpJitter
;
...
...
@@ -109,8 +109,8 @@ public:
virtual
~
SrsTSMuxer
();
public
:
virtual
int
open
(
std
::
string
_path
);
virtual
int
write_audio
(
SrsMpegtsFrame
*
af
,
SrsCodecBuffer
*
ab
);
virtual
int
write_video
(
SrsMpegtsFrame
*
vf
,
SrsCodecBuffer
*
vb
);
virtual
int
write_audio
(
SrsMpegtsFrame
*
af
,
SrsBuffer
*
ab
);
virtual
int
write_video
(
SrsMpegtsFrame
*
vf
,
SrsBuffer
*
vb
);
virtual
void
close
();
};
...
...
@@ -196,8 +196,8 @@ public:
* that is whether the current segment duration >= the segment in config
*/
virtual
bool
is_segment_overflow
();
virtual
int
flush_audio
(
SrsMpegtsFrame
*
af
,
SrsCodecBuffer
*
ab
);
virtual
int
flush_video
(
SrsMpegtsFrame
*
af
,
SrsCodecBuffer
*
ab
,
SrsMpegtsFrame
*
vf
,
SrsCodecBuffer
*
vb
);
virtual
int
flush_audio
(
SrsMpegtsFrame
*
af
,
SrsBuffer
*
ab
);
virtual
int
flush_video
(
SrsMpegtsFrame
*
af
,
SrsBuffer
*
ab
,
SrsMpegtsFrame
*
vf
,
SrsBuffer
*
vb
);
/**
* close segment(ts).
* @param log_desc the description for log.
...
...
@@ -231,9 +231,9 @@ class SrsHlsCache
private
:
// current frame and buffer
SrsMpegtsFrame
*
af
;
Srs
Codec
Buffer
*
ab
;
SrsBuffer
*
ab
;
SrsMpegtsFrame
*
vf
;
Srs
Codec
Buffer
*
vb
;
SrsBuffer
*
vb
;
private
:
// the audio cache buffer start pts, to flush audio if full.
int64_t
audio_buffer_start_pts
;
...
...
trunk/src/core/srs_core.hpp
查看文件 @
a4d3283
...
...
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR "0"
#define VERSION_MINOR "9"
#define VERSION_REVISION "16
0
"
#define VERSION_REVISION "16
1
"
#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
// server info.
#define RTMP_SIG_SRS_KEY "SRS"
...
...
请
注册
或
登录
后发表评论