Help us shape the future of Go! Take the 2026 Go Developer Survey

vp8

package module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 4, 2026 License: BSD-3-Clause Imports: 3 Imported by: 0

README

vp8

Pure-Go (CGO=0) reader for the parts of a VP8 frame that are plain bytes and bit fields: the frame tag, and the key-frame header behind it.

tag, err := vp8.ParseFrameTag(frame)   // key?, size, where the coded part begins
if tag.Key {
    h, err := vp8.ParseKeyFrameHeader(frame)   // segmentation, loop filter, quantiser
}

What it is not

It does not decode frames. There is no prediction, no residual, no reconstruction and no loop filter — nothing here turns a bitstream into pixels. FrameTag.HeaderOffset says where the arithmetic-coded part begins, and go-avkit/boolcoder is what reads it.

What is in it

ParseFrameTag, FrameTag key/inter, version, show_frame, first-partition length, size, scale, and where the coded part starts
ParseKeyFrameHeader, KeyFrameHeader Segmentation, LoopFilter, Quantiser

Two things it carries deliberately rather than resolving:

  • The scale is carried, not applied. A frame may ask to be stretched when shown; stretching it is a decision about display, not about decoding, so the factor is reported and left alone.
  • Width and height appear on a key frame only. An inter frame takes them from the key frame before it, so a caller walking a stream has to remember them — this package reads one frame at a time and does not hold that state for you.

Windows, macOS, Linux; six 64-bit architectures. 100% statement coverage, gated in CI.

Licence

BSD-3-Clause.

Documentation

Overview

Package vp8 reads a VP8 bitstream in pure Go, with no libvpx or ffmpeg linkage and no external binaries.

Almost all of a VP8 frame is arithmetic-coded, and that coding is go-avkit/boolcoder's -- shared with VP9. Only the first three bytes of a frame, and seven more on a key frame, are plain bit fields; everything after them goes through the coder. That makes this package the end-to-end witness for the shared engine: a header read correctly is a header whose every symbol came out of it in the right order.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrShortFrame means a frame is too small to hold the header it must have.
	ErrShortFrame = errors.New("vp8: frame is too short for its header")
	// ErrStartCode means a key frame's start code is not the one VP8 states.
	ErrStartCode = errors.New("vp8: wrong start code")
	// ErrPartition means the first partition does not fit inside the frame.
	ErrPartition = errors.New("vp8: first partition runs past the end of the frame")
)

Errors a frame can be refused with.

Functions

This section is empty.

Types

type FrameTag

type FrameTag struct {
	Key          bool
	Version      uint8
	Show         bool
	FirstPartLen uint32
	// Width and Height are stated on a key frame only, and an inter frame takes
	// them from the key frame before it.
	Width, Height uint16
	// Scale is what the frame asks to be stretched by when shown: zero means not
	// at all. It is carried rather than applied, because applying it is a
	// decision about display and not about decoding.
	WidthScale, HeightScale uint8
	// HeaderOffset is where the arithmetic-coded part begins.
	HeaderOffset int
}

FrameTag is what the plain bytes at the start of a frame state.

⛔ Key is true when the bit on the wire is ZERO. The field is a frame TYPE and zero means the key frame; reading it as a flag the other way round makes every key frame look like an inter frame, and a decoder would then look for reference frames that do not exist yet.

func ParseFrameTag

func ParseFrameTag(frame []byte) (FrameTag, error)

ParseFrameTag reads the plain bytes at the start of a frame.

type KeyFrameHeader

type KeyFrameHeader struct {
	Tag          FrameTag
	ColourSpace  uint8
	ClampingType uint8
	Segmentation Segmentation
	LoopFilter   LoopFilter
	Partitions   uint8 // the number of DCT partitions, 1, 2, 4 or 8
	Quantiser    Quantiser
}

KeyFrameHeader is what a key frame states before its token probabilities.

It stops there deliberately. What follows is four by eight by three by eleven conditional probability updates -- over a thousand reads whose only witness would be that nothing after them is misread -- and none of it is needed to say what a frame is, how large, how strongly filtered or how coarsely quantised. Where this stops is stated rather than implied, because the coder cannot tell a caller that it stopped early: there is no end marker to land on.

func ParseKeyFrameHeader

func ParseKeyFrameHeader(frame []byte) (KeyFrameHeader, error)

ParseKeyFrameHeader reads a key frame's tag and the arithmetic-coded header after it.

type LoopFilter

type LoopFilter struct {
	Simple    bool
	Level     uint8
	Sharpness uint8
	// Deltas adjust the level per reference frame and per prediction mode.
	DeltasEnabled bool
	RefDelta      [4]int32
	ModeDelta     [4]int32
}

LoopFilter is what a frame says about the filter applied across block edges.

type Quantiser

type Quantiser struct {
	YACIndex  uint8 // 0 to 127
	YDCDelta  int32
	Y2DCDelta int32
	Y2ACDelta int32
	UVDCDelta int32
	UVACDelta int32
}

Quantiser is the frame's base index and the deltas from it.

type Segmentation

type Segmentation struct {
	Enabled     bool
	UpdateMap   bool
	UpdateData  bool
	Absolute    bool     // the values replace the frame's rather than adjusting it
	Quantiser   [4]int32 // per segment
	FilterLevel [4]int32 // per segment
	TreeProbs   [3]uint8 // how the map itself is coded
}

Segmentation is what a frame says about dividing macroblocks into segments that carry their own quantiser and filter strength.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL