mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	For regression test, add srs-bench to 3rdparty
This commit is contained in:
		
							parent
							
								
									de87dd427d
								
							
						
					
					
						commit
						876210f6c9
					
				
					 1158 changed files with 256967 additions and 3 deletions
				
			
		
							
								
								
									
										2
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/codecs.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/codecs.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
// Package codecs implements codec specific RTP payloader/depayloaders
 | 
			
		||||
package codecs
 | 
			
		||||
							
								
								
									
										8
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/common.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/common.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
package codecs
 | 
			
		||||
 | 
			
		||||
func min(a, b int) int {
 | 
			
		||||
	if a < b {
 | 
			
		||||
		return a
 | 
			
		||||
	}
 | 
			
		||||
	return b
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/error.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/error.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
package codecs
 | 
			
		||||
 | 
			
		||||
import "errors"
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errShortPacket          = errors.New("packet is not large enough")
 | 
			
		||||
	errNilPacket            = errors.New("invalid nil packet")
 | 
			
		||||
	errTooManyPDiff         = errors.New("too many PDiff")
 | 
			
		||||
	errTooManySpatialLayers = errors.New("too many spatial layers")
 | 
			
		||||
	errUnhandledNALUType    = errors.New("NALU Type is unhandled")
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										22
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/g711_packet.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/g711_packet.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
package codecs
 | 
			
		||||
 | 
			
		||||
// G711Payloader payloads G711 packets
 | 
			
		||||
type G711Payloader struct{}
 | 
			
		||||
 | 
			
		||||
// Payload fragments an G711 packet across one or more byte arrays
 | 
			
		||||
func (p *G711Payloader) Payload(mtu int, payload []byte) [][]byte {
 | 
			
		||||
	var out [][]byte
 | 
			
		||||
	if payload == nil || mtu <= 0 {
 | 
			
		||||
		return out
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for len(payload) > mtu {
 | 
			
		||||
		o := make([]byte, mtu)
 | 
			
		||||
		copy(o, payload[:mtu])
 | 
			
		||||
		payload = payload[mtu:]
 | 
			
		||||
		out = append(out, o)
 | 
			
		||||
	}
 | 
			
		||||
	o := make([]byte, len(payload))
 | 
			
		||||
	copy(o, payload)
 | 
			
		||||
	return append(out, o)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/g722_packet.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/g722_packet.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
package codecs
 | 
			
		||||
 | 
			
		||||
// G722Payloader payloads G722 packets
 | 
			
		||||
type G722Payloader struct{}
 | 
			
		||||
 | 
			
		||||
// Payload fragments an G722 packet across one or more byte arrays
 | 
			
		||||
func (p *G722Payloader) Payload(mtu int, payload []byte) [][]byte {
 | 
			
		||||
	var out [][]byte
 | 
			
		||||
	if payload == nil || mtu <= 0 {
 | 
			
		||||
		return out
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for len(payload) > mtu {
 | 
			
		||||
		o := make([]byte, mtu)
 | 
			
		||||
		copy(o, payload[:mtu])
 | 
			
		||||
		payload = payload[mtu:]
 | 
			
		||||
		out = append(out, o)
 | 
			
		||||
	}
 | 
			
		||||
	o := make([]byte, len(payload))
 | 
			
		||||
	copy(o, payload)
 | 
			
		||||
	return append(out, o)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										205
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/h264_packet.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/h264_packet.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,205 @@
 | 
			
		|||
package codecs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// H264Payloader payloads H264 packets
 | 
			
		||||
type H264Payloader struct{}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	stapaNALUType = 24
 | 
			
		||||
	fuaNALUType   = 28
 | 
			
		||||
 | 
			
		||||
	fuaHeaderSize       = 2
 | 
			
		||||
	stapaHeaderSize     = 1
 | 
			
		||||
	stapaNALULengthSize = 2
 | 
			
		||||
 | 
			
		||||
	naluTypeBitmask   = 0x1F
 | 
			
		||||
	naluRefIdcBitmask = 0x60
 | 
			
		||||
	fuaStartBitmask   = 0x80
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func annexbNALUStartCode() []byte { return []byte{0x00, 0x00, 0x00, 0x01} }
 | 
			
		||||
 | 
			
		||||
func emitNalus(nals []byte, emit func([]byte)) {
 | 
			
		||||
	nextInd := func(nalu []byte, start int) (indStart int, indLen int) {
 | 
			
		||||
		zeroCount := 0
 | 
			
		||||
 | 
			
		||||
		for i, b := range nalu[start:] {
 | 
			
		||||
			if b == 0 {
 | 
			
		||||
				zeroCount++
 | 
			
		||||
				continue
 | 
			
		||||
			} else if b == 1 {
 | 
			
		||||
				if zeroCount >= 2 {
 | 
			
		||||
					return start + i - zeroCount, zeroCount + 1
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			zeroCount = 0
 | 
			
		||||
		}
 | 
			
		||||
		return -1, -1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	nextIndStart, nextIndLen := nextInd(nals, 0)
 | 
			
		||||
	if nextIndStart == -1 {
 | 
			
		||||
		emit(nals)
 | 
			
		||||
	} else {
 | 
			
		||||
		for nextIndStart != -1 {
 | 
			
		||||
			prevStart := nextIndStart + nextIndLen
 | 
			
		||||
			nextIndStart, nextIndLen = nextInd(nals, prevStart)
 | 
			
		||||
			if nextIndStart != -1 {
 | 
			
		||||
				emit(nals[prevStart:nextIndStart])
 | 
			
		||||
			} else {
 | 
			
		||||
				// Emit until end of stream, no end indicator found
 | 
			
		||||
				emit(nals[prevStart:])
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Payload fragments a H264 packet across one or more byte arrays
 | 
			
		||||
func (p *H264Payloader) Payload(mtu int, payload []byte) [][]byte {
 | 
			
		||||
	var payloads [][]byte
 | 
			
		||||
	if len(payload) == 0 {
 | 
			
		||||
		return payloads
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	emitNalus(payload, func(nalu []byte) {
 | 
			
		||||
		if len(nalu) == 0 {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		naluType := nalu[0] & naluTypeBitmask
 | 
			
		||||
		naluRefIdc := nalu[0] & naluRefIdcBitmask
 | 
			
		||||
 | 
			
		||||
		if naluType == 9 || naluType == 12 {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Single NALU
 | 
			
		||||
		if len(nalu) <= mtu {
 | 
			
		||||
			out := make([]byte, len(nalu))
 | 
			
		||||
			copy(out, nalu)
 | 
			
		||||
			payloads = append(payloads, out)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// FU-A
 | 
			
		||||
		maxFragmentSize := mtu - fuaHeaderSize
 | 
			
		||||
 | 
			
		||||
		// The FU payload consists of fragments of the payload of the fragmented
 | 
			
		||||
		// NAL unit so that if the fragmentation unit payloads of consecutive
 | 
			
		||||
		// FUs are sequentially concatenated, the payload of the fragmented NAL
 | 
			
		||||
		// unit can be reconstructed.  The NAL unit type octet of the fragmented
 | 
			
		||||
		// NAL unit is not included as such in the fragmentation unit payload,
 | 
			
		||||
		// 	but rather the information of the NAL unit type octet of the
 | 
			
		||||
		// fragmented NAL unit is conveyed in the F and NRI fields of the FU
 | 
			
		||||
		// indicator octet of the fragmentation unit and in the type field of
 | 
			
		||||
		// the FU header.  An FU payload MAY have any number of octets and MAY
 | 
			
		||||
		// be empty.
 | 
			
		||||
 | 
			
		||||
		naluData := nalu
 | 
			
		||||
		// According to the RFC, the first octet is skipped due to redundant information
 | 
			
		||||
		naluDataIndex := 1
 | 
			
		||||
		naluDataLength := len(nalu) - naluDataIndex
 | 
			
		||||
		naluDataRemaining := naluDataLength
 | 
			
		||||
 | 
			
		||||
		if min(maxFragmentSize, naluDataRemaining) <= 0 {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for naluDataRemaining > 0 {
 | 
			
		||||
			currentFragmentSize := min(maxFragmentSize, naluDataRemaining)
 | 
			
		||||
			out := make([]byte, fuaHeaderSize+currentFragmentSize)
 | 
			
		||||
 | 
			
		||||
			// +---------------+
 | 
			
		||||
			// |0|1|2|3|4|5|6|7|
 | 
			
		||||
			// +-+-+-+-+-+-+-+-+
 | 
			
		||||
			// |F|NRI|  Type   |
 | 
			
		||||
			// +---------------+
 | 
			
		||||
			out[0] = fuaNALUType
 | 
			
		||||
			out[0] |= naluRefIdc
 | 
			
		||||
 | 
			
		||||
			// +---------------+
 | 
			
		||||
			// |0|1|2|3|4|5|6|7|
 | 
			
		||||
			// +-+-+-+-+-+-+-+-+
 | 
			
		||||
			// |S|E|R|  Type   |
 | 
			
		||||
			// +---------------+
 | 
			
		||||
 | 
			
		||||
			out[1] = naluType
 | 
			
		||||
			if naluDataRemaining == naluDataLength {
 | 
			
		||||
				// Set start bit
 | 
			
		||||
				out[1] |= 1 << 7
 | 
			
		||||
			} else if naluDataRemaining-currentFragmentSize == 0 {
 | 
			
		||||
				// Set end bit
 | 
			
		||||
				out[1] |= 1 << 6
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			copy(out[fuaHeaderSize:], naluData[naluDataIndex:naluDataIndex+currentFragmentSize])
 | 
			
		||||
			payloads = append(payloads, out)
 | 
			
		||||
 | 
			
		||||
			naluDataRemaining -= currentFragmentSize
 | 
			
		||||
			naluDataIndex += currentFragmentSize
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return payloads
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// H264Packet represents the H264 header that is stored in the payload of an RTP Packet
 | 
			
		||||
type H264Packet struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unmarshal parses the passed byte slice and stores the result in the H264Packet this method is called upon
 | 
			
		||||
func (p *H264Packet) Unmarshal(payload []byte) ([]byte, error) {
 | 
			
		||||
	if payload == nil {
 | 
			
		||||
		return nil, errNilPacket
 | 
			
		||||
	} else if len(payload) <= 2 {
 | 
			
		||||
		return nil, fmt.Errorf("%w: %d <= 2", errShortPacket, len(payload))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// NALU Types
 | 
			
		||||
	// https://tools.ietf.org/html/rfc6184#section-5.4
 | 
			
		||||
	naluType := payload[0] & naluTypeBitmask
 | 
			
		||||
	switch {
 | 
			
		||||
	case naluType > 0 && naluType < 24:
 | 
			
		||||
		return append(annexbNALUStartCode(), payload...), nil
 | 
			
		||||
 | 
			
		||||
	case naluType == stapaNALUType:
 | 
			
		||||
		currOffset := int(stapaHeaderSize)
 | 
			
		||||
		result := []byte{}
 | 
			
		||||
		for currOffset < len(payload) {
 | 
			
		||||
			naluSize := int(binary.BigEndian.Uint16(payload[currOffset:]))
 | 
			
		||||
			currOffset += stapaNALULengthSize
 | 
			
		||||
 | 
			
		||||
			if len(payload) < currOffset+naluSize {
 | 
			
		||||
				return nil, fmt.Errorf("%w STAP-A declared size(%d) is larger than buffer(%d)", errShortPacket, naluSize, len(payload)-currOffset)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			result = append(result, annexbNALUStartCode()...)
 | 
			
		||||
			result = append(result, payload[currOffset:currOffset+naluSize]...)
 | 
			
		||||
			currOffset += naluSize
 | 
			
		||||
		}
 | 
			
		||||
		return result, nil
 | 
			
		||||
 | 
			
		||||
	case naluType == fuaNALUType:
 | 
			
		||||
		if len(payload) < fuaHeaderSize {
 | 
			
		||||
			return nil, errShortPacket
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if payload[1]&fuaStartBitmask != 0 {
 | 
			
		||||
			naluRefIdc := payload[0] & naluRefIdcBitmask
 | 
			
		||||
			fragmentedNaluType := payload[1] & naluTypeBitmask
 | 
			
		||||
 | 
			
		||||
			// Take a copy of payload since we are mutating it.
 | 
			
		||||
			payloadCopy := append([]byte{}, payload...)
 | 
			
		||||
			payloadCopy[fuaHeaderSize-1] = naluRefIdc | fragmentedNaluType
 | 
			
		||||
			return append(annexbNALUStartCode(), payloadCopy[fuaHeaderSize-1:]...), nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return payload[fuaHeaderSize:], nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil, fmt.Errorf("%w: %d", errUnhandledNALUType, naluType)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/opus_packet.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/opus_packet.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
package codecs
 | 
			
		||||
 | 
			
		||||
// OpusPayloader payloads Opus packets
 | 
			
		||||
type OpusPayloader struct{}
 | 
			
		||||
 | 
			
		||||
// Payload fragments an Opus packet across one or more byte arrays
 | 
			
		||||
func (p *OpusPayloader) Payload(mtu int, payload []byte) [][]byte {
 | 
			
		||||
	if payload == nil {
 | 
			
		||||
		return [][]byte{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	out := make([]byte, len(payload))
 | 
			
		||||
	copy(out, payload)
 | 
			
		||||
	return [][]byte{out}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OpusPacket represents the Opus header that is stored in the payload of an RTP Packet
 | 
			
		||||
type OpusPacket struct {
 | 
			
		||||
	Payload []byte
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unmarshal parses the passed byte slice and stores the result in the OpusPacket this method is called upon
 | 
			
		||||
func (p *OpusPacket) Unmarshal(packet []byte) ([]byte, error) {
 | 
			
		||||
	if packet == nil {
 | 
			
		||||
		return nil, errNilPacket
 | 
			
		||||
	} else if len(packet) == 0 {
 | 
			
		||||
		return nil, errShortPacket
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.Payload = packet
 | 
			
		||||
	return packet, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OpusPartitionHeadChecker checks Opus partition head
 | 
			
		||||
type OpusPartitionHeadChecker struct{}
 | 
			
		||||
 | 
			
		||||
// IsPartitionHead checks whether if this is a head of the Opus partition
 | 
			
		||||
func (*OpusPartitionHeadChecker) IsPartitionHead(packet []byte) bool {
 | 
			
		||||
	p := &OpusPacket{}
 | 
			
		||||
	if _, err := p.Unmarshal(packet); err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										143
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/vp8_packet.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/vp8_packet.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,143 @@
 | 
			
		|||
package codecs
 | 
			
		||||
 | 
			
		||||
// VP8Payloader payloads VP8 packets
 | 
			
		||||
type VP8Payloader struct{}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	vp8HeaderSize = 1
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Payload fragments a VP8 packet across one or more byte arrays
 | 
			
		||||
func (p *VP8Payloader) Payload(mtu int, payload []byte) [][]byte {
 | 
			
		||||
	/*
 | 
			
		||||
	 * https://tools.ietf.org/html/rfc7741#section-4.2
 | 
			
		||||
	 *
 | 
			
		||||
	 *       0 1 2 3 4 5 6 7
 | 
			
		||||
	 *      +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *      |X|R|N|S|R| PID | (REQUIRED)
 | 
			
		||||
	 *      +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 * X:   |I|L|T|K| RSV   | (OPTIONAL)
 | 
			
		||||
	 *      +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 * I:   |M| PictureID   | (OPTIONAL)
 | 
			
		||||
	 *      +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 * L:   |   TL0PICIDX   | (OPTIONAL)
 | 
			
		||||
	 *      +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 * T/K: |TID|Y| KEYIDX  | (OPTIONAL)
 | 
			
		||||
	 *      +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *  S: Start of VP8 partition.  SHOULD be set to 1 when the first payload
 | 
			
		||||
	 *     octet of the RTP packet is the beginning of a new VP8 partition,
 | 
			
		||||
	 *     and MUST NOT be 1 otherwise.  The S bit MUST be set to 1 for the
 | 
			
		||||
	 *     first packet of each encoded frame.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	maxFragmentSize := mtu - vp8HeaderSize
 | 
			
		||||
 | 
			
		||||
	payloadData := payload
 | 
			
		||||
	payloadDataRemaining := len(payload)
 | 
			
		||||
 | 
			
		||||
	payloadDataIndex := 0
 | 
			
		||||
	var payloads [][]byte
 | 
			
		||||
 | 
			
		||||
	// Make sure the fragment/payload size is correct
 | 
			
		||||
	if min(maxFragmentSize, payloadDataRemaining) <= 0 {
 | 
			
		||||
		return payloads
 | 
			
		||||
	}
 | 
			
		||||
	for payloadDataRemaining > 0 {
 | 
			
		||||
		currentFragmentSize := min(maxFragmentSize, payloadDataRemaining)
 | 
			
		||||
		out := make([]byte, vp8HeaderSize+currentFragmentSize)
 | 
			
		||||
		if payloadDataRemaining == len(payload) {
 | 
			
		||||
			out[0] = 0x10
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		copy(out[vp8HeaderSize:], payloadData[payloadDataIndex:payloadDataIndex+currentFragmentSize])
 | 
			
		||||
		payloads = append(payloads, out)
 | 
			
		||||
 | 
			
		||||
		payloadDataRemaining -= currentFragmentSize
 | 
			
		||||
		payloadDataIndex += currentFragmentSize
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return payloads
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// VP8Packet represents the VP8 header that is stored in the payload of an RTP Packet
 | 
			
		||||
type VP8Packet struct {
 | 
			
		||||
	// Required Header
 | 
			
		||||
	X   uint8 /* extended controlbits present */
 | 
			
		||||
	N   uint8 /* (non-reference frame)  when set to 1 this frame can be discarded */
 | 
			
		||||
	S   uint8 /* start of VP8 partition */
 | 
			
		||||
	PID uint8 /* partition index */
 | 
			
		||||
 | 
			
		||||
	// Optional Header
 | 
			
		||||
	I         uint8  /* 1 if PictureID is present */
 | 
			
		||||
	L         uint8  /* 1 if TL0PICIDX is present */
 | 
			
		||||
	T         uint8  /* 1 if TID is present */
 | 
			
		||||
	K         uint8  /* 1 if KEYIDX is present */
 | 
			
		||||
	PictureID uint16 /* 8 or 16 bits, picture ID */
 | 
			
		||||
	TL0PICIDX uint8  /* 8 bits temporal level zero index */
 | 
			
		||||
 | 
			
		||||
	Payload []byte
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unmarshal parses the passed byte slice and stores the result in the VP8Packet this method is called upon
 | 
			
		||||
func (p *VP8Packet) Unmarshal(payload []byte) ([]byte, error) {
 | 
			
		||||
	if payload == nil {
 | 
			
		||||
		return nil, errNilPacket
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	payloadLen := len(payload)
 | 
			
		||||
 | 
			
		||||
	if payloadLen < 4 {
 | 
			
		||||
		return nil, errShortPacket
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	payloadIndex := 0
 | 
			
		||||
 | 
			
		||||
	p.X = (payload[payloadIndex] & 0x80) >> 7
 | 
			
		||||
	p.N = (payload[payloadIndex] & 0x20) >> 5
 | 
			
		||||
	p.S = (payload[payloadIndex] & 0x10) >> 4
 | 
			
		||||
	p.PID = payload[payloadIndex] & 0x07
 | 
			
		||||
 | 
			
		||||
	payloadIndex++
 | 
			
		||||
 | 
			
		||||
	if p.X == 1 {
 | 
			
		||||
		p.I = (payload[payloadIndex] & 0x80) >> 7
 | 
			
		||||
		p.L = (payload[payloadIndex] & 0x40) >> 6
 | 
			
		||||
		p.T = (payload[payloadIndex] & 0x20) >> 5
 | 
			
		||||
		p.K = (payload[payloadIndex] & 0x10) >> 4
 | 
			
		||||
		payloadIndex++
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if p.I == 1 { // PID present?
 | 
			
		||||
		if payload[payloadIndex]&0x80 > 0 { // M == 1, PID is 16bit
 | 
			
		||||
			payloadIndex += 2
 | 
			
		||||
		} else {
 | 
			
		||||
			payloadIndex++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if p.L == 1 {
 | 
			
		||||
		payloadIndex++
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if p.T == 1 || p.K == 1 {
 | 
			
		||||
		payloadIndex++
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if payloadIndex >= payloadLen {
 | 
			
		||||
		return nil, errShortPacket
 | 
			
		||||
	}
 | 
			
		||||
	p.Payload = payload[payloadIndex:]
 | 
			
		||||
	return p.Payload, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// VP8PartitionHeadChecker checks VP8 partition head
 | 
			
		||||
type VP8PartitionHeadChecker struct{}
 | 
			
		||||
 | 
			
		||||
// IsPartitionHead checks whether if this is a head of the VP8 partition
 | 
			
		||||
func (*VP8PartitionHeadChecker) IsPartitionHead(packet []byte) bool {
 | 
			
		||||
	p := &VP8Packet{}
 | 
			
		||||
	if _, err := p.Unmarshal(packet); err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return p.S == 1
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										385
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/vp9_packet.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										385
									
								
								trunk/3rdparty/srs-bench/vendor/github.com/pion/rtp/codecs/vp9_packet.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,385 @@
 | 
			
		|||
package codecs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/pion/randutil"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Use global random generator to properly seed by crypto grade random.
 | 
			
		||||
var globalMathRandomGenerator = randutil.NewMathRandomGenerator() // nolint:gochecknoglobals
 | 
			
		||||
 | 
			
		||||
// VP9Payloader payloads VP9 packets
 | 
			
		||||
type VP9Payloader struct {
 | 
			
		||||
	pictureID   uint16
 | 
			
		||||
	initialized bool
 | 
			
		||||
 | 
			
		||||
	// InitialPictureIDFn is a function that returns random initial picture ID.
 | 
			
		||||
	InitialPictureIDFn func() uint16
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	vp9HeaderSize    = 3 // Flexible mode 15 bit picture ID
 | 
			
		||||
	maxSpatialLayers = 5
 | 
			
		||||
	maxVP9RefPics    = 3
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Payload fragments an VP9 packet across one or more byte arrays
 | 
			
		||||
func (p *VP9Payloader) Payload(mtu int, payload []byte) [][]byte {
 | 
			
		||||
	/*
 | 
			
		||||
	 * https://www.ietf.org/id/draft-ietf-payload-vp9-10.txt
 | 
			
		||||
	 *
 | 
			
		||||
	 * Flexible mode (F=1)
 | 
			
		||||
	 *        0 1 2 3 4 5 6 7
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *       |I|P|L|F|B|E|V|-| (REQUIRED)
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *  I:   |M| PICTURE ID  | (REQUIRED)
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *  M:   | EXTENDED PID  | (RECOMMENDED)
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *  L:   | TID |U| SID |D| (CONDITIONALLY RECOMMENDED)
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+                             -\
 | 
			
		||||
	 *  P,F: | P_DIFF      |N| (CONDITIONALLY REQUIRED)    - up to 3 times
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+                             -/
 | 
			
		||||
	 *  V:   | SS            |
 | 
			
		||||
	 *       | ..            |
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *
 | 
			
		||||
	 * Non-flexible mode (F=0)
 | 
			
		||||
	 *        0 1 2 3 4 5 6 7
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *       |I|P|L|F|B|E|V|-| (REQUIRED)
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *  I:   |M| PICTURE ID  | (RECOMMENDED)
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *  M:   | EXTENDED PID  | (RECOMMENDED)
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *  L:   | TID |U| SID |D| (CONDITIONALLY RECOMMENDED)
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *       |   TL0PICIDX   | (CONDITIONALLY REQUIRED)
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 *  V:   | SS            |
 | 
			
		||||
	 *       | ..            |
 | 
			
		||||
	 *       +-+-+-+-+-+-+-+-+
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	if !p.initialized {
 | 
			
		||||
		if p.InitialPictureIDFn == nil {
 | 
			
		||||
			p.InitialPictureIDFn = func() uint16 {
 | 
			
		||||
				return uint16(globalMathRandomGenerator.Intn(0x7FFF))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		p.pictureID = p.InitialPictureIDFn() & 0x7FFF
 | 
			
		||||
		p.initialized = true
 | 
			
		||||
	}
 | 
			
		||||
	if payload == nil {
 | 
			
		||||
		return [][]byte{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	maxFragmentSize := mtu - vp9HeaderSize
 | 
			
		||||
	payloadDataRemaining := len(payload)
 | 
			
		||||
	payloadDataIndex := 0
 | 
			
		||||
 | 
			
		||||
	if min(maxFragmentSize, payloadDataRemaining) <= 0 {
 | 
			
		||||
		return [][]byte{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var payloads [][]byte
 | 
			
		||||
	for payloadDataRemaining > 0 {
 | 
			
		||||
		currentFragmentSize := min(maxFragmentSize, payloadDataRemaining)
 | 
			
		||||
		out := make([]byte, vp9HeaderSize+currentFragmentSize)
 | 
			
		||||
 | 
			
		||||
		out[0] = 0x90 // F=1 I=1
 | 
			
		||||
		if payloadDataIndex == 0 {
 | 
			
		||||
			out[0] |= 0x08 // B=1
 | 
			
		||||
		}
 | 
			
		||||
		if payloadDataRemaining == currentFragmentSize {
 | 
			
		||||
			out[0] |= 0x04 // E=1
 | 
			
		||||
		}
 | 
			
		||||
		out[1] = byte(p.pictureID>>8) | 0x80
 | 
			
		||||
		out[2] = byte(p.pictureID)
 | 
			
		||||
		copy(out[vp9HeaderSize:], payload[payloadDataIndex:payloadDataIndex+currentFragmentSize])
 | 
			
		||||
		payloads = append(payloads, out)
 | 
			
		||||
 | 
			
		||||
		payloadDataRemaining -= currentFragmentSize
 | 
			
		||||
		payloadDataIndex += currentFragmentSize
 | 
			
		||||
	}
 | 
			
		||||
	p.pictureID++
 | 
			
		||||
	if p.pictureID >= 0x8000 {
 | 
			
		||||
		p.pictureID = 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return payloads
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// VP9Packet represents the VP9 header that is stored in the payload of an RTP Packet
 | 
			
		||||
type VP9Packet struct {
 | 
			
		||||
	// Required header
 | 
			
		||||
	I bool // PictureID is present
 | 
			
		||||
	P bool // Inter-picture predicted frame
 | 
			
		||||
	L bool // Layer indices is present
 | 
			
		||||
	F bool // Flexible mode
 | 
			
		||||
	B bool // Start of a frame
 | 
			
		||||
	E bool // End of a frame
 | 
			
		||||
	V bool // Scalability structure (SS) data present
 | 
			
		||||
 | 
			
		||||
	// Recommended headers
 | 
			
		||||
	PictureID uint16 // 7 or 16 bits, picture ID
 | 
			
		||||
 | 
			
		||||
	// Conditionally recommended headers
 | 
			
		||||
	TID uint8 // Temporal layer ID
 | 
			
		||||
	U   bool  // Switching up point
 | 
			
		||||
	SID uint8 // Spatial layer ID
 | 
			
		||||
	D   bool  // Inter-layer dependency used
 | 
			
		||||
 | 
			
		||||
	// Conditionally required headers
 | 
			
		||||
	PDiff     []uint8 // Reference index (F=1)
 | 
			
		||||
	TL0PICIDX uint8   // Temporal layer zero index (F=0)
 | 
			
		||||
 | 
			
		||||
	// Scalability structure headers
 | 
			
		||||
	NS      uint8 // N_S + 1 indicates the number of spatial layers present in the VP9 stream
 | 
			
		||||
	Y       bool  // Each spatial layer's frame resolution present
 | 
			
		||||
	G       bool  // PG description present flag.
 | 
			
		||||
	NG      uint8 // N_G indicates the number of pictures in a Picture Group (PG)
 | 
			
		||||
	Width   []uint16
 | 
			
		||||
	Height  []uint16
 | 
			
		||||
	PGTID   []uint8   // Temporal layer ID of pictures in a Picture Group
 | 
			
		||||
	PGU     []bool    // Switching up point of pictures in a Picture Group
 | 
			
		||||
	PGPDiff [][]uint8 // Reference indecies of pictures in a Picture Group
 | 
			
		||||
 | 
			
		||||
	Payload []byte
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unmarshal parses the passed byte slice and stores the result in the VP9Packet this method is called upon
 | 
			
		||||
func (p *VP9Packet) Unmarshal(packet []byte) ([]byte, error) {
 | 
			
		||||
	if packet == nil {
 | 
			
		||||
		return nil, errNilPacket
 | 
			
		||||
	}
 | 
			
		||||
	if len(packet) < 1 {
 | 
			
		||||
		return nil, errShortPacket
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.I = packet[0]&0x80 != 0
 | 
			
		||||
	p.P = packet[0]&0x40 != 0
 | 
			
		||||
	p.L = packet[0]&0x20 != 0
 | 
			
		||||
	p.F = packet[0]&0x10 != 0
 | 
			
		||||
	p.B = packet[0]&0x08 != 0
 | 
			
		||||
	p.E = packet[0]&0x04 != 0
 | 
			
		||||
	p.V = packet[0]&0x02 != 0
 | 
			
		||||
 | 
			
		||||
	pos := 1
 | 
			
		||||
	var err error
 | 
			
		||||
 | 
			
		||||
	if p.I {
 | 
			
		||||
		pos, err = p.parsePictureID(packet, pos)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if p.L {
 | 
			
		||||
		pos, err = p.parseLayerInfo(packet, pos)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if p.F && p.P {
 | 
			
		||||
		pos, err = p.parseRefIndices(packet, pos)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if p.V {
 | 
			
		||||
		pos, err = p.parseSSData(packet, pos)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.Payload = packet[pos:]
 | 
			
		||||
	return p.Payload, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Picture ID:
 | 
			
		||||
//
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+
 | 
			
		||||
// I:   |M| PICTURE ID  |   M:0 => picture id is 7 bits.
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+   M:1 => picture id is 15 bits.
 | 
			
		||||
// M:   | EXTENDED PID  |
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+
 | 
			
		||||
//
 | 
			
		||||
func (p *VP9Packet) parsePictureID(packet []byte, pos int) (int, error) {
 | 
			
		||||
	if len(packet) <= pos {
 | 
			
		||||
		return pos, errShortPacket
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.PictureID = uint16(packet[pos] & 0x7F)
 | 
			
		||||
	if packet[pos]&0x80 != 0 {
 | 
			
		||||
		pos++
 | 
			
		||||
		if len(packet) <= pos {
 | 
			
		||||
			return pos, errShortPacket
 | 
			
		||||
		}
 | 
			
		||||
		p.PictureID = p.PictureID<<8 | uint16(packet[pos])
 | 
			
		||||
	}
 | 
			
		||||
	pos++
 | 
			
		||||
	return pos, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *VP9Packet) parseLayerInfo(packet []byte, pos int) (int, error) {
 | 
			
		||||
	pos, err := p.parseLayerInfoCommon(packet, pos)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return pos, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if p.F {
 | 
			
		||||
		return pos, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return p.parseLayerInfoNonFlexibleMode(packet, pos)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Layer indices (flexible mode):
 | 
			
		||||
//
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+
 | 
			
		||||
// L:   |  T  |U|  S  |D|
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+
 | 
			
		||||
//
 | 
			
		||||
func (p *VP9Packet) parseLayerInfoCommon(packet []byte, pos int) (int, error) {
 | 
			
		||||
	if len(packet) <= pos {
 | 
			
		||||
		return pos, errShortPacket
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.TID = packet[pos] >> 5
 | 
			
		||||
	p.U = packet[pos]&0x10 != 0
 | 
			
		||||
	p.SID = (packet[pos] >> 1) & 0x7
 | 
			
		||||
	p.D = packet[pos]&0x01 != 0
 | 
			
		||||
 | 
			
		||||
	if p.SID >= maxSpatialLayers {
 | 
			
		||||
		return pos, errTooManySpatialLayers
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pos++
 | 
			
		||||
	return pos, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Layer indices (non-flexible mode):
 | 
			
		||||
//
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+
 | 
			
		||||
// L:   |  T  |U|  S  |D|
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+
 | 
			
		||||
//      |   TL0PICIDX   |
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+
 | 
			
		||||
//
 | 
			
		||||
func (p *VP9Packet) parseLayerInfoNonFlexibleMode(packet []byte, pos int) (int, error) {
 | 
			
		||||
	if len(packet) <= pos {
 | 
			
		||||
		return pos, errShortPacket
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.TL0PICIDX = packet[pos]
 | 
			
		||||
	pos++
 | 
			
		||||
	return pos, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Reference indices:
 | 
			
		||||
//
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+                P=1,F=1: At least one reference index
 | 
			
		||||
// P,F: | P_DIFF      |N|  up to 3 times          has to be specified.
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+                    N=1: An additional P_DIFF follows
 | 
			
		||||
//                                                current P_DIFF.
 | 
			
		||||
//
 | 
			
		||||
func (p *VP9Packet) parseRefIndices(packet []byte, pos int) (int, error) {
 | 
			
		||||
	for {
 | 
			
		||||
		if len(packet) <= pos {
 | 
			
		||||
			return pos, errShortPacket
 | 
			
		||||
		}
 | 
			
		||||
		p.PDiff = append(p.PDiff, packet[pos]>>1)
 | 
			
		||||
		if packet[pos]&0x01 == 0 {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if len(p.PDiff) >= maxVP9RefPics {
 | 
			
		||||
			return pos, errTooManyPDiff
 | 
			
		||||
		}
 | 
			
		||||
		pos++
 | 
			
		||||
	}
 | 
			
		||||
	pos++
 | 
			
		||||
 | 
			
		||||
	return pos, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Scalability structure (SS):
 | 
			
		||||
//
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+
 | 
			
		||||
// V:   | N_S |Y|G|-|-|-|
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+              -|
 | 
			
		||||
// Y:   |     WIDTH     | (OPTIONAL)    .
 | 
			
		||||
//      +               +               .
 | 
			
		||||
//      |               | (OPTIONAL)    .
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+               . N_S + 1 times
 | 
			
		||||
//      |     HEIGHT    | (OPTIONAL)    .
 | 
			
		||||
//      +               +               .
 | 
			
		||||
//      |               | (OPTIONAL)    .
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+              -|
 | 
			
		||||
// G:   |      N_G      | (OPTIONAL)
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+                           -|
 | 
			
		||||
// N_G: |  T  |U| R |-|-| (OPTIONAL)                 .
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+              -|            . N_G times
 | 
			
		||||
//      |    P_DIFF     | (OPTIONAL)    . R times    .
 | 
			
		||||
//      +-+-+-+-+-+-+-+-+              -|           -|
 | 
			
		||||
//
 | 
			
		||||
func (p *VP9Packet) parseSSData(packet []byte, pos int) (int, error) {
 | 
			
		||||
	if len(packet) <= pos {
 | 
			
		||||
		return pos, errShortPacket
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.NS = packet[pos] >> 5
 | 
			
		||||
	p.Y = packet[pos]&0x10 != 0
 | 
			
		||||
	p.G = (packet[pos]>>1)&0x7 != 0
 | 
			
		||||
	pos++
 | 
			
		||||
 | 
			
		||||
	NS := p.NS + 1
 | 
			
		||||
	p.NG = 0
 | 
			
		||||
 | 
			
		||||
	if p.Y {
 | 
			
		||||
		p.Width = make([]uint16, NS)
 | 
			
		||||
		p.Height = make([]uint16, NS)
 | 
			
		||||
		for i := 0; i < int(NS); i++ {
 | 
			
		||||
			p.Width[i] = uint16(packet[pos])<<8 | uint16(packet[pos+1])
 | 
			
		||||
			pos += 2
 | 
			
		||||
			p.Height[i] = uint16(packet[pos])<<8 | uint16(packet[pos+1])
 | 
			
		||||
			pos += 2
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if p.G {
 | 
			
		||||
		p.NG = packet[pos]
 | 
			
		||||
		pos++
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < int(p.NG); i++ {
 | 
			
		||||
		p.PGTID = append(p.PGTID, packet[pos]>>5)
 | 
			
		||||
		p.PGU = append(p.PGU, packet[pos]&0x10 != 0)
 | 
			
		||||
		R := (packet[pos] >> 2) & 0x3
 | 
			
		||||
		pos++
 | 
			
		||||
 | 
			
		||||
		p.PGPDiff = append(p.PGPDiff, []uint8{})
 | 
			
		||||
		for j := 0; j < int(R); j++ {
 | 
			
		||||
			p.PGPDiff[i] = append(p.PGPDiff[i], packet[pos])
 | 
			
		||||
			pos++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return pos, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// VP9PartitionHeadChecker checks VP9 partition head
 | 
			
		||||
type VP9PartitionHeadChecker struct{}
 | 
			
		||||
 | 
			
		||||
// IsPartitionHead checks whether if this is a head of the VP9 partition
 | 
			
		||||
func (*VP9PartitionHeadChecker) IsPartitionHead(packet []byte) bool {
 | 
			
		||||
	p := &VP9Packet{}
 | 
			
		||||
	if _, err := p.Unmarshal(packet); err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return p.B
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue