正在显示
4 个修改的文件
包含
45 行增加
和
18 行删除
| @@ -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,9 +701,26 @@ int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample | @@ -698,9 +701,26 @@ 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){ |
| 704 | + if ((ret = video_nalu_demux(stream, sample)) != ERROR_SUCCESS) { | ||
| 705 | + return ret; | ||
| 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 | +} | ||
| 716 | + | ||
| 717 | +int SrsAvcAacCodec::video_nalu_demux(SrsStream* stream, SrsCodecSample* sample) | ||
| 718 | +{ | ||
| 719 | + int ret = ERROR_SUCCESS; | ||
| 720 | + | ||
| 701 | // ensure the sequence header demuxed | 721 | // ensure the sequence header demuxed |
| 702 | if (!is_avc_codec_ok()) { | 722 | if (!is_avc_codec_ok()) { |
| 703 | - srs_warn("avc ignore type=%d for no sequence header. ret=%d", avc_packet_type, ret); | 723 | + srs_warn("avc ignore type=%d for no sequence header. ret=%d", SrsCodecVideoAVCTypeNALU, ret); |
| 704 | return ret; | 724 | return ret; |
| 705 | } | 725 | } |
| 706 | 726 | ||
| @@ -752,12 +772,11 @@ int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample | @@ -752,12 +772,11 @@ int SrsAvcAacCodec::video_avc_demux(char* data, int size, SrsCodecSample* sample | ||
| 752 | } | 772 | } |
| 753 | srs_info("hls decode avc payload in annexb format."); | 773 | srs_info("hls decode avc payload in annexb format."); |
| 754 | } | 774 | } |
| 755 | - } else { | ||
| 756 | - // ignored. | ||
| 757 | - } | ||
| 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 |
-
请 注册 或 登录 后发表评论