mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
for #635, support IDR and NonIDR(open-gop).
This commit is contained in:
parent
c9a71b7fb2
commit
4104f25069
4 changed files with 91 additions and 64 deletions
|
@ -1071,7 +1071,7 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
|
||||||
// b. always reap when not wait keyframe.
|
// b. always reap when not wait keyframe.
|
||||||
if (!muxer->wait_keyframe() || sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) {
|
if (!muxer->wait_keyframe() || sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) {
|
||||||
// when wait keyframe, there must exists idr frame in sample, or NonIDR(open gop) specified.
|
// 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);
|
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);
|
srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sample->reset();
|
||||||
|
|
||||||
hls_enabled = false;
|
hls_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -324,13 +324,20 @@ SrsCodecSampleUnit::~SrsCodecSampleUnit()
|
||||||
|
|
||||||
SrsCodecSample::SrsCodecSample()
|
SrsCodecSample::SrsCodecSample()
|
||||||
{
|
{
|
||||||
clear();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsCodecSample::~SrsCodecSample()
|
SrsCodecSample::~SrsCodecSample()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsCodecSample::reset()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
open_gop = false;
|
||||||
|
}
|
||||||
|
|
||||||
void SrsCodecSample::clear()
|
void SrsCodecSample::clear()
|
||||||
{
|
{
|
||||||
is_video = false;
|
is_video = false;
|
||||||
|
@ -339,7 +346,7 @@ void SrsCodecSample::clear()
|
||||||
cts = 0;
|
cts = 0;
|
||||||
frame_type = SrsCodecVideoAVCFrameReserved;
|
frame_type = SrsCodecVideoAVCFrameReserved;
|
||||||
avc_packet_type = SrsCodecVideoAVCTypeReserved;
|
avc_packet_type = SrsCodecVideoAVCTypeReserved;
|
||||||
has_aud = has_sei = has_non_idr = has_idr = false;
|
has_aud = has_idr = false;
|
||||||
first_nalu_type = SrsAvcNaluTypeReserved;
|
first_nalu_type = SrsAvcNaluTypeReserved;
|
||||||
|
|
||||||
acodec = SrsCodecAudioReserved1;
|
acodec = SrsCodecAudioReserved1;
|
||||||
|
@ -370,10 +377,6 @@ int SrsCodecSample::add_sample_unit(char* bytes, int size)
|
||||||
|
|
||||||
if (nal_unit_type == SrsAvcNaluTypeIDR) {
|
if (nal_unit_type == SrsAvcNaluTypeIDR) {
|
||||||
has_idr = true;
|
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) {
|
} else if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) {
|
||||||
has_aud = true;
|
has_aud = true;
|
||||||
}
|
}
|
||||||
|
@ -698,9 +701,26 @@ int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} else if (avc_packet_type == SrsCodecVideoAVCTypeNALU){
|
} else if (avc_packet_type == SrsCodecVideoAVCTypeNALU){
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsAvcAacCodec::video_nalu_demux(SrsStream* stream, SrsCodecSample* sample)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// ensure the sequence header demuxed
|
// ensure the sequence header demuxed
|
||||||
if (!is_avc_codec_ok()) {
|
if (!is_avc_codec_ok()) {
|
||||||
srs_warn("avc ignore type=%d for no sequence header. ret=%d", avc_packet_type, ret);
|
srs_warn("avc ignore type=%d for no sequence header. ret=%d", SrsCodecVideoAVCTypeNALU, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -752,12 +772,11 @@ int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample
|
||||||
}
|
}
|
||||||
srs_info("hls decode avc payload in annexb format.");
|
srs_info("hls decode avc payload in annexb format.");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// ignored.
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_info("avc decoded, type=%d, codec=%d, avc=%d, cts=%d, size=%d",
|
// for keyframe, but not IDR, it's open gop.
|
||||||
frame_type, video_codec_id, avc_packet_type, composition_time, size);
|
if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame && !sample->has_idr) {
|
||||||
|
sample->open_gop = true;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,14 +385,14 @@ public:
|
||||||
SrsCodecVideoAVCType avc_packet_type;
|
SrsCodecVideoAVCType avc_packet_type;
|
||||||
// whether sample_units contains IDR frame.
|
// whether sample_units contains IDR frame.
|
||||||
bool has_idr;
|
bool has_idr;
|
||||||
// Whether exists NonIDR NALU.
|
|
||||||
bool has_non_idr;
|
|
||||||
// Whether exists SEI NALU.
|
|
||||||
bool has_sei;
|
|
||||||
// Whether exists AUD NALU.
|
// Whether exists AUD NALU.
|
||||||
bool has_aud;
|
bool has_aud;
|
||||||
// The first nalu type.
|
// The first nalu type.
|
||||||
SrsAvcNaluType 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:
|
public:
|
||||||
// audio specified
|
// audio specified
|
||||||
SrsCodecAudio acodec;
|
SrsCodecAudio acodec;
|
||||||
|
@ -405,6 +405,8 @@ public:
|
||||||
SrsCodecSample();
|
SrsCodecSample();
|
||||||
virtual ~SrsCodecSample();
|
virtual ~SrsCodecSample();
|
||||||
public:
|
public:
|
||||||
|
// Reset the sample, clear the sample-base and stream-base data.
|
||||||
|
void reset();
|
||||||
/**
|
/**
|
||||||
* clear all samples.
|
* clear all samples.
|
||||||
* the sample units never copy the bytes, it directly use the ptr,
|
* 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.
|
* demux the h.264 NALUs to sampe units.
|
||||||
*/
|
*/
|
||||||
virtual int video_avc_demux(char* data, int size, SrsCodecSample* sample);
|
virtual int video_avc_demux(char* data, int size, SrsCodecSample* sample);
|
||||||
|
private:
|
||||||
|
virtual int video_nalu_demux(SrsStream* stream, SrsCodecSample* sample);
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* directly demux the sequence header, without RTMP packet header.
|
* directly demux the sequence header, without RTMP packet header.
|
||||||
|
|
|
@ -3010,7 +3010,7 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample)
|
||||||
static u_int8_t aud_nalu_7[] = { 0x09, 0xf0};
|
static u_int8_t aud_nalu_7[] = { 0x09, 0xf0};
|
||||||
|
|
||||||
// For NonIDR(open gop), we directly appends all frames.
|
// 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++) {
|
for (int i = 0; i < sample->nb_sample_units; i++) {
|
||||||
SrsCodecSampleUnit* sample_unit = &sample->sample_units[i];
|
SrsCodecSampleUnit* sample_unit = &sample->sample_units[i];
|
||||||
int32_t size = sample_unit->size;
|
int32_t size = sample_unit->size;
|
||||||
|
@ -3132,6 +3132,8 @@ int SrsTsEncoder::initialize(SrsFileWriter* fw)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sample->reset();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue