|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|