正在显示
4 个修改的文件
包含
86 行增加
和
59 行删除
@@ -1071,7 +1071,7 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | @@ -1071,7 +1071,7 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t | ||
1071 | // b. always reap when not wait keyframe. | 1071 | // b. always reap when not wait keyframe. |
1072 | if (!muxer->wait_keyframe() || sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) { | 1072 | if (!muxer->wait_keyframe() || sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) { |
1073 | // when wait keyframe, there must exists idr frame in sample, or NonIDR(open gop) specified. | 1073 | // when wait keyframe, there must exists idr frame in sample, or NonIDR(open gop) specified. |
1074 | - if (!sample->has_non_idr && !sample->has_idr && muxer->wait_keyframe()) { | 1074 | + if (!sample->open_gop && !sample->has_idr && muxer->wait_keyframe()) { |
1075 | srs_warn("hls: ts starts without IDR, first nalu=%d, idr=%d", sample->first_nalu_type, sample->has_idr); | 1075 | srs_warn("hls: ts starts without IDR, first nalu=%d, idr=%d", sample->first_nalu_type, sample->has_idr); |
1076 | } | 1076 | } |
1077 | 1077 | ||
@@ -1274,6 +1274,8 @@ void SrsHls::on_unpublish() | @@ -1274,6 +1274,8 @@ void SrsHls::on_unpublish() | ||
1274 | srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret); | 1274 | srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret); |
1275 | } | 1275 | } |
1276 | 1276 | ||
1277 | + sample->reset(); | ||
1278 | + | ||
1277 | hls_enabled = false; | 1279 | hls_enabled = false; |
1278 | } | 1280 | } |
1279 | 1281 |
@@ -324,13 +324,20 @@ SrsCodecSampleUnit::~SrsCodecSampleUnit() | @@ -324,13 +324,20 @@ SrsCodecSampleUnit::~SrsCodecSampleUnit() | ||
324 | 324 | ||
325 | SrsCodecSample::SrsCodecSample() | 325 | SrsCodecSample::SrsCodecSample() |
326 | { | 326 | { |
327 | - clear(); | 327 | + reset(); |
328 | } | 328 | } |
329 | 329 | ||
330 | SrsCodecSample::~SrsCodecSample() | 330 | SrsCodecSample::~SrsCodecSample() |
331 | { | 331 | { |
332 | } | 332 | } |
333 | 333 | ||
334 | +void SrsCodecSample::reset() | ||
335 | +{ | ||
336 | + clear(); | ||
337 | + | ||
338 | + open_gop = false; | ||
339 | +} | ||
340 | + | ||
334 | void SrsCodecSample::clear() | 341 | void SrsCodecSample::clear() |
335 | { | 342 | { |
336 | is_video = false; | 343 | is_video = false; |
@@ -339,7 +346,7 @@ void SrsCodecSample::clear() | @@ -339,7 +346,7 @@ void SrsCodecSample::clear() | ||
339 | cts = 0; | 346 | cts = 0; |
340 | frame_type = SrsCodecVideoAVCFrameReserved; | 347 | frame_type = SrsCodecVideoAVCFrameReserved; |
341 | avc_packet_type = SrsCodecVideoAVCTypeReserved; | 348 | avc_packet_type = SrsCodecVideoAVCTypeReserved; |
342 | - has_aud = has_sei = has_non_idr = has_idr = false; | 349 | + has_aud = has_idr = false; |
343 | first_nalu_type = SrsAvcNaluTypeReserved; | 350 | first_nalu_type = SrsAvcNaluTypeReserved; |
344 | 351 | ||
345 | acodec = SrsCodecAudioReserved1; | 352 | acodec = SrsCodecAudioReserved1; |
@@ -370,10 +377,6 @@ int SrsCodecSample::add_sample_unit(char* bytes, int size) | @@ -370,10 +377,6 @@ int SrsCodecSample::add_sample_unit(char* bytes, int size) | ||
370 | 377 | ||
371 | if (nal_unit_type == SrsAvcNaluTypeIDR) { | 378 | if (nal_unit_type == SrsAvcNaluTypeIDR) { |
372 | has_idr = true; | 379 | has_idr = true; |
373 | - } else if (nal_unit_type == SrsAvcNaluTypeNonIDR) { | ||
374 | - has_non_idr = true; | ||
375 | - } else if (nal_unit_type == SrsAvcNaluTypeSEI) { | ||
376 | - has_sei = true; | ||
377 | } else if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) { | 380 | } else if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) { |
378 | has_aud = true; | 381 | has_aud = true; |
379 | } | 382 | } |
@@ -698,66 +701,82 @@ int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample | @@ -698,66 +701,82 @@ int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample | ||
698 | return ret; | 701 | return ret; |
699 | } | 702 | } |
700 | } else if (avc_packet_type == SrsCodecVideoAVCTypeNALU){ | 703 | } else if (avc_packet_type == SrsCodecVideoAVCTypeNALU){ |
701 | - // ensure the sequence header demuxed | ||
702 | - if (!is_avc_codec_ok()) { | ||
703 | - srs_warn("avc ignore type=%d for no sequence header. ret=%d", avc_packet_type, ret); | 704 | + if ((ret = video_nalu_demux(stream, sample)) != ERROR_SUCCESS) { |
704 | return ret; | 705 | return ret; |
705 | } | 706 | } |
707 | + } else { | ||
708 | + // ignored. | ||
709 | + } | ||
710 | + | ||
711 | + srs_info("avc decoded, type=%d, codec=%d, avc=%d, cts=%d, size=%d", | ||
712 | + frame_type, video_codec_id, avc_packet_type, composition_time, size); | ||
713 | + | ||
714 | + return ret; | ||
715 | +} | ||
706 | 716 | ||
707 | - // guess for the first time. | ||
708 | - if (payload_format == SrsAvcPayloadFormatGuess) { | ||
709 | - // One or more NALUs (Full frames are required) | ||
710 | - // try "AnnexB" from H.264-AVC-ISO_IEC_14496-10.pdf, page 211. | ||
711 | - if ((ret = avc_demux_annexb_format(stream, sample)) != ERROR_SUCCESS) { | ||
712 | - // stop try when system error. | ||
713 | - if (ret != ERROR_HLS_AVC_TRY_OTHERS) { | ||
714 | - srs_error("avc demux for annexb failed. ret=%d", ret); | ||
715 | - return ret; | ||
716 | - } | ||
717 | - | ||
718 | - // try "ISO Base Media File Format" from H.264-AVC-ISO_IEC_14496-15.pdf, page 20 | ||
719 | - if ((ret = avc_demux_ibmf_format(stream, sample)) != ERROR_SUCCESS) { | ||
720 | - return ret; | ||
721 | - } else { | ||
722 | - payload_format = SrsAvcPayloadFormatIbmf; | ||
723 | - srs_info("hls guess avc payload is ibmf format."); | ||
724 | - } | ||
725 | - } else { | ||
726 | - payload_format = SrsAvcPayloadFormatAnnexb; | ||
727 | - srs_info("hls guess avc payload is annexb format."); | 717 | +int SrsAvcAacCodec::video_nalu_demux(SrsStream* stream, SrsCodecSample* sample) |
718 | +{ | ||
719 | + int ret = ERROR_SUCCESS; | ||
720 | + | ||
721 | + // ensure the sequence header demuxed | ||
722 | + if (!is_avc_codec_ok()) { | ||
723 | + srs_warn("avc ignore type=%d for no sequence header. ret=%d", SrsCodecVideoAVCTypeNALU, ret); | ||
724 | + return ret; | ||
725 | + } | ||
726 | + | ||
727 | + // guess for the first time. | ||
728 | + if (payload_format == SrsAvcPayloadFormatGuess) { | ||
729 | + // One or more NALUs (Full frames are required) | ||
730 | + // try "AnnexB" from H.264-AVC-ISO_IEC_14496-10.pdf, page 211. | ||
731 | + if ((ret = avc_demux_annexb_format(stream, sample)) != ERROR_SUCCESS) { | ||
732 | + // stop try when system error. | ||
733 | + if (ret != ERROR_HLS_AVC_TRY_OTHERS) { | ||
734 | + srs_error("avc demux for annexb failed. ret=%d", ret); | ||
735 | + return ret; | ||
728 | } | 736 | } |
729 | - } else if (payload_format == SrsAvcPayloadFormatIbmf) { | 737 | + |
730 | // try "ISO Base Media File Format" from H.264-AVC-ISO_IEC_14496-15.pdf, page 20 | 738 | // try "ISO Base Media File Format" from H.264-AVC-ISO_IEC_14496-15.pdf, page 20 |
731 | if ((ret = avc_demux_ibmf_format(stream, sample)) != ERROR_SUCCESS) { | 739 | if ((ret = avc_demux_ibmf_format(stream, sample)) != ERROR_SUCCESS) { |
732 | return ret; | 740 | return ret; |
741 | + } else { | ||
742 | + payload_format = SrsAvcPayloadFormatIbmf; | ||
743 | + srs_info("hls guess avc payload is ibmf format."); | ||
733 | } | 744 | } |
734 | - srs_info("hls decode avc payload in ibmf format."); | ||
735 | } else { | 745 | } else { |
736 | - // One or more NALUs (Full frames are required) | ||
737 | - // try "AnnexB" from H.264-AVC-ISO_IEC_14496-10.pdf, page 211. | ||
738 | - if ((ret = avc_demux_annexb_format(stream, sample)) != ERROR_SUCCESS) { | ||
739 | - // ok, we guess out the payload is annexb, but maybe changed to ibmf. | ||
740 | - if (ret != ERROR_HLS_AVC_TRY_OTHERS) { | ||
741 | - srs_error("avc demux for annexb failed. ret=%d", ret); | ||
742 | - return ret; | ||
743 | - } | ||
744 | - | ||
745 | - // try "ISO Base Media File Format" from H.264-AVC-ISO_IEC_14496-15.pdf, page 20 | ||
746 | - if ((ret = avc_demux_ibmf_format(stream, sample)) != ERROR_SUCCESS) { | ||
747 | - return ret; | ||
748 | - } else { | ||
749 | - payload_format = SrsAvcPayloadFormatIbmf; | ||
750 | - srs_warn("hls avc payload change from annexb to ibmf format."); | ||
751 | - } | ||
752 | - } | ||
753 | - srs_info("hls decode avc payload in annexb format."); | 746 | + payload_format = SrsAvcPayloadFormatAnnexb; |
747 | + srs_info("hls guess avc payload is annexb format."); | ||
754 | } | 748 | } |
749 | + } else if (payload_format == SrsAvcPayloadFormatIbmf) { | ||
750 | + // try "ISO Base Media File Format" from H.264-AVC-ISO_IEC_14496-15.pdf, page 20 | ||
751 | + if ((ret = avc_demux_ibmf_format(stream, sample)) != ERROR_SUCCESS) { | ||
752 | + return ret; | ||
753 | + } | ||
754 | + srs_info("hls decode avc payload in ibmf format."); | ||
755 | } else { | 755 | } else { |
756 | - // ignored. | 756 | + // One or more NALUs (Full frames are required) |
757 | + // try "AnnexB" from H.264-AVC-ISO_IEC_14496-10.pdf, page 211. | ||
758 | + if ((ret = avc_demux_annexb_format(stream, sample)) != ERROR_SUCCESS) { | ||
759 | + // ok, we guess out the payload is annexb, but maybe changed to ibmf. | ||
760 | + if (ret != ERROR_HLS_AVC_TRY_OTHERS) { | ||
761 | + srs_error("avc demux for annexb failed. ret=%d", ret); | ||
762 | + return ret; | ||
763 | + } | ||
764 | + | ||
765 | + // try "ISO Base Media File Format" from H.264-AVC-ISO_IEC_14496-15.pdf, page 20 | ||
766 | + if ((ret = avc_demux_ibmf_format(stream, sample)) != ERROR_SUCCESS) { | ||
767 | + return ret; | ||
768 | + } else { | ||
769 | + payload_format = SrsAvcPayloadFormatIbmf; | ||
770 | + srs_warn("hls avc payload change from annexb to ibmf format."); | ||
771 | + } | ||
772 | + } | ||
773 | + srs_info("hls decode avc payload in annexb format."); | ||
757 | } | 774 | } |
758 | 775 | ||
759 | - srs_info("avc decoded, type=%d, codec=%d, avc=%d, cts=%d, size=%d", | ||
760 | - frame_type, video_codec_id, avc_packet_type, composition_time, size); | 776 | + // for keyframe, but not IDR, it's open gop. |
777 | + if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame && !sample->has_idr) { | ||
778 | + sample->open_gop = true; | ||
779 | + } | ||
761 | 780 | ||
762 | return ret; | 781 | return ret; |
763 | } | 782 | } |
@@ -385,15 +385,15 @@ public: | @@ -385,15 +385,15 @@ public: | ||
385 | SrsCodecVideoAVCType avc_packet_type; | 385 | SrsCodecVideoAVCType avc_packet_type; |
386 | // whether sample_units contains IDR frame. | 386 | // whether sample_units contains IDR frame. |
387 | bool has_idr; | 387 | bool has_idr; |
388 | - // Whether exists NonIDR NALU. | ||
389 | - bool has_non_idr; | ||
390 | - // Whether exists SEI NALU. | ||
391 | - bool has_sei; | ||
392 | // Whether exists AUD NALU. | 388 | // Whether exists AUD NALU. |
393 | bool has_aud; | 389 | bool has_aud; |
394 | // The first nalu type. | 390 | // The first nalu type. |
395 | SrsAvcNaluType first_nalu_type; | 391 | SrsAvcNaluType first_nalu_type; |
396 | public: | 392 | public: |
393 | + // Whether stream is open gop, which means the keyframe is not IDR but NonIDR. | ||
394 | + // @remark we will identify whether stream is open-gop util reset. | ||
395 | + bool open_gop; | ||
396 | +public: | ||
397 | // audio specified | 397 | // audio specified |
398 | SrsCodecAudio acodec; | 398 | SrsCodecAudio acodec; |
399 | // audio aac specified. | 399 | // audio aac specified. |
@@ -405,6 +405,8 @@ public: | @@ -405,6 +405,8 @@ public: | ||
405 | SrsCodecSample(); | 405 | SrsCodecSample(); |
406 | virtual ~SrsCodecSample(); | 406 | virtual ~SrsCodecSample(); |
407 | public: | 407 | public: |
408 | + // Reset the sample, clear the sample-base and stream-base data. | ||
409 | + void reset(); | ||
408 | /** | 410 | /** |
409 | * clear all samples. | 411 | * clear all samples. |
410 | * the sample units never copy the bytes, it directly use the ptr, | 412 | * the sample units never copy the bytes, it directly use the ptr, |
@@ -637,6 +639,8 @@ public: | @@ -637,6 +639,8 @@ public: | ||
637 | * demux the h.264 NALUs to sampe units. | 639 | * demux the h.264 NALUs to sampe units. |
638 | */ | 640 | */ |
639 | virtual int video_avc_demux(char* data, int size, SrsCodecSample* sample); | 641 | virtual int video_avc_demux(char* data, int size, SrsCodecSample* sample); |
642 | +private: | ||
643 | + virtual int video_nalu_demux(SrsStream* stream, SrsCodecSample* sample); | ||
640 | public: | 644 | public: |
641 | /** | 645 | /** |
642 | * directly demux the sequence header, without RTMP packet header. | 646 | * directly demux the sequence header, without RTMP packet header. |
@@ -3010,7 +3010,7 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample) | @@ -3010,7 +3010,7 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample) | ||
3010 | static u_int8_t aud_nalu_7[] = { 0x09, 0xf0}; | 3010 | static u_int8_t aud_nalu_7[] = { 0x09, 0xf0}; |
3011 | 3011 | ||
3012 | // For NonIDR(open gop), we directly appends all frames. | 3012 | // For NonIDR(open gop), we directly appends all frames. |
3013 | - if (sample->has_non_idr || (sample->has_aud && sample->has_sei)) { | 3013 | + if (sample->open_gop) { |
3014 | for (int i = 0; i < sample->nb_sample_units; i++) { | 3014 | for (int i = 0; i < sample->nb_sample_units; i++) { |
3015 | SrsCodecSampleUnit* sample_unit = &sample->sample_units[i]; | 3015 | SrsCodecSampleUnit* sample_unit = &sample->sample_units[i]; |
3016 | int32_t size = sample_unit->size; | 3016 | int32_t size = sample_unit->size; |
@@ -3132,6 +3132,8 @@ int SrsTsEncoder::initialize(SrsFileWriter* fw) | @@ -3132,6 +3132,8 @@ int SrsTsEncoder::initialize(SrsFileWriter* fw) | ||
3132 | return ret; | 3132 | return ret; |
3133 | } | 3133 | } |
3134 | 3134 | ||
3135 | + sample->reset(); | ||
3136 | + | ||
3135 | return ret; | 3137 | return ret; |
3136 | } | 3138 | } |
3137 | 3139 |
-
请 注册 或 登录 后发表评论