正在显示
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 | ||
| @@ -1271,6 +1271,8 @@ void SrsHls::on_unpublish() | @@ -1271,6 +1271,8 @@ void SrsHls::on_unpublish() | ||
| 1271 | srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret); | 1271 | srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret); |
| 1272 | } | 1272 | } |
| 1273 | 1273 | ||
| 1274 | + sample->reset(); | ||
| 1275 | + | ||
| 1274 | hls_enabled = false; | 1276 | hls_enabled = false; |
| 1275 | } | 1277 | } |
| 1276 | 1278 |
| @@ -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. |
| @@ -3022,7 +3022,7 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample) | @@ -3022,7 +3022,7 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample) | ||
| 3022 | static u_int8_t aud_nalu_7[] = { 0x09, 0xf0}; | 3022 | static u_int8_t aud_nalu_7[] = { 0x09, 0xf0}; |
| 3023 | 3023 | ||
| 3024 | // For NonIDR(open gop), we directly appends all frames. | 3024 | // For NonIDR(open gop), we directly appends all frames. |
| 3025 | - if (sample->has_non_idr || (sample->has_aud && sample->has_sei)) { | 3025 | + if (sample->open_gop) { |
| 3026 | for (int i = 0; i < sample->nb_sample_units; i++) { | 3026 | for (int i = 0; i < sample->nb_sample_units; i++) { |
| 3027 | SrsCodecSampleUnit* sample_unit = &sample->sample_units[i]; | 3027 | SrsCodecSampleUnit* sample_unit = &sample->sample_units[i]; |
| 3028 | int32_t size = sample_unit->size; | 3028 | int32_t size = sample_unit->size; |
| @@ -3144,6 +3144,8 @@ int SrsTsEncoder::initialize(SrsFileWriter* fw) | @@ -3144,6 +3144,8 @@ int SrsTsEncoder::initialize(SrsFileWriter* fw) | ||
| 3144 | return ret; | 3144 | return ret; |
| 3145 | } | 3145 | } |
| 3146 | 3146 | ||
| 3147 | + sample->reset(); | ||
| 3148 | + | ||
| 3147 | return ret; | 3149 | return ret; |
| 3148 | } | 3150 | } |
| 3149 | 3151 |
-
请 注册 或 登录 后发表评论