for #304, rewrite annexb mux for ts, refer to apple sample. 2.0.157.
正在显示
6 个修改的文件
包含
209 行增加
和
93 行删除
| @@ -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); |
-
请 注册 或 登录 后发表评论