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 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; diff --git a/trunk/src/app/srs_app_mpegts_udp.cpp b/trunk/src/app/srs_app_mpegts_udp.cpp index 459959286..94e2488b0 100644 --- a/trunk/src/app/srs_app_mpegts_udp.cpp +++ b/trunk/src/app/srs_app_mpegts_udp.cpp @@ -355,11 +355,14 @@ 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) { + + // 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) + if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) { continue; } @@ -402,6 +405,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 +462,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..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; } @@ -929,7 +936,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 +951,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 +962,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 +988,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 +1009,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 +1030,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 +1040,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..32598a13f 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,13 +67,13 @@ 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; } 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); } 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.