From 4329366c08f52f70b1eb97fb02d1ef5a5d59f671 Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 4 Apr 2015 15:00:24 +0800 Subject: [PATCH 1/5] for #304, do not add deviation for absolute overflow. --- trunk/src/app/srs_app_hls.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/trunk/src/app/srs_app_hls.cpp b/trunk/src/app/srs_app_hls.cpp index 57e77153a..87e208d3f 100644 --- a/trunk/src/app/srs_app_hls.cpp +++ b/trunk/src/app/srs_app_hls.cpp @@ -487,11 +487,7 @@ bool SrsHlsMuxer::is_segment_absolutely_overflow() { // @see https://github.com/winlinvip/simple-rtmp-server/issues/151#issuecomment-83553950 srs_assert(current); - - // use N% deviation, to smoother. - double deviation = hls_ts_floor? SRS_HLS_FLOOR_REAP_PERCENT * hls_fragment_deviation : 0.0; - - return current->duration >= hls_aof_ratio * (hls_fragment + deviation); + return current->duration >= hls_aof_ratio * hls_fragment; } int SrsHlsMuxer::update_acodec(SrsCodecAudio ac) @@ -922,7 +918,7 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t // 2. some gops duration overflow. if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame && muxer->is_segment_overflow()) { if (!sample->has_idr) { - srs_warn("hls: ts starts without IDR, first nalu=%d", sample->first_nalu_type); + srs_warn("hls: ts starts without IDR, first nalu=%d, idr=%d", sample->first_nalu_type, sample->has_idr); } if ((ret = reap_segment("video", muxer, cache->video->dts)) != ERROR_SUCCESS) { return ret; From 61d5b78ae54dded05d642c534bad17fb3f816335 Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 4 Apr 2015 15:53:36 +0800 Subject: [PATCH 2/5] refine the h264 parser, one ts message should parsed to one rtmp/flv message. --- trunk/src/app/srs_app_mpegts_udp.cpp | 35 +++++++++++++++++++------ trunk/src/app/srs_app_rtsp.cpp | 14 ++++++++-- trunk/src/kernel/srs_kernel_codec.cpp | 26 +++++++++--------- trunk/src/kernel/srs_kernel_utility.cpp | 4 +-- trunk/src/kernel/srs_kernel_utility.hpp | 2 +- trunk/src/libs/srs_librtmp.cpp | 16 ++++++++--- trunk/src/protocol/srs_raw_avc.cpp | 15 ++--------- trunk/src/protocol/srs_raw_avc.hpp | 2 +- 8 files changed, 71 insertions(+), 43 deletions(-) diff --git a/trunk/src/app/srs_app_mpegts_udp.cpp b/trunk/src/app/srs_app_mpegts_udp.cpp index 459959286..dd7a1c27b 100644 --- a/trunk/src/app/srs_app_mpegts_udp.cpp +++ b/trunk/src/app/srs_app_mpegts_udp.cpp @@ -355,12 +355,20 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsStream* avs) if ((ret = avc->annexb_demux(avs, &frame, &frame_size)) != ERROR_SUCCESS) { return ret; } - - // ignore invalid frame, - // * atleast 1bytes for SPS to decode the type - // * ignore the auth bytes '09f0' - if (frame_size <= 2) { - continue; + + // 5bits, 7.3.1 NAL unit syntax, + // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. + // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame + SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f); + + // ignore the nalu type sps(7), pps(8), aud(9) + switch (nal_unit_type) { + case SrsAvcNaluTypeSPS: + case SrsAvcNaluTypePPS: + case SrsAvcNaluTypeAccessUnitDelimiter: + continue; + default: + break; } // for sps @@ -402,6 +410,7 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsStream* avs) } // ibp frame. + // TODO: FIXME: we should group all frames to a rtmp/flv message from one ts message. srs_info("mpegts: demux avc ibp frame size=%d, dts=%d", ibpframe_size, dts); if ((ret = write_h264_ipb_frame(frame, frame_size, dts, pts)) != ERROR_SUCCESS) { return ret; @@ -458,10 +467,20 @@ int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, u_int32_ if (!h264_sps_pps_sent) { return ERROR_H264_DROP_BEFORE_SPS_PPS; } + + // 5bits, 7.3.1 NAL unit syntax, + // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. + // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame + SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f); + + // for IDR frame, the frame is keyframe. + SrsCodecVideoAVCFrame frame_type = SrsCodecVideoAVCFrameInterFrame; + if (nal_unit_type == SrsAvcNaluTypeIDR) { + frame_type = SrsCodecVideoAVCFrameKeyFrame; + } std::string ibp; - int8_t frame_type; - if ((ret = avc->mux_ipb_frame(frame, frame_size, dts, pts, ibp, frame_type)) != ERROR_SUCCESS) { + if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) { return ret; } diff --git a/trunk/src/app/srs_app_rtsp.cpp b/trunk/src/app/srs_app_rtsp.cpp index 504532ecc..27798392f 100644 --- a/trunk/src/app/srs_app_rtsp.cpp +++ b/trunk/src/app/srs_app_rtsp.cpp @@ -579,10 +579,20 @@ int SrsRtspConn::write_h264_sps_pps(u_int32_t dts, u_int32_t pts) int SrsRtspConn::write_h264_ipb_frame(char* frame, int frame_size, u_int32_t dts, u_int32_t pts) { int ret = ERROR_SUCCESS; + + // 5bits, 7.3.1 NAL unit syntax, + // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. + // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame + SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f); + + // for IDR frame, the frame is keyframe. + SrsCodecVideoAVCFrame frame_type = SrsCodecVideoAVCFrameInterFrame; + if (nal_unit_type == SrsAvcNaluTypeIDR) { + frame_type = SrsCodecVideoAVCFrameKeyFrame; + } std::string ibp; - int8_t frame_type; - if ((ret = avc->mux_ipb_frame(frame, frame_size, dts, pts, ibp, frame_type)) != ERROR_SUCCESS) { + if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) { return ret; } diff --git a/trunk/src/kernel/srs_kernel_codec.cpp b/trunk/src/kernel/srs_kernel_codec.cpp index 640b4db1a..ca5a7d05b 100644 --- a/trunk/src/kernel/srs_kernel_codec.cpp +++ b/trunk/src/kernel/srs_kernel_codec.cpp @@ -929,7 +929,7 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp) return ret; } - int64_t seq_parameter_set_id = -1; + int32_t seq_parameter_set_id = -1; if ((ret = srs_avc_nalu_read_uev(&bs, seq_parameter_set_id)) != ERROR_SUCCESS) { return ret; } @@ -944,7 +944,7 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp) || profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118 || profile_idc == 128 ) { - int64_t chroma_format_idc = -1; + int32_t chroma_format_idc = -1; if ((ret = srs_avc_nalu_read_uev(&bs, chroma_format_idc)) != ERROR_SUCCESS) { return ret; } @@ -955,12 +955,12 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp) } } - int64_t bit_depth_luma_minus8 = -1; + int32_t bit_depth_luma_minus8 = -1; if ((ret = srs_avc_nalu_read_uev(&bs, bit_depth_luma_minus8)) != ERROR_SUCCESS) { return ret; } - int64_t bit_depth_chroma_minus8 = -1; + int32_t bit_depth_chroma_minus8 = -1; if ((ret = srs_avc_nalu_read_uev(&bs, bit_depth_chroma_minus8)) != ERROR_SUCCESS) { return ret; } @@ -981,18 +981,18 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp) } } - int64_t log2_max_frame_num_minus4 = -1; + int32_t log2_max_frame_num_minus4 = -1; if ((ret = srs_avc_nalu_read_uev(&bs, log2_max_frame_num_minus4)) != ERROR_SUCCESS) { return ret; } - int64_t pic_order_cnt_type = -1; + int32_t pic_order_cnt_type = -1; if ((ret = srs_avc_nalu_read_uev(&bs, pic_order_cnt_type)) != ERROR_SUCCESS) { return ret; } if (pic_order_cnt_type == 0) { - int64_t log2_max_pic_order_cnt_lsb_minus4 = -1; + int32_t log2_max_pic_order_cnt_lsb_minus4 = -1; if ((ret = srs_avc_nalu_read_uev(&bs, log2_max_pic_order_cnt_lsb_minus4)) != ERROR_SUCCESS) { return ret; } @@ -1002,17 +1002,17 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp) return ret; } - int64_t offset_for_non_ref_pic = -1; + int32_t offset_for_non_ref_pic = -1; if ((ret = srs_avc_nalu_read_uev(&bs, offset_for_non_ref_pic)) != ERROR_SUCCESS) { return ret; } - int64_t offset_for_top_to_bottom_field = -1; + int32_t offset_for_top_to_bottom_field = -1; if ((ret = srs_avc_nalu_read_uev(&bs, offset_for_top_to_bottom_field)) != ERROR_SUCCESS) { return ret; } - int64_t num_ref_frames_in_pic_order_cnt_cycle = -1; + int32_t num_ref_frames_in_pic_order_cnt_cycle = -1; if ((ret = srs_avc_nalu_read_uev(&bs, num_ref_frames_in_pic_order_cnt_cycle)) != ERROR_SUCCESS) { return ret; } @@ -1023,7 +1023,7 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp) } } - int64_t max_num_ref_frames = -1; + int32_t max_num_ref_frames = -1; if ((ret = srs_avc_nalu_read_uev(&bs, max_num_ref_frames)) != ERROR_SUCCESS) { return ret; } @@ -1033,12 +1033,12 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp) return ret; } - int64_t pic_width_in_mbs_minus1 = -1; + int32_t pic_width_in_mbs_minus1 = -1; if ((ret = srs_avc_nalu_read_uev(&bs, pic_width_in_mbs_minus1)) != ERROR_SUCCESS) { return ret; } - int64_t pic_height_in_map_units_minus1 = -1; + int32_t pic_height_in_map_units_minus1 = -1; if ((ret = srs_avc_nalu_read_uev(&bs, pic_height_in_map_units_minus1)) != ERROR_SUCCESS) { return ret; } diff --git a/trunk/src/kernel/srs_kernel_utility.cpp b/trunk/src/kernel/srs_kernel_utility.cpp index 6e1a50b90..218ac153b 100644 --- a/trunk/src/kernel/srs_kernel_utility.cpp +++ b/trunk/src/kernel/srs_kernel_utility.cpp @@ -46,7 +46,7 @@ using namespace std; // @see SRS_SYS_TIME_RESOLUTION_MS_TIMES #define SYS_TIME_RESOLUTION_US 300*1000 -int srs_avc_nalu_read_uev(SrsBitStream* stream, int64_t& v) +int srs_avc_nalu_read_uev(SrsBitStream* stream, int32_t& v) { int ret = ERROR_SUCCESS; @@ -67,7 +67,7 @@ int srs_avc_nalu_read_uev(SrsBitStream* stream, int64_t& v) b = stream->read_bit(); } - if (leadingZeroBits >= 64) { + if (leadingZeroBits >= 31) { return ERROR_AVC_NALU_UEV; } diff --git a/trunk/src/kernel/srs_kernel_utility.hpp b/trunk/src/kernel/srs_kernel_utility.hpp index a23474afa..9f333ef94 100644 --- a/trunk/src/kernel/srs_kernel_utility.hpp +++ b/trunk/src/kernel/srs_kernel_utility.hpp @@ -40,7 +40,7 @@ class SrsBitStream; #define srs_max(a, b) (((a) < (b))? (b) : (a)) // read nalu uev. -extern int srs_avc_nalu_read_uev(SrsBitStream* stream, int64_t& v); +extern int srs_avc_nalu_read_uev(SrsBitStream* stream, int32_t& v); extern int srs_avc_nalu_read_bit(SrsBitStream* stream, int8_t& v); // get current system time in ms, use cache to avoid performance problem diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index 84f61fc6f..b2c623718 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -1243,10 +1243,20 @@ int srs_write_h264_ipb_frame(Context* context, if (!context->h264_sps_pps_sent) { return ERROR_H264_DROP_BEFORE_SPS_PPS; } - + + // 5bits, 7.3.1 NAL unit syntax, + // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. + // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame + SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f); + + // for IDR frame, the frame is keyframe. + SrsCodecVideoAVCFrame frame_type = SrsCodecVideoAVCFrameInterFrame; + if (nal_unit_type == SrsAvcNaluTypeIDR) { + frame_type = SrsCodecVideoAVCFrameKeyFrame; + } + std::string ibp; - int8_t frame_type; - if ((ret = context->avc_raw.mux_ipb_frame(frame, frame_size, dts, pts, ibp, frame_type)) != ERROR_SUCCESS) { + if ((ret = context->avc_raw.mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) { return ret; } diff --git a/trunk/src/protocol/srs_raw_avc.cpp b/trunk/src/protocol/srs_raw_avc.cpp index d3efced03..4e95db40f 100644 --- a/trunk/src/protocol/srs_raw_avc.cpp +++ b/trunk/src/protocol/srs_raw_avc.cpp @@ -226,15 +226,10 @@ int SrsRawH264Stream::mux_sequence_header(string sps, string pps, u_int32_t dts, return ret; } -int SrsRawH264Stream::mux_ipb_frame(char* frame, int nb_frame, u_int32_t dts, u_int32_t pts, string& ibp, int8_t& frame_type) +int SrsRawH264Stream::mux_ipb_frame(char* frame, int nb_frame, string& ibp) { int ret = ERROR_SUCCESS; - // 5bits, 7.3.1 NAL unit syntax, - // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. - // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame - u_int8_t nal_unit_type = (char)frame[0] & 0x1f; - // 4bytes size of nalu: // NALUnitLength // Nbytes of nalu. @@ -260,12 +255,6 @@ int SrsRawH264Stream::mux_ipb_frame(char* frame, int nb_frame, u_int32_t dts, u_ // NALUnit stream.write_bytes(frame, nb_frame); - // send out h264 packet. - frame_type = SrsCodecVideoAVCFrameInterFrame; - if (nal_unit_type != 1) { - frame_type = SrsCodecVideoAVCFrameKeyFrame; - } - ibp = ""; ibp.append(packet, nb_packet); @@ -281,7 +270,7 @@ int SrsRawH264Stream::mux_avc2flv(string video, int8_t frame_type, int8_t avc_pa // 1bytes, AVCPacketType // 3bytes, CompositionTime, the cts. // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78 - int size = video.length() + 5; + int size = (int)video.length() + 5; char* data = new char[size]; char* p = data; diff --git a/trunk/src/protocol/srs_raw_avc.hpp b/trunk/src/protocol/srs_raw_avc.hpp index 0dc05dc6f..f12633869 100644 --- a/trunk/src/protocol/srs_raw_avc.hpp +++ b/trunk/src/protocol/srs_raw_avc.hpp @@ -76,7 +76,7 @@ public: * @param ibp output the packet. * @param frame_type output the frame type. */ - virtual int mux_ipb_frame(char* frame, int nb_frame, u_int32_t dts, u_int32_t pts, std::string& ibp, int8_t& frame_type); + virtual int mux_ipb_frame(char* frame, int nb_frame, std::string& ibp); /** * mux the avc video packet to flv video packet. * @param frame_type, SrsCodecVideoAVCFrameKeyFrame or SrsCodecVideoAVCFrameInterFrame. From bd7db5aed6eafbf477d1c42bcb1fd42b33e9dcb5 Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 4 Apr 2015 16:05:11 +0800 Subject: [PATCH 3/5] only ignore the aud message. --- trunk/src/app/srs_app_mpegts_udp.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/trunk/src/app/srs_app_mpegts_udp.cpp b/trunk/src/app/srs_app_mpegts_udp.cpp index dd7a1c27b..94e2488b0 100644 --- a/trunk/src/app/srs_app_mpegts_udp.cpp +++ b/trunk/src/app/srs_app_mpegts_udp.cpp @@ -362,13 +362,8 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsStream* avs) SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f); // ignore the nalu type sps(7), pps(8), aud(9) - switch (nal_unit_type) { - case SrsAvcNaluTypeSPS: - case SrsAvcNaluTypePPS: - case SrsAvcNaluTypeAccessUnitDelimiter: - continue; - default: - break; + if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) { + continue; } // for sps From 3fcc26a499951a99de09525368ad71940496891a Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 4 Apr 2015 16:24:33 +0800 Subject: [PATCH 4/5] update donation. --- DONATIONS.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DONATIONS.txt b/DONATIONS.txt index a28d0164b..d4fbc796d 100644 --- a/DONATIONS.txt +++ b/DONATIONS.txt @@ -7,7 +7,7 @@ RMB 10000+ * [2015-03-03 13:25] 郭强 RMB 1000-9999 -* [2015-xx-xx xx:xx] xxx +* [2015-04-04 16:19] 蔡汉城 RMB 500-999 * [2015-xx-xx xx:xx] xxx From 6e2d756e1bde43a0d725a59614423853987e6106 Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 4 Apr 2015 18:24:07 +0800 Subject: [PATCH 5/5] fix the bug of h.264 bit stream demux. --- trunk/src/kernel/srs_kernel_codec.cpp | 7 +++++++ trunk/src/kernel/srs_kernel_utility.cpp | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/trunk/src/kernel/srs_kernel_codec.cpp b/trunk/src/kernel/srs_kernel_codec.cpp index ca5a7d05b..906bf46c1 100644 --- a/trunk/src/kernel/srs_kernel_codec.cpp +++ b/trunk/src/kernel/srs_kernel_codec.cpp @@ -876,6 +876,13 @@ int SrsAvcAacCodec::avc_demux_sps() // XX 00 00 03 XX, the 03 byte should be drop. if (nb_rbsp > 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) { + // read 1byte more. + if (stream.empty()) { + break; + } + rbsp[nb_rbsp] = stream.read_1bytes(); + nb_rbsp++; + continue; } diff --git a/trunk/src/kernel/srs_kernel_utility.cpp b/trunk/src/kernel/srs_kernel_utility.cpp index 218ac153b..32598a13f 100644 --- a/trunk/src/kernel/srs_kernel_utility.cpp +++ b/trunk/src/kernel/srs_kernel_utility.cpp @@ -73,7 +73,7 @@ int srs_avc_nalu_read_uev(SrsBitStream* stream, int32_t& v) v = (1 << leadingZeroBits) - 1; for (int i = 0; i < leadingZeroBits; i++) { - int64_t b = stream->read_bit(); + int32_t b = stream->read_bit(); v += b << (leadingZeroBits - 1); }