Merge branch '2.0release' into develop

pull/737/head
winlin 8 years ago
commit ae1920e91a

@ -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);
} }
@ -1271,6 +1271,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,66 +701,82 @@ 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){
// ensure the sequence header demuxed if ((ret = video_nalu_demux(stream, sample)) != ERROR_SUCCESS) {
if (!is_avc_codec_ok()) {
srs_warn("avc ignore type=%d for no sequence header. ret=%d", avc_packet_type, ret);
return ret; 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. int SrsAvcAacCodec::video_nalu_demux(SrsStream* stream, SrsCodecSample* sample)
if (payload_format == SrsAvcPayloadFormatGuess) { {
// One or more NALUs (Full frames are required) int ret = ERROR_SUCCESS;
// try "AnnexB" from H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
if ((ret = avc_demux_annexb_format(stream, sample)) != ERROR_SUCCESS) { // ensure the sequence header demuxed
// stop try when system error. if (!is_avc_codec_ok()) {
if (ret != ERROR_HLS_AVC_TRY_OTHERS) { srs_warn("avc ignore type=%d for no sequence header. ret=%d", SrsCodecVideoAVCTypeNALU, ret);
srs_error("avc demux for annexb failed. ret=%d", ret); return ret;
return ret; }
}
// guess for the first time.
// try "ISO Base Media File Format" from H.264-AVC-ISO_IEC_14496-15.pdf, page 20 if (payload_format == SrsAvcPayloadFormatGuess) {
if ((ret = avc_demux_ibmf_format(stream, sample)) != ERROR_SUCCESS) { // One or more NALUs (Full frames are required)
return ret; // try "AnnexB" from H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
} else { if ((ret = avc_demux_annexb_format(stream, sample)) != ERROR_SUCCESS) {
payload_format = SrsAvcPayloadFormatIbmf; // stop try when system error.
srs_info("hls guess avc payload is ibmf format."); if (ret != ERROR_HLS_AVC_TRY_OTHERS) {
} srs_error("avc demux for annexb failed. ret=%d", ret);
} else { return ret;
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 // 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) { if ((ret = avc_demux_ibmf_format(stream, sample)) != ERROR_SUCCESS) {
return ret; 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 { } else {
// One or more NALUs (Full frames are required) payload_format = SrsAvcPayloadFormatAnnexb;
// try "AnnexB" from H.264-AVC-ISO_IEC_14496-10.pdf, page 211. srs_info("hls guess avc payload is annexb format.");
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.");
} }
} 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 { } 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", // 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.

@ -3022,7 +3022,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;
@ -3144,6 +3144,8 @@ int SrsTsEncoder::initialize(SrsFileWriter* fw)
return ret; return ret;
} }
sample->reset();
return ret; return ret;
} }

Loading…
Cancel
Save