# gizhw:codec

the GPU's video codecs. NVIDIA's encoder (NVENC) makes H.264, HEVC and AV1 tracks (gizlang:mp4) from frames on the GPU; NVIDIA's decoder (NVDEC) reads video files into RGBA frames on the GPU.

```gizlang
import * as Codec from "gizhw:codec";
```

## Types

### `Session`

```gizlang
type Session = { nat: Native; list: u64; encoder: u64; scratch: u64; }
```

An open NVENC session: the native calls, the function list, the encoder, and host scratch memory.

- `nat`: `gizlang_native.Native`
- `list`: `u64`
- `encoder`: `u64`
- `scratch`: `u64`

### `Encoder`

```gizlang
type Encoder
```

An NVENC session that encodes the NV12 picture in `frame` (on the GPU: rows of `pitch` bytes, its chroma after
`height` rows) into a track each time `push` is called; `close` ends it and gives the track.

- `width`: `i64`
- `height`: `i64`
- `pitch`: `i64`
- `frame`: `M10.Buffer`

### `Decoder`

```gizlang
type Decoder
```

A video file being decoded into frames on the GPU: its frames' width and height after the turn.

- `width`: `i64`
- `height`: `i64`

### `VaProfile`

```gizlang
type VaProfile = { profile: i64; entrypoints: Vec<i64>; }
```

One VAAPI profile (VAProfile) and the entrypoints (VAEntrypoint) that the GPU has for it.

- `profile`: `i64`
- `entrypoints`: `Vec<i64>`

## Functions

### `codecs`

```gizlang
function codecs(): Vec<string>
```

The codecs NVENC encodes here.

Effects: fail.

### `encoder`

```gizlang
function encoder(sys: System, gpu: Gpu, codec: string, width: i64, height: i64, fps: i64, quality: i64): Encoder throws string
```

An encoder of `codec` (codecs()) of width x height frames (even) at `fps`: P frames only, a key frame each 250
frames, at constant quality `quality` (0 to 51, lower is better), on the GPU's stream.

Effects: fail, read, write, io.

### `annexB`

```gizlang
function annexB(stream: bytes): Vec<bytes>
```

The NAL units of an Annex B stream (after each start code of 3 or 4 bytes).

Effects: fail.

### `nv12Kernel`

```gizlang
function nv12Kernel(rgba: bool): Kernel
```

Frame `f` of planar RGB [3, n, h, w] in [0, 1] (`rgba`: of an RGBA image, 4 bytes a pixel, rows of 4 w bytes) to
NV12 of `pitch` bytes a row: a thread a 2 x 2 block, BT.601 with limited range (as ffmpeg's rgb24 to yuv420p), its
chroma from the block's mean.

Effects: fail.

### `decodable`

```gizlang
function decodable(): Vec<string>
```

The codecs NVDEC decodes here, as ffprobe names them.

Effects: fail.

### `nvdecodes`

```gizlang
function nvdecodes(codec: string, pixels: string): bool
```

Whether NVDEC decodes a stream of `codec` whose pixels ffprobe names `pixels` (pix_fmt): 4:2:0 of 8 or 10 bits.
decoder() gives ffmpeg the others.

Effects: fail.

### `decoder`

```gizlang
function decoder(sys: System, gpu: Gpu, ffmpeg: string, path: string, codec: string, pixels: string, turn: i64, width: i64, height: i64): Decoder throws string
```

A decoder of the first video stream of the file (or URL) `path`, whose codec and pixels ffprobe names `codec` and
`pixels`, on `gpu` (NVIDIA): its frames turned `turn` degrees clockwise (0, 90, 180 or 270; a phone video's
rotation), `width` x `height` after the turn. NVDEC decodes what nvdecodes() names: ffmpeg (its name on PATH, or a
path) only copies the stream out. ffmpeg decodes any other stream it reads into RGBA frames, each copied to the GPU.
An error says when the driver has no NVDEC (libnvcuvid.so.1), the format is not one it decodes, or the file has no
picture.

Effects: fail, read, write, console, io.

### `vaapiProfiles`

```gizlang
function vaapiProfiles(sys: System, node: string): Vec<VaProfile> throws string
```

The profiles of the render node `node` (/dev/dri/renderDN), each with its entrypoints.

Effects: fail, io.

## Methods

### `Encoder.encode`

```gizlang
function Encoder.encode(self: mut Encoder, kernel: u64, rgb: u64, f: i64, n: i64): void throws string
```

Frame `f` of `n` of planar RGB f32 at `rgb` (or of an RGBA image when `kernel` is nv12Kernel(true) and n is 1)
through `kernel` (compiled from nv12Kernel) into the encoder's frame, then encoded.

Effects: fail, read, write, io.

### `Encoder.push`

```gizlang
function Encoder.push(self: mut Encoder): void throws string
```

Encodes the picture in `frame`, once the GPU's stream has written it.

Effects: fail, read, write, io.

### `Encoder.close`

```gizlang
function Encoder.close(self: mut Encoder): Track
```

Ends the session and frees it: the track of the frames pushed.

Effects: fail, io.

### `Decoder.next`

```gizlang
function Decoder.next(self: mut Decoder, rgba: Buffer): bool throws string
```

Writes the next frame into `rgba` (on the GPU: width x height, 4 bytes a pixel, rows of 4 width bytes) and gives
true, or gives false at the end of the video.

Effects: fail, read, write, io.

### `Decoder.close`

```gizlang
function Decoder.close(self: mut Decoder): string
```

Frees the decoder and stops ffmpeg: what ffmpeg wrote to its errors.

Effects: fail, io.

