winlin

for #304, rewrite annexb mux for ts, refer to apple sample. 2.0.157.

@@ -562,6 +562,7 @@ Supported operating systems and hardware: @@ -562,6 +562,7 @@ Supported operating systems and hardware:
562 562
563 ### SRS 2.0 history 563 ### SRS 2.0 history
564 564
  565 +* v2.0, 2015-04-04, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), rewrite annexb mux for ts, refer to apple sample. 2.0.157.
565 * v2.0, 2015-04-03, enhanced avc decode, parse the sps get width+height. 2.0.156. 566 * v2.0, 2015-04-03, enhanced avc decode, parse the sps get width+height. 2.0.156.
566 * v2.0, 2015-04-03, for [#372](https://github.com/winlinvip/simple-rtmp-server/issues/372), support transform vhost of edge 2.0.155. 567 * v2.0, 2015-04-03, for [#372](https://github.com/winlinvip/simple-rtmp-server/issues/372), support transform vhost of edge 2.0.155.
567 * v2.0, 2015-03-30, for [#366](https://github.com/winlinvip/simple-rtmp-server/issues/366), config hls to disable cleanup of ts. 2.0.154. 568 * v2.0, 2015-03-30, for [#366](https://github.com/winlinvip/simple-rtmp-server/issues/366), config hls to disable cleanup of ts. 2.0.154.
@@ -754,7 +754,7 @@ int SrsHlsMuxer::_refresh_m3u8(string m3u8_file) @@ -754,7 +754,7 @@ int SrsHlsMuxer::_refresh_m3u8(string m3u8_file)
754 // "#EXTINF:4294967295.208,\n" 754 // "#EXTINF:4294967295.208,\n"
755 ss.precision(3); 755 ss.precision(3);
756 ss.setf(std::ios::fixed, std::ios::floatfield); 756 ss.setf(std::ios::fixed, std::ios::floatfield);
757 - ss << "#EXTINF:" << segment->duration << "," << SRS_CONSTS_LF; 757 + ss << "#EXTINF:" << segment->duration << ", no desc" << SRS_CONSTS_LF;
758 srs_verbose("write m3u8 segment info success."); 758 srs_verbose("write m3u8 segment info success.");
759 759
760 // {file name}\n 760 // {file name}\n
@@ -918,9 +918,12 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t @@ -918,9 +918,12 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
918 } 918 }
919 919
920 // new segment when: 920 // new segment when:
921 - // 1. base on gop. 921 + // 1. base on gop(IDR).
922 // 2. some gops duration overflow. 922 // 2. some gops duration overflow.
923 if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame && muxer->is_segment_overflow()) { 923 if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame && muxer->is_segment_overflow()) {
  924 + if (!sample->has_idr) {
  925 + srs_warn("hls: ts starts without IDR, first nalu=%d", sample->first_nalu_type);
  926 + }
924 if ((ret = reap_segment("video", muxer, cache->video->dts)) != ERROR_SUCCESS) { 927 if ((ret = reap_segment("video", muxer, cache->video->dts)) != ERROR_SUCCESS) {
925 return ret; 928 return ret;
926 } 929 }
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 156 34 +#define VERSION_REVISION 157
35 35
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "SRS" 37 #define RTMP_SIG_SRS_KEY "SRS"
@@ -266,6 +266,30 @@ bool SrsFlvCodec::audio_is_aac(char* data, int size) @@ -266,6 +266,30 @@ bool SrsFlvCodec::audio_is_aac(char* data, int size)
266 return sound_format == SrsCodecAudioAAC; 266 return sound_format == SrsCodecAudioAAC;
267 } 267 }
268 268
  269 +string srs_codec_avc_nalu2str(SrsAvcNaluType nalu_type)
  270 +{
  271 + switch (nalu_type) {
  272 + case SrsAvcNaluTypeNonIDR: return "NonIDR";
  273 + case SrsAvcNaluTypeDataPartitionA: return "DataPartitionA";
  274 + case SrsAvcNaluTypeDataPartitionB: return "DataPartitionB";
  275 + case SrsAvcNaluTypeDataPartitionC: return "DataPartitionC";
  276 + case SrsAvcNaluTypeIDR: return "IDR";
  277 + case SrsAvcNaluTypeSEI: return "SEI";
  278 + case SrsAvcNaluTypeSPS: return "SPS";
  279 + case SrsAvcNaluTypePPS: return "PPS";
  280 + case SrsAvcNaluTypeAccessUnitDelimiter: return "AccessUnitDelimiter";
  281 + case SrsAvcNaluTypeEOSequence: return "EOSequence";
  282 + case SrsAvcNaluTypeEOStream: return "EOStream";
  283 + case SrsAvcNaluTypeFilterData: return "FilterData";
  284 + case SrsAvcNaluTypeSPSExt: return "SPSExt";
  285 + case SrsAvcNaluTypePrefixNALU: return "PrefixNALU";
  286 + case SrsAvcNaluTypeSubsetSPS: return "SubsetSPS";
  287 + case SrsAvcNaluTypeLayerWithoutPartition: return "LayerWithoutPartition";
  288 + case SrsAvcNaluTypeCodedSliceExt: return "CodedSliceExt";
  289 + case SrsAvcNaluTypeReserved: default: return "Other";
  290 + }
  291 +}
  292 +
269 SrsCodecSampleUnit::SrsCodecSampleUnit() 293 SrsCodecSampleUnit::SrsCodecSampleUnit()
270 { 294 {
271 size = 0; 295 size = 0;
@@ -293,6 +317,8 @@ void SrsCodecSample::clear() @@ -293,6 +317,8 @@ void SrsCodecSample::clear()
293 cts = 0; 317 cts = 0;
294 frame_type = SrsCodecVideoAVCFrameReserved; 318 frame_type = SrsCodecVideoAVCFrameReserved;
295 avc_packet_type = SrsCodecVideoAVCTypeReserved; 319 avc_packet_type = SrsCodecVideoAVCTypeReserved;
  320 + has_idr = false;
  321 + first_nalu_type = SrsAvcNaluTypeReserved;
296 322
297 acodec = SrsCodecAudioReserved1; 323 acodec = SrsCodecAudioReserved1;
298 sound_rate = SrsCodecAudioSampleRateReserved; 324 sound_rate = SrsCodecAudioSampleRateReserved;
@@ -316,6 +342,19 @@ int SrsCodecSample::add_sample_unit(char* bytes, int size) @@ -316,6 +342,19 @@ int SrsCodecSample::add_sample_unit(char* bytes, int size)
316 sample_unit->bytes = bytes; 342 sample_unit->bytes = bytes;
317 sample_unit->size = size; 343 sample_unit->size = size;
318 344
  345 + // for video, parse the nalu type, set the IDR flag.
  346 + if (is_video) {
  347 + SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(bytes[0] & 0x1f);
  348 +
  349 + if (nal_unit_type == SrsAvcNaluTypeIDR) {
  350 + has_idr = true;
  351 + }
  352 +
  353 + if (first_nalu_type == SrsAvcNaluTypeReserved) {
  354 + first_nalu_type = nal_unit_type;
  355 + }
  356 + }
  357 +
319 return ret; 358 return ret;
320 } 359 }
321 360
@@ -791,7 +830,7 @@ int SrsAvcAacCodec::avc_demux_sps() @@ -791,7 +830,7 @@ int SrsAvcAacCodec::avc_demux_sps()
791 } 830 }
792 831
793 // for NALU, 7.3.1 NAL unit syntax 832 // for NALU, 7.3.1 NAL unit syntax
794 - // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. 833 + // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 61.
795 if (!stream.require(1)) { 834 if (!stream.require(1)) {
796 ret = ERROR_HLS_DECODE_ERROR; 835 ret = ERROR_HLS_DECODE_ERROR;
797 srs_error("avc decode sps failed. ret=%d", ret); 836 srs_error("avc decode sps failed. ret=%d", ret);
@@ -816,10 +855,10 @@ int SrsAvcAacCodec::avc_demux_sps() @@ -816,10 +855,10 @@ int SrsAvcAacCodec::avc_demux_sps()
816 return ret; 855 return ret;
817 } 856 }
818 857
  858 + // 7.4.1 NAL unit semantics
  859 + // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 61.
