mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	SRS5: DVR: Support blackbox test based on hooks. v5.0.132 (#3365)
PICK e655948e96
			
			
This commit is contained in:
		
							parent
							
								
									3c6ade8721
								
							
						
					
					
						commit
						f06a2d61f7
					
				
					 31 changed files with 4704 additions and 3925 deletions
				
			
		
							
								
								
									
										274
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/aac.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										274
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/aac.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -12,25 +12,25 @@ import "errors"
 | 
			
		|||
type AAC_PROFILE int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	MAIN AAC_PROFILE = iota
 | 
			
		||||
	LC
 | 
			
		||||
	SSR
 | 
			
		||||
    MAIN AAC_PROFILE = iota
 | 
			
		||||
    LC
 | 
			
		||||
    SSR
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type AAC_SAMPLING_FREQUENCY int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	AAC_SAMPLE_96000 AAC_SAMPLING_FREQUENCY = iota
 | 
			
		||||
	AAC_SAMPLE_88200
 | 
			
		||||
	AAC_SAMPLE_64000
 | 
			
		||||
	AAC_SAMPLE_48000
 | 
			
		||||
	AAC_SAMPLE_44100
 | 
			
		||||
	AAC_SAMPLE_32000
 | 
			
		||||
	AAC_SAMPLE_24000
 | 
			
		||||
	AAC_SAMPLE_22050
 | 
			
		||||
	AAC_SAMPLE_16000
 | 
			
		||||
	AAC_SAMPLE_11025
 | 
			
		||||
	AAC_SAMPLE_8000
 | 
			
		||||
    AAC_SAMPLE_96000 AAC_SAMPLING_FREQUENCY = iota
 | 
			
		||||
    AAC_SAMPLE_88200
 | 
			
		||||
    AAC_SAMPLE_64000
 | 
			
		||||
    AAC_SAMPLE_48000
 | 
			
		||||
    AAC_SAMPLE_44100
 | 
			
		||||
    AAC_SAMPLE_32000
 | 
			
		||||
    AAC_SAMPLE_24000
 | 
			
		||||
    AAC_SAMPLE_22050
 | 
			
		||||
    AAC_SAMPLE_16000
 | 
			
		||||
    AAC_SAMPLE_11025
 | 
			
		||||
    AAC_SAMPLE_8000
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var AAC_Sampling_Idx [11]int = [11]int{96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000}
 | 
			
		||||
| 
						 | 
				
			
			@ -73,15 +73,15 @@ var AAC_Sampling_Idx [11]int = [11]int{96000, 88200, 64000, 48000, 44100, 32000,
 | 
			
		|||
// }
 | 
			
		||||
 | 
			
		||||
type ADTS_Fix_Header struct {
 | 
			
		||||
	ID                       uint8
 | 
			
		||||
	Layer                    uint8
 | 
			
		||||
	Protection_absent        uint8
 | 
			
		||||
	Profile                  uint8
 | 
			
		||||
	Sampling_frequency_index uint8
 | 
			
		||||
	Private_bit              uint8
 | 
			
		||||
	Channel_configuration    uint8
 | 
			
		||||
	Originalorcopy           uint8
 | 
			
		||||
	Home                     uint8
 | 
			
		||||
    ID                       uint8
 | 
			
		||||
    Layer                    uint8
 | 
			
		||||
    Protection_absent        uint8
 | 
			
		||||
    Profile                  uint8
 | 
			
		||||
    Sampling_frequency_index uint8
 | 
			
		||||
    Private_bit              uint8
 | 
			
		||||
    Channel_configuration    uint8
 | 
			
		||||
    Originalorcopy           uint8
 | 
			
		||||
    Home                     uint8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// adts_variable_header() {
 | 
			
		||||
| 
						 | 
				
			
			@ -93,91 +93,91 @@ type ADTS_Fix_Header struct {
 | 
			
		|||
// }
 | 
			
		||||
 | 
			
		||||
type ADTS_Variable_Header struct {
 | 
			
		||||
	Copyright_identification_bit       uint8
 | 
			
		||||
	copyright_identification_start     uint8
 | 
			
		||||
	Frame_length                       uint16
 | 
			
		||||
	Adts_buffer_fullness               uint16
 | 
			
		||||
	Number_of_raw_data_blocks_in_frame uint8
 | 
			
		||||
    Copyright_identification_bit       uint8
 | 
			
		||||
    copyright_identification_start     uint8
 | 
			
		||||
    Frame_length                       uint16
 | 
			
		||||
    Adts_buffer_fullness               uint16
 | 
			
		||||
    Number_of_raw_data_blocks_in_frame uint8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ADTS_Frame_Header struct {
 | 
			
		||||
	Fix_Header      ADTS_Fix_Header
 | 
			
		||||
	Variable_Header ADTS_Variable_Header
 | 
			
		||||
    Fix_Header      ADTS_Fix_Header
 | 
			
		||||
    Variable_Header ADTS_Variable_Header
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewAdtsFrameHeader() *ADTS_Frame_Header {
 | 
			
		||||
	return &ADTS_Frame_Header{
 | 
			
		||||
		Fix_Header: ADTS_Fix_Header{
 | 
			
		||||
			ID:                       0,
 | 
			
		||||
			Layer:                    0,
 | 
			
		||||
			Protection_absent:        1,
 | 
			
		||||
			Profile:                  uint8(MAIN),
 | 
			
		||||
			Sampling_frequency_index: uint8(AAC_SAMPLE_44100),
 | 
			
		||||
			Private_bit:              0,
 | 
			
		||||
			Channel_configuration:    0,
 | 
			
		||||
			Originalorcopy:           0,
 | 
			
		||||
			Home:                     0,
 | 
			
		||||
		},
 | 
			
		||||
    return &ADTS_Frame_Header{
 | 
			
		||||
        Fix_Header: ADTS_Fix_Header{
 | 
			
		||||
            ID:                       0,
 | 
			
		||||
            Layer:                    0,
 | 
			
		||||
            Protection_absent:        1,
 | 
			
		||||
            Profile:                  uint8(MAIN),
 | 
			
		||||
            Sampling_frequency_index: uint8(AAC_SAMPLE_44100),
 | 
			
		||||
            Private_bit:              0,
 | 
			
		||||
            Channel_configuration:    0,
 | 
			
		||||
            Originalorcopy:           0,
 | 
			
		||||
            Home:                     0,
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
		Variable_Header: ADTS_Variable_Header{
 | 
			
		||||
			copyright_identification_start:     0,
 | 
			
		||||
			Copyright_identification_bit:       0,
 | 
			
		||||
			Frame_length:                       0,
 | 
			
		||||
			Adts_buffer_fullness:               0,
 | 
			
		||||
			Number_of_raw_data_blocks_in_frame: 0,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
        Variable_Header: ADTS_Variable_Header{
 | 
			
		||||
            copyright_identification_start:     0,
 | 
			
		||||
            Copyright_identification_bit:       0,
 | 
			
		||||
            Frame_length:                       0,
 | 
			
		||||
            Adts_buffer_fullness:               0,
 | 
			
		||||
            Number_of_raw_data_blocks_in_frame: 0,
 | 
			
		||||
        },
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (frame *ADTS_Frame_Header) Decode(aac []byte) error {
 | 
			
		||||
	_ = aac[6]
 | 
			
		||||
	frame.Fix_Header.ID = aac[1] >> 3
 | 
			
		||||
	frame.Fix_Header.Layer = aac[1] >> 1 & 0x03
 | 
			
		||||
	frame.Fix_Header.Protection_absent = aac[1] & 0x01
 | 
			
		||||
	frame.Fix_Header.Profile = aac[2] >> 6 & 0x03
 | 
			
		||||
	frame.Fix_Header.Sampling_frequency_index = aac[2] >> 2 & 0x0F
 | 
			
		||||
	frame.Fix_Header.Private_bit = aac[2] >> 1 & 0x01
 | 
			
		||||
	frame.Fix_Header.Channel_configuration = (aac[2] & 0x01 << 2) | (aac[3] >> 6)
 | 
			
		||||
	frame.Fix_Header.Originalorcopy = aac[3] >> 5 & 0x01
 | 
			
		||||
	frame.Fix_Header.Home = aac[3] >> 4 & 0x01
 | 
			
		||||
	frame.Variable_Header.Copyright_identification_bit = aac[3] >> 3 & 0x01
 | 
			
		||||
	frame.Variable_Header.copyright_identification_start = aac[3] >> 2 & 0x01
 | 
			
		||||
	frame.Variable_Header.Frame_length = (uint16(aac[3]&0x03) << 11) | (uint16(aac[4]) << 3) | (uint16(aac[5]>>5) & 0x07)
 | 
			
		||||
	frame.Variable_Header.Adts_buffer_fullness = (uint16(aac[5]&0x1F) << 6) | uint16(aac[6]>>2)
 | 
			
		||||
	frame.Variable_Header.Number_of_raw_data_blocks_in_frame = aac[6] & 0x03
 | 
			
		||||
	return nil
 | 
			
		||||
    _ = aac[6]
 | 
			
		||||
    frame.Fix_Header.ID = aac[1] >> 3
 | 
			
		||||
    frame.Fix_Header.Layer = aac[1] >> 1 & 0x03
 | 
			
		||||
    frame.Fix_Header.Protection_absent = aac[1] & 0x01
 | 
			
		||||
    frame.Fix_Header.Profile = aac[2] >> 6 & 0x03
 | 
			
		||||
    frame.Fix_Header.Sampling_frequency_index = aac[2] >> 2 & 0x0F
 | 
			
		||||
    frame.Fix_Header.Private_bit = aac[2] >> 1 & 0x01
 | 
			
		||||
    frame.Fix_Header.Channel_configuration = (aac[2] & 0x01 << 2) | (aac[3] >> 6)
 | 
			
		||||
    frame.Fix_Header.Originalorcopy = aac[3] >> 5 & 0x01
 | 
			
		||||
    frame.Fix_Header.Home = aac[3] >> 4 & 0x01
 | 
			
		||||
    frame.Variable_Header.Copyright_identification_bit = aac[3] >> 3 & 0x01
 | 
			
		||||
    frame.Variable_Header.copyright_identification_start = aac[3] >> 2 & 0x01
 | 
			
		||||
    frame.Variable_Header.Frame_length = (uint16(aac[3]&0x03) << 11) | (uint16(aac[4]) << 3) | (uint16(aac[5]>>5) & 0x07)
 | 
			
		||||
    frame.Variable_Header.Adts_buffer_fullness = (uint16(aac[5]&0x1F) << 6) | uint16(aac[6]>>2)
 | 
			
		||||
    frame.Variable_Header.Number_of_raw_data_blocks_in_frame = aac[6] & 0x03
 | 
			
		||||
    return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (frame *ADTS_Frame_Header) Encode() []byte {
 | 
			
		||||
	var hdr []byte
 | 
			
		||||
	if frame.Fix_Header.Protection_absent == 1 {
 | 
			
		||||
		hdr = make([]byte, 7)
 | 
			
		||||
	} else {
 | 
			
		||||
		hdr = make([]byte, 9)
 | 
			
		||||
	}
 | 
			
		||||
	hdr[0] = 0xFF
 | 
			
		||||
	hdr[1] = 0xF0
 | 
			
		||||
	hdr[1] = hdr[1] | (frame.Fix_Header.ID << 3) | (frame.Fix_Header.Layer << 1) | frame.Fix_Header.Protection_absent
 | 
			
		||||
	hdr[2] = frame.Fix_Header.Profile<<6 | frame.Fix_Header.Sampling_frequency_index<<2 | frame.Fix_Header.Private_bit<<1 | frame.Fix_Header.Channel_configuration>>2
 | 
			
		||||
	hdr[3] = frame.Fix_Header.Channel_configuration<<6 | frame.Fix_Header.Originalorcopy<<5 | frame.Fix_Header.Home<<4
 | 
			
		||||
	hdr[3] = hdr[3] | frame.Variable_Header.copyright_identification_start<<3 | frame.Variable_Header.Copyright_identification_bit<<2 | byte(frame.Variable_Header.Frame_length<<11)
 | 
			
		||||
	hdr[4] = byte(frame.Variable_Header.Frame_length >> 3)
 | 
			
		||||
	hdr[5] = byte((frame.Variable_Header.Frame_length&0x07)<<5) | byte(frame.Variable_Header.Adts_buffer_fullness>>3)
 | 
			
		||||
	hdr[6] = byte(frame.Variable_Header.Adts_buffer_fullness&0x3F<<2) | frame.Variable_Header.Number_of_raw_data_blocks_in_frame
 | 
			
		||||
	return hdr
 | 
			
		||||
    var hdr []byte
 | 
			
		||||
    if frame.Fix_Header.Protection_absent == 1 {
 | 
			
		||||
        hdr = make([]byte, 7)
 | 
			
		||||
    } else {
 | 
			
		||||
        hdr = make([]byte, 9)
 | 
			
		||||
    }
 | 
			
		||||
    hdr[0] = 0xFF
 | 
			
		||||
    hdr[1] = 0xF0
 | 
			
		||||
    hdr[1] = hdr[1] | (frame.Fix_Header.ID << 3) | (frame.Fix_Header.Layer << 1) | frame.Fix_Header.Protection_absent
 | 
			
		||||
    hdr[2] = frame.Fix_Header.Profile<<6 | frame.Fix_Header.Sampling_frequency_index<<2 | frame.Fix_Header.Private_bit<<1 | frame.Fix_Header.Channel_configuration>>2
 | 
			
		||||
    hdr[3] = frame.Fix_Header.Channel_configuration<<6 | frame.Fix_Header.Originalorcopy<<5 | frame.Fix_Header.Home<<4
 | 
			
		||||
    hdr[3] = hdr[3] | frame.Variable_Header.copyright_identification_start<<3 | frame.Variable_Header.Copyright_identification_bit<<2 | byte(frame.Variable_Header.Frame_length<<11)
 | 
			
		||||
    hdr[4] = byte(frame.Variable_Header.Frame_length >> 3)
 | 
			
		||||
    hdr[5] = byte((frame.Variable_Header.Frame_length&0x07)<<5) | byte(frame.Variable_Header.Adts_buffer_fullness>>3)
 | 
			
		||||
    hdr[6] = byte(frame.Variable_Header.Adts_buffer_fullness&0x3F<<2) | frame.Variable_Header.Number_of_raw_data_blocks_in_frame
 | 
			
		||||
    return hdr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SampleToAACSampleIndex(sampling int) int {
 | 
			
		||||
	for i, v := range AAC_Sampling_Idx {
 | 
			
		||||
		if v == sampling {
 | 
			
		||||
			return i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	panic("not Found AAC Sample Index")
 | 
			
		||||
    for i, v := range AAC_Sampling_Idx {
 | 
			
		||||
        if v == sampling {
 | 
			
		||||
            return i
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    panic("not Found AAC Sample Index")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func AACSampleIdxToSample(idx int) int {
 | 
			
		||||
	return AAC_Sampling_Idx[idx]
 | 
			
		||||
    return AAC_Sampling_Idx[idx]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 | 
			
		||||
| 
						 | 
				
			
			@ -185,71 +185,71 @@ func AACSampleIdxToSample(idx int) int {
 | 
			
		|||
// +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
type AudioSpecificConfiguration struct {
 | 
			
		||||
	Audio_object_type        uint8
 | 
			
		||||
	Sample_freq_index        uint8
 | 
			
		||||
	Channel_configuration    uint8
 | 
			
		||||
	GA_framelength_flag      uint8
 | 
			
		||||
	GA_depends_on_core_coder uint8
 | 
			
		||||
	GA_extension_flag        uint8
 | 
			
		||||
    Audio_object_type        uint8
 | 
			
		||||
    Sample_freq_index        uint8
 | 
			
		||||
    Channel_configuration    uint8
 | 
			
		||||
    GA_framelength_flag      uint8
 | 
			
		||||
    GA_depends_on_core_coder uint8
 | 
			
		||||
    GA_extension_flag        uint8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewAudioSpecificConfiguration() *AudioSpecificConfiguration {
 | 
			
		||||
	return &AudioSpecificConfiguration{
 | 
			
		||||
		Audio_object_type:        0,
 | 
			
		||||
		Sample_freq_index:        0,
 | 
			
		||||
		Channel_configuration:    0,
 | 
			
		||||
		GA_framelength_flag:      0,
 | 
			
		||||
		GA_depends_on_core_coder: 0,
 | 
			
		||||
		GA_extension_flag:        0,
 | 
			
		||||
	}
 | 
			
		||||
    return &AudioSpecificConfiguration{
 | 
			
		||||
        Audio_object_type:        0,
 | 
			
		||||
        Sample_freq_index:        0,
 | 
			
		||||
        Channel_configuration:    0,
 | 
			
		||||
        GA_framelength_flag:      0,
 | 
			
		||||
        GA_depends_on_core_coder: 0,
 | 
			
		||||
        GA_extension_flag:        0,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (asc *AudioSpecificConfiguration) Encode() []byte {
 | 
			
		||||
	buf := make([]byte, 2)
 | 
			
		||||
	buf[0] = (asc.Audio_object_type & 0x1f << 3) | (asc.Sample_freq_index & 0x0F >> 1)
 | 
			
		||||
	buf[1] = (asc.Sample_freq_index & 0x0F << 7) | (asc.Channel_configuration & 0x0F << 3) | (asc.GA_framelength_flag & 0x01 << 2) | (asc.GA_depends_on_core_coder & 0x01 << 1) | (asc.GA_extension_flag & 0x01)
 | 
			
		||||
	return buf
 | 
			
		||||
    buf := make([]byte, 2)
 | 
			
		||||
    buf[0] = (asc.Audio_object_type & 0x1f << 3) | (asc.Sample_freq_index & 0x0F >> 1)
 | 
			
		||||
    buf[1] = (asc.Sample_freq_index & 0x0F << 7) | (asc.Channel_configuration & 0x0F << 3) | (asc.GA_framelength_flag & 0x01 << 2) | (asc.GA_depends_on_core_coder & 0x01 << 1) | (asc.GA_extension_flag & 0x01)
 | 
			
		||||
    return buf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (asc *AudioSpecificConfiguration) Decode(buf []byte) error {
 | 
			
		||||
 | 
			
		||||
	if len(buf) < 2 {
 | 
			
		||||
		return errors.New("len of buf < 2 ")
 | 
			
		||||
	}
 | 
			
		||||
    if len(buf) < 2 {
 | 
			
		||||
        return errors.New("len of buf < 2 ")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	asc.Audio_object_type = buf[0] >> 3
 | 
			
		||||
	asc.Sample_freq_index = (buf[0] & 0x07 << 1) | (buf[1] >> 7)
 | 
			
		||||
	asc.Channel_configuration = buf[1] >> 3 & 0x0F
 | 
			
		||||
	asc.GA_framelength_flag = buf[1] >> 2 & 0x01
 | 
			
		||||
	asc.GA_depends_on_core_coder = buf[1] >> 1 & 0x01
 | 
			
		||||
	asc.GA_extension_flag = buf[1] & 0x01
 | 
			
		||||
	return nil
 | 
			
		||||
    asc.Audio_object_type = buf[0] >> 3
 | 
			
		||||
    asc.Sample_freq_index = (buf[0] & 0x07 << 1) | (buf[1] >> 7)
 | 
			
		||||
    asc.Channel_configuration = buf[1] >> 3 & 0x0F
 | 
			
		||||
    asc.GA_framelength_flag = buf[1] >> 2 & 0x01
 | 
			
		||||
    asc.GA_depends_on_core_coder = buf[1] >> 1 & 0x01
 | 
			
		||||
    asc.GA_extension_flag = buf[1] & 0x01
 | 
			
		||||
    return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ConvertADTSToASC(frame []byte) ([]byte, error) {
 | 
			
		||||
 | 
			
		||||
	if len(frame) < 7 {
 | 
			
		||||
		return nil, errors.New("len of frame < 7")
 | 
			
		||||
	}
 | 
			
		||||
    if len(frame) < 7 {
 | 
			
		||||
        return nil, errors.New("len of frame < 7")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	adts := NewAdtsFrameHeader()
 | 
			
		||||
	adts.Decode(frame)
 | 
			
		||||
	asc := NewAudioSpecificConfiguration()
 | 
			
		||||
	asc.Audio_object_type = adts.Fix_Header.Profile + 1
 | 
			
		||||
	asc.Channel_configuration = adts.Fix_Header.Channel_configuration
 | 
			
		||||
	asc.Sample_freq_index = adts.Fix_Header.Sampling_frequency_index
 | 
			
		||||
	return asc.Encode(), nil
 | 
			
		||||
    adts := NewAdtsFrameHeader()
 | 
			
		||||
    adts.Decode(frame)
 | 
			
		||||
    asc := NewAudioSpecificConfiguration()
 | 
			
		||||
    asc.Audio_object_type = adts.Fix_Header.Profile + 1
 | 
			
		||||
    asc.Channel_configuration = adts.Fix_Header.Channel_configuration
 | 
			
		||||
    asc.Sample_freq_index = adts.Fix_Header.Sampling_frequency_index
 | 
			
		||||
    return asc.Encode(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ConvertASCToADTS(asc []byte, aacbytes int) []byte {
 | 
			
		||||
	aac_asc := NewAudioSpecificConfiguration()
 | 
			
		||||
	aac_asc.Decode(asc)
 | 
			
		||||
	aac_adts := NewAdtsFrameHeader()
 | 
			
		||||
	aac_adts.Fix_Header.Profile = aac_asc.Audio_object_type - 1
 | 
			
		||||
	aac_adts.Fix_Header.Channel_configuration = aac_asc.Channel_configuration
 | 
			
		||||
	aac_adts.Fix_Header.Sampling_frequency_index = aac_asc.Sample_freq_index
 | 
			
		||||
	aac_adts.Fix_Header.Protection_absent = 1
 | 
			
		||||
	aac_adts.Variable_Header.Adts_buffer_fullness = 0x3F
 | 
			
		||||
	aac_adts.Variable_Header.Frame_length = uint16(aacbytes)
 | 
			
		||||
	return aac_adts.Encode()
 | 
			
		||||
    aac_asc := NewAudioSpecificConfiguration()
 | 
			
		||||
    aac_asc.Decode(asc)
 | 
			
		||||
    aac_adts := NewAdtsFrameHeader()
 | 
			
		||||
    aac_adts.Fix_Header.Profile = aac_asc.Audio_object_type - 1
 | 
			
		||||
    aac_adts.Fix_Header.Channel_configuration = aac_asc.Channel_configuration
 | 
			
		||||
    aac_adts.Fix_Header.Sampling_frequency_index = aac_asc.Sample_freq_index
 | 
			
		||||
    aac_adts.Fix_Header.Protection_absent = 1
 | 
			
		||||
    aac_adts.Variable_Header.Adts_buffer_fullness = 0x3F
 | 
			
		||||
    aac_adts.Variable_Header.Frame_length = uint16(aacbytes)
 | 
			
		||||
    return aac_adts.Encode()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										454
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/bitstream.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										454
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/bitstream.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,358 +1,358 @@
 | 
			
		|||
package codec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
    "encoding/binary"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var BitMask [8]byte = [8]byte{0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF}
 | 
			
		||||
 | 
			
		||||
type BitStream struct {
 | 
			
		||||
	bits        []byte
 | 
			
		||||
	bytesOffset int
 | 
			
		||||
	bitsOffset  int
 | 
			
		||||
	bitsmark    int
 | 
			
		||||
	bytemark    int
 | 
			
		||||
    bits        []byte
 | 
			
		||||
    bytesOffset int
 | 
			
		||||
    bitsOffset  int
 | 
			
		||||
    bitsmark    int
 | 
			
		||||
    bytemark    int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewBitStream(buf []byte) *BitStream {
 | 
			
		||||
	return &BitStream{
 | 
			
		||||
		bits:        buf,
 | 
			
		||||
		bytesOffset: 0,
 | 
			
		||||
		bitsOffset:  0,
 | 
			
		||||
		bitsmark:    0,
 | 
			
		||||
		bytemark:    0,
 | 
			
		||||
	}
 | 
			
		||||
    return &BitStream{
 | 
			
		||||
        bits:        buf,
 | 
			
		||||
        bytesOffset: 0,
 | 
			
		||||
        bitsOffset:  0,
 | 
			
		||||
        bitsmark:    0,
 | 
			
		||||
        bytemark:    0,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) Uint8(n int) uint8 {
 | 
			
		||||
	return uint8(bs.GetBits(n))
 | 
			
		||||
    return uint8(bs.GetBits(n))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) Uint16(n int) uint16 {
 | 
			
		||||
	return uint16(bs.GetBits(n))
 | 
			
		||||
    return uint16(bs.GetBits(n))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) Uint32(n int) uint32 {
 | 
			
		||||
	return uint32(bs.GetBits(n))
 | 
			
		||||
    return uint32(bs.GetBits(n))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) GetBytes(n int) []byte {
 | 
			
		||||
	if bs.bytesOffset+n > len(bs.bits) {
 | 
			
		||||
		panic("OUT OF RANGE")
 | 
			
		||||
	}
 | 
			
		||||
	if bs.bitsOffset != 0 {
 | 
			
		||||
		panic("invaild operation")
 | 
			
		||||
	}
 | 
			
		||||
	data := make([]byte, n)
 | 
			
		||||
	copy(data, bs.bits[bs.bytesOffset:bs.bytesOffset+n])
 | 
			
		||||
	bs.bytesOffset += n
 | 
			
		||||
	return data
 | 
			
		||||
    if bs.bytesOffset+n > len(bs.bits) {
 | 
			
		||||
        panic("OUT OF RANGE")
 | 
			
		||||
    }
 | 
			
		||||
    if bs.bitsOffset != 0 {
 | 
			
		||||
        panic("invaild operation")
 | 
			
		||||
    }
 | 
			
		||||
    data := make([]byte, n)
 | 
			
		||||
    copy(data, bs.bits[bs.bytesOffset:bs.bytesOffset+n])
 | 
			
		||||
    bs.bytesOffset += n
 | 
			
		||||
    return data
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//n <= 64
 | 
			
		||||
func (bs *BitStream) GetBits(n int) uint64 {
 | 
			
		||||
	if bs.bytesOffset >= len(bs.bits) {
 | 
			
		||||
		panic("OUT OF RANGE")
 | 
			
		||||
	}
 | 
			
		||||
	var ret uint64 = 0
 | 
			
		||||
	if 8-bs.bitsOffset >= n {
 | 
			
		||||
		ret = uint64((bs.bits[bs.bytesOffset] >> (8 - bs.bitsOffset - n)) & BitMask[n-1])
 | 
			
		||||
		bs.bitsOffset += n
 | 
			
		||||
		if bs.bitsOffset == 8 {
 | 
			
		||||
			bs.bytesOffset++
 | 
			
		||||
			bs.bitsOffset = 0
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		ret = uint64(bs.bits[bs.bytesOffset] & BitMask[8-bs.bitsOffset-1])
 | 
			
		||||
		bs.bytesOffset++
 | 
			
		||||
		n -= 8 - bs.bitsOffset
 | 
			
		||||
		bs.bitsOffset = 0
 | 
			
		||||
		for n > 0 {
 | 
			
		||||
			if bs.bytesOffset >= len(bs.bits) {
 | 
			
		||||
				panic("OUT OF RANGE")
 | 
			
		||||
			}
 | 
			
		||||
			if n >= 8 {
 | 
			
		||||
				ret = ret<<8 | uint64(bs.bits[bs.bytesOffset])
 | 
			
		||||
				bs.bytesOffset++
 | 
			
		||||
				n -= 8
 | 
			
		||||
			} else {
 | 
			
		||||
				ret = (ret << n) | uint64((bs.bits[bs.bytesOffset]>>(8-n))&BitMask[n-1])
 | 
			
		||||
				bs.bitsOffset = n
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
    if bs.bytesOffset >= len(bs.bits) {
 | 
			
		||||
        panic("OUT OF RANGE")
 | 
			
		||||
    }
 | 
			
		||||
    var ret uint64 = 0
 | 
			
		||||
    if 8-bs.bitsOffset >= n {
 | 
			
		||||
        ret = uint64((bs.bits[bs.bytesOffset] >> (8 - bs.bitsOffset - n)) & BitMask[n-1])
 | 
			
		||||
        bs.bitsOffset += n
 | 
			
		||||
        if bs.bitsOffset == 8 {
 | 
			
		||||
            bs.bytesOffset++
 | 
			
		||||
            bs.bitsOffset = 0
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        ret = uint64(bs.bits[bs.bytesOffset] & BitMask[8-bs.bitsOffset-1])
 | 
			
		||||
        bs.bytesOffset++
 | 
			
		||||
        n -= 8 - bs.bitsOffset
 | 
			
		||||
        bs.bitsOffset = 0
 | 
			
		||||
        for n > 0 {
 | 
			
		||||
            if bs.bytesOffset >= len(bs.bits) {
 | 
			
		||||
                panic("OUT OF RANGE")
 | 
			
		||||
            }
 | 
			
		||||
            if n >= 8 {
 | 
			
		||||
                ret = ret<<8 | uint64(bs.bits[bs.bytesOffset])
 | 
			
		||||
                bs.bytesOffset++
 | 
			
		||||
                n -= 8
 | 
			
		||||
            } else {
 | 
			
		||||
                ret = (ret << n) | uint64((bs.bits[bs.bytesOffset]>>(8-n))&BitMask[n-1])
 | 
			
		||||
                bs.bitsOffset = n
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) GetBit() uint8 {
 | 
			
		||||
	if bs.bytesOffset >= len(bs.bits) {
 | 
			
		||||
		panic("OUT OF RANGE")
 | 
			
		||||
	}
 | 
			
		||||
	ret := bs.bits[bs.bytesOffset] >> (7 - bs.bitsOffset) & 0x01
 | 
			
		||||
	bs.bitsOffset++
 | 
			
		||||
	if bs.bitsOffset >= 8 {
 | 
			
		||||
		bs.bytesOffset++
 | 
			
		||||
		bs.bitsOffset = 0
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
    if bs.bytesOffset >= len(bs.bits) {
 | 
			
		||||
        panic("OUT OF RANGE")
 | 
			
		||||
    }
 | 
			
		||||
    ret := bs.bits[bs.bytesOffset] >> (7 - bs.bitsOffset) & 0x01
 | 
			
		||||
    bs.bitsOffset++
 | 
			
		||||
    if bs.bitsOffset >= 8 {
 | 
			
		||||
        bs.bytesOffset++
 | 
			
		||||
        bs.bitsOffset = 0
 | 
			
		||||
    }
 | 
			
		||||
    return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) SkipBits(n int) {
 | 
			
		||||
	bytecount := n / 8
 | 
			
		||||
	bitscount := n % 8
 | 
			
		||||
	bs.bytesOffset += bytecount
 | 
			
		||||
	if bs.bitsOffset+bitscount < 8 {
 | 
			
		||||
		bs.bitsOffset += bitscount
 | 
			
		||||
	} else {
 | 
			
		||||
		bs.bytesOffset += 1
 | 
			
		||||
		bs.bitsOffset += bitscount - 8
 | 
			
		||||
	}
 | 
			
		||||
    bytecount := n / 8
 | 
			
		||||
    bitscount := n % 8
 | 
			
		||||
    bs.bytesOffset += bytecount
 | 
			
		||||
    if bs.bitsOffset+bitscount < 8 {
 | 
			
		||||
        bs.bitsOffset += bitscount
 | 
			
		||||
    } else {
 | 
			
		||||
        bs.bytesOffset += 1
 | 
			
		||||
        bs.bitsOffset += bitscount - 8
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) Markdot() {
 | 
			
		||||
	bs.bitsmark = bs.bitsOffset
 | 
			
		||||
	bs.bytemark = bs.bytesOffset
 | 
			
		||||
    bs.bitsmark = bs.bitsOffset
 | 
			
		||||
    bs.bytemark = bs.bytesOffset
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) DistanceFromMarkDot() int {
 | 
			
		||||
	bytecount := bs.bytesOffset - bs.bytemark - 1
 | 
			
		||||
	bitscount := bs.bitsOffset + (8 - bs.bitsmark)
 | 
			
		||||
	return bytecount*8 + bitscount
 | 
			
		||||
    bytecount := bs.bytesOffset - bs.bytemark - 1
 | 
			
		||||
    bitscount := bs.bitsOffset + (8 - bs.bitsmark)
 | 
			
		||||
    return bytecount*8 + bitscount
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) RemainBytes() int {
 | 
			
		||||
	if bs.bitsOffset > 0 {
 | 
			
		||||
		return len(bs.bits) - bs.bytesOffset - 1
 | 
			
		||||
	} else {
 | 
			
		||||
		return len(bs.bits) - bs.bytesOffset
 | 
			
		||||
	}
 | 
			
		||||
    if bs.bitsOffset > 0 {
 | 
			
		||||
        return len(bs.bits) - bs.bytesOffset - 1
 | 
			
		||||
    } else {
 | 
			
		||||
        return len(bs.bits) - bs.bytesOffset
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) RemainBits() int {
 | 
			
		||||
	if bs.bitsOffset > 0 {
 | 
			
		||||
		return bs.RemainBytes()*8 + 8 - bs.bitsOffset
 | 
			
		||||
	} else {
 | 
			
		||||
		return bs.RemainBytes() * 8
 | 
			
		||||
	}
 | 
			
		||||
    if bs.bitsOffset > 0 {
 | 
			
		||||
        return bs.RemainBytes()*8 + 8 - bs.bitsOffset
 | 
			
		||||
    } else {
 | 
			
		||||
        return bs.RemainBytes() * 8
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) Bits() []byte {
 | 
			
		||||
	return bs.bits
 | 
			
		||||
    return bs.bits
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) RemainData() []byte {
 | 
			
		||||
	return bs.bits[bs.bytesOffset:]
 | 
			
		||||
    return bs.bits[bs.bytesOffset:]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//无符号哥伦布熵编码
 | 
			
		||||
func (bs *BitStream) ReadUE() uint64 {
 | 
			
		||||
	leadingZeroBits := 0
 | 
			
		||||
	for bs.GetBit() == 0 {
 | 
			
		||||
		leadingZeroBits++
 | 
			
		||||
	}
 | 
			
		||||
	if leadingZeroBits == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	info := bs.GetBits(leadingZeroBits)
 | 
			
		||||
	return uint64(1)<<leadingZeroBits - 1 + info
 | 
			
		||||
    leadingZeroBits := 0
 | 
			
		||||
    for bs.GetBit() == 0 {
 | 
			
		||||
        leadingZeroBits++
 | 
			
		||||
    }
 | 
			
		||||
    if leadingZeroBits == 0 {
 | 
			
		||||
        return 0
 | 
			
		||||
    }
 | 
			
		||||
    info := bs.GetBits(leadingZeroBits)
 | 
			
		||||
    return uint64(1)<<leadingZeroBits - 1 + info
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//有符号哥伦布熵编码
 | 
			
		||||
func (bs *BitStream) ReadSE() int64 {
 | 
			
		||||
	v := bs.ReadUE()
 | 
			
		||||
	if v%2 == 0 {
 | 
			
		||||
		return -1 * int64(v/2)
 | 
			
		||||
	} else {
 | 
			
		||||
		return int64(v+1) / 2
 | 
			
		||||
	}
 | 
			
		||||
    v := bs.ReadUE()
 | 
			
		||||
    if v%2 == 0 {
 | 
			
		||||
        return -1 * int64(v/2)
 | 
			
		||||
    } else {
 | 
			
		||||
        return int64(v+1) / 2
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) ByteOffset() int {
 | 
			
		||||
	return bs.bytesOffset
 | 
			
		||||
    return bs.bytesOffset
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) UnRead(n int) {
 | 
			
		||||
	if n-bs.bitsOffset <= 0 {
 | 
			
		||||
		bs.bitsOffset -= n
 | 
			
		||||
	} else {
 | 
			
		||||
		least := n - bs.bitsOffset
 | 
			
		||||
		for least >= 8 {
 | 
			
		||||
			bs.bytesOffset--
 | 
			
		||||
			least -= 8
 | 
			
		||||
		}
 | 
			
		||||
		if least > 0 {
 | 
			
		||||
			bs.bytesOffset--
 | 
			
		||||
			bs.bitsOffset = 8 - least
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    if n-bs.bitsOffset <= 0 {
 | 
			
		||||
        bs.bitsOffset -= n
 | 
			
		||||
    } else {
 | 
			
		||||
        least := n - bs.bitsOffset
 | 
			
		||||
        for least >= 8 {
 | 
			
		||||
            bs.bytesOffset--
 | 
			
		||||
            least -= 8
 | 
			
		||||
        }
 | 
			
		||||
        if least > 0 {
 | 
			
		||||
            bs.bytesOffset--
 | 
			
		||||
            bs.bitsOffset = 8 - least
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) NextBits(n int) uint64 {
 | 
			
		||||
	r := bs.GetBits(n)
 | 
			
		||||
	bs.UnRead(n)
 | 
			
		||||
	return r
 | 
			
		||||
    r := bs.GetBits(n)
 | 
			
		||||
    bs.UnRead(n)
 | 
			
		||||
    return r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bs *BitStream) EOS() bool {
 | 
			
		||||
	return bs.bytesOffset == len(bs.bits) && bs.bitsOffset == 0
 | 
			
		||||
    return bs.bytesOffset == len(bs.bits) && bs.bitsOffset == 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type BitStreamWriter struct {
 | 
			
		||||
	bits       []byte
 | 
			
		||||
	byteoffset int
 | 
			
		||||
	bitsoffset int
 | 
			
		||||
	bitsmark   int
 | 
			
		||||
	bytemark   int
 | 
			
		||||
    bits       []byte
 | 
			
		||||
    byteoffset int
 | 
			
		||||
    bitsoffset int
 | 
			
		||||
    bitsmark   int
 | 
			
		||||
    bytemark   int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewBitStreamWriter(n int) *BitStreamWriter {
 | 
			
		||||
	return &BitStreamWriter{
 | 
			
		||||
		bits:       make([]byte, n),
 | 
			
		||||
		byteoffset: 0,
 | 
			
		||||
		bitsoffset: 0,
 | 
			
		||||
		bitsmark:   0,
 | 
			
		||||
		bytemark:   0,
 | 
			
		||||
	}
 | 
			
		||||
    return &BitStreamWriter{
 | 
			
		||||
        bits:       make([]byte, n),
 | 
			
		||||
        byteoffset: 0,
 | 
			
		||||
        bitsoffset: 0,
 | 
			
		||||
        bitsmark:   0,
 | 
			
		||||
        bytemark:   0,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) expandSpace(n int) {
 | 
			
		||||
	if (len(bsw.bits)-bsw.byteoffset-1)*8+8-bsw.bitsoffset < n {
 | 
			
		||||
		newlen := 0
 | 
			
		||||
		if len(bsw.bits)*8 < n {
 | 
			
		||||
			newlen = len(bsw.bits) + n/8 + 1
 | 
			
		||||
		} else {
 | 
			
		||||
			newlen = len(bsw.bits) * 2
 | 
			
		||||
		}
 | 
			
		||||
		tmp := make([]byte, newlen)
 | 
			
		||||
		copy(tmp, bsw.bits)
 | 
			
		||||
		bsw.bits = tmp
 | 
			
		||||
	}
 | 
			
		||||
    if (len(bsw.bits)-bsw.byteoffset-1)*8+8-bsw.bitsoffset < n {
 | 
			
		||||
        newlen := 0
 | 
			
		||||
        if len(bsw.bits)*8 < n {
 | 
			
		||||
            newlen = len(bsw.bits) + n/8 + 1
 | 
			
		||||
        } else {
 | 
			
		||||
            newlen = len(bsw.bits) * 2
 | 
			
		||||
        }
 | 
			
		||||
        tmp := make([]byte, newlen)
 | 
			
		||||
        copy(tmp, bsw.bits)
 | 
			
		||||
        bsw.bits = tmp
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) ByteOffset() int {
 | 
			
		||||
	return bsw.byteoffset
 | 
			
		||||
    return bsw.byteoffset
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) BitOffset() int {
 | 
			
		||||
	return bsw.bitsoffset
 | 
			
		||||
    return bsw.bitsoffset
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) Markdot() {
 | 
			
		||||
	bsw.bitsmark = bsw.bitsoffset
 | 
			
		||||
	bsw.bytemark = bsw.byteoffset
 | 
			
		||||
    bsw.bitsmark = bsw.bitsoffset
 | 
			
		||||
    bsw.bytemark = bsw.byteoffset
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) DistanceFromMarkDot() int {
 | 
			
		||||
	bytecount := bsw.byteoffset - bsw.bytemark - 1
 | 
			
		||||
	bitscount := bsw.bitsoffset + (8 - bsw.bitsmark)
 | 
			
		||||
	return bytecount*8 + bitscount
 | 
			
		||||
    bytecount := bsw.byteoffset - bsw.bytemark - 1
 | 
			
		||||
    bitscount := bsw.bitsoffset + (8 - bsw.bitsmark)
 | 
			
		||||
    return bytecount*8 + bitscount
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) PutByte(v byte) {
 | 
			
		||||
	bsw.expandSpace(8)
 | 
			
		||||
	if bsw.bitsoffset == 0 {
 | 
			
		||||
		bsw.bits[bsw.byteoffset] = v
 | 
			
		||||
		bsw.byteoffset++
 | 
			
		||||
	} else {
 | 
			
		||||
		bsw.bits[bsw.byteoffset] |= v >> byte(bsw.bitsoffset)
 | 
			
		||||
		bsw.byteoffset++
 | 
			
		||||
		bsw.bits[bsw.byteoffset] = v & BitMask[bsw.bitsoffset-1]
 | 
			
		||||
	}
 | 
			
		||||
    bsw.expandSpace(8)
 | 
			
		||||
    if bsw.bitsoffset == 0 {
 | 
			
		||||
        bsw.bits[bsw.byteoffset] = v
 | 
			
		||||
        bsw.byteoffset++
 | 
			
		||||
    } else {
 | 
			
		||||
        bsw.bits[bsw.byteoffset] |= v >> byte(bsw.bitsoffset)
 | 
			
		||||
        bsw.byteoffset++
 | 
			
		||||
        bsw.bits[bsw.byteoffset] = v & BitMask[bsw.bitsoffset-1]
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) PutBytes(v []byte) {
 | 
			
		||||
	if bsw.bitsoffset != 0 {
 | 
			
		||||
		panic("bsw.bitsoffset > 0")
 | 
			
		||||
	}
 | 
			
		||||
	bsw.expandSpace(8 * len(v))
 | 
			
		||||
	copy(bsw.bits[bsw.byteoffset:], v)
 | 
			
		||||
	bsw.byteoffset += len(v)
 | 
			
		||||
    if bsw.bitsoffset != 0 {
 | 
			
		||||
        panic("bsw.bitsoffset > 0")
 | 
			
		||||
    }
 | 
			
		||||
    bsw.expandSpace(8 * len(v))
 | 
			
		||||
    copy(bsw.bits[bsw.byteoffset:], v)
 | 
			
		||||
    bsw.byteoffset += len(v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) PutRepetValue(v byte, n int) {
 | 
			
		||||
	if bsw.bitsoffset != 0 {
 | 
			
		||||
		panic("bsw.bitsoffset > 0")
 | 
			
		||||
	}
 | 
			
		||||
	bsw.expandSpace(8 * n)
 | 
			
		||||
	for i := 0; i < n; i++ {
 | 
			
		||||
		bsw.bits[bsw.byteoffset] = v
 | 
			
		||||
		bsw.byteoffset++
 | 
			
		||||
	}
 | 
			
		||||
    if bsw.bitsoffset != 0 {
 | 
			
		||||
        panic("bsw.bitsoffset > 0")
 | 
			
		||||
    }
 | 
			
		||||
    bsw.expandSpace(8 * n)
 | 
			
		||||
    for i := 0; i < n; i++ {
 | 
			
		||||
        bsw.bits[bsw.byteoffset] = v
 | 
			
		||||
        bsw.byteoffset++
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) PutUint8(v uint8, n int) {
 | 
			
		||||
	bsw.PutUint64(uint64(v), n)
 | 
			
		||||
    bsw.PutUint64(uint64(v), n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) PutUint16(v uint16, n int) {
 | 
			
		||||
	bsw.PutUint64(uint64(v), n)
 | 
			
		||||
    bsw.PutUint64(uint64(v), n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) PutUint32(v uint32, n int) {
 | 
			
		||||
	bsw.PutUint64(uint64(v), n)
 | 
			
		||||
    bsw.PutUint64(uint64(v), n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) PutUint64(v uint64, n int) {
 | 
			
		||||
	bsw.expandSpace(n)
 | 
			
		||||
	if 8-bsw.bitsoffset >= n {
 | 
			
		||||
		bsw.bits[bsw.byteoffset] |= uint8(v) & BitMask[n-1] << (8 - bsw.bitsoffset - n)
 | 
			
		||||
		bsw.bitsoffset += n
 | 
			
		||||
		if bsw.bitsoffset == 8 {
 | 
			
		||||
			bsw.bitsoffset = 0
 | 
			
		||||
			bsw.byteoffset++
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		bsw.bits[bsw.byteoffset] |= uint8(v>>(n-int(8-bsw.bitsoffset))) & BitMask[8-bsw.bitsoffset-1]
 | 
			
		||||
		bsw.byteoffset++
 | 
			
		||||
		n -= 8 - bsw.bitsoffset
 | 
			
		||||
		for n-8 >= 0 {
 | 
			
		||||
			bsw.bits[bsw.byteoffset] = uint8(v>>(n-8)) & 0xFF
 | 
			
		||||
			bsw.byteoffset++
 | 
			
		||||
			n -= 8
 | 
			
		||||
		}
 | 
			
		||||
		bsw.bitsoffset = n
 | 
			
		||||
		if n > 0 {
 | 
			
		||||
			bsw.bits[bsw.byteoffset] |= (uint8(v) & BitMask[n-1]) << (8 - n)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    bsw.expandSpace(n)
 | 
			
		||||
    if 8-bsw.bitsoffset >= n {
 | 
			
		||||
        bsw.bits[bsw.byteoffset] |= uint8(v) & BitMask[n-1] << (8 - bsw.bitsoffset - n)
 | 
			
		||||
        bsw.bitsoffset += n
 | 
			
		||||
        if bsw.bitsoffset == 8 {
 | 
			
		||||
            bsw.bitsoffset = 0
 | 
			
		||||
            bsw.byteoffset++
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        bsw.bits[bsw.byteoffset] |= uint8(v>>(n-int(8-bsw.bitsoffset))) & BitMask[8-bsw.bitsoffset-1]
 | 
			
		||||
        bsw.byteoffset++
 | 
			
		||||
        n -= 8 - bsw.bitsoffset
 | 
			
		||||
        for n-8 >= 0 {
 | 
			
		||||
            bsw.bits[bsw.byteoffset] = uint8(v>>(n-8)) & 0xFF
 | 
			
		||||
            bsw.byteoffset++
 | 
			
		||||
            n -= 8
 | 
			
		||||
        }
 | 
			
		||||
        bsw.bitsoffset = n
 | 
			
		||||
        if n > 0 {
 | 
			
		||||
            bsw.bits[bsw.byteoffset] |= (uint8(v) & BitMask[n-1]) << (8 - n)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) SetByte(v byte, where int) {
 | 
			
		||||
	bsw.bits[where] = v
 | 
			
		||||
    bsw.bits[where] = v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) SetUint16(v uint16, where int) {
 | 
			
		||||
	binary.BigEndian.PutUint16(bsw.bits[where:where+2], v)
 | 
			
		||||
    binary.BigEndian.PutUint16(bsw.bits[where:where+2], v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) Bits() []byte {
 | 
			
		||||
	if bsw.byteoffset == len(bsw.bits) {
 | 
			
		||||
		return bsw.bits
 | 
			
		||||
	}
 | 
			
		||||
	if bsw.bitsoffset > 0 {
 | 
			
		||||
		return bsw.bits[0 : bsw.byteoffset+1]
 | 
			
		||||
	} else {
 | 
			
		||||
		return bsw.bits[0:bsw.byteoffset]
 | 
			
		||||
	}
 | 
			
		||||
    if bsw.byteoffset == len(bsw.bits) {
 | 
			
		||||
        return bsw.bits
 | 
			
		||||
    }
 | 
			
		||||
    if bsw.bitsoffset > 0 {
 | 
			
		||||
        return bsw.bits[0 : bsw.byteoffset+1]
 | 
			
		||||
    } else {
 | 
			
		||||
        return bsw.bits[0:bsw.byteoffset]
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//用v 填充剩余字节
 | 
			
		||||
func (bsw *BitStreamWriter) FillRemainData(v byte) {
 | 
			
		||||
	for i := bsw.byteoffset; i < len(bsw.bits); i++ {
 | 
			
		||||
		bsw.bits[i] = v
 | 
			
		||||
	}
 | 
			
		||||
	bsw.byteoffset = len(bsw.bits)
 | 
			
		||||
	bsw.bitsoffset = 0
 | 
			
		||||
    for i := bsw.byteoffset; i < len(bsw.bits); i++ {
 | 
			
		||||
        bsw.bits[i] = v
 | 
			
		||||
    }
 | 
			
		||||
    bsw.byteoffset = len(bsw.bits)
 | 
			
		||||
    bsw.bitsoffset = 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bsw *BitStreamWriter) Reset() {
 | 
			
		||||
	for i := 0; i < len(bsw.bits); i++ {
 | 
			
		||||
		bsw.bits[i] = 0
 | 
			
		||||
	}
 | 
			
		||||
	bsw.bitsmark = 0
 | 
			
		||||
	bsw.bytemark = 0
 | 
			
		||||
	bsw.bitsoffset = 0
 | 
			
		||||
	bsw.byteoffset = 0
 | 
			
		||||
    for i := 0; i < len(bsw.bits); i++ {
 | 
			
		||||
        bsw.bits[i] = 0
 | 
			
		||||
    }
 | 
			
		||||
    bsw.bitsmark = 0
 | 
			
		||||
    bsw.bytemark = 0
 | 
			
		||||
    bsw.bitsoffset = 0
 | 
			
		||||
    bsw.byteoffset = 0
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										86
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/codec.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										86
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/codec.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -3,62 +3,62 @@ package codec
 | 
			
		|||
type CodecID int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	CODECID_VIDEO_H264 CodecID = iota
 | 
			
		||||
	CODECID_VIDEO_H265
 | 
			
		||||
	CODECID_VIDEO_VP8
 | 
			
		||||
    CODECID_VIDEO_H264 CodecID = iota
 | 
			
		||||
    CODECID_VIDEO_H265
 | 
			
		||||
    CODECID_VIDEO_VP8
 | 
			
		||||
 | 
			
		||||
	CODECID_AUDIO_AAC CodecID = iota + 98
 | 
			
		||||
	CODECID_AUDIO_G711A
 | 
			
		||||
	CODECID_AUDIO_G711U
 | 
			
		||||
	CODECID_AUDIO_OPUS
 | 
			
		||||
    CODECID_AUDIO_AAC CodecID = iota + 98
 | 
			
		||||
    CODECID_AUDIO_G711A
 | 
			
		||||
    CODECID_AUDIO_G711U
 | 
			
		||||
    CODECID_AUDIO_OPUS
 | 
			
		||||
 | 
			
		||||
	CODECID_UNRECOGNIZED = 999
 | 
			
		||||
    CODECID_UNRECOGNIZED = 999
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type H264_NAL_TYPE int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	H264_NAL_RESERVED H264_NAL_TYPE = iota
 | 
			
		||||
	H264_NAL_P_SLICE
 | 
			
		||||
	H264_NAL_SLICE_A
 | 
			
		||||
	H264_NAL_SLICE_B
 | 
			
		||||
	H264_NAL_SLICE_C
 | 
			
		||||
	H264_NAL_I_SLICE
 | 
			
		||||
	H264_NAL_SEI
 | 
			
		||||
	H264_NAL_SPS
 | 
			
		||||
	H264_NAL_PPS
 | 
			
		||||
	H264_NAL_AUD
 | 
			
		||||
    H264_NAL_RESERVED H264_NAL_TYPE = iota
 | 
			
		||||
    H264_NAL_P_SLICE
 | 
			
		||||
    H264_NAL_SLICE_A
 | 
			
		||||
    H264_NAL_SLICE_B
 | 
			
		||||
    H264_NAL_SLICE_C
 | 
			
		||||
    H264_NAL_I_SLICE
 | 
			
		||||
    H264_NAL_SEI
 | 
			
		||||
    H264_NAL_SPS
 | 
			
		||||
    H264_NAL_PPS
 | 
			
		||||
    H264_NAL_AUD
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type H265_NAL_TYPE int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	H265_NAL_Slice_TRAIL_N H265_NAL_TYPE = iota
 | 
			
		||||
	H265_NAL_LICE_TRAIL_R
 | 
			
		||||
	H265_NAL_SLICE_TSA_N
 | 
			
		||||
	H265_NAL_SLICE_TSA_R
 | 
			
		||||
	H265_NAL_SLICE_STSA_N
 | 
			
		||||
	H265_NAL_SLICE_STSA_R
 | 
			
		||||
	H265_NAL_SLICE_RADL_N
 | 
			
		||||
	H265_NAL_SLICE_RADL_R
 | 
			
		||||
	H265_NAL_SLICE_RASL_N
 | 
			
		||||
	H265_NAL_SLICE_RASL_R
 | 
			
		||||
    H265_NAL_Slice_TRAIL_N H265_NAL_TYPE = iota
 | 
			
		||||
    H265_NAL_LICE_TRAIL_R
 | 
			
		||||
    H265_NAL_SLICE_TSA_N
 | 
			
		||||
    H265_NAL_SLICE_TSA_R
 | 
			
		||||
    H265_NAL_SLICE_STSA_N
 | 
			
		||||
    H265_NAL_SLICE_STSA_R
 | 
			
		||||
    H265_NAL_SLICE_RADL_N
 | 
			
		||||
    H265_NAL_SLICE_RADL_R
 | 
			
		||||
    H265_NAL_SLICE_RASL_N
 | 
			
		||||
    H265_NAL_SLICE_RASL_R
 | 
			
		||||
 | 
			
		||||
	//IDR
 | 
			
		||||
	H265_NAL_SLICE_BLA_W_LP H265_NAL_TYPE = iota + 6
 | 
			
		||||
	H265_NAL_SLICE_BLA_W_RADL
 | 
			
		||||
	H265_NAL_SLICE_BLA_N_LP
 | 
			
		||||
	H265_NAL_SLICE_IDR_W_RADL
 | 
			
		||||
	H265_NAL_SLICE_IDR_N_LP
 | 
			
		||||
	H265_NAL_SLICE_CRA
 | 
			
		||||
    //IDR
 | 
			
		||||
    H265_NAL_SLICE_BLA_W_LP H265_NAL_TYPE = iota + 6
 | 
			
		||||
    H265_NAL_SLICE_BLA_W_RADL
 | 
			
		||||
    H265_NAL_SLICE_BLA_N_LP
 | 
			
		||||
    H265_NAL_SLICE_IDR_W_RADL
 | 
			
		||||
    H265_NAL_SLICE_IDR_N_LP
 | 
			
		||||
    H265_NAL_SLICE_CRA
 | 
			
		||||
 | 
			
		||||
	//vps pps sps
 | 
			
		||||
	H265_NAL_VPS H265_NAL_TYPE = iota + 16
 | 
			
		||||
	H265_NAL_SPS
 | 
			
		||||
	H265_NAL_PPS
 | 
			
		||||
	H265_NAL_AUD
 | 
			
		||||
    //vps pps sps
 | 
			
		||||
    H265_NAL_VPS H265_NAL_TYPE = iota + 16
 | 
			
		||||
    H265_NAL_SPS
 | 
			
		||||
    H265_NAL_PPS
 | 
			
		||||
    H265_NAL_AUD
 | 
			
		||||
 | 
			
		||||
	//SEI
 | 
			
		||||
	H265_NAL_SEI H265_NAL_TYPE = iota + 19
 | 
			
		||||
	H265_NAL_SEI_SUFFIX
 | 
			
		||||
    //SEI
 | 
			
		||||
    H265_NAL_SEI H265_NAL_TYPE = iota + 19
 | 
			
		||||
    H265_NAL_SEI_SUFFIX
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										500
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/h264.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										500
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/h264.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -9,241 +9,241 @@ import "encoding/binary"
 | 
			
		|||
// }
 | 
			
		||||
 | 
			
		||||
type H264NaluHdr struct {
 | 
			
		||||
	Forbidden_zero_bit uint8
 | 
			
		||||
	Nal_ref_idc        uint8
 | 
			
		||||
	Nal_unit_type      uint8
 | 
			
		||||
    Forbidden_zero_bit uint8
 | 
			
		||||
    Nal_ref_idc        uint8
 | 
			
		||||
    Nal_unit_type      uint8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (hdr *H264NaluHdr) Decode(bs *BitStream) {
 | 
			
		||||
	hdr.Forbidden_zero_bit = bs.GetBit()
 | 
			
		||||
	hdr.Nal_ref_idc = bs.Uint8(2)
 | 
			
		||||
	hdr.Nal_unit_type = bs.Uint8(5)
 | 
			
		||||
    hdr.Forbidden_zero_bit = bs.GetBit()
 | 
			
		||||
    hdr.Nal_ref_idc = bs.Uint8(2)
 | 
			
		||||
    hdr.Nal_unit_type = bs.Uint8(5)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type SliceHeader struct {
 | 
			
		||||
	First_mb_in_slice    uint64
 | 
			
		||||
	Slice_type           uint64
 | 
			
		||||
	Pic_parameter_set_id uint64
 | 
			
		||||
	Frame_num            uint64
 | 
			
		||||
    First_mb_in_slice    uint64
 | 
			
		||||
    Slice_type           uint64
 | 
			
		||||
    Pic_parameter_set_id uint64
 | 
			
		||||
    Frame_num            uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//调用方根据sps中的log2_max_frame_num_minus4的值来解析Frame_num
 | 
			
		||||
func (sh *SliceHeader) Decode(bs *BitStream) {
 | 
			
		||||
	sh.First_mb_in_slice = bs.ReadUE()
 | 
			
		||||
	sh.Slice_type = bs.ReadUE()
 | 
			
		||||
	sh.Pic_parameter_set_id = bs.ReadUE()
 | 
			
		||||
    sh.First_mb_in_slice = bs.ReadUE()
 | 
			
		||||
    sh.Slice_type = bs.ReadUE()
 | 
			
		||||
    sh.Pic_parameter_set_id = bs.ReadUE()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type SPS struct {
 | 
			
		||||
	Profile_idc                          uint8
 | 
			
		||||
	Constraint_set0_flag                 uint8
 | 
			
		||||
	Constraint_set1_flag                 uint8
 | 
			
		||||
	Constraint_set2_flag                 uint8
 | 
			
		||||
	Constraint_set3_flag                 uint8
 | 
			
		||||
	Constraint_set4_flag                 uint8
 | 
			
		||||
	Constraint_set5_flag                 uint8
 | 
			
		||||
	Reserved_zero_2bits                  uint8
 | 
			
		||||
	Level_idc                            uint8
 | 
			
		||||
	Seq_parameter_set_id                 uint64
 | 
			
		||||
	Chroma_format_idc                    uint64
 | 
			
		||||
	Separate_colour_plane_flag           uint8
 | 
			
		||||
	Bit_depth_luma_minus8                uint64
 | 
			
		||||
	Bit_depth_chroma_minus8              uint64
 | 
			
		||||
	Log2_max_frame_num_minus4            uint64
 | 
			
		||||
	Pic_order_cnt_type                   uint64
 | 
			
		||||
	Max_num_ref_frames                   uint64
 | 
			
		||||
	Gaps_in_frame_num_value_allowed_flag uint8
 | 
			
		||||
	Pic_width_in_mbs_minus1              uint64
 | 
			
		||||
	Pic_height_in_map_units_minus1       uint64
 | 
			
		||||
	Frame_mbs_only_flag                  uint8
 | 
			
		||||
	Direct_8x8_inference_flag            uint8
 | 
			
		||||
	Frame_cropping_flag                  uint8
 | 
			
		||||
	Frame_crop_left_offset               uint64
 | 
			
		||||
	Frame_crop_right_offset              uint64
 | 
			
		||||
	Frame_crop_top_offset                uint64
 | 
			
		||||
	Frame_crop_bottom_offset             uint64
 | 
			
		||||
	Vui_parameters_present_flag          uint8
 | 
			
		||||
    Profile_idc                          uint8
 | 
			
		||||
    Constraint_set0_flag                 uint8
 | 
			
		||||
    Constraint_set1_flag                 uint8
 | 
			
		||||
    Constraint_set2_flag                 uint8
 | 
			
		||||
    Constraint_set3_flag                 uint8
 | 
			
		||||
    Constraint_set4_flag                 uint8
 | 
			
		||||
    Constraint_set5_flag                 uint8
 | 
			
		||||
    Reserved_zero_2bits                  uint8
 | 
			
		||||
    Level_idc                            uint8
 | 
			
		||||
    Seq_parameter_set_id                 uint64
 | 
			
		||||
    Chroma_format_idc                    uint64
 | 
			
		||||
    Separate_colour_plane_flag           uint8
 | 
			
		||||
    Bit_depth_luma_minus8                uint64
 | 
			
		||||
    Bit_depth_chroma_minus8              uint64
 | 
			
		||||
    Log2_max_frame_num_minus4            uint64
 | 
			
		||||
    Pic_order_cnt_type                   uint64
 | 
			
		||||
    Max_num_ref_frames                   uint64
 | 
			
		||||
    Gaps_in_frame_num_value_allowed_flag uint8
 | 
			
		||||
    Pic_width_in_mbs_minus1              uint64
 | 
			
		||||
    Pic_height_in_map_units_minus1       uint64
 | 
			
		||||
    Frame_mbs_only_flag                  uint8
 | 
			
		||||
    Direct_8x8_inference_flag            uint8
 | 
			
		||||
    Frame_cropping_flag                  uint8
 | 
			
		||||
    Frame_crop_left_offset               uint64
 | 
			
		||||
    Frame_crop_right_offset              uint64
 | 
			
		||||
    Frame_crop_top_offset                uint64
 | 
			
		||||
    Frame_crop_bottom_offset             uint64
 | 
			
		||||
    Vui_parameters_present_flag          uint8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (sps *SPS) Decode(bs *BitStream) {
 | 
			
		||||
	sps.Profile_idc = bs.Uint8(8)
 | 
			
		||||
	sps.Constraint_set0_flag = bs.GetBit()
 | 
			
		||||
	sps.Constraint_set1_flag = bs.GetBit()
 | 
			
		||||
	sps.Constraint_set2_flag = bs.GetBit()
 | 
			
		||||
	sps.Constraint_set3_flag = bs.GetBit()
 | 
			
		||||
	sps.Constraint_set4_flag = bs.GetBit()
 | 
			
		||||
	sps.Constraint_set5_flag = bs.GetBit()
 | 
			
		||||
	sps.Reserved_zero_2bits = bs.Uint8(2)
 | 
			
		||||
	sps.Level_idc = bs.Uint8(8)
 | 
			
		||||
	sps.Seq_parameter_set_id = bs.ReadUE()
 | 
			
		||||
	if sps.Profile_idc == 100 || sps.Profile_idc == 110 ||
 | 
			
		||||
		sps.Profile_idc == 122 || sps.Profile_idc == 244 ||
 | 
			
		||||
		sps.Profile_idc == 44 || sps.Profile_idc == 83 ||
 | 
			
		||||
		sps.Profile_idc == 86 || sps.Profile_idc == 118 || sps.Profile_idc == 128 {
 | 
			
		||||
		sps.Chroma_format_idc = bs.ReadUE()
 | 
			
		||||
		if sps.Chroma_format_idc == 3 {
 | 
			
		||||
			sps.Separate_colour_plane_flag = bs.Uint8(1) //separate_colour_plane_flag
 | 
			
		||||
		}
 | 
			
		||||
		sps.Bit_depth_luma_minus8 = bs.ReadUE()   //bit_depth_luma_minus8
 | 
			
		||||
		sps.Bit_depth_chroma_minus8 = bs.ReadUE() //bit_depth_chroma_minus8
 | 
			
		||||
		bs.SkipBits(1)                            //qpprime_y_zero_transform_bypass_flag
 | 
			
		||||
		seq_scaling_matrix_present_flag := bs.GetBit()
 | 
			
		||||
		if seq_scaling_matrix_present_flag == 1 {
 | 
			
		||||
			//seq_scaling_list_present_flag[i]
 | 
			
		||||
			if sps.Chroma_format_idc == 3 {
 | 
			
		||||
				bs.SkipBits(12)
 | 
			
		||||
			} else {
 | 
			
		||||
				bs.SkipBits(8)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sps.Log2_max_frame_num_minus4 = bs.ReadUE()
 | 
			
		||||
	sps.Pic_order_cnt_type = bs.ReadUE()
 | 
			
		||||
	if sps.Pic_order_cnt_type == 0 {
 | 
			
		||||
		bs.ReadUE() // log2_max_pic_order_cnt_lsb_minus4
 | 
			
		||||
	} else if sps.Pic_order_cnt_type == 1 {
 | 
			
		||||
		bs.SkipBits(1) //delta_pic_order_always_zero_flag
 | 
			
		||||
		bs.ReadSE()    //offset_for_non_ref_pic
 | 
			
		||||
		bs.ReadSE()    //offset_for_top_to_bottom_field
 | 
			
		||||
		num_ref_frames_in_pic_order_cnt_cycle := bs.ReadUE()
 | 
			
		||||
		for i := 0; i < int(num_ref_frames_in_pic_order_cnt_cycle); i++ {
 | 
			
		||||
			bs.ReadSE() //offset_for_ref_frame
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sps.Max_num_ref_frames = bs.ReadUE()
 | 
			
		||||
	sps.Gaps_in_frame_num_value_allowed_flag = bs.GetBit()
 | 
			
		||||
	sps.Pic_width_in_mbs_minus1 = bs.ReadUE()
 | 
			
		||||
	sps.Pic_height_in_map_units_minus1 = bs.ReadUE()
 | 
			
		||||
	sps.Frame_mbs_only_flag = bs.GetBit()
 | 
			
		||||
	if sps.Frame_mbs_only_flag == 0 {
 | 
			
		||||
		bs.SkipBits(1) // mb_adaptive_frame_field_flag
 | 
			
		||||
	}
 | 
			
		||||
	sps.Direct_8x8_inference_flag = bs.GetBit()
 | 
			
		||||
	sps.Frame_cropping_flag = bs.GetBit()
 | 
			
		||||
	if sps.Frame_cropping_flag == 1 {
 | 
			
		||||
		sps.Frame_crop_left_offset = bs.ReadUE()   //frame_crop_left_offset
 | 
			
		||||
		sps.Frame_crop_right_offset = bs.ReadUE()  //frame_crop_right_offset
 | 
			
		||||
		sps.Frame_crop_top_offset = bs.ReadUE()    //frame_crop_top_offset
 | 
			
		||||
		sps.Frame_crop_bottom_offset = bs.ReadUE() //frame_crop_bottom_offset
 | 
			
		||||
	}
 | 
			
		||||
	sps.Vui_parameters_present_flag = bs.GetBit()
 | 
			
		||||
    sps.Profile_idc = bs.Uint8(8)
 | 
			
		||||
    sps.Constraint_set0_flag = bs.GetBit()
 | 
			
		||||
    sps.Constraint_set1_flag = bs.GetBit()
 | 
			
		||||
    sps.Constraint_set2_flag = bs.GetBit()
 | 
			
		||||
    sps.Constraint_set3_flag = bs.GetBit()
 | 
			
		||||
    sps.Constraint_set4_flag = bs.GetBit()
 | 
			
		||||
    sps.Constraint_set5_flag = bs.GetBit()
 | 
			
		||||
    sps.Reserved_zero_2bits = bs.Uint8(2)
 | 
			
		||||
    sps.Level_idc = bs.Uint8(8)
 | 
			
		||||
    sps.Seq_parameter_set_id = bs.ReadUE()
 | 
			
		||||
    if sps.Profile_idc == 100 || sps.Profile_idc == 110 ||
 | 
			
		||||
        sps.Profile_idc == 122 || sps.Profile_idc == 244 ||
 | 
			
		||||
        sps.Profile_idc == 44 || sps.Profile_idc == 83 ||
 | 
			
		||||
        sps.Profile_idc == 86 || sps.Profile_idc == 118 || sps.Profile_idc == 128 {
 | 
			
		||||
        sps.Chroma_format_idc = bs.ReadUE()
 | 
			
		||||
        if sps.Chroma_format_idc == 3 {
 | 
			
		||||
            sps.Separate_colour_plane_flag = bs.Uint8(1) //separate_colour_plane_flag
 | 
			
		||||
        }
 | 
			
		||||
        sps.Bit_depth_luma_minus8 = bs.ReadUE()   //bit_depth_luma_minus8
 | 
			
		||||
        sps.Bit_depth_chroma_minus8 = bs.ReadUE() //bit_depth_chroma_minus8
 | 
			
		||||
        bs.SkipBits(1)                            //qpprime_y_zero_transform_bypass_flag
 | 
			
		||||
        seq_scaling_matrix_present_flag := bs.GetBit()
 | 
			
		||||
        if seq_scaling_matrix_present_flag == 1 {
 | 
			
		||||
            //seq_scaling_list_present_flag[i]
 | 
			
		||||
            if sps.Chroma_format_idc == 3 {
 | 
			
		||||
                bs.SkipBits(12)
 | 
			
		||||
            } else {
 | 
			
		||||
                bs.SkipBits(8)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    sps.Log2_max_frame_num_minus4 = bs.ReadUE()
 | 
			
		||||
    sps.Pic_order_cnt_type = bs.ReadUE()
 | 
			
		||||
    if sps.Pic_order_cnt_type == 0 {
 | 
			
		||||
        bs.ReadUE() // log2_max_pic_order_cnt_lsb_minus4
 | 
			
		||||
    } else if sps.Pic_order_cnt_type == 1 {
 | 
			
		||||
        bs.SkipBits(1) //delta_pic_order_always_zero_flag
 | 
			
		||||
        bs.ReadSE()    //offset_for_non_ref_pic
 | 
			
		||||
        bs.ReadSE()    //offset_for_top_to_bottom_field
 | 
			
		||||
        num_ref_frames_in_pic_order_cnt_cycle := bs.ReadUE()
 | 
			
		||||
        for i := 0; i < int(num_ref_frames_in_pic_order_cnt_cycle); i++ {
 | 
			
		||||
            bs.ReadSE() //offset_for_ref_frame
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    sps.Max_num_ref_frames = bs.ReadUE()
 | 
			
		||||
    sps.Gaps_in_frame_num_value_allowed_flag = bs.GetBit()
 | 
			
		||||
    sps.Pic_width_in_mbs_minus1 = bs.ReadUE()
 | 
			
		||||
    sps.Pic_height_in_map_units_minus1 = bs.ReadUE()
 | 
			
		||||
    sps.Frame_mbs_only_flag = bs.GetBit()
 | 
			
		||||
    if sps.Frame_mbs_only_flag == 0 {
 | 
			
		||||
        bs.SkipBits(1) // mb_adaptive_frame_field_flag
 | 
			
		||||
    }
 | 
			
		||||
    sps.Direct_8x8_inference_flag = bs.GetBit()
 | 
			
		||||
    sps.Frame_cropping_flag = bs.GetBit()
 | 
			
		||||
    if sps.Frame_cropping_flag == 1 {
 | 
			
		||||
        sps.Frame_crop_left_offset = bs.ReadUE()   //frame_crop_left_offset
 | 
			
		||||
        sps.Frame_crop_right_offset = bs.ReadUE()  //frame_crop_right_offset
 | 
			
		||||
        sps.Frame_crop_top_offset = bs.ReadUE()    //frame_crop_top_offset
 | 
			
		||||
        sps.Frame_crop_bottom_offset = bs.ReadUE() //frame_crop_bottom_offset
 | 
			
		||||
    }
 | 
			
		||||
    sps.Vui_parameters_present_flag = bs.GetBit()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type PPS struct {
 | 
			
		||||
	Pic_parameter_set_id                         uint64
 | 
			
		||||
	Seq_parameter_set_id                         uint64
 | 
			
		||||
	Entropy_coding_mode_flag                     uint8
 | 
			
		||||
	Bottom_field_pic_order_in_frame_present_flag uint8
 | 
			
		||||
	Num_slice_groups_minus1                      uint64
 | 
			
		||||
    Pic_parameter_set_id                         uint64
 | 
			
		||||
    Seq_parameter_set_id                         uint64
 | 
			
		||||
    Entropy_coding_mode_flag                     uint8
 | 
			
		||||
    Bottom_field_pic_order_in_frame_present_flag uint8
 | 
			
		||||
    Num_slice_groups_minus1                      uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (pps *PPS) Decode(bs *BitStream) {
 | 
			
		||||
	pps.Pic_parameter_set_id = bs.ReadUE()
 | 
			
		||||
	pps.Seq_parameter_set_id = bs.ReadUE()
 | 
			
		||||
	pps.Entropy_coding_mode_flag = bs.GetBit()
 | 
			
		||||
	pps.Bottom_field_pic_order_in_frame_present_flag = bs.GetBit()
 | 
			
		||||
	pps.Num_slice_groups_minus1 = bs.ReadUE()
 | 
			
		||||
    pps.Pic_parameter_set_id = bs.ReadUE()
 | 
			
		||||
    pps.Seq_parameter_set_id = bs.ReadUE()
 | 
			
		||||
    pps.Entropy_coding_mode_flag = bs.GetBit()
 | 
			
		||||
    pps.Bottom_field_pic_order_in_frame_present_flag = bs.GetBit()
 | 
			
		||||
    pps.Num_slice_groups_minus1 = bs.ReadUE()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type SEIReaderWriter interface {
 | 
			
		||||
	Read(size uint16, bs *BitStream)
 | 
			
		||||
	Write(bsw *BitStreamWriter)
 | 
			
		||||
    Read(size uint16, bs *BitStream)
 | 
			
		||||
    Write(bsw *BitStreamWriter)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type UserDataUnregistered struct {
 | 
			
		||||
	UUID     []byte
 | 
			
		||||
	UserData []byte
 | 
			
		||||
    UUID     []byte
 | 
			
		||||
    UserData []byte
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (udu *UserDataUnregistered) Read(size uint16, bs *BitStream) {
 | 
			
		||||
	udu.UUID = bs.GetBytes(16)
 | 
			
		||||
	udu.UserData = bs.GetBytes(int(size - 16))
 | 
			
		||||
    udu.UUID = bs.GetBytes(16)
 | 
			
		||||
    udu.UserData = bs.GetBytes(int(size - 16))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (udu *UserDataUnregistered) Write(bsw *BitStreamWriter) {
 | 
			
		||||
	bsw.PutBytes(udu.UUID)
 | 
			
		||||
	bsw.PutBytes(udu.UserData)
 | 
			
		||||
    bsw.PutBytes(udu.UUID)
 | 
			
		||||
    bsw.PutBytes(udu.UserData)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type SEI struct {
 | 
			
		||||
	PayloadType uint16
 | 
			
		||||
	PayloadSize uint16
 | 
			
		||||
	Sei_payload SEIReaderWriter
 | 
			
		||||
    PayloadType uint16
 | 
			
		||||
    PayloadSize uint16
 | 
			
		||||
    Sei_payload SEIReaderWriter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (sei *SEI) Decode(bs *BitStream) {
 | 
			
		||||
	for bs.NextBits(8) == 0xFF {
 | 
			
		||||
		sei.PayloadType += 255
 | 
			
		||||
	}
 | 
			
		||||
	sei.PayloadType += uint16(bs.Uint8(8))
 | 
			
		||||
	for bs.NextBits(8) == 0xFF {
 | 
			
		||||
		sei.PayloadSize += 255
 | 
			
		||||
	}
 | 
			
		||||
	sei.PayloadSize += uint16(bs.Uint8(8))
 | 
			
		||||
	if sei.PayloadType == 5 {
 | 
			
		||||
		sei.Sei_payload = new(UserDataUnregistered)
 | 
			
		||||
		sei.Sei_payload.Read(sei.PayloadSize, bs)
 | 
			
		||||
	}
 | 
			
		||||
    for bs.NextBits(8) == 0xFF {
 | 
			
		||||
        sei.PayloadType += 255
 | 
			
		||||
    }
 | 
			
		||||
    sei.PayloadType += uint16(bs.Uint8(8))
 | 
			
		||||
    for bs.NextBits(8) == 0xFF {
 | 
			
		||||
        sei.PayloadSize += 255
 | 
			
		||||
    }
 | 
			
		||||
    sei.PayloadSize += uint16(bs.Uint8(8))
 | 
			
		||||
    if sei.PayloadType == 5 {
 | 
			
		||||
        sei.Sei_payload = new(UserDataUnregistered)
 | 
			
		||||
        sei.Sei_payload.Read(sei.PayloadSize, bs)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (sei *SEI) Encode(bsw *BitStreamWriter) []byte {
 | 
			
		||||
	payloadType := sei.PayloadType
 | 
			
		||||
	payloadSize := sei.PayloadSize
 | 
			
		||||
	for payloadType >= 0xFF {
 | 
			
		||||
		bsw.PutByte(0xFF)
 | 
			
		||||
		payloadType -= 255
 | 
			
		||||
	}
 | 
			
		||||
	bsw.PutByte(uint8(payloadType))
 | 
			
		||||
	for payloadSize >= 0xFF {
 | 
			
		||||
		bsw.PutByte(0xFF)
 | 
			
		||||
		payloadSize -= 255
 | 
			
		||||
	}
 | 
			
		||||
	bsw.PutByte(uint8(payloadSize))
 | 
			
		||||
	sei.Sei_payload.Write(bsw)
 | 
			
		||||
	return bsw.Bits()
 | 
			
		||||
    payloadType := sei.PayloadType
 | 
			
		||||
    payloadSize := sei.PayloadSize
 | 
			
		||||
    for payloadType >= 0xFF {
 | 
			
		||||
        bsw.PutByte(0xFF)
 | 
			
		||||
        payloadType -= 255
 | 
			
		||||
    }
 | 
			
		||||
    bsw.PutByte(uint8(payloadType))
 | 
			
		||||
    for payloadSize >= 0xFF {
 | 
			
		||||
        bsw.PutByte(0xFF)
 | 
			
		||||
        payloadSize -= 255
 | 
			
		||||
    }
 | 
			
		||||
    bsw.PutByte(uint8(payloadSize))
 | 
			
		||||
    sei.Sei_payload.Write(bsw)
 | 
			
		||||
    return bsw.Bits()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetSPSIdWithStartCode(sps []byte) uint64 {
 | 
			
		||||
	start, sc := FindStartCode(sps, 0)
 | 
			
		||||
	return GetSPSId(sps[start+int(sc):])
 | 
			
		||||
    start, sc := FindStartCode(sps, 0)
 | 
			
		||||
    return GetSPSId(sps[start+int(sc):])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetSPSId(sps []byte) uint64 {
 | 
			
		||||
	sps = sps[1:]
 | 
			
		||||
	bs := NewBitStream(sps)
 | 
			
		||||
	bs.SkipBits(24)
 | 
			
		||||
	return bs.ReadUE()
 | 
			
		||||
    sps = sps[1:]
 | 
			
		||||
    bs := NewBitStream(sps)
 | 
			
		||||
    bs.SkipBits(24)
 | 
			
		||||
    return bs.ReadUE()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetPPSIdWithStartCode(pps []byte) uint64 {
 | 
			
		||||
	start, sc := FindStartCode(pps, 0)
 | 
			
		||||
	return GetPPSId(pps[start+int(sc):])
 | 
			
		||||
    start, sc := FindStartCode(pps, 0)
 | 
			
		||||
    return GetPPSId(pps[start+int(sc):])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetPPSId(pps []byte) uint64 {
 | 
			
		||||
	pps = pps[1:]
 | 
			
		||||
	bs := NewBitStream(pps)
 | 
			
		||||
	return bs.ReadUE()
 | 
			
		||||
    pps = pps[1:]
 | 
			
		||||
    bs := NewBitStream(pps)
 | 
			
		||||
    return bs.ReadUE()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//https://stackoverflow.com/questions/12018535/get-the-width-height-of-the-video-from-h-264-nalu
 | 
			
		||||
//int Width = ((pic_width_in_mbs_minus1 +1)*16) - frame_crop_right_offset *2 - frame_crop_left_offset *2;
 | 
			
		||||
//int Height = ((2 - frame_mbs_only_flag)* (pic_height_in_map_units_minus1 +1) * 16) - (frame_crop_bottom_offset* 2) - (frame_crop_top_offset* 2);
 | 
			
		||||
func GetH264Resolution(sps []byte) (width uint32, height uint32) {
 | 
			
		||||
	start, sc := FindStartCode(sps, 0)
 | 
			
		||||
	bs := NewBitStream(sps[start+int(sc)+1:])
 | 
			
		||||
	var s SPS
 | 
			
		||||
	s.Decode(bs)
 | 
			
		||||
    start, sc := FindStartCode(sps, 0)
 | 
			
		||||
    bs := NewBitStream(sps[start+int(sc)+1:])
 | 
			
		||||
    var s SPS
 | 
			
		||||
    s.Decode(bs)
 | 
			
		||||
 | 
			
		||||
	widthInSample := (uint32(s.Pic_width_in_mbs_minus1) + 1) * 16
 | 
			
		||||
	widthCrop := uint32(s.Frame_crop_left_offset)*2 - uint32(s.Frame_crop_right_offset)*2
 | 
			
		||||
	width = widthInSample - widthCrop
 | 
			
		||||
    widthInSample := (uint32(s.Pic_width_in_mbs_minus1) + 1) * 16
 | 
			
		||||
    widthCrop := uint32(s.Frame_crop_left_offset)*2 - uint32(s.Frame_crop_right_offset)*2
 | 
			
		||||
    width = widthInSample - widthCrop
 | 
			
		||||
 | 
			
		||||
	heightInSample := ((2 - uint32(s.Frame_mbs_only_flag)) * (uint32(s.Pic_height_in_map_units_minus1) + 1) * 16)
 | 
			
		||||
	heightCrop := uint32(s.Frame_crop_bottom_offset)*2 - uint32(s.Frame_crop_top_offset)*2
 | 
			
		||||
	height = heightInSample - heightCrop
 | 
			
		||||
    heightInSample := ((2 - uint32(s.Frame_mbs_only_flag)) * (uint32(s.Pic_height_in_map_units_minus1) + 1) * 16)
 | 
			
		||||
    heightCrop := uint32(s.Frame_crop_bottom_offset)*2 - uint32(s.Frame_crop_top_offset)*2
 | 
			
		||||
    height = heightInSample - heightCrop
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
    return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// aligned(8) class AVCDecoderConfigurationRecord {
 | 
			
		||||
| 
						 | 
				
			
			@ -302,95 +302,95 @@ func GetH264Resolution(sps []byte) (width uint32, height uint32) {
 | 
			
		|||
//   variable PPS NALU data
 | 
			
		||||
 | 
			
		||||
func CreateH264AVCCExtradata(spss [][]byte, ppss [][]byte) []byte {
 | 
			
		||||
	extradata := make([]byte, 6, 256)
 | 
			
		||||
	for i, sps := range spss {
 | 
			
		||||
		start, sc := FindStartCode(sps, 0)
 | 
			
		||||
		spss[i] = sps[start+int(sc):]
 | 
			
		||||
	}
 | 
			
		||||
    extradata := make([]byte, 6, 256)
 | 
			
		||||
    for i, sps := range spss {
 | 
			
		||||
        start, sc := FindStartCode(sps, 0)
 | 
			
		||||
        spss[i] = sps[start+int(sc):]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	for i, pps := range ppss {
 | 
			
		||||
		start, sc := FindStartCode(pps, 0)
 | 
			
		||||
		ppss[i] = pps[start+int(sc):]
 | 
			
		||||
	}
 | 
			
		||||
    for i, pps := range ppss {
 | 
			
		||||
        start, sc := FindStartCode(pps, 0)
 | 
			
		||||
        ppss[i] = pps[start+int(sc):]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	extradata[0] = 0x01
 | 
			
		||||
	extradata[1] = spss[0][1]
 | 
			
		||||
	extradata[2] = spss[0][2]
 | 
			
		||||
	extradata[3] = spss[0][3]
 | 
			
		||||
	extradata[4] = 0xFF
 | 
			
		||||
	extradata[5] = 0xE0 | uint8(len(spss))
 | 
			
		||||
	for _, sps := range spss {
 | 
			
		||||
		spssize := make([]byte, 2)
 | 
			
		||||
		binary.BigEndian.PutUint16(spssize, uint16(len(sps)))
 | 
			
		||||
		extradata = append(extradata, spssize...)
 | 
			
		||||
		extradata = append(extradata, sps...)
 | 
			
		||||
	}
 | 
			
		||||
	extradata = append(extradata, uint8(len(ppss)))
 | 
			
		||||
	for _, pps := range ppss {
 | 
			
		||||
		ppssize := make([]byte, 2)
 | 
			
		||||
		binary.BigEndian.PutUint16(ppssize, uint16(len(pps)))
 | 
			
		||||
		extradata = append(extradata, ppssize...)
 | 
			
		||||
		extradata = append(extradata, pps...)
 | 
			
		||||
	}
 | 
			
		||||
	var h264sps SPS
 | 
			
		||||
	h264sps.Decode(NewBitStream(spss[0][1:]))
 | 
			
		||||
	if h264sps.Profile_idc == 100 ||
 | 
			
		||||
		h264sps.Profile_idc == 110 ||
 | 
			
		||||
		h264sps.Profile_idc == 122 ||
 | 
			
		||||
		h264sps.Profile_idc == 144 {
 | 
			
		||||
		tmp := make([]byte, 4)
 | 
			
		||||
		tmp[0] = 0xFC | uint8(h264sps.Chroma_format_idc&0x03)
 | 
			
		||||
		tmp[1] = 0xF8 | uint8(h264sps.Bit_depth_luma_minus8&0x07)
 | 
			
		||||
		tmp[2] = 0xF8 | uint8(h264sps.Bit_depth_chroma_minus8&0x07)
 | 
			
		||||
		tmp[3] = 0
 | 
			
		||||
		extradata = append(extradata, tmp...)
 | 
			
		||||
	}
 | 
			
		||||
    extradata[0] = 0x01
 | 
			
		||||
    extradata[1] = spss[0][1]
 | 
			
		||||
    extradata[2] = spss[0][2]
 | 
			
		||||
    extradata[3] = spss[0][3]
 | 
			
		||||
    extradata[4] = 0xFF
 | 
			
		||||
    extradata[5] = 0xE0 | uint8(len(spss))
 | 
			
		||||
    for _, sps := range spss {
 | 
			
		||||
        spssize := make([]byte, 2)
 | 
			
		||||
        binary.BigEndian.PutUint16(spssize, uint16(len(sps)))
 | 
			
		||||
        extradata = append(extradata, spssize...)
 | 
			
		||||
        extradata = append(extradata, sps...)
 | 
			
		||||
    }
 | 
			
		||||
    extradata = append(extradata, uint8(len(ppss)))
 | 
			
		||||
    for _, pps := range ppss {
 | 
			
		||||
        ppssize := make([]byte, 2)
 | 
			
		||||
        binary.BigEndian.PutUint16(ppssize, uint16(len(pps)))
 | 
			
		||||
        extradata = append(extradata, ppssize...)
 | 
			
		||||
        extradata = append(extradata, pps...)
 | 
			
		||||
    }
 | 
			
		||||
    var h264sps SPS
 | 
			
		||||
    h264sps.Decode(NewBitStream(spss[0][1:]))
 | 
			
		||||
    if h264sps.Profile_idc == 100 ||
 | 
			
		||||
        h264sps.Profile_idc == 110 ||
 | 
			
		||||
        h264sps.Profile_idc == 122 ||
 | 
			
		||||
        h264sps.Profile_idc == 144 {
 | 
			
		||||
        tmp := make([]byte, 4)
 | 
			
		||||
        tmp[0] = 0xFC | uint8(h264sps.Chroma_format_idc&0x03)
 | 
			
		||||
        tmp[1] = 0xF8 | uint8(h264sps.Bit_depth_luma_minus8&0x07)
 | 
			
		||||
        tmp[2] = 0xF8 | uint8(h264sps.Bit_depth_chroma_minus8&0x07)
 | 
			
		||||
        tmp[3] = 0
 | 
			
		||||
        extradata = append(extradata, tmp...)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	return extradata
 | 
			
		||||
    return extradata
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CovertExtradata(extraData []byte) ([][]byte, [][]byte) {
 | 
			
		||||
	spsnum := extraData[5] & 0x1F
 | 
			
		||||
	spss := make([][]byte, spsnum)
 | 
			
		||||
	offset := 6
 | 
			
		||||
	for i := 0; i < int(spsnum); i++ {
 | 
			
		||||
		spssize := binary.BigEndian.Uint16(extraData[offset:])
 | 
			
		||||
		sps := make([]byte, spssize+4)
 | 
			
		||||
		copy(sps, []byte{0x00, 0x00, 0x00, 0x01})
 | 
			
		||||
		copy(sps[4:], extraData[offset+2:offset+2+int(spssize)])
 | 
			
		||||
		offset += 2 + int(spssize)
 | 
			
		||||
		spss[i] = sps
 | 
			
		||||
	}
 | 
			
		||||
	ppsnum := extraData[offset]
 | 
			
		||||
	ppss := make([][]byte, ppsnum)
 | 
			
		||||
	offset++
 | 
			
		||||
	for i := 0; i < int(ppsnum); i++ {
 | 
			
		||||
		ppssize := binary.BigEndian.Uint16(extraData[offset:])
 | 
			
		||||
		pps := make([]byte, ppssize+4)
 | 
			
		||||
		copy(pps, []byte{0x00, 0x00, 0x00, 0x01})
 | 
			
		||||
		copy(pps[4:], extraData[offset+2:offset+2+int(ppssize)])
 | 
			
		||||
		offset += 2 + int(ppssize)
 | 
			
		||||
		ppss[i] = pps
 | 
			
		||||
	}
 | 
			
		||||
	return spss, ppss
 | 
			
		||||
    spsnum := extraData[5] & 0x1F
 | 
			
		||||
    spss := make([][]byte, spsnum)
 | 
			
		||||
    offset := 6
 | 
			
		||||
    for i := 0; i < int(spsnum); i++ {
 | 
			
		||||
        spssize := binary.BigEndian.Uint16(extraData[offset:])
 | 
			
		||||
        sps := make([]byte, spssize+4)
 | 
			
		||||
        copy(sps, []byte{0x00, 0x00, 0x00, 0x01})
 | 
			
		||||
        copy(sps[4:], extraData[offset+2:offset+2+int(spssize)])
 | 
			
		||||
        offset += 2 + int(spssize)
 | 
			
		||||
        spss[i] = sps
 | 
			
		||||
    }
 | 
			
		||||
    ppsnum := extraData[offset]
 | 
			
		||||
    ppss := make([][]byte, ppsnum)
 | 
			
		||||
    offset++
 | 
			
		||||
    for i := 0; i < int(ppsnum); i++ {
 | 
			
		||||
        ppssize := binary.BigEndian.Uint16(extraData[offset:])
 | 
			
		||||
        pps := make([]byte, ppssize+4)
 | 
			
		||||
        copy(pps, []byte{0x00, 0x00, 0x00, 0x01})
 | 
			
		||||
        copy(pps[4:], extraData[offset+2:offset+2+int(ppssize)])
 | 
			
		||||
        offset += 2 + int(ppssize)
 | 
			
		||||
        ppss[i] = pps
 | 
			
		||||
    }
 | 
			
		||||
    return spss, ppss
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ConvertAnnexBToAVCC(annexb []byte) []byte {
 | 
			
		||||
	start, sc := FindStartCode(annexb, 0)
 | 
			
		||||
	if sc == START_CODE_4 {
 | 
			
		||||
		binary.BigEndian.PutUint32(annexb[start:], uint32(len(annexb)-4))
 | 
			
		||||
		return annexb
 | 
			
		||||
	} else {
 | 
			
		||||
		avcc := make([]byte, 1+len(annexb))
 | 
			
		||||
		binary.BigEndian.PutUint32(avcc, uint32(len(annexb)-3))
 | 
			
		||||
		copy(avcc[4:], annexb[start+3:])
 | 
			
		||||
		return avcc
 | 
			
		||||
	}
 | 
			
		||||
    start, sc := FindStartCode(annexb, 0)
 | 
			
		||||
    if sc == START_CODE_4 {
 | 
			
		||||
        binary.BigEndian.PutUint32(annexb[start:], uint32(len(annexb)-4))
 | 
			
		||||
        return annexb
 | 
			
		||||
    } else {
 | 
			
		||||
        avcc := make([]byte, 1+len(annexb))
 | 
			
		||||
        binary.BigEndian.PutUint32(avcc, uint32(len(annexb)-3))
 | 
			
		||||
        copy(avcc[4:], annexb[start+3:])
 | 
			
		||||
        return avcc
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CovertAVCCToAnnexB(avcc []byte) {
 | 
			
		||||
	avcc[0] = 0x00
 | 
			
		||||
	avcc[1] = 0x00
 | 
			
		||||
	avcc[2] = 0x00
 | 
			
		||||
	avcc[3] = 0x01
 | 
			
		||||
    avcc[0] = 0x00
 | 
			
		||||
    avcc[1] = 0x00
 | 
			
		||||
    avcc[2] = 0x00
 | 
			
		||||
    avcc[3] = 0x01
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1652
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/h265.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1652
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/h265.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										398
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/opus.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										398
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/opus.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
package codec
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"errors"
 | 
			
		||||
    "encoding/binary"
 | 
			
		||||
    "errors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// rfc6716 https://datatracker.ietf.org/doc/html/rfc6716
 | 
			
		||||
| 
						 | 
				
			
			@ -157,169 +157,169 @@ import (
 | 
			
		|||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	/// 10ms,20ms,40ms,60ms, samplerate 48000
 | 
			
		||||
	//  sample num per millisecond
 | 
			
		||||
	//  48000 / 1000ms * 10 = 480 ...
 | 
			
		||||
	SLKOpusSampleSize    [4]int = [4]int{480, 960, 1920, 2880}
 | 
			
		||||
	HybridOpusSampleSize [4]int = [4]int{480, 960}
 | 
			
		||||
	CELTOpusSampleSize   [4]int = [4]int{120, 210, 480, 960}
 | 
			
		||||
    /// 10ms,20ms,40ms,60ms, samplerate 48000
 | 
			
		||||
    //  sample num per millisecond
 | 
			
		||||
    //  48000 / 1000ms * 10 = 480 ...
 | 
			
		||||
    SLKOpusSampleSize    [4]int = [4]int{480, 960, 1920, 2880}
 | 
			
		||||
    HybridOpusSampleSize [4]int = [4]int{480, 960}
 | 
			
		||||
    CELTOpusSampleSize   [4]int = [4]int{120, 210, 480, 960}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func OpusPacketDuration(packet []byte) uint64 {
 | 
			
		||||
	config := int(packet[0] >> 3)
 | 
			
		||||
	code := packet[0] & 0x03
 | 
			
		||||
	frameCount := 0
 | 
			
		||||
	var duration uint64
 | 
			
		||||
	if code == 0 {
 | 
			
		||||
		frameCount = 1
 | 
			
		||||
	} else if code == 1 || code == 2 {
 | 
			
		||||
		frameCount = 2
 | 
			
		||||
	} else if code == 3 {
 | 
			
		||||
		frameCount = int(packet[1] & 0x1F)
 | 
			
		||||
	} else {
 | 
			
		||||
		panic("code must <= 3")
 | 
			
		||||
	}
 | 
			
		||||
    config := int(packet[0] >> 3)
 | 
			
		||||
    code := packet[0] & 0x03
 | 
			
		||||
    frameCount := 0
 | 
			
		||||
    var duration uint64
 | 
			
		||||
    if code == 0 {
 | 
			
		||||
        frameCount = 1
 | 
			
		||||
    } else if code == 1 || code == 2 {
 | 
			
		||||
        frameCount = 2
 | 
			
		||||
    } else if code == 3 {
 | 
			
		||||
        frameCount = int(packet[1] & 0x1F)
 | 
			
		||||
    } else {
 | 
			
		||||
        panic("code must <= 3")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	switch {
 | 
			
		||||
	case config >= 0 && config < 12:
 | 
			
		||||
		duration = uint64(frameCount * SLKOpusSampleSize[config%4])
 | 
			
		||||
	case config >= 12 && config < 16:
 | 
			
		||||
		duration = uint64(frameCount * HybridOpusSampleSize[config%2])
 | 
			
		||||
	case config >= 16 && config < 32:
 | 
			
		||||
		duration = uint64(frameCount * CELTOpusSampleSize[config%4])
 | 
			
		||||
	default:
 | 
			
		||||
		panic("unkown opus config")
 | 
			
		||||
	}
 | 
			
		||||
    switch {
 | 
			
		||||
    case config >= 0 && config < 12:
 | 
			
		||||
        duration = uint64(frameCount * SLKOpusSampleSize[config%4])
 | 
			
		||||
    case config >= 12 && config < 16:
 | 
			
		||||
        duration = uint64(frameCount * HybridOpusSampleSize[config%2])
 | 
			
		||||
    case config >= 16 && config < 32:
 | 
			
		||||
        duration = uint64(frameCount * CELTOpusSampleSize[config%4])
 | 
			
		||||
    default:
 | 
			
		||||
        panic("unkown opus config")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	return duration
 | 
			
		||||
    return duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//ffmpeg opus.h OpusPacket
 | 
			
		||||
type OpusPacket struct {
 | 
			
		||||
	Code       int
 | 
			
		||||
	Config     int
 | 
			
		||||
	Stereo     int
 | 
			
		||||
	Vbr        int
 | 
			
		||||
	FrameCount int
 | 
			
		||||
	FrameLen   []uint16
 | 
			
		||||
	Frame      []byte
 | 
			
		||||
	Duration   uint64
 | 
			
		||||
    Code       int
 | 
			
		||||
    Config     int
 | 
			
		||||
    Stereo     int
 | 
			
		||||
    Vbr        int
 | 
			
		||||
    FrameCount int
 | 
			
		||||
    FrameLen   []uint16
 | 
			
		||||
    Frame      []byte
 | 
			
		||||
    Duration   uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DecodeOpusPacket(packet []byte) *OpusPacket {
 | 
			
		||||
	pkt := &OpusPacket{}
 | 
			
		||||
	pkt.Code = int(packet[0] & 0x03)
 | 
			
		||||
	pkt.Stereo = int((packet[0] >> 2) & 0x01)
 | 
			
		||||
	pkt.Config = int(packet[0] >> 3)
 | 
			
		||||
    pkt := &OpusPacket{}
 | 
			
		||||
    pkt.Code = int(packet[0] & 0x03)
 | 
			
		||||
    pkt.Stereo = int((packet[0] >> 2) & 0x01)
 | 
			
		||||
    pkt.Config = int(packet[0] >> 3)
 | 
			
		||||
 | 
			
		||||
	switch pkt.Code {
 | 
			
		||||
	case 0:
 | 
			
		||||
		pkt.FrameCount = 1
 | 
			
		||||
		pkt.FrameLen = make([]uint16, 1)
 | 
			
		||||
		pkt.FrameLen[0] = uint16(len(packet) - 1)
 | 
			
		||||
		pkt.Frame = packet[1:]
 | 
			
		||||
	case 1:
 | 
			
		||||
		pkt.FrameCount = 2
 | 
			
		||||
		pkt.FrameLen = make([]uint16, 1)
 | 
			
		||||
		pkt.FrameLen[0] = uint16(len(packet)-1) / 2
 | 
			
		||||
		pkt.Frame = packet[1:]
 | 
			
		||||
	case 2:
 | 
			
		||||
		pkt.FrameCount = 2
 | 
			
		||||
		hdr := 1
 | 
			
		||||
		N1 := int(packet[1])
 | 
			
		||||
		if N1 >= 252 {
 | 
			
		||||
			N1 = N1 + int(packet[2]*4)
 | 
			
		||||
			hdr = 2
 | 
			
		||||
		}
 | 
			
		||||
		pkt.FrameLen = make([]uint16, 2)
 | 
			
		||||
		pkt.FrameLen[0] = uint16(N1)
 | 
			
		||||
		pkt.FrameLen[1] = uint16(len(packet)-hdr) - uint16(N1)
 | 
			
		||||
	case 3:
 | 
			
		||||
		hdr := 2
 | 
			
		||||
		pkt.Vbr = int(packet[1] >> 7)
 | 
			
		||||
		padding := packet[1] >> 6
 | 
			
		||||
		pkt.FrameCount = int(packet[1] & 0x1F)
 | 
			
		||||
		paddingLen := 0
 | 
			
		||||
		if padding == 1 {
 | 
			
		||||
			for packet[hdr] == 255 {
 | 
			
		||||
				paddingLen += 254
 | 
			
		||||
				hdr++
 | 
			
		||||
			}
 | 
			
		||||
			paddingLen += int(packet[hdr])
 | 
			
		||||
		}
 | 
			
		||||
    switch pkt.Code {
 | 
			
		||||
    case 0:
 | 
			
		||||
        pkt.FrameCount = 1
 | 
			
		||||
        pkt.FrameLen = make([]uint16, 1)
 | 
			
		||||
        pkt.FrameLen[0] = uint16(len(packet) - 1)
 | 
			
		||||
        pkt.Frame = packet[1:]
 | 
			
		||||
    case 1:
 | 
			
		||||
        pkt.FrameCount = 2
 | 
			
		||||
        pkt.FrameLen = make([]uint16, 1)
 | 
			
		||||
        pkt.FrameLen[0] = uint16(len(packet)-1) / 2
 | 
			
		||||
        pkt.Frame = packet[1:]
 | 
			
		||||
    case 2:
 | 
			
		||||
        pkt.FrameCount = 2
 | 
			
		||||
        hdr := 1
 | 
			
		||||
        N1 := int(packet[1])
 | 
			
		||||
        if N1 >= 252 {
 | 
			
		||||
            N1 = N1 + int(packet[2]*4)
 | 
			
		||||
            hdr = 2
 | 
			
		||||
        }
 | 
			
		||||
        pkt.FrameLen = make([]uint16, 2)
 | 
			
		||||
        pkt.FrameLen[0] = uint16(N1)
 | 
			
		||||
        pkt.FrameLen[1] = uint16(len(packet)-hdr) - uint16(N1)
 | 
			
		||||
    case 3:
 | 
			
		||||
        hdr := 2
 | 
			
		||||
        pkt.Vbr = int(packet[1] >> 7)
 | 
			
		||||
        padding := packet[1] >> 6
 | 
			
		||||
        pkt.FrameCount = int(packet[1] & 0x1F)
 | 
			
		||||
        paddingLen := 0
 | 
			
		||||
        if padding == 1 {
 | 
			
		||||
            for packet[hdr] == 255 {
 | 
			
		||||
                paddingLen += 254
 | 
			
		||||
                hdr++
 | 
			
		||||
            }
 | 
			
		||||
            paddingLen += int(packet[hdr])
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		if pkt.Vbr == 0 {
 | 
			
		||||
			pkt.FrameLen = make([]uint16, 1)
 | 
			
		||||
			pkt.FrameLen[0] = uint16(len(packet)-hdr-paddingLen) / uint16(pkt.FrameCount)
 | 
			
		||||
			pkt.Frame = packet[hdr : hdr+int(pkt.FrameLen[0]*uint16(pkt.FrameCount))]
 | 
			
		||||
		} else {
 | 
			
		||||
			n := 0
 | 
			
		||||
			for i := 0; i < int(pkt.FrameCount)-1; i++ {
 | 
			
		||||
				N1 := int(packet[hdr])
 | 
			
		||||
				hdr += 1
 | 
			
		||||
				if N1 >= 252 {
 | 
			
		||||
					N1 = N1 + int(packet[hdr]*4)
 | 
			
		||||
					hdr += 1
 | 
			
		||||
				}
 | 
			
		||||
				n += N1
 | 
			
		||||
				pkt.FrameLen = append(pkt.FrameLen, uint16(N1))
 | 
			
		||||
			}
 | 
			
		||||
			lastFrameLen := len(packet) - hdr - paddingLen - n
 | 
			
		||||
			pkt.FrameLen = append(pkt.FrameLen, uint16(lastFrameLen))
 | 
			
		||||
			pkt.Frame = packet[hdr : hdr+n+lastFrameLen]
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		panic("Error C must <= 3")
 | 
			
		||||
	}
 | 
			
		||||
	OpusPacketDuration(packet)
 | 
			
		||||
	return pkt
 | 
			
		||||
        if pkt.Vbr == 0 {
 | 
			
		||||
            pkt.FrameLen = make([]uint16, 1)
 | 
			
		||||
            pkt.FrameLen[0] = uint16(len(packet)-hdr-paddingLen) / uint16(pkt.FrameCount)
 | 
			
		||||
            pkt.Frame = packet[hdr : hdr+int(pkt.FrameLen[0]*uint16(pkt.FrameCount))]
 | 
			
		||||
        } else {
 | 
			
		||||
            n := 0
 | 
			
		||||
            for i := 0; i < int(pkt.FrameCount)-1; i++ {
 | 
			
		||||
                N1 := int(packet[hdr])
 | 
			
		||||
                hdr += 1
 | 
			
		||||
                if N1 >= 252 {
 | 
			
		||||
                    N1 = N1 + int(packet[hdr]*4)
 | 
			
		||||
                    hdr += 1
 | 
			
		||||
                }
 | 
			
		||||
                n += N1
 | 
			
		||||
                pkt.FrameLen = append(pkt.FrameLen, uint16(N1))
 | 
			
		||||
            }
 | 
			
		||||
            lastFrameLen := len(packet) - hdr - paddingLen - n
 | 
			
		||||
            pkt.FrameLen = append(pkt.FrameLen, uint16(lastFrameLen))
 | 
			
		||||
            pkt.Frame = packet[hdr : hdr+n+lastFrameLen]
 | 
			
		||||
        }
 | 
			
		||||
    default:
 | 
			
		||||
        panic("Error C must <= 3")
 | 
			
		||||
    }
 | 
			
		||||
    OpusPacketDuration(packet)
 | 
			
		||||
    return pkt
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	LEFT_CHANNEL  = 0
 | 
			
		||||
	RIGHT_CHANNEL = 1
 | 
			
		||||
    LEFT_CHANNEL  = 0
 | 
			
		||||
    RIGHT_CHANNEL = 1
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	vorbisChanLayoutOffset [8][8]byte = [8][8]byte{
 | 
			
		||||
		{0},
 | 
			
		||||
		{0, 1},
 | 
			
		||||
		{0, 2, 1},
 | 
			
		||||
		{0, 1, 2, 3},
 | 
			
		||||
		{0, 2, 1, 3, 4},
 | 
			
		||||
		{0, 2, 1, 5, 3, 4},
 | 
			
		||||
		{0, 2, 1, 6, 5, 3, 4},
 | 
			
		||||
		{0, 2, 1, 7, 5, 6, 3, 4},
 | 
			
		||||
	}
 | 
			
		||||
    vorbisChanLayoutOffset [8][8]byte = [8][8]byte{
 | 
			
		||||
        {0},
 | 
			
		||||
        {0, 1},
 | 
			
		||||
        {0, 2, 1},
 | 
			
		||||
        {0, 1, 2, 3},
 | 
			
		||||
        {0, 2, 1, 3, 4},
 | 
			
		||||
        {0, 2, 1, 5, 3, 4},
 | 
			
		||||
        {0, 2, 1, 6, 5, 3, 4},
 | 
			
		||||
        {0, 2, 1, 7, 5, 6, 3, 4},
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type ChannelOrder func(channels int, idx int) int
 | 
			
		||||
 | 
			
		||||
func defalutOrder(channels int, idx int) int {
 | 
			
		||||
	return idx
 | 
			
		||||
    return idx
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func vorbisOrder(channels int, idx int) int {
 | 
			
		||||
	return int(vorbisChanLayoutOffset[channels-1][idx])
 | 
			
		||||
    return int(vorbisChanLayoutOffset[channels-1][idx])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ChannelMap struct {
 | 
			
		||||
	StreamIdx  int
 | 
			
		||||
	ChannelIdx int
 | 
			
		||||
	Silence    bool
 | 
			
		||||
	Copy       bool
 | 
			
		||||
	CopyFrom   int
 | 
			
		||||
    StreamIdx  int
 | 
			
		||||
    ChannelIdx int
 | 
			
		||||
    Silence    bool
 | 
			
		||||
    Copy       bool
 | 
			
		||||
    CopyFrom   int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type OpusContext struct {
 | 
			
		||||
	Preskip           int
 | 
			
		||||
	SampleRate        int
 | 
			
		||||
	ChannelCount      int
 | 
			
		||||
	StreamCount       int
 | 
			
		||||
	StereoStreamCount int
 | 
			
		||||
	OutputGain        uint16
 | 
			
		||||
	MapType           uint8
 | 
			
		||||
	ChannelMaps       []ChannelMap
 | 
			
		||||
    Preskip           int
 | 
			
		||||
    SampleRate        int
 | 
			
		||||
    ChannelCount      int
 | 
			
		||||
    StreamCount       int
 | 
			
		||||
    StereoStreamCount int
 | 
			
		||||
    OutputGain        uint16
 | 
			
		||||
    MapType           uint8
 | 
			
		||||
    ChannelMaps       []ChannelMap
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// opus ID Head
 | 
			
		||||
| 
						 | 
				
			
			@ -348,83 +348,83 @@ type OpusContext struct {
 | 
			
		|||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
			
		||||
//
 | 
			
		||||
func (ctx *OpusContext) ParseExtranData(extraData []byte) error {
 | 
			
		||||
	if string(extraData[0:8]) != "OpusHead" {
 | 
			
		||||
		return errors.New("magic signature must equal OpusHead")
 | 
			
		||||
	}
 | 
			
		||||
    if string(extraData[0:8]) != "OpusHead" {
 | 
			
		||||
        return errors.New("magic signature must equal OpusHead")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	_ = extraData[8] // version
 | 
			
		||||
	ctx.ChannelCount = int(extraData[9])
 | 
			
		||||
	ctx.Preskip = int(binary.LittleEndian.Uint16(extraData[10:]))
 | 
			
		||||
	ctx.SampleRate = int(binary.LittleEndian.Uint32(extraData[12:]))
 | 
			
		||||
	ctx.OutputGain = binary.LittleEndian.Uint16(extraData[16:])
 | 
			
		||||
	ctx.MapType = extraData[18]
 | 
			
		||||
	var channel []byte
 | 
			
		||||
	var order ChannelOrder
 | 
			
		||||
	if ctx.MapType == 0 {
 | 
			
		||||
		ctx.StreamCount = 1
 | 
			
		||||
		ctx.StereoStreamCount = ctx.ChannelCount - 1
 | 
			
		||||
		channel = []byte{0, 1}
 | 
			
		||||
		order = defalutOrder
 | 
			
		||||
	} else if ctx.MapType == 1 || ctx.MapType == 2 || ctx.MapType == 255 {
 | 
			
		||||
		ctx.StreamCount = int(extraData[19])
 | 
			
		||||
		ctx.StereoStreamCount = int(extraData[20])
 | 
			
		||||
		if ctx.MapType == 1 {
 | 
			
		||||
			channel = extraData[21 : 21+ctx.ChannelCount]
 | 
			
		||||
			order = vorbisOrder
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		return errors.New("unsupport map type 255")
 | 
			
		||||
	}
 | 
			
		||||
    _ = extraData[8] // version
 | 
			
		||||
    ctx.ChannelCount = int(extraData[9])
 | 
			
		||||
    ctx.Preskip = int(binary.LittleEndian.Uint16(extraData[10:]))
 | 
			
		||||
    ctx.SampleRate = int(binary.LittleEndian.Uint32(extraData[12:]))
 | 
			
		||||
    ctx.OutputGain = binary.LittleEndian.Uint16(extraData[16:])
 | 
			
		||||
    ctx.MapType = extraData[18]
 | 
			
		||||
    var channel []byte
 | 
			
		||||
    var order ChannelOrder
 | 
			
		||||
    if ctx.MapType == 0 {
 | 
			
		||||
        ctx.StreamCount = 1
 | 
			
		||||
        ctx.StereoStreamCount = ctx.ChannelCount - 1
 | 
			
		||||
        channel = []byte{0, 1}
 | 
			
		||||
        order = defalutOrder
 | 
			
		||||
    } else if ctx.MapType == 1 || ctx.MapType == 2 || ctx.MapType == 255 {
 | 
			
		||||
        ctx.StreamCount = int(extraData[19])
 | 
			
		||||
        ctx.StereoStreamCount = int(extraData[20])
 | 
			
		||||
        if ctx.MapType == 1 {
 | 
			
		||||
            channel = extraData[21 : 21+ctx.ChannelCount]
 | 
			
		||||
            order = vorbisOrder
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        return errors.New("unsupport map type 255")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < ctx.ChannelCount; i++ {
 | 
			
		||||
		cm := ChannelMap{}
 | 
			
		||||
		index := channel[order(ctx.ChannelCount, i)]
 | 
			
		||||
		if index == 255 {
 | 
			
		||||
			cm.Silence = true
 | 
			
		||||
			continue
 | 
			
		||||
		} else if index > byte(ctx.StereoStreamCount)+byte(ctx.StreamCount) {
 | 
			
		||||
			return errors.New("index must < (streamcount + stereo streamcount)")
 | 
			
		||||
		}
 | 
			
		||||
    for i := 0; i < ctx.ChannelCount; i++ {
 | 
			
		||||
        cm := ChannelMap{}
 | 
			
		||||
        index := channel[order(ctx.ChannelCount, i)]
 | 
			
		||||
        if index == 255 {
 | 
			
		||||
            cm.Silence = true
 | 
			
		||||
            continue
 | 
			
		||||
        } else if index > byte(ctx.StereoStreamCount)+byte(ctx.StreamCount) {
 | 
			
		||||
            return errors.New("index must < (streamcount + stereo streamcount)")
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		for j := 0; j < i; j++ {
 | 
			
		||||
			if channel[order(ctx.ChannelCount, i)] == index {
 | 
			
		||||
				cm.Copy = true
 | 
			
		||||
				cm.CopyFrom = j
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
        for j := 0; j < i; j++ {
 | 
			
		||||
            if channel[order(ctx.ChannelCount, i)] == index {
 | 
			
		||||
                cm.Copy = true
 | 
			
		||||
                cm.CopyFrom = j
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		if int(index) < 2*ctx.StereoStreamCount {
 | 
			
		||||
			cm.StreamIdx = int(index) / 2
 | 
			
		||||
			if index&1 == 0 {
 | 
			
		||||
				cm.ChannelIdx = LEFT_CHANNEL
 | 
			
		||||
			} else {
 | 
			
		||||
				cm.ChannelIdx = RIGHT_CHANNEL
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			cm.StreamIdx = int(index) - ctx.StereoStreamCount
 | 
			
		||||
			cm.ChannelIdx = 0
 | 
			
		||||
		}
 | 
			
		||||
		ctx.ChannelMaps = append(ctx.ChannelMaps, cm)
 | 
			
		||||
	}
 | 
			
		||||
        if int(index) < 2*ctx.StereoStreamCount {
 | 
			
		||||
            cm.StreamIdx = int(index) / 2
 | 
			
		||||
            if index&1 == 0 {
 | 
			
		||||
                cm.ChannelIdx = LEFT_CHANNEL
 | 
			
		||||
            } else {
 | 
			
		||||
                cm.ChannelIdx = RIGHT_CHANNEL
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            cm.StreamIdx = int(index) - ctx.StereoStreamCount
 | 
			
		||||
            cm.ChannelIdx = 0
 | 
			
		||||
        }
 | 
			
		||||
        ctx.ChannelMaps = append(ctx.ChannelMaps, cm)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
    return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ctx *OpusContext) WriteOpusExtraData() []byte {
 | 
			
		||||
	extraData := make([]byte, 19)
 | 
			
		||||
	copy(extraData, string("OpusHead"))
 | 
			
		||||
	extraData[8] = 0x01
 | 
			
		||||
	extraData[9] = byte(ctx.ChannelCount)
 | 
			
		||||
	binary.LittleEndian.PutUint16(extraData[10:], uint16(ctx.Preskip))
 | 
			
		||||
	binary.LittleEndian.PutUint32(extraData[12:], uint32(ctx.SampleRate))
 | 
			
		||||
	return extraData
 | 
			
		||||
    extraData := make([]byte, 19)
 | 
			
		||||
    copy(extraData, string("OpusHead"))
 | 
			
		||||
    extraData[8] = 0x01
 | 
			
		||||
    extraData[9] = byte(ctx.ChannelCount)
 | 
			
		||||
    binary.LittleEndian.PutUint16(extraData[10:], uint16(ctx.Preskip))
 | 
			
		||||
    binary.LittleEndian.PutUint32(extraData[12:], uint32(ctx.SampleRate))
 | 
			
		||||
    return extraData
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func WriteDefaultOpusExtraData() []byte {
 | 
			
		||||
	return []byte{
 | 
			
		||||
		'O', 'p', 'u', 's', 'H', 'e', 'a', 'd',
 | 
			
		||||
		1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 | 
			
		||||
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 | 
			
		||||
	}
 | 
			
		||||
    return []byte{
 | 
			
		||||
        'O', 'p', 'u', 's', 'H', 'e', 'a', 'd',
 | 
			
		||||
        1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 | 
			
		||||
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										370
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/util.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										370
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/util.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -5,253 +5,253 @@ import "fmt"
 | 
			
		|||
type START_CODE_TYPE int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	START_CODE_3 START_CODE_TYPE = 3
 | 
			
		||||
	START_CODE_4                 = 4
 | 
			
		||||
    START_CODE_3 START_CODE_TYPE = 3
 | 
			
		||||
    START_CODE_4                 = 4
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func FindStartCode(nalu []byte, offset int) (int, START_CODE_TYPE) {
 | 
			
		||||
	for i := offset; i < len(nalu)-4; i++ {
 | 
			
		||||
		if nalu[i] == 0x00 && nalu[i+1] == 0x00 {
 | 
			
		||||
			if nalu[i+2] == 0x01 {
 | 
			
		||||
				return i, START_CODE_3
 | 
			
		||||
			} else if nalu[i+2] == 0x00 && nalu[i+3] == 0x01 {
 | 
			
		||||
				return i, START_CODE_4
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return -1, START_CODE_3
 | 
			
		||||
    for i := offset; i < len(nalu)-4; i++ {
 | 
			
		||||
        if nalu[i] == 0x00 && nalu[i+1] == 0x00 {
 | 
			
		||||
            if nalu[i+2] == 0x01 {
 | 
			
		||||
                return i, START_CODE_3
 | 
			
		||||
            } else if nalu[i+2] == 0x00 && nalu[i+3] == 0x01 {
 | 
			
		||||
                return i, START_CODE_4
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return -1, START_CODE_3
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func FindSyncword(aac []byte, offset int) int {
 | 
			
		||||
	for i := offset; i < len(aac); i++ {
 | 
			
		||||
		if aac[i] == 0xFF && aac[i+1]&0xF0 == 0xF0 {
 | 
			
		||||
			return i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return -1
 | 
			
		||||
    for i := offset; i < len(aac); i++ {
 | 
			
		||||
        if aac[i] == 0xFF && aac[i+1]&0xF0 == 0xF0 {
 | 
			
		||||
            return i
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SplitFrame(frames []byte, onFrame func(nalu []byte) bool) {
 | 
			
		||||
	beg, sc := FindStartCode(frames, 0)
 | 
			
		||||
	for beg >= 0 {
 | 
			
		||||
		end, sc2 := FindStartCode(frames, beg+int(sc))
 | 
			
		||||
		if end == -1 {
 | 
			
		||||
			if onFrame != nil {
 | 
			
		||||
				onFrame(frames[beg+int(sc):])
 | 
			
		||||
			}
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if onFrame != nil && onFrame(frames[beg+int(sc):end]) == false {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		beg = end
 | 
			
		||||
		sc = sc2
 | 
			
		||||
	}
 | 
			
		||||
    beg, sc := FindStartCode(frames, 0)
 | 
			
		||||
    for beg >= 0 {
 | 
			
		||||
        end, sc2 := FindStartCode(frames, beg+int(sc))
 | 
			
		||||
        if end == -1 {
 | 
			
		||||
            if onFrame != nil {
 | 
			
		||||
                onFrame(frames[beg+int(sc):])
 | 
			
		||||
            }
 | 
			
		||||
            break
 | 
			
		||||
        }
 | 
			
		||||
        if onFrame != nil && onFrame(frames[beg+int(sc):end]) == false {
 | 
			
		||||
            break
 | 
			
		||||
        }
 | 
			
		||||
        beg = end
 | 
			
		||||
        sc = sc2
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SplitFrameWithStartCode(frames []byte, onFrame func(nalu []byte) bool) {
 | 
			
		||||
	beg, sc := FindStartCode(frames, 0)
 | 
			
		||||
	for beg >= 0 {
 | 
			
		||||
		end, sc2 := FindStartCode(frames, beg+int(sc))
 | 
			
		||||
		if end == -1 {
 | 
			
		||||
			if onFrame != nil {
 | 
			
		||||
				onFrame(frames[beg:])
 | 
			
		||||
			}
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if onFrame != nil && onFrame(frames[beg:end]) == false {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		beg = end
 | 
			
		||||
		sc = sc2
 | 
			
		||||
	}
 | 
			
		||||
    beg, sc := FindStartCode(frames, 0)
 | 
			
		||||
    for beg >= 0 {
 | 
			
		||||
        end, sc2 := FindStartCode(frames, beg+int(sc))
 | 
			
		||||
        if end == -1 {
 | 
			
		||||
            if onFrame != nil {
 | 
			
		||||
                onFrame(frames[beg:])
 | 
			
		||||
            }
 | 
			
		||||
            break
 | 
			
		||||
        }
 | 
			
		||||
        if onFrame != nil && onFrame(frames[beg:end]) == false {
 | 
			
		||||
            break
 | 
			
		||||
        }
 | 
			
		||||
        beg = end
 | 
			
		||||
        sc = sc2
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SplitAACFrame(frames []byte, onFrame func(aac []byte)) {
 | 
			
		||||
	var adts ADTS_Frame_Header
 | 
			
		||||
	start := FindSyncword(frames, 0)
 | 
			
		||||
	for start >= 0 {
 | 
			
		||||
		adts.Decode(frames[start:])
 | 
			
		||||
		onFrame(frames[start : start+int(adts.Variable_Header.Frame_length)])
 | 
			
		||||
		start = FindSyncword(frames, start+int(adts.Variable_Header.Frame_length))
 | 
			
		||||
	}
 | 
			
		||||
    var adts ADTS_Frame_Header
 | 
			
		||||
    start := FindSyncword(frames, 0)
 | 
			
		||||
    for start >= 0 {
 | 
			
		||||
        adts.Decode(frames[start:])
 | 
			
		||||
        onFrame(frames[start : start+int(adts.Variable_Header.Frame_length)])
 | 
			
		||||
        start = FindSyncword(frames, start+int(adts.Variable_Header.Frame_length))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func H264NaluType(h264 []byte) H264_NAL_TYPE {
 | 
			
		||||
	loc, sc := FindStartCode(h264, 0)
 | 
			
		||||
	return H264_NAL_TYPE(h264[loc+int(sc)] & 0x1F)
 | 
			
		||||
    loc, sc := FindStartCode(h264, 0)
 | 
			
		||||
    return H264_NAL_TYPE(h264[loc+int(sc)] & 0x1F)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func H264NaluTypeWithoutStartCode(h264 []byte) H264_NAL_TYPE {
 | 
			
		||||
	return H264_NAL_TYPE(h264[0] & 0x1F)
 | 
			
		||||
    return H264_NAL_TYPE(h264[0] & 0x1F)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func H265NaluType(h265 []byte) H265_NAL_TYPE {
 | 
			
		||||
	loc, sc := FindStartCode(h265, 0)
 | 
			
		||||
	return H265_NAL_TYPE((h265[loc+int(sc)] >> 1) & 0x3F)
 | 
			
		||||
    loc, sc := FindStartCode(h265, 0)
 | 
			
		||||
    return H265_NAL_TYPE((h265[loc+int(sc)] >> 1) & 0x3F)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func H265NaluTypeWithoutStartCode(h265 []byte) H265_NAL_TYPE {
 | 
			
		||||
	return H265_NAL_TYPE((h265[0] >> 1) & 0x3F)
 | 
			
		||||
    return H265_NAL_TYPE((h265[0] >> 1) & 0x3F)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetH264FirstMbInSlice(nalu []byte) uint64 {
 | 
			
		||||
	start, sc := FindStartCode(nalu, 0)
 | 
			
		||||
	bs := NewBitStream(nalu[start+int(sc)+1:])
 | 
			
		||||
	sliceHdr := &SliceHeader{}
 | 
			
		||||
	sliceHdr.Decode(bs)
 | 
			
		||||
	return sliceHdr.First_mb_in_slice
 | 
			
		||||
    start, sc := FindStartCode(nalu, 0)
 | 
			
		||||
    bs := NewBitStream(nalu[start+int(sc)+1:])
 | 
			
		||||
    sliceHdr := &SliceHeader{}
 | 
			
		||||
    sliceHdr.Decode(bs)
 | 
			
		||||
    return sliceHdr.First_mb_in_slice
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetH265FirstMbInSlice(nalu []byte) uint64 {
 | 
			
		||||
	start, sc := FindStartCode(nalu, 0)
 | 
			
		||||
	bs := NewBitStream(nalu[start+int(sc)+2:])
 | 
			
		||||
	sliceHdr := &SliceHeader{}
 | 
			
		||||
	sliceHdr.Decode(bs)
 | 
			
		||||
	return sliceHdr.First_mb_in_slice
 | 
			
		||||
    start, sc := FindStartCode(nalu, 0)
 | 
			
		||||
    bs := NewBitStream(nalu[start+int(sc)+2:])
 | 
			
		||||
    sliceHdr := &SliceHeader{}
 | 
			
		||||
    sliceHdr.Decode(bs)
 | 
			
		||||
    return sliceHdr.First_mb_in_slice
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IsH264IDRFrame(h264 []byte) bool {
 | 
			
		||||
 | 
			
		||||
	ret := false
 | 
			
		||||
	onnalu := func(nalu []byte) bool {
 | 
			
		||||
		nal_type := H264NaluTypeWithoutStartCode(nalu)
 | 
			
		||||
		if nal_type < 5 {
 | 
			
		||||
			return false
 | 
			
		||||
		} else if nal_type == 5 {
 | 
			
		||||
			ret = true
 | 
			
		||||
			return false
 | 
			
		||||
		} else {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	SplitFrame(h264, onnalu)
 | 
			
		||||
	return ret
 | 
			
		||||
    ret := false
 | 
			
		||||
    onnalu := func(nalu []byte) bool {
 | 
			
		||||
        nal_type := H264NaluTypeWithoutStartCode(nalu)
 | 
			
		||||
        if nal_type < 5 {
 | 
			
		||||
            return false
 | 
			
		||||
        } else if nal_type == 5 {
 | 
			
		||||
            ret = true
 | 
			
		||||
            return false
 | 
			
		||||
        } else {
 | 
			
		||||
            return true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    SplitFrame(h264, onnalu)
 | 
			
		||||
    return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IsH264VCLNaluType(nal_type H264_NAL_TYPE) bool {
 | 
			
		||||
	if nal_type <= H264_NAL_I_SLICE && nal_type > H264_NAL_RESERVED {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
    if nal_type <= H264_NAL_I_SLICE && nal_type > H264_NAL_RESERVED {
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
    return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IsH265VCLNaluType(nal_type H265_NAL_TYPE) bool {
 | 
			
		||||
	if (nal_type <= H265_NAL_SLICE_CRA && nal_type >= H265_NAL_SLICE_BLA_W_LP) ||
 | 
			
		||||
		(nal_type <= H265_NAL_SLICE_RASL_R && nal_type >= H265_NAL_Slice_TRAIL_N) {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
    if (nal_type <= H265_NAL_SLICE_CRA && nal_type >= H265_NAL_SLICE_BLA_W_LP) ||
 | 
			
		||||
        (nal_type <= H265_NAL_SLICE_RASL_R && nal_type >= H265_NAL_Slice_TRAIL_N) {
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
    return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IsH265IDRFrame(h265 []byte) bool {
 | 
			
		||||
	ret := false
 | 
			
		||||
	onnalu := func(nalu []byte) bool {
 | 
			
		||||
		nal_type := H264NaluTypeWithoutStartCode(nalu)
 | 
			
		||||
		if nal_type <= 9 && nal_type >= 0 {
 | 
			
		||||
			return false
 | 
			
		||||
		} else if nal_type >= 16 && nal_type <= 21 {
 | 
			
		||||
			ret = true
 | 
			
		||||
			return false
 | 
			
		||||
		} else {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	SplitFrame(h265, onnalu)
 | 
			
		||||
	return ret
 | 
			
		||||
    ret := false
 | 
			
		||||
    onnalu := func(nalu []byte) bool {
 | 
			
		||||
        nal_type := H264NaluTypeWithoutStartCode(nalu)
 | 
			
		||||
        if nal_type <= 9 && nal_type >= 0 {
 | 
			
		||||
            return false
 | 
			
		||||
        } else if nal_type >= 16 && nal_type <= 21 {
 | 
			
		||||
            ret = true
 | 
			
		||||
            return false
 | 
			
		||||
        } else {
 | 
			
		||||
            return true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    SplitFrame(h265, onnalu)
 | 
			
		||||
    return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Max(x, y int) int {
 | 
			
		||||
	if x > y {
 | 
			
		||||
		return x
 | 
			
		||||
	} else {
 | 
			
		||||
		return y
 | 
			
		||||
	}
 | 
			
		||||
    if x > y {
 | 
			
		||||
        return x
 | 
			
		||||
    } else {
 | 
			
		||||
        return y
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Min(x, y int) int {
 | 
			
		||||
	if x > y {
 | 
			
		||||
		return y
 | 
			
		||||
	} else {
 | 
			
		||||
		return x
 | 
			
		||||
	}
 | 
			
		||||
    if x > y {
 | 
			
		||||
        return y
 | 
			
		||||
    } else {
 | 
			
		||||
        return x
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ShowPacketHexdump(data []byte) {
 | 
			
		||||
	for k := 0; k < len(data); k++ {
 | 
			
		||||
		if k%8 == 0 && k != 0 {
 | 
			
		||||
			fmt.Printf("\n")
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Printf("%02x ", data[k])
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Printf("\n")
 | 
			
		||||
    for k := 0; k < len(data); k++ {
 | 
			
		||||
        if k%8 == 0 && k != 0 {
 | 
			
		||||
            fmt.Printf("\n")
 | 
			
		||||
        }
 | 
			
		||||
        fmt.Printf("%02x ", data[k])
 | 
			
		||||
    }
 | 
			
		||||
    fmt.Printf("\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var crc32table [256]uint32 = [256]uint32{
 | 
			
		||||
	0x00000000, 0xB71DC104, 0x6E3B8209, 0xD926430D, 0xDC760413, 0x6B6BC517,
 | 
			
		||||
	0xB24D861A, 0x0550471E, 0xB8ED0826, 0x0FF0C922, 0xD6D68A2F, 0x61CB4B2B,
 | 
			
		||||
	0x649B0C35, 0xD386CD31, 0x0AA08E3C, 0xBDBD4F38, 0x70DB114C, 0xC7C6D048,
 | 
			
		||||
	0x1EE09345, 0xA9FD5241, 0xACAD155F, 0x1BB0D45B, 0xC2969756, 0x758B5652,
 | 
			
		||||
	0xC836196A, 0x7F2BD86E, 0xA60D9B63, 0x11105A67, 0x14401D79, 0xA35DDC7D,
 | 
			
		||||
	0x7A7B9F70, 0xCD665E74, 0xE0B62398, 0x57ABE29C, 0x8E8DA191, 0x39906095,
 | 
			
		||||
	0x3CC0278B, 0x8BDDE68F, 0x52FBA582, 0xE5E66486, 0x585B2BBE, 0xEF46EABA,
 | 
			
		||||
	0x3660A9B7, 0x817D68B3, 0x842D2FAD, 0x3330EEA9, 0xEA16ADA4, 0x5D0B6CA0,
 | 
			
		||||
	0x906D32D4, 0x2770F3D0, 0xFE56B0DD, 0x494B71D9, 0x4C1B36C7, 0xFB06F7C3,
 | 
			
		||||
	0x2220B4CE, 0x953D75CA, 0x28803AF2, 0x9F9DFBF6, 0x46BBB8FB, 0xF1A679FF,
 | 
			
		||||
	0xF4F63EE1, 0x43EBFFE5, 0x9ACDBCE8, 0x2DD07DEC, 0x77708634, 0xC06D4730,
 | 
			
		||||
	0x194B043D, 0xAE56C539, 0xAB068227, 0x1C1B4323, 0xC53D002E, 0x7220C12A,
 | 
			
		||||
	0xCF9D8E12, 0x78804F16, 0xA1A60C1B, 0x16BBCD1F, 0x13EB8A01, 0xA4F64B05,
 | 
			
		||||
	0x7DD00808, 0xCACDC90C, 0x07AB9778, 0xB0B6567C, 0x69901571, 0xDE8DD475,
 | 
			
		||||
	0xDBDD936B, 0x6CC0526F, 0xB5E61162, 0x02FBD066, 0xBF469F5E, 0x085B5E5A,
 | 
			
		||||
	0xD17D1D57, 0x6660DC53, 0x63309B4D, 0xD42D5A49, 0x0D0B1944, 0xBA16D840,
 | 
			
		||||
	0x97C6A5AC, 0x20DB64A8, 0xF9FD27A5, 0x4EE0E6A1, 0x4BB0A1BF, 0xFCAD60BB,
 | 
			
		||||
	0x258B23B6, 0x9296E2B2, 0x2F2BAD8A, 0x98366C8E, 0x41102F83, 0xF60DEE87,
 | 
			
		||||
	0xF35DA999, 0x4440689D, 0x9D662B90, 0x2A7BEA94, 0xE71DB4E0, 0x500075E4,
 | 
			
		||||
	0x892636E9, 0x3E3BF7ED, 0x3B6BB0F3, 0x8C7671F7, 0x555032FA, 0xE24DF3FE,
 | 
			
		||||
	0x5FF0BCC6, 0xE8ED7DC2, 0x31CB3ECF, 0x86D6FFCB, 0x8386B8D5, 0x349B79D1,
 | 
			
		||||
	0xEDBD3ADC, 0x5AA0FBD8, 0xEEE00C69, 0x59FDCD6D, 0x80DB8E60, 0x37C64F64,
 | 
			
		||||
	0x3296087A, 0x858BC97E, 0x5CAD8A73, 0xEBB04B77, 0x560D044F, 0xE110C54B,
 | 
			
		||||
	0x38368646, 0x8F2B4742, 0x8A7B005C, 0x3D66C158, 0xE4408255, 0x535D4351,
 | 
			
		||||
	0x9E3B1D25, 0x2926DC21, 0xF0009F2C, 0x471D5E28, 0x424D1936, 0xF550D832,
 | 
			
		||||
	0x2C769B3F, 0x9B6B5A3B, 0x26D61503, 0x91CBD407, 0x48ED970A, 0xFFF0560E,
 | 
			
		||||
	0xFAA01110, 0x4DBDD014, 0x949B9319, 0x2386521D, 0x0E562FF1, 0xB94BEEF5,
 | 
			
		||||
	0x606DADF8, 0xD7706CFC, 0xD2202BE2, 0x653DEAE6, 0xBC1BA9EB, 0x0B0668EF,
 | 
			
		||||
	0xB6BB27D7, 0x01A6E6D3, 0xD880A5DE, 0x6F9D64DA, 0x6ACD23C4, 0xDDD0E2C0,
 | 
			
		||||
	0x04F6A1CD, 0xB3EB60C9, 0x7E8D3EBD, 0xC990FFB9, 0x10B6BCB4, 0xA7AB7DB0,
 | 
			
		||||
	0xA2FB3AAE, 0x15E6FBAA, 0xCCC0B8A7, 0x7BDD79A3, 0xC660369B, 0x717DF79F,
 | 
			
		||||
	0xA85BB492, 0x1F467596, 0x1A163288, 0xAD0BF38C, 0x742DB081, 0xC3307185,
 | 
			
		||||
	0x99908A5D, 0x2E8D4B59, 0xF7AB0854, 0x40B6C950, 0x45E68E4E, 0xF2FB4F4A,
 | 
			
		||||
	0x2BDD0C47, 0x9CC0CD43, 0x217D827B, 0x9660437F, 0x4F460072, 0xF85BC176,
 | 
			
		||||
	0xFD0B8668, 0x4A16476C, 0x93300461, 0x242DC565, 0xE94B9B11, 0x5E565A15,
 | 
			
		||||
	0x87701918, 0x306DD81C, 0x353D9F02, 0x82205E06, 0x5B061D0B, 0xEC1BDC0F,
 | 
			
		||||
	0x51A69337, 0xE6BB5233, 0x3F9D113E, 0x8880D03A, 0x8DD09724, 0x3ACD5620,
 | 
			
		||||
	0xE3EB152D, 0x54F6D429, 0x7926A9C5, 0xCE3B68C1, 0x171D2BCC, 0xA000EAC8,
 | 
			
		||||
	0xA550ADD6, 0x124D6CD2, 0xCB6B2FDF, 0x7C76EEDB, 0xC1CBA1E3, 0x76D660E7,
 | 
			
		||||
	0xAFF023EA, 0x18EDE2EE, 0x1DBDA5F0, 0xAAA064F4, 0x738627F9, 0xC49BE6FD,
 | 
			
		||||
	0x09FDB889, 0xBEE0798D, 0x67C63A80, 0xD0DBFB84, 0xD58BBC9A, 0x62967D9E,
 | 
			
		||||
	0xBBB03E93, 0x0CADFF97, 0xB110B0AF, 0x060D71AB, 0xDF2B32A6, 0x6836F3A2,
 | 
			
		||||
	0x6D66B4BC, 0xDA7B75B8, 0x035D36B5, 0xB440F7B1,
 | 
			
		||||
    0x00000000, 0xB71DC104, 0x6E3B8209, 0xD926430D, 0xDC760413, 0x6B6BC517,
 | 
			
		||||
    0xB24D861A, 0x0550471E, 0xB8ED0826, 0x0FF0C922, 0xD6D68A2F, 0x61CB4B2B,
 | 
			
		||||
    0x649B0C35, 0xD386CD31, 0x0AA08E3C, 0xBDBD4F38, 0x70DB114C, 0xC7C6D048,
 | 
			
		||||
    0x1EE09345, 0xA9FD5241, 0xACAD155F, 0x1BB0D45B, 0xC2969756, 0x758B5652,
 | 
			
		||||
    0xC836196A, 0x7F2BD86E, 0xA60D9B63, 0x11105A67, 0x14401D79, 0xA35DDC7D,
 | 
			
		||||
    0x7A7B9F70, 0xCD665E74, 0xE0B62398, 0x57ABE29C, 0x8E8DA191, 0x39906095,
 | 
			
		||||
    0x3CC0278B, 0x8BDDE68F, 0x52FBA582, 0xE5E66486, 0x585B2BBE, 0xEF46EABA,
 | 
			
		||||
    0x3660A9B7, 0x817D68B3, 0x842D2FAD, 0x3330EEA9, 0xEA16ADA4, 0x5D0B6CA0,
 | 
			
		||||
    0x906D32D4, 0x2770F3D0, 0xFE56B0DD, 0x494B71D9, 0x4C1B36C7, 0xFB06F7C3,
 | 
			
		||||
    0x2220B4CE, 0x953D75CA, 0x28803AF2, 0x9F9DFBF6, 0x46BBB8FB, 0xF1A679FF,
 | 
			
		||||
    0xF4F63EE1, 0x43EBFFE5, 0x9ACDBCE8, 0x2DD07DEC, 0x77708634, 0xC06D4730,
 | 
			
		||||
    0x194B043D, 0xAE56C539, 0xAB068227, 0x1C1B4323, 0xC53D002E, 0x7220C12A,
 | 
			
		||||
    0xCF9D8E12, 0x78804F16, 0xA1A60C1B, 0x16BBCD1F, 0x13EB8A01, 0xA4F64B05,
 | 
			
		||||
    0x7DD00808, 0xCACDC90C, 0x07AB9778, 0xB0B6567C, 0x69901571, 0xDE8DD475,
 | 
			
		||||
    0xDBDD936B, 0x6CC0526F, 0xB5E61162, 0x02FBD066, 0xBF469F5E, 0x085B5E5A,
 | 
			
		||||
    0xD17D1D57, 0x6660DC53, 0x63309B4D, 0xD42D5A49, 0x0D0B1944, 0xBA16D840,
 | 
			
		||||
    0x97C6A5AC, 0x20DB64A8, 0xF9FD27A5, 0x4EE0E6A1, 0x4BB0A1BF, 0xFCAD60BB,
 | 
			
		||||
    0x258B23B6, 0x9296E2B2, 0x2F2BAD8A, 0x98366C8E, 0x41102F83, 0xF60DEE87,
 | 
			
		||||
    0xF35DA999, 0x4440689D, 0x9D662B90, 0x2A7BEA94, 0xE71DB4E0, 0x500075E4,
 | 
			
		||||
    0x892636E9, 0x3E3BF7ED, 0x3B6BB0F3, 0x8C7671F7, 0x555032FA, 0xE24DF3FE,
 | 
			
		||||
    0x5FF0BCC6, 0xE8ED7DC2, 0x31CB3ECF, 0x86D6FFCB, 0x8386B8D5, 0x349B79D1,
 | 
			
		||||
    0xEDBD3ADC, 0x5AA0FBD8, 0xEEE00C69, 0x59FDCD6D, 0x80DB8E60, 0x37C64F64,
 | 
			
		||||
    0x3296087A, 0x858BC97E, 0x5CAD8A73, 0xEBB04B77, 0x560D044F, 0xE110C54B,
 | 
			
		||||
    0x38368646, 0x8F2B4742, 0x8A7B005C, 0x3D66C158, 0xE4408255, 0x535D4351,
 | 
			
		||||
    0x9E3B1D25, 0x2926DC21, 0xF0009F2C, 0x471D5E28, 0x424D1936, 0xF550D832,
 | 
			
		||||
    0x2C769B3F, 0x9B6B5A3B, 0x26D61503, 0x91CBD407, 0x48ED970A, 0xFFF0560E,
 | 
			
		||||
    0xFAA01110, 0x4DBDD014, 0x949B9319, 0x2386521D, 0x0E562FF1, 0xB94BEEF5,
 | 
			
		||||
    0x606DADF8, 0xD7706CFC, 0xD2202BE2, 0x653DEAE6, 0xBC1BA9EB, 0x0B0668EF,
 | 
			
		||||
    0xB6BB27D7, 0x01A6E6D3, 0xD880A5DE, 0x6F9D64DA, 0x6ACD23C4, 0xDDD0E2C0,
 | 
			
		||||
    0x04F6A1CD, 0xB3EB60C9, 0x7E8D3EBD, 0xC990FFB9, 0x10B6BCB4, 0xA7AB7DB0,
 | 
			
		||||
    0xA2FB3AAE, 0x15E6FBAA, 0xCCC0B8A7, 0x7BDD79A3, 0xC660369B, 0x717DF79F,
 | 
			
		||||
    0xA85BB492, 0x1F467596, 0x1A163288, 0xAD0BF38C, 0x742DB081, 0xC3307185,
 | 
			
		||||
    0x99908A5D, 0x2E8D4B59, 0xF7AB0854, 0x40B6C950, 0x45E68E4E, 0xF2FB4F4A,
 | 
			
		||||
    0x2BDD0C47, 0x9CC0CD43, 0x217D827B, 0x9660437F, 0x4F460072, 0xF85BC176,
 | 
			
		||||
    0xFD0B8668, 0x4A16476C, 0x93300461, 0x242DC565, 0xE94B9B11, 0x5E565A15,
 | 
			
		||||
    0x87701918, 0x306DD81C, 0x353D9F02, 0x82205E06, 0x5B061D0B, 0xEC1BDC0F,
 | 
			
		||||
    0x51A69337, 0xE6BB5233, 0x3F9D113E, 0x8880D03A, 0x8DD09724, 0x3ACD5620,
 | 
			
		||||
    0xE3EB152D, 0x54F6D429, 0x7926A9C5, 0xCE3B68C1, 0x171D2BCC, 0xA000EAC8,
 | 
			
		||||
    0xA550ADD6, 0x124D6CD2, 0xCB6B2FDF, 0x7C76EEDB, 0xC1CBA1E3, 0x76D660E7,
 | 
			
		||||
    0xAFF023EA, 0x18EDE2EE, 0x1DBDA5F0, 0xAAA064F4, 0x738627F9, 0xC49BE6FD,
 | 
			
		||||
    0x09FDB889, 0xBEE0798D, 0x67C63A80, 0xD0DBFB84, 0xD58BBC9A, 0x62967D9E,
 | 
			
		||||
    0xBBB03E93, 0x0CADFF97, 0xB110B0AF, 0x060D71AB, 0xDF2B32A6, 0x6836F3A2,
 | 
			
		||||
    0x6D66B4BC, 0xDA7B75B8, 0x035D36B5, 0xB440F7B1,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CalcCrc32(crc uint32, buffer []byte) uint32 {
 | 
			
		||||
	var i int = 0
 | 
			
		||||
	for i = 0; i < len(buffer); i++ {
 | 
			
		||||
		crc = crc32table[(crc^uint32(buffer[i]))&0xff] ^ (crc >> 8)
 | 
			
		||||
	}
 | 
			
		||||
	return crc
 | 
			
		||||
    var i int = 0
 | 
			
		||||
    for i = 0; i < len(buffer); i++ {
 | 
			
		||||
        crc = crc32table[(crc^uint32(buffer[i]))&0xff] ^ (crc >> 8)
 | 
			
		||||
    }
 | 
			
		||||
    return crc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CovertRbspToSodb(rbsp []byte) []byte {
 | 
			
		||||
	bs := NewBitStream(rbsp)
 | 
			
		||||
	bsw := NewBitStreamWriter(len(rbsp))
 | 
			
		||||
	for !bs.EOS() {
 | 
			
		||||
		if bs.RemainBytes() > 3 && bs.NextBits(24) == 0x000003 {
 | 
			
		||||
			bsw.PutByte(bs.Uint8(8))
 | 
			
		||||
			bsw.PutByte(bs.Uint8(8))
 | 
			
		||||
			bs.SkipBits(8)
 | 
			
		||||
		} else {
 | 
			
		||||
			bsw.PutByte(bs.Uint8(8))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return bsw.Bits()
 | 
			
		||||
    bs := NewBitStream(rbsp)
 | 
			
		||||
    bsw := NewBitStreamWriter(len(rbsp))
 | 
			
		||||
    for !bs.EOS() {
 | 
			
		||||
        if bs.RemainBytes() > 3 && bs.NextBits(24) == 0x000003 {
 | 
			
		||||
            bsw.PutByte(bs.Uint8(8))
 | 
			
		||||
            bsw.PutByte(bs.Uint8(8))
 | 
			
		||||
            bs.SkipBits(8)
 | 
			
		||||
        } else {
 | 
			
		||||
            bsw.PutByte(bs.Uint8(8))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return bsw.Bits()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										94
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/vp8.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										94
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/yapingcat/gomedia/codec/vp8.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -3,70 +3,70 @@ package codec
 | 
			
		|||
import "errors"
 | 
			
		||||
 | 
			
		||||
type VP8FrameTag struct {
 | 
			
		||||
	FrameType     uint32 //0: I frame , 1: P frame
 | 
			
		||||
	Version       uint32
 | 
			
		||||
	Display       uint32
 | 
			
		||||
	FirstPartSize uint32
 | 
			
		||||
    FrameType     uint32 //0: I frame , 1: P frame
 | 
			
		||||
    Version       uint32
 | 
			
		||||
    Display       uint32
 | 
			
		||||
    FirstPartSize uint32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type VP8KeyFrameHead struct {
 | 
			
		||||
	Width      int
 | 
			
		||||
	Height     int
 | 
			
		||||
	HorizScale int
 | 
			
		||||
	VertScale  int
 | 
			
		||||
    Width      int
 | 
			
		||||
    Height     int
 | 
			
		||||
    HorizScale int
 | 
			
		||||
    VertScale  int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DecodeFrameTag(frame []byte) (*VP8FrameTag, error) {
 | 
			
		||||
	if len(frame) < 3 {
 | 
			
		||||
		return nil, errors.New("frame bytes < 3")
 | 
			
		||||
	}
 | 
			
		||||
	var tmp uint32 = (uint32(frame[2]) << 16) | (uint32(frame[1]) << 8) | uint32(frame[0])
 | 
			
		||||
	tag := &VP8FrameTag{}
 | 
			
		||||
	tag.FrameType = tmp & 0x01
 | 
			
		||||
	tag.Version = (tmp >> 1) & 0x07
 | 
			
		||||
	tag.Display = (tmp >> 4) & 0x01
 | 
			
		||||
	tag.FirstPartSize = (tmp >> 5) & 0x7FFFF
 | 
			
		||||
	return tag, nil
 | 
			
		||||
    if len(frame) < 3 {
 | 
			
		||||
        return nil, errors.New("frame bytes < 3")
 | 
			
		||||
    }
 | 
			
		||||
    var tmp uint32 = (uint32(frame[2]) << 16) | (uint32(frame[1]) << 8) | uint32(frame[0])
 | 
			
		||||
    tag := &VP8FrameTag{}
 | 
			
		||||
    tag.FrameType = tmp & 0x01
 | 
			
		||||
    tag.Version = (tmp >> 1) & 0x07
 | 
			
		||||
    tag.Display = (tmp >> 4) & 0x01
 | 
			
		||||
    tag.FirstPartSize = (tmp >> 5) & 0x7FFFF
 | 
			
		||||
    return tag, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DecodeKeyFrameHead(frame []byte) (*VP8KeyFrameHead, error) {
 | 
			
		||||
	if len(frame) < 7 {
 | 
			
		||||
		return nil, errors.New("frame bytes < 3")
 | 
			
		||||
	}
 | 
			
		||||
    if len(frame) < 7 {
 | 
			
		||||
        return nil, errors.New("frame bytes < 3")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	if frame[0] != 0x9d || frame[1] != 0x01 || frame[2] != 0x2a {
 | 
			
		||||
		return nil, errors.New("not find Start code")
 | 
			
		||||
	}
 | 
			
		||||
    if frame[0] != 0x9d || frame[1] != 0x01 || frame[2] != 0x2a {
 | 
			
		||||
        return nil, errors.New("not find Start code")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	head := &VP8KeyFrameHead{}
 | 
			
		||||
	head.Width = int(uint16(frame[4]&0x3f)<<8 | uint16(frame[3]))
 | 
			
		||||
	head.HorizScale = int(frame[4] >> 6)
 | 
			
		||||
	head.Height = int(uint16(frame[6]&0x3f)<<8 | uint16(frame[5]))
 | 
			
		||||
	head.VertScale = int(frame[6] >> 6)
 | 
			
		||||
	return head, nil
 | 
			
		||||
    head := &VP8KeyFrameHead{}
 | 
			
		||||
    head.Width = int(uint16(frame[4]&0x3f)<<8 | uint16(frame[3]))
 | 
			
		||||
    head.HorizScale = int(frame[4] >> 6)
 | 
			
		||||
    head.Height = int(uint16(frame[6]&0x3f)<<8 | uint16(frame[5]))
 | 
			
		||||
    head.VertScale = int(frame[6] >> 6)
 | 
			
		||||
    return head, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IsKeyFrame(frame []byte) bool {
 | 
			
		||||
	tag, err := DecodeFrameTag(frame)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
    tag, err := DecodeFrameTag(frame)
 | 
			
		||||
    if err != nil {
 | 
			
		||||
        return false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	if tag.FrameType == 0 {
 | 
			
		||||
		return true
 | 
			
		||||
	} else {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
    if tag.FrameType == 0 {
 | 
			
		||||
        return true
 | 
			
		||||
    } else {
 | 
			
		||||
        return false
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetResloution(frame []byte) (width int, height int, err error) {
 | 
			
		||||
	if !IsKeyFrame(frame) {
 | 
			
		||||
		return 0, 0, errors.New("the frame is not Key frame")
 | 
			
		||||
	}
 | 
			
		||||
    if !IsKeyFrame(frame) {
 | 
			
		||||
        return 0, 0, errors.New("the frame is not Key frame")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	head, err := DecodeKeyFrameHead(frame[3:])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return head.Width, head.Height, nil
 | 
			
		||||
    head, err := DecodeKeyFrameHead(frame[3:])
 | 
			
		||||
    if err != nil {
 | 
			
		||||
        return 0, 0, err
 | 
			
		||||
    }
 | 
			
		||||
    return head.Width, head.Height, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue