直播:后台 JWT 推流、前台画中画;WebRTC 服务与 Nginx WebSocket 代理
Made-with: Cursor
This commit is contained in:
221
server/vendor/github.com/pion/rtp/codecs/vp9/header.go
generated
vendored
Normal file
221
server/vendor/github.com/pion/rtp/codecs/vp9/header.go
generated
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Package vp9 contains a VP9 header parser.
|
||||
package vp9
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
errInvalidFrameMarker = errors.New("invalid frame marker")
|
||||
errWrongFrameSyncByte0 = errors.New("wrong frame_sync_byte_0")
|
||||
errWrongFrameSyncByte1 = errors.New("wrong frame_sync_byte_1")
|
||||
errWrongFrameSyncByte2 = errors.New("wrong frame_sync_byte_2")
|
||||
)
|
||||
|
||||
// HeaderColorConfig is the color_config member of an header.
|
||||
type HeaderColorConfig struct {
|
||||
TenOrTwelveBit bool
|
||||
BitDepth uint8
|
||||
ColorSpace uint8
|
||||
ColorRange bool
|
||||
SubsamplingX bool
|
||||
SubsamplingY bool
|
||||
}
|
||||
|
||||
func (c *HeaderColorConfig) unmarshal(profile uint8, buf []byte, pos *int) error {
|
||||
if profile >= 2 {
|
||||
var err error
|
||||
c.TenOrTwelveBit, err = readFlag(buf, pos)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.TenOrTwelveBit {
|
||||
c.BitDepth = 12
|
||||
} else {
|
||||
c.BitDepth = 10
|
||||
}
|
||||
} else {
|
||||
c.BitDepth = 8
|
||||
}
|
||||
|
||||
tmp, err := readBits(buf, pos, 3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.ColorSpace = uint8(tmp)
|
||||
|
||||
if c.ColorSpace != 7 {
|
||||
var err error
|
||||
c.ColorRange, err = readFlag(buf, pos)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if profile == 1 || profile == 3 {
|
||||
err := hasSpace(buf, *pos, 3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.SubsamplingX = readFlagUnsafe(buf, pos)
|
||||
c.SubsamplingY = readFlagUnsafe(buf, pos)
|
||||
*pos++
|
||||
} else {
|
||||
c.SubsamplingX = true
|
||||
c.SubsamplingY = true
|
||||
}
|
||||
} else {
|
||||
c.ColorRange = true
|
||||
|
||||
if profile == 1 || profile == 3 {
|
||||
c.SubsamplingX = false
|
||||
c.SubsamplingY = false
|
||||
|
||||
err := hasSpace(buf, *pos, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*pos++
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HeaderFrameSize is the frame_size member of an header.
|
||||
type HeaderFrameSize struct {
|
||||
FrameWidthMinus1 uint16
|
||||
FrameHeightMinus1 uint16
|
||||
}
|
||||
|
||||
func (s *HeaderFrameSize) unmarshal(buf []byte, pos *int) error {
|
||||
err := hasSpace(buf, *pos, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.FrameWidthMinus1 = uint16(readBitsUnsafe(buf, pos, 16))
|
||||
s.FrameHeightMinus1 = uint16(readBitsUnsafe(buf, pos, 16))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Header is a VP9 Frame header.
|
||||
// Specification:
|
||||
// https://storage.googleapis.com/downloads.webmproject.org/docs/vp9/vp9-bitstream-specification-v0.6-20160331-draft.pdf
|
||||
type Header struct {
|
||||
Profile uint8
|
||||
ShowExistingFrame bool
|
||||
FrameToShowMapIdx uint8
|
||||
NonKeyFrame bool
|
||||
ShowFrame bool
|
||||
ErrorResilientMode bool
|
||||
ColorConfig *HeaderColorConfig
|
||||
FrameSize *HeaderFrameSize
|
||||
}
|
||||
|
||||
// Unmarshal decodes a Header.
|
||||
func (h *Header) Unmarshal(buf []byte) error {
|
||||
pos := 0
|
||||
|
||||
err := hasSpace(buf, pos, 4)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
frameMarker := readBitsUnsafe(buf, &pos, 2)
|
||||
if frameMarker != 2 {
|
||||
return errInvalidFrameMarker
|
||||
}
|
||||
|
||||
profileLowBit := uint8(readBitsUnsafe(buf, &pos, 1))
|
||||
profileHighBit := uint8(readBitsUnsafe(buf, &pos, 1))
|
||||
h.Profile = profileHighBit<<1 + profileLowBit
|
||||
|
||||
if h.Profile == 3 {
|
||||
err = hasSpace(buf, pos, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pos++
|
||||
}
|
||||
|
||||
h.ShowExistingFrame, err = readFlag(buf, &pos)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if h.ShowExistingFrame {
|
||||
var tmp uint64
|
||||
tmp, err = readBits(buf, &pos, 3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
h.FrameToShowMapIdx = uint8(tmp)
|
||||
return nil
|
||||
}
|
||||
|
||||
err = hasSpace(buf, pos, 3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h.NonKeyFrame = readFlagUnsafe(buf, &pos)
|
||||
h.ShowFrame = readFlagUnsafe(buf, &pos)
|
||||
h.ErrorResilientMode = readFlagUnsafe(buf, &pos)
|
||||
|
||||
if !h.NonKeyFrame {
|
||||
err := hasSpace(buf, pos, 24)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
frameSyncByte0 := uint8(readBitsUnsafe(buf, &pos, 8))
|
||||
if frameSyncByte0 != 0x49 {
|
||||
return errWrongFrameSyncByte0
|
||||
}
|
||||
|
||||
frameSyncByte1 := uint8(readBitsUnsafe(buf, &pos, 8))
|
||||
if frameSyncByte1 != 0x83 {
|
||||
return errWrongFrameSyncByte1
|
||||
}
|
||||
|
||||
frameSyncByte2 := uint8(readBitsUnsafe(buf, &pos, 8))
|
||||
if frameSyncByte2 != 0x42 {
|
||||
return errWrongFrameSyncByte2
|
||||
}
|
||||
|
||||
h.ColorConfig = &HeaderColorConfig{}
|
||||
err = h.ColorConfig.unmarshal(h.Profile, buf, &pos)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h.FrameSize = &HeaderFrameSize{}
|
||||
err = h.FrameSize.unmarshal(buf, &pos)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Width returns the video width.
|
||||
func (h Header) Width() uint16 {
|
||||
if h.FrameSize == nil {
|
||||
return 0
|
||||
}
|
||||
return h.FrameSize.FrameWidthMinus1 + 1
|
||||
}
|
||||
|
||||
// Height returns the video height.
|
||||
func (h Header) Height() uint16 {
|
||||
if h.FrameSize == nil {
|
||||
return 0
|
||||
}
|
||||
return h.FrameSize.FrameHeightMinus1 + 1
|
||||
}
|
||||
Reference in New Issue
Block a user