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
2017-01-10 17:17:23 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
4104f25069d36b6d2e9fd6da3e8dca9ad83c2758
4104f250
1 parent
c9a71b7f
for #635, support IDR and NonIDR(open-gop).
隐藏空白字符变更
内嵌
并排对比
正在显示
4 个修改的文件
包含
86 行增加
和
59 行删除
trunk/src/app/srs_app_hls.cpp
trunk/src/kernel/srs_kernel_codec.cpp
trunk/src/kernel/srs_kernel_codec.hpp
trunk/src/kernel/srs_kernel_ts.cpp
trunk/src/app/srs_app_hls.cpp
查看文件 @
4104f25
...
...
@@ -1071,7 +1071,7 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
// b. always reap when not wait keyframe.
if
(
!
muxer
->
wait_keyframe
()
||
sample
->
frame_type
==
SrsCodecVideoAVCFrameKeyFrame
)
{
// when wait keyframe, there must exists idr frame in sample, or NonIDR(open gop) specified.
if
(
!
sample
->
has_non_idr
&&
!
sample
->
has_idr
&&
muxer
->
wait_keyframe
())
{
if
(
!
sample
->
open_gop
&&
!
sample
->
has_idr
&&
muxer
->
wait_keyframe
())
{
srs_warn
(
"hls: ts starts without IDR, first nalu=%d, idr=%d"
,
sample
->
first_nalu_type
,
sample
->
has_idr
);
}
...
...
@@ -1274,6 +1274,8 @@ void SrsHls::on_unpublish()
srs_error
(
"ignore m3u8 muxer flush/close audio failed. ret=%d"
,
ret
);
}
sample
->
reset
();
hls_enabled
=
false
;
}
...
...
trunk/src/kernel/srs_kernel_codec.cpp
查看文件 @
4104f25
...
...
@@ -324,13 +324,20 @@ SrsCodecSampleUnit::~SrsCodecSampleUnit()
SrsCodecSample
::
SrsCodecSample
()
{
clear
();
reset
();
}
SrsCodecSample
::~
SrsCodecSample
()
{
}
void
SrsCodecSample
::
reset
()
{
clear
();
open_gop
=
false
;
}
void
SrsCodecSample
::
clear
()
{
is_video
=
false
;
...
...
@@ -339,7 +346,7 @@ void SrsCodecSample::clear()
cts
=
0
;
frame_type
=
SrsCodecVideoAVCFrameReserved
;
avc_packet_type
=
SrsCodecVideoAVCTypeReserved
;
has_aud
=
has_
sei
=
has_non_idr
=
has_
idr
=
false
;
has_aud
=
has_idr
=
false
;
first_nalu_type
=
SrsAvcNaluTypeReserved
;
acodec
=
SrsCodecAudioReserved1
;
...
...
@@ -370,10 +377,6 @@ int SrsCodecSample::add_sample_unit(char* bytes, int size)
if
(
nal_unit_type
==
SrsAvcNaluTypeIDR
)
{
has_idr
=
true
;
}
else
if
(
nal_unit_type
==
SrsAvcNaluTypeNonIDR
)
{
has_non_idr
=
true
;
}
else
if
(
nal_unit_type
==
SrsAvcNaluTypeSEI
)
{
has_sei
=
true
;
}
else
if
(
nal_unit_type
==
SrsAvcNaluTypeAccessUnitDelimiter
)
{
has_aud
=
true
;
}
...
...
@@ -698,66 +701,82 @@ int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample
return
ret
;
}
}
else
if
(
avc_packet_type
==
SrsCodecVideoAVCTypeNALU
){
// ensure the sequence header demuxed
if
(
!
is_avc_codec_ok
())
{
srs_warn
(
"avc ignore type=%d for no sequence header. ret=%d"
,
avc_packet_type
,
ret
);
if
((
ret
=
video_nalu_demux
(
stream
,
sample
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
else
{
// ignored.
}
srs_info
(
"avc decoded, type=%d, codec=%d, avc=%d, cts=%d, size=%d"
,
frame_type
,
video_codec_id
,
avc_packet_type
,
composition_time
,
size
);
return
ret
;
}
// guess for the first time.
if
(
payload_format
==
SrsAvcPayloadFormatGuess
)
{
// One or more NALUs (Full frames are required)
// try "AnnexB" from H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
if
((
ret
=
avc_demux_annexb_format
(
stream
,
sample
))
!=
ERROR_SUCCESS
)
{
// stop try when system error.
if
(
ret
!=
ERROR_HLS_AVC_TRY_OTHERS
)
{
srs_error
(
"avc demux for annexb failed. ret=%d"
,
ret
);
return
ret
;
}
// try "ISO Base Media File Format" from H.264-AVC-ISO_IEC_14496-15.pdf, page 20
if
((
ret
=
avc_demux_ibmf_format
(
stream
,
sample
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
else
{
payload_format
=
SrsAvcPayloadFormatIbmf
;
srs_info
(
"hls guess avc payload is ibmf format."
);
}
}
else
{
payload_format
=
SrsAvcPayloadFormatAnnexb
;
srs_info
(
"hls guess avc payload is annexb format."
);
int
SrsAvcAacCodec
::
video_nalu_demux
(
SrsStream
*
stream
,
SrsCodecSample
*
sample
)
{
int
ret
=
ERROR_SUCCESS
;
// ensure the sequence header demuxed
if
(
!
is_avc_codec_ok
())
{
srs_warn
(
"avc ignore type=%d for no sequence header. ret=%d"
,
SrsCodecVideoAVCTypeNALU
,
ret
);
return
ret
;
}
// guess for the first time.
if
(
payload_format
==
SrsAvcPayloadFormatGuess
)
{
// One or more NALUs (Full frames are required)
// try "AnnexB" from H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
if
((
ret
=
avc_demux_annexb_format
(
stream
,
sample
))
!=
ERROR_SUCCESS
)
{
// stop try when system error.
if
(
ret
!=
ERROR_HLS_AVC_TRY_OTHERS
)
{
srs_error
(
"avc demux for annexb failed. ret=%d"
,
ret
);
return
ret
;
}
}
else
if
(
payload_format
==
SrsAvcPayloadFormatIbmf
)
{
// try "ISO Base Media File Format" from H.264-AVC-ISO_IEC_14496-15.pdf, page 20
if
((
ret
=
avc_demux_ibmf_format
(
stream
,
sample
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
else
{
payload_format
=
SrsAvcPayloadFormatIbmf
;
srs_info
(
"hls guess avc payload is ibmf format."
);
}
srs_info
(
"hls decode avc payload in ibmf format."
);
}
else
{
// One or more NALUs (Full frames are required)
// try "AnnexB" from H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
if
((
ret
=
avc_demux_annexb_format
(
stream
,
sample
))
!=
ERROR_SUCCESS
)
{
// ok, we guess out the payload is annexb, but maybe changed to ibmf.
if
(
ret
!=
ERROR_HLS_AVC_TRY_OTHERS
)
{
srs_error
(
"avc demux for annexb failed. ret=%d"
,
ret
);
return
ret
;
}
// try "ISO Base Media File Format" from H.264-AVC-ISO_IEC_14496-15.pdf, page 20
if
((
ret
=
avc_demux_ibmf_format
(
stream
,
sample
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
else
{
payload_format
=
SrsAvcPayloadFormatIbmf
;
srs_warn
(
"hls avc payload change from annexb to ibmf format."
);
}
}
srs_info
(
"hls decode avc payload in annexb format."
);
payload_format
=
SrsAvcPayloadFormatAnnexb
;
srs_info
(
"hls guess avc payload is annexb format."
);
}
}
else
if
(
payload_format
==
SrsAvcPayloadFormatIbmf
)
{
// try "ISO Base Media File Format" from H.264-AVC-ISO_IEC_14496-15.pdf, page 20
if
((
ret
=
avc_demux_ibmf_format
(
stream
,
sample
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
srs_info
(
"hls decode avc payload in ibmf format."
);
}
else
{
// ignored.
// One or more NALUs (Full frames are required)
// try "AnnexB" from H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
if
((
ret
=
avc_demux_annexb_format
(
stream
,
sample
))
!=
ERROR_SUCCESS
)
{
// ok, we guess out the payload is annexb, but maybe changed to ibmf.
if
(
ret
!=
ERROR_HLS_AVC_TRY_OTHERS
)
{
srs_error
(
"avc demux for annexb failed. ret=%d"
,
ret
);
return
ret
;
}
// try "ISO Base Media File Format" from H.264-AVC-ISO_IEC_14496-15.pdf, page 20
if
((
ret
=
avc_demux_ibmf_format
(
stream
,
sample
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
else
{
payload_format
=
SrsAvcPayloadFormatIbmf
;
srs_warn
(
"hls avc payload change from annexb to ibmf format."
);
}
}
srs_info
(
"hls decode avc payload in annexb format."
);
}
srs_info
(
"avc decoded, type=%d, codec=%d, avc=%d, cts=%d, size=%d"
,
frame_type
,
video_codec_id
,
avc_packet_type
,
composition_time
,
size
);
// for keyframe, but not IDR, it's open gop.
if
(
sample
->
frame_type
==
SrsCodecVideoAVCFrameKeyFrame
&&
!
sample
->
has_idr
)
{
sample
->
open_gop
=
true
;
}
return
ret
;
}
...
...
trunk/src/kernel/srs_kernel_codec.hpp
查看文件 @
4104f25
...
...
@@ -385,15 +385,15 @@ public:
SrsCodecVideoAVCType
avc_packet_type
;
// whether sample_units contains IDR frame.
bool
has_idr
;
// Whether exists NonIDR NALU.
bool
has_non_idr
;
// Whether exists SEI NALU.
bool
has_sei
;
// Whether exists AUD NALU.
bool
has_aud
;
// The first nalu type.
SrsAvcNaluType
first_nalu_type
;
public
:
// Whether stream is open gop, which means the keyframe is not IDR but NonIDR.
// @remark we will identify whether stream is open-gop util reset.
bool
open_gop
;
public
:
// audio specified
SrsCodecAudio
acodec
;
// audio aac specified.
...
...
@@ -405,6 +405,8 @@ public:
SrsCodecSample
();
virtual
~
SrsCodecSample
();
public
:
// Reset the sample, clear the sample-base and stream-base data.
void
reset
();
/**
* clear all samples.
* the sample units never copy the bytes, it directly use the ptr,
...
...
@@ -637,6 +639,8 @@ public:
* demux the h.264 NALUs to sampe units.
*/
virtual
int
video_avc_demux
(
char
*
data
,
int
size
,
SrsCodecSample
*
sample
);
private
:
virtual
int
video_nalu_demux
(
SrsStream
*
stream
,
SrsCodecSample
*
sample
);
public
:
/**
* directly demux the sequence header, without RTMP packet header.
...
...
trunk/src/kernel/srs_kernel_ts.cpp
查看文件 @
4104f25
...
...
@@ -3010,7 +3010,7 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample)
static
u_int8_t
aud_nalu_7
[]
=
{
0x09
,
0xf0
};
// For NonIDR(open gop), we directly appends all frames.
if
(
sample
->
has_non_idr
||
(
sample
->
has_aud
&&
sample
->
has_sei
)
)
{
if
(
sample
->
open_gop
)
{
for
(
int
i
=
0
;
i
<
sample
->
nb_sample_units
;
i
++
)
{
SrsCodecSampleUnit
*
sample_unit
=
&
sample
->
sample_units
[
i
];
int32_t
size
=
sample_unit
->
size
;
...
...
@@ -3132,6 +3132,8 @@ int SrsTsEncoder::initialize(SrsFileWriter* fw)
return
ret
;
}
sample
->
reset
();
return
ret
;
}
...
...
请
注册
或
登录
后发表评论