encode

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Feb 17, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package encode implements H.264/AVC encoding for IDR frames.

Index

Constants

This section is empty.

Variables

View Source
var MF4x4 = [6][3]int32{
	{13107, 8066, 5243},
	{11916, 7490, 4660},
	{10082, 6554, 4194},
	{9362, 5825, 3647},
	{8192, 5243, 3355},
	{7282, 4559, 2893},
}

MF4x4 is the forward quantization multiplication factor table. Indexed by QP%6 and position category (same as dequant LevelScale). These are the standard forward quantization factors from JM reference.

Functions

func BuildNALU

func BuildNALU(naluType, refIDC byte, rbsp []byte) []byte

BuildNALU returns a complete NALU byte slice (header + EBSP) without Annex-B start codes. Useful for MP4 sample descriptions (e.g. SetAVCDescriptor) which want raw NALUs.

func ChromaQP

func ChromaQP(qpY int) int

ChromaQP maps luma QP to chroma QP (Table 8-15).

func EncodePPS

func EncodePPS(disableDeblock int) []byte

EncodePPS generates a minimal PPS RBSP for CAVLC encoding. disableDeblock: 0=enable (default), 1=disable, 2=disable across slices.

func EncodePPSCABAC

func EncodePPSCABAC(disableDeblock int) []byte

EncodePPSCABAC generates a minimal PPS RBSP for CABAC encoding. entropy_coding_mode_flag = 1 (CABAC).

func EncodePSkipSlice

func EncodePSkipSlice(sps *avc.SPS, pps *avc.PPS, frameNum uint32, disableDeblock int) ([]byte, error)

EncodePSkipSlice encodes a P_Skip slice (all MBs skip, copying from reference) using parameters from parsed SPS and PPS structures. Supports both CAVLC and CABAC entropy coding based on PPS.EntropyCodingModeFlag. frameNum is the frame_num value for this slice. disableDeblock: 0=enable (with offsets=0), 1=disable, 2=disable across slices. Returns an Annex-B framed non-IDR NALU (type=1, ref_idc=2).

func EncodeResidualBlock

func EncodeResidualBlock(w *BitWriter, coeffs []int32, nC, maxNumCoeff int) int

EncodeResidualBlock encodes a CAVLC residual block. coeffs: coefficients in scan order (zigzag for 4x4). nC: context number for coeff_token table selection (-1 for chroma DC, >=0 for others). maxNumCoeff: 4 (chroma DC), 15 (AC blocks), or 16 (4x4 blocks). Returns the number of non-zero coefficients (totalCoeff) for nC tracking.

func EncodeSPS

func EncodeSPS(width, height, maxRef int, cs yuv.ColorSpace, rng yuv.Range) []byte

EncodeSPS generates a minimal SPS RBSP for Baseline profile. width and height are in pixels (must be even; non-16-multiples use frame cropping). maxRef is the max_num_ref_frames value (0 for IDR-only, 1+ for P-frames).

func EncodeSPSMain

func EncodeSPSMain(width, height, maxRef int, cs yuv.ColorSpace, rng yuv.Range) []byte

EncodeSPSMain generates a minimal SPS RBSP for Main profile (profile_idc=77). Main profile is required for CABAC entropy coding. width and height are in pixels (must be even; non-16-multiples use frame cropping). maxRef is the max_num_ref_frames value (0 for IDR-only, 1+ for P-frames).

func FillerNALU

func FillerNALU(size int) ([]byte, error)

FillerNALU returns an Annex-B filler NALU (nal_unit_type 12) of exactly size bytes. The minimum size is 6 bytes (4-byte start code + 1-byte header + 1-byte RBSP stop bit). Returns an error if size is less than 6. Fill bytes are 0xFF which never trigger EBSP prevention.

func ForwardDequantRoundTrip

func ForwardDequantRoundTrip(dc int32, qp int) (quantized, dequantized int32)

ForwardDequantRoundTrip verifies that forward quant + dequant of a DC value round-trips correctly. Used only for testing.

func ForwardHadamard2x2

func ForwardHadamard2x2(dc [4]int32) [4]int32

ForwardHadamard2x2 performs the forward 2x2 Hadamard transform for chroma DC. Self-inverse (up to scaling).

func ForwardHadamard4x4

func ForwardHadamard4x4(dc [16]int32) [16]int32

ForwardHadamard4x4 performs the forward 4x4 Hadamard transform for luma DC. The Hadamard transform is self-inverse (up to scaling), so we use the same butterfly structure as the inverse.

func ForwardTransformDC4x4

func ForwardTransformDC4x4(residual int32) int32

ForwardTransformDC4x4 computes the DC coefficient of a 4x4 block from a constant residual value. For a constant block with value R: DC = 16*R (forward 4x4 DCT: row sum 4R, column sum 4*4R = 16R).

func GenerateIDR

func GenerateIDR(p EncodeParams, grid *yuv.Grid, colors yuv.ColorMap, idrPicID uint32) ([]byte, error)

GenerateIDR encodes a flat-color IDR frame from a Grid/ColorMap. Returns the IDR slice NALU in Annex-B format (no SPS/PPS).

func GeneratePPS

func GeneratePPS(p EncodeParams) ([]byte, error)

GeneratePPS returns PPS NALU bytes in Annex-B format.

func GeneratePSkip

func GeneratePSkip(p EncodeParams, frameNum uint32) ([]byte, error)

GeneratePSkip returns a P_Skip slice NALU in Annex-B format.

func GenerateSPS

func GenerateSPS(p EncodeParams) ([]byte, error)

GenerateSPS returns SPS NALU bytes in Annex-B format.

func InsertEBSPPrevention

func InsertEBSPPrevention(rbsp []byte) []byte

InsertEBSPPrevention inserts emulation prevention bytes (0x03) after each occurrence of 0x00 0x00 in the RBSP data. This is the inverse of removeEBSPPrevention in the decoder.

func PadSlice

func PadSlice(slice []byte, targetBytes int) ([]byte, error)

PadSlice appends a filler NALU to slice so the total is exactly targetBytes. Returns an error if the slice already exceeds targetBytes, or if the gap is too small for a filler NALU (1-5 bytes).

func Quantize4x4

func Quantize4x4(coeffs [16]int32, qp int) [16]int32

Quantize4x4 performs forward quantization on a 4x4 block. Returns quantized coefficients (levels).

func QuantizeChromaDC2x2

func QuantizeChromaDC2x2(coeffs [4]int32, qpc int) [4]int32

QuantizeChromaDC2x2 performs forward quantization on chroma DC coefficients (4:2:0).

func QuantizeDC4x4

func QuantizeDC4x4(coeffs [16]int32, qp int, wsDC int32) [16]int32

QuantizeDC4x4 performs forward quantization on 16x16 luma DC coefficients. wsDC is the scaling list DC value (typically 16 for flat default).

func WriteNALU

func WriteNALU(w io.Writer, naluType, refIDC byte, rbsp []byte) error

WriteNALU writes an Annex-B framed NALU to w. naluType: NALU type (e.g., 5 for IDR, 7 for SPS, 8 for PPS). refIDC: nal_ref_idc (0-3). rbsp: raw byte sequence payload (before EBSP prevention insertion).

func WritePSliceHeader

func WritePSliceHeader(w *BitWriter, frameNum uint32, qpDelta int32,
	disableDeblock int, log2MaxFrameNumMinus4 uint32,
	log2MaxPicOrderCntLsbMinus4 uint32, ppsID uint32, deblockControlPresent bool,
	cabacInitIDC int)

WritePSliceHeader writes the slice header for a P-slice (non-IDR). frameNum is the frame_num value (increments for each non-IDR frame). log2MaxFrameNumMinus4 must match the SPS value. log2MaxPicOrderCntLsbMinus4 controls the POC LSB bit width (from SPS). ppsID is the pic_parameter_set_id written in the slice header. deblockControlPresent controls whether deblocking syntax is written (from PPS). cabacInitIDC: when >= 0, write cabac_init_idc (0-2) for CABAC slices; -1 for CAVLC.

func WritePSliceHeaderCABAC

func WritePSliceHeaderCABAC(w *BitWriter, frameNum uint32, qpDelta int32,
	disableDeblock int, log2MaxFrameNumMinus4 uint32,
	log2MaxPicOrderCntLsbMinus4 uint32, ppsID uint32, deblockControlPresent bool,
	cabacInitIDC int)

WritePSliceHeaderCABAC writes a CABAC P-slice header with alignment bits. cabacInitIDC is the cabac_init_idc value (0-2).

func WriteSliceHeader

func WriteSliceHeader(w *BitWriter, qpDelta int32, disableDeblock int, idrPicID uint32)

WriteSliceHeader writes the slice header fields for an IDR I-slice to the given BitWriter. qpDelta: slice_qp_delta (se(v)), offset from pic_init_qp. disableDeblock: 0=enable (with offsets=0), 1=disable, 2=disable across slices. idrPicID: idr_pic_id (ue(v)), used to distinguish consecutive IDR pictures. Does NOT include the NALU header byte (that's written separately).

func WriteSliceHeaderCABAC

func WriteSliceHeaderCABAC(w *BitWriter, qpDelta int32, disableDeblock int, idrPicID uint32)

WriteSliceHeaderCABAC writes the slice header for a CABAC-encoded IDR I-slice. After the header fields, it appends CABAC alignment bits (1-bits until byte-aligned) as required by section 7.3.2.1. idrPicID: idr_pic_id (ue(v)), used to distinguish consecutive IDR pictures. Note: For I-slices, cabac_init_idc is NOT present (spec: only for non-I/SI slices), so the header fields are identical to CAVLC except for the byte-alignment suffix.

Types

type BitWriter

type BitWriter struct {
	// contains filtered or unexported fields
}

BitWriter writes individual bits to a byte buffer, MSB first. It is the inverse of cavlc.BitReader.

func NewBitWriter

func NewBitWriter() *BitWriter

NewBitWriter creates a new BitWriter with pre-allocated buffer capacity.

func (*BitWriter) AlignToByte

func (w *BitWriter) AlignToByte()

AlignToByte pads with zero bits to reach the next byte boundary.

func (*BitWriter) BitsWritten

func (w *BitWriter) BitsWritten() int

BitsWritten returns the total number of bits written.

func (*BitWriter) Bytes

func (w *BitWriter) Bytes() []byte

Bytes returns the written data. If the last byte is partially written, it is included (remaining bits are zero-padded).

func (*BitWriter) WriteBit

func (w *BitWriter) WriteBit(b uint8)

WriteBit writes a single bit (0 or 1).

func (*BitWriter) WriteBits

func (w *BitWriter) WriteBits(val uint32, n int)

WriteBits writes the lower n bits of val, MSB first.

func (*BitWriter) WriteSE

func (w *BitWriter) WriteSE(val int32)

WriteSE writes a signed Exp-Golomb coded value.

func (*BitWriter) WriteUE

func (w *BitWriter) WriteUE(val uint32)

WriteUE writes an unsigned Exp-Golomb coded value.

type EncodeParams

type EncodeParams struct {
	Width          int            // frame width in pixels (must be even)
	Height         int            // frame height in pixels (must be even)
	QP             int            // quantization parameter (0-51, default 26)
	CABAC          bool           // true=Main profile CABAC, false=Baseline CAVLC
	DisableDeblock int            // 0=enable, 1=disable
	MaxRefFrames   int            // max_num_ref_frames (0=IDR-only, 1+=P-frames)
	ColorSpace     yuv.ColorSpace // YCbCr matrix standard (default BT601)
	Range          yuv.Range      // sample value range (default LimitedRange)
}

EncodeParams holds H.264 encoding parameters.

type FrameEncoder

type FrameEncoder struct {
	Grid            *yuv.Grid
	Colors          yuv.ColorMap
	QP              int
	DisableDeblock  int            // 0=enable, 1=disable
	CABAC           bool           // use CABAC entropy coding (Main profile) instead of CAVLC (Baseline)
	MaxNumRefFrames int            // max_num_ref_frames in SPS (0 for IDR-only, 1+ for P-frames)
	Width           int            // actual pixel width for SPS (0 = Grid.Width*16)
	Height          int            // actual pixel height for SPS (0 = Grid.Height*16)
	ColorSpace      yuv.ColorSpace // YCbCr matrix standard (default BT601)
	Range           yuv.Range      // sample value range (default LimitedRange)
}

FrameEncoder encodes a grid-based image as an H.264 IDR frame.

func (*FrameEncoder) Encode

func (e *FrameEncoder) Encode() ([]byte, error)

Encode produces an Annex-B bitstream containing SPS, PPS, and one IDR slice.

func (*FrameEncoder) EncodePSkipSlice

func (e *FrameEncoder) EncodePSkipSlice(frameNum uint32) ([]byte, error)

EncodePSkipSlice encodes a P_Skip slice (all MBs skip, copying from reference). frameNum is the frame_num value for this slice. Returns an Annex-B framed non-IDR NALU (type=1, ref_idc=2).

func (*FrameEncoder) EncodeSPSPPS

func (e *FrameEncoder) EncodeSPSPPS(buf *bytes.Buffer) error

EncodeSPSPPS writes SPS and PPS NALUs to buf (profile-aware).

func (*FrameEncoder) EncodeSlice

func (e *FrameEncoder) EncodeSlice(idrPicID uint32) ([]byte, error)

EncodeSlice encodes a single IDR slice NALU and returns it as Annex-B framed bytes. idrPicID is the idr_pic_id value (alternating 0/1 for consecutive IDR pictures).

Jump to

Keyboard shortcuts

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