819 // nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1. 860 // nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1.
820 - // VCL NAL units are specified as those NAL units having nal_unit_type equal to 1, 2, 3, 4, 5, or 12.  
821 - // All remaining NAL units are called non-VCL NAL units.  
822 - int8_t nal_unit_type = nutv & 0x1f; 861 + SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(nutv & 0x1f);
823 if (nal_unit_type != 7) { 862 if (nal_unit_type != 7) {
824 ret = ERROR_HLS_DECODE_ERROR; 863 ret = ERROR_HLS_DECODE_ERROR;
825 srs_error("for sps, nal_unit_type shall be equal to 7. ret=%d", ret); 864 srs_error("for sps, nal_unit_type shall be equal to 7. ret=%d", ret);
@@ -276,6 +276,52 @@ enum SrsCodecAudioSoundType @@ -276,6 +276,52 @@ enum SrsCodecAudioSoundType
276 }; 276 };
277 277
278 /** 278 /**
  279 + * Table 7-1 – NAL unit type codes, syntax element categories, and NAL unit type classes
  280 + * H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 83.
  281 + */
  282 +enum SrsAvcNaluType
  283 +{
  284 + // Unspecified
  285 + SrsAvcNaluTypeReserved = 0,
  286 +
  287 + // Coded slice of a non-IDR picture slice_layer_without_partitioning_rbsp( )
  288 + SrsAvcNaluTypeNonIDR = 1,
  289 + // Coded slice data partition A slice_data_partition_a_layer_rbsp( )
  290 + SrsAvcNaluTypeDataPartitionA = 2,
  291 + // Coded slice data partition B slice_data_partition_b_layer_rbsp( )
  292 + SrsAvcNaluTypeDataPartitionB = 3,
  293 + // Coded slice data partition C slice_data_partition_c_layer_rbsp( )
  294 + SrsAvcNaluTypeDataPartitionC = 4,
  295 + // Coded slice of an IDR picture slice_layer_without_partitioning_rbsp( )
  296 + SrsAvcNaluTypeIDR = 5,
  297 + // Supplemental enhancement information (SEI) sei_rbsp( )
  298 + SrsAvcNaluTypeSEI = 6,
  299 + // Sequence parameter set seq_parameter_set_rbsp( )
  300 + SrsAvcNaluTypeSPS = 7,
  301 + // Picture parameter set pic_parameter_set_rbsp( )
  302 + SrsAvcNaluTypePPS = 8,
  303 + // Access unit delimiter access_unit_delimiter_rbsp( )
  304 + SrsAvcNaluTypeAccessUnitDelimiter = 9,
  305 + // End of sequence end_of_seq_rbsp( )
  306 + SrsAvcNaluTypeEOSequence = 10,
  307 + // End of stream end_of_stream_rbsp( )
  308 + SrsAvcNaluTypeEOStream = 11,
  309 + // Filler data filler_data_rbsp( )
  310 + SrsAvcNaluTypeFilterData = 12,
  311 + // Sequence parameter set extension seq_parameter_set_extension_rbsp( )
  312 + SrsAvcNaluTypeSPSExt = 13,
  313 + // Prefix NAL unit prefix_nal_unit_rbsp( )
  314 + SrsAvcNaluTypePrefixNALU = 14,
  315 + // Subset sequence parameter set subset_seq_parameter_set_rbsp( )
  316 + SrsAvcNaluTypeSubsetSPS = 15,
  317 + // Coded slice of an auxiliary coded picture without partitioning slice_layer_without_partitioning_rbsp( )
  318 + SrsAvcNaluTypeLayerWithoutPartition = 19,
  319 + // Coded slice extension slice_layer_extension_rbsp( )
  320 + SrsAvcNaluTypeCodedSliceExt = 20,
  321 +};
  322 +std::string srs_codec_avc_nalu2str(SrsAvcNaluType nalu_type);
  323 +
  324 +/**
279 * the codec sample unit. 325 * the codec sample unit.
280 * for h.264 video packet, a NALU is a sample unit. 326 * for h.264 video packet, a NALU is a sample unit.
281 * for aac raw audio packet, a NALU is the entire aac raw data. 327 * for aac raw audio packet, a NALU is the entire aac raw data.
@@ -334,6 +380,9 @@ public: @@ -334,6 +380,9 @@ public:
334 // video specified 380 // video specified
335 SrsCodecVideoAVCFrame frame_type; 381 SrsCodecVideoAVCFrame frame_type;
336 SrsCodecVideoAVCType avc_packet_type; 382 SrsCodecVideoAVCType avc_packet_type;
  383 + // whether sample_units contains IDR frame.
  384 + bool has_idr;
  385 + SrsAvcNaluType first_nalu_type;
337 public: 386 public:
338 // audio specified 387 // audio specified
339 SrsCodecAudio acodec; 388 SrsCodecAudio acodec;
@@ -2835,19 +2835,104 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample) @@ -2835,19 +2835,104 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample)
2835 { 2835 {
2836 int ret = ERROR_SUCCESS; 2836 int ret = ERROR_SUCCESS;
2837 2837
2838 - // for type1/5/6, insert aud packet.  
2839 - u_int8_t aud_nal[] = { 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0 };  
2840 -  
2841 - bool sps_pps_sent = false;  
2842 - bool aud_sent = false; 2838 + // mux the samples in annexb format,
  2839 + // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 324.
2843 /** 2840 /**
2844 - * a ts sample is format as:  
2845 - * 00 00 00 01 // header  
2846 - * xxxxxxx // data bytes  
2847 - * 00 00 01 // continue header  
2848 - * xxxxxxx // data bytes.  
2849 - * so, for each sample, we append header in aud_nal, then appends the bytes in sample.  
2850 - */ 2841 + * 00 00 00 01 // header
  2842 + * xxxxxxx // data bytes
  2843 + * 00 00 01 // continue header
  2844 + * xxxxxxx // data bytes.
  2845 + *
  2846 + * nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1.
  2847 + * Table 7-1 – NAL unit type codes, syntax element categories, and NAL unit type classes
  2848 + * H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 83.
  2849 + * 1, Coded slice of a non-IDR picture slice_layer_without_partitioning_rbsp( )
  2850 + * 2, Coded slice data partition A slice_data_partition_a_layer_rbsp( )
  2851 + * 3, Coded slice data partition B slice_data_partition_b_layer_rbsp( )
  2852 + * 4, Coded slice data partition C slice_data_partition_c_layer_rbsp( )
  2853 + * 5, Coded slice of an IDR picture slice_layer_without_partitioning_rbsp( )
  2854 + * 6, Supplemental enhancement information (SEI) sei_rbsp( )
  2855 + * 7, Sequence parameter set seq_parameter_set_rbsp( )
  2856 + * 8, Picture parameter set pic_parameter_set_rbsp( )
  2857 + * 9, Access unit delimiter access_unit_delimiter_rbsp( )
  2858 + * 10, End of sequence end_of_seq_rbsp( )
  2859 + * 11, End of stream end_of_stream_rbsp( )
  2860 + * 12, Filler data filler_data_rbsp( )
  2861 + * 13, Sequence parameter set extension seq_parameter_set_extension_rbsp( )
  2862 + * 14, Prefix NAL unit prefix_nal_unit_rbsp( )
  2863 + * 15, Subset sequence parameter set subset_seq_parameter_set_rbsp( )
  2864 + * 19, Coded slice of an auxiliary coded picture without partitioning slice_layer_without_partitioning_rbsp( )
  2865 + * 20, Coded slice extension slice_layer_extension_rbsp( )
  2866 + * the first ts message of apple sample:
  2867 + * annexb 4B header, 2B aud(nal_unit_type:6)(0x09 0xf0)
  2868 + * annexb 4B header, 19B sps(nal_unit_type:7)
  2869 + * annexb 3B header, 4B pps(nal_unit_type:8)
  2870 + * annexb 3B header, 12B nalu(nal_unit_type:6)
  2871 + * annexb 3B header, 21B nalu(nal_unit_type:6)
  2872 + * annexb 3B header, 2762B nalu(nal_unit_type:5)
  2873 + * annexb 3B header, 3535B nalu(nal_unit_type:5)
  2874 + * the second ts message of apple ts sample:
  2875 + * annexb 4B header, 2B aud(nal_unit_type:6)(0x09 0xf0)
  2876 + * annexb 3B header, 21B nalu(nal_unit_type:6)
  2877 + * annexb 3B header, 379B nalu(nal_unit_type:1)
  2878 + * annexb 3B header, 406B nalu(nal_unit_type:1)
  2879 + */
  2880 + static u_int8_t fresh_nalu_header[] = { 0x00, 0x00, 0x00, 0x01 };
  2881 + static u_int8_t cont_nalu_header[] = { 0x00, 0x00, 0x01 };
  2882 +
  2883 + // the aud(access unit delimiter) before each frame.
  2884 + // 7.3.2.4 Access unit delimiter RBSP syntax
  2885 + // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 66.
  2886 + //
  2887 + // primary_pic_type u(3), the first 3bits, primary_pic_type indicates that the slice_type values
  2888 + // for all slices of the primary coded picture are members of the set listed in Table 7-5 for
  2889 + // the given value of primary_pic_type.
  2890 + // 0, slice_type 2, 7
  2891 + // 1, slice_type 0, 2, 5, 7
  2892 + // 2, slice_type 0, 1, 2, 5, 6, 7
  2893 + // 3, slice_type 4, 9
  2894 + // 4, slice_type 3, 4, 8, 9
  2895 + // 5, slice_type 2, 4, 7, 9
  2896 + // 6, slice_type 0, 2, 3, 4, 5, 7, 8, 9
  2897 + // 7, slice_type 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
  2898 + // 7.4.2.4 Access unit delimiter RBSP semantics
  2899 + // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 102.
  2900 + //
  2901 + // slice_type specifies the coding type of the slice according to Table 7-6.
  2902 + // 0, P (P slice)
  2903 + // 1, B (B slice)
  2904 + // 2, I (I slice)
  2905 + // 3, SP (SP slice)
  2906 + // 4, SI (SI slice)
  2907 + // 5, P (P slice)
  2908 + // 6, B (B slice)
  2909 + // 7, I (I slice)
  2910 + // 8, SP (SP slice)
  2911 + // 9, SI (SI slice)
  2912 + // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 105.
  2913 + static u_int8_t aud_nalu_7[] = { 0x09, 0xf0};
  2914 + video->payload->append((const char*)fresh_nalu_header, 4);
  2915 + video->payload->append((const char*)aud_nalu_7, 2);
  2916 +
  2917 + // when ts message(samples) contains IDR, insert sps+pps.
  2918 + if (sample->has_idr) {
  2919 + // fresh nalu header before sps.
  2920 + if (codec->sequenceParameterSetLength > 0) {
  2921 + // AnnexB prefix, for sps always 4 bytes header
  2922 + video->payload->append((const char*)fresh_nalu_header, 4);
  2923 + // sps
  2924 + video->payload->append(codec->sequenceParameterSetNALUnit, codec->sequenceParameterSetLength);
  2925 + }
  2926 + // cont nalu header before pps.
  2927 + if (codec->pictureParameterSetLength > 0) {
  2928 + // AnnexB prefix, for pps always 3 bytes header
  2929 + video->payload->append((const char*)cont_nalu_header, 3);
  2930 + // pps
  2931 + video->payload->append(codec->pictureParameterSetNALUnit, codec->pictureParameterSetLength);
  2932 + }
  2933 + }
  2934 +
  2935 + // all sample use cont nalu header, except the sps-pps before IDR frame.
2851 for (int i = 0; i < sample->nb_sample_units; i++) { 2936 for (int i = 0; i < sample->nb_sample_units; i++) {
2852 SrsCodecSampleUnit* sample_unit = &sample->sample_units[i]; 2937 SrsCodecSampleUnit* sample_unit = &sample->sample_units[i];
2853 int32_t size = sample_unit->size; 2938 int32_t size = sample_unit->size;
@@ -2858,83 +2943,22 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample) @@ -2858,83 +2943,22 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample)
2858 return ret; 2943 return ret;
2859 } 2944 }
2860 2945
2861 - /**  
2862 - * step 1:  
2863 - * first, before each "real" sample,  
2864 - * we add some packets according to the nal_unit_type,  
2865 - * for example, when got nal_unit_type=5, insert SPS/PPS before sample.  
2866 - */  
2867 -  
2868 - // 5bits, 7.3.1 NAL unit syntax,  
2869 - // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.  
2870 - u_int8_t nal_unit_type;  
2871 - nal_unit_type = *sample_unit->bytes;  
2872 - nal_unit_type &= 0x1f;  
2873 -  
2874 - // @see: ngx_rtmp_hls_video  
2875 - // Table 7-1 NAL unit type codes, page 61  
2876 - // 1: Coded slice  
2877 - if (nal_unit_type == 1) {  
2878 - sps_pps_sent = false;  
2879 - }  
2880 -  
2881 - // 6: Supplemental enhancement information (SEI) sei_rbsp( ), page 61  
2882 - // @see: ngx_rtmp_hls_append_aud  
2883 - if (!aud_sent) {  
2884 - // @remark, when got type 9, we donot send aud_nal, but it will make  
2885 - // ios unhappy, so we remove it.  
2886 - // @see https://github.com/winlinvip/simple-rtmp-server/issues/281  
2887 - /*if (nal_unit_type == 9) {  
2888 - aud_sent = true;  
2889 - }*/  
2890 -  
2891 - if (nal_unit_type == 1 || nal_unit_type == 5 || nal_unit_type == 6) {  
2892 - // for type 6, append a aud with type 9.  
2893 - video->payload->append((const char*)aud_nal, sizeof(aud_nal));  
2894 - aud_sent = true;  
2895 - }  
2896 - }  
2897 -  
2898 - // 5: Coded slice of an IDR picture.  
2899 - // insert sps/pps before IDR or key frame is ok.  
2900 - if (nal_unit_type == 5 && !sps_pps_sent) {  
2901 - sps_pps_sent = true;  
2902 -  
2903 - // @see: ngx_rtmp_hls_append_sps_pps  
2904 - if (codec->sequenceParameterSetLength > 0) {  
2905 - // AnnexB prefix, for sps always 4 bytes header  
2906 - video->payload->append((const char*)aud_nal, 4);  
2907 - // sps  
2908 - video->payload->append(codec->sequenceParameterSetNALUnit, codec->sequenceParameterSetLength);  
2909 - }  
2910 - if (codec->pictureParameterSetLength > 0) {  
2911 - // AnnexB prefix, for pps always 4 bytes header  
2912 - video->payload->append((const char*)aud_nal, 4);  
2913 - // pps  
2914 - video->payload->append(codec->pictureParameterSetNALUnit, codec->pictureParameterSetLength);  
2915 - }  
2916 - } 2946 + // 5bits, 7.3.1 NAL unit syntax,
  2947 + // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 83.
  2948 + SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(sample_unit->bytes[0] & 0x1f);
2917 2949
2918 - // 7-9, ignore, @see: ngx_rtmp_hls_video  
2919 - if (nal_unit_type >= 7 && nal_unit_type <= 9) {  
2920 - continue; 2950 + // ignore SPS/PPS/AUD
  2951 + switch (nal_unit_type) {
  2952 + case SrsAvcNaluTypeSPS:
  2953 + case SrsAvcNaluTypePPS:
  2954 + case SrsAvcNaluTypeAccessUnitDelimiter:
  2955 + continue;
  2956 + default:
  2957 + break;
2921 } 2958 }
2922 2959
2923 - /**  
2924 - * step 2:  
2925 - * output the "real" sample, in buf.  
2926 - * when we output some special assist packets according to nal_unit_type  
2927 - */  
2928 -  
2929 - // sample start prefix, '00 00 00 01' or '00 00 01'  
2930 - u_int8_t* p = aud_nal + 1;  
2931 - u_int8_t* end = p + 3;  
2932 -  
2933 - // first AnnexB prefix is long (4 bytes)  
2934 - if (video->payload->length() == 0) {  
2935 - p = aud_nal;  
2936 - }  
2937 - video->payload->append((const char*)p, end - p); 2960 + // insert cont nalu header before frame.
  2961 + video->payload->append((const char*)cont_nalu_header, 3);
2938 2962
2939 // sample data 2963 // sample data
2940 video->payload->append(sample_unit->bytes, sample_unit->size); 2964 video->payload->append(sample_unit->bytes, sample_unit->size);