mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
HLS: Ignore empty NALU to avoid error. v6.0.65 (#3750)
For the DJI M30, there is a bug where empty NALU packets with a size of zero are causing issues with HLS streaming. This bug leads to random unpublish events due to the SRS disconnecting the connection for the HLS module when it fails to handle empty NALU packets. To address this bug, we have patched the system to ignore any empty NALU packets with a size of zero. Additionally, we have created a tool in the srs-bench to replay pcapng files captured by tcpdump or Wireshark. We have also added utest using mprotect and asan to detect any memory corruption. It is important to note that this bug has been fixed in versions 4.0.2716477f31004
and 5.0.170939f6b484b
. This patch specifically addresses the issue in SRS 6.0. Please be aware that there is another commit related to this bug that partially fixes the issue but still leaves a small problem for asan to detect memory corruption. This commit,577cd299e1
, only ignores empty NALU packets but still reads beyond the memory. --------- Co-authored-by: chundonglinlin <chundonglinlin@163.com>
This commit is contained in:
parent
e19efe0bcd
commit
73dd8af4c9
182 changed files with 46111 additions and 3914 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