# VideoEncoder

VideoEncoder node is used to encode [ImgFrame](https://docs.luxonis.com/software/depthai-components/messages/img_frame.md) into
either H264, H265, or MJPEG streams. Only NV12 or GRAY8 (which gets converted to NV12) format is supported as an input. All codecs
are lossy (except lossless MJPEG), for more information please see [encoding quality
docs](https://github.com/luxonis/oak-examples/tree/master/gen2-record-replay/encoding_quality).

Encoded bitstream (either MJPEG, H264, or H265) from the device can also be saved directly into .mp4 container with no
computational overhead on the host computer. See [demo
here](https://github.com/luxonis/oak-examples/tree/master/gen2-container-encoding). for more information.

VideoEncoder requires either NV12 or GRAY8 input format for frames. So other outputs, so eg. isp output (required for >4K
resolution) from ColorCamera, which is YUV420, needs to be converted to NV12 before feeding them to the VideoEncoder. Here's an
example of [12MP H265 video encoding @
20FPS](https://gist.github.com/Erol444/a281bbc6cbb8e759e9442a57543edbcc#file-video_enc_12mp_h26x-py).

Matroska

Besides ffmpeg and .mp4 video container (which is patent encumbered), you could also use the mkvmerge (see
[MKVToolNix](https://mkvtoolnix.download/doc/mkvmerge.html) for GUI usage) and .mkv video container to mux encoded stream into
video file that is supported by all major video players (eg. [VLC](https://www.videolan.org/vlc/)).

```bash
mkvmerge -o vid.mkv video.h265
```

## How to place it

#### Python

```python
pipeline = dai.Pipeline()
encoder = pipeline.create(dai.node.VideoEncoder)
```

#### C++

```cpp
dai::Pipeline pipeline;
auto encoder = pipeline.create<dai::node::VideoEncoder>();
```

## Inputs and Outputs

> **Note**
> Output message types
> `bitstream`
> and
> `out`
> are mutually exclusive.

## Usage

#### Python

```python
pipeline = dai.Pipeline()

# Create ColorCamera beforehand
# Set H265 encoding for the ColorCamera video output
videoEncoder = pipeline.create(dai.node.VideoEncoder)
videoEncoder.setDefaultProfilePreset(cam.getFps(), dai.VideoEncoderProperties.Profile.H265_MAIN)
videoEncoder.setBitrateKbps(500) # 0.5 Mbps

# Create MJPEG encoding for still images
stillEncoder = pipeline.create(dai.node.VideoEncoder)
stillEncoder.setDefaultProfilePreset(1, dai.VideoEncoderProperties.Profile.MJPEG)
# stillEncoder.setLossless(True) # Lossless only for MJPEG
stillEncoder.setQuality(90) # 0-100, 100 being the best quality (not lossless though)

cam.still.link(stillEncoder.input)
cam.video.link(videoEncoder.input)
```

#### C++

```cpp
dai::Pipeline pipeline;

// Create ColorCamera beforehand
// Set H265 encoding for the ColorCamera video output
auto videoEncoder = pipeline.create<dai::node::VideoEncoder>();
videoEncoder->setDefaultProfilePreset(cam->getFps(), dai::VideoEncoderProperties::Profile::H265_MAIN);
videoEncoder->setBitrateKbps(500); // 0.5 Mbps

// Create MJPEG encoding for still images
stillEncoder = pipeline.create(dai.node.VideoEncoder);
stillEncoder->setDefaultProfilePreset(1, dai::VideoEncoderProperties::Profile::MJPEG);
// stillEncoder->setLossless(true); // Lossless only for MJPEG
stillEncoder->setQuality(90); // 0-100, 100 being the best quality (not lossless though)

cam->still.link(stillEncoder->input);
cam->video.link(videoEncoder->input);
```

## Limitations

For H.264 / H.265 encoding, we have the following limits:

 * 248 million pixels/second (4K@30 / 12MP@20) limit for the encoder. The resolution and frame rate can be divided into multiple
   streams - but the sum of all the pixels/second needs to be below 248 million.
 * Due to a HW constraint, video encoding can be done only on frames whose width values are multiples of 32.
 * 4096 pixel max width for a frame.

The MJPEG encoder is capable of 16384x8192 resolution at 450 MPix/sec. From our testing, we were able to encode 4K at 30FPS and 2x
800P at 55FPS.

> **Shared resources**
> Note the processing resources of the encoder
> **are shared**
> between H.26x and JPEG.

## Examples of functionality

 * [RGB Encoding](https://docs.luxonis.com/software/depthai/examples/rgb_encoding.md)
 * [Encoding Max Limit](https://docs.luxonis.com/software/depthai/examples/encoding_max_limit.md)
 * [RGB Encoding & MobilenetSSD](https://docs.luxonis.com/software/depthai/examples/rgb_encoding_mobilenet.md)

## Reference

### depthai.node.VideoEncoder(depthai.Node)

Kind: Class

VideoEncoder node. Encodes frames into MJPEG, H264 or H265.

#### getBitrate(self) -> int: int

Kind: Method

Get bitrate in bps

#### getBitrateKbps(self) -> int: int

Kind: Method

Get bitrate in kbps

#### getFrameRate(self) -> float: float

Kind: Method

Get frame rate

#### getHeight(self) -> int: int

Kind: Method

Get input height

#### getKeyframeFrequency(self) -> int: int

Kind: Method

Get keyframe frequency

#### getLossless(self) -> bool: bool

Kind: Method

Get lossless mode. Applies only when using [M]JPEG profile.

#### getMaxOutputFrameSize(self) -> int: int

Kind: Method

#### getNumBFrames(self) -> int: int

Kind: Method

Get number of B frames

#### getNumFramesPool(self) -> int: int

Kind: Method

Get number of frames in pool

Returns:
Number of pool frames

#### getProfile(self) -> depthai.VideoEncoderProperties.Profile: depthai.VideoEncoderProperties.Profile

Kind: Method

Get profile

#### getQuality(self) -> int: int

Kind: Method

Get quality

#### getRateControlMode(self) -> depthai.VideoEncoderProperties.RateControlMode: depthai.VideoEncoderProperties.RateControlMode

Kind: Method

Get rate control mode

#### getSize(self) -> tuple[int, int]: tuple[int, int]

Kind: Method

Get input size

#### getWidth(self) -> int: int

Kind: Method

Get input width

#### setBitrate(self, bitrate: typing.SupportsInt)

Kind: Method

Set output bitrate in bps, for CBR rate control mode. 0 for auto (based on frame
size and FPS). Applicable only to H264 and H265 profiles

#### setBitrateKbps(self, bitrateKbps: typing.SupportsInt)

Kind: Method

Set output bitrate in kbps, for CBR rate control mode. 0 for auto (based on
frame size and FPS). Applicable only to H264 and H265 profiles

#### setDefaultProfilePreset()

Kind: Method

#### setFrameRate(self, frameRate: typing.SupportsFloat)

Kind: Method

Sets expected frame rate

Parameter ``frameRate``:
Frame rate in frames per second

#### setKeyframeFrequency(self, freq: typing.SupportsInt)

Kind: Method

Set keyframe frequency. Every Nth frame a keyframe is inserted.

Applicable only to H264 and H265 profiles

Examples:

- 30 FPS video, keyframe frequency: 30. Every 1s a keyframe will be inserted

- 60 FPS video, keyframe frequency: 180. Every 3s a keyframe will be inserted

#### setLossless(self, arg0: bool)

Kind: Method

Set lossless mode. Applies only to [M]JPEG profile

Parameter ``lossless``:
True to enable lossless jpeg encoding, false otherwise

#### setMaxOutputFrameSize(self, maxFrameSize: typing.SupportsInt)

Kind: Method

Specifies maximum output encoded frame size

#### setNumBFrames(self, numBFrames: typing.SupportsInt)

Kind: Method

Set number of B frames to be inserted. Applicable only to H264 and H265 profiles

#### setNumFramesPool(self, frames: typing.SupportsInt)

Kind: Method

Set number of frames in pool

Parameter ``frames``:
Number of pool frames

#### setProfile()

Kind: Method

#### setQuality(self, quality: typing.SupportsInt)

Kind: Method

Set quality for [M]JPEG profile

Parameter ``quality``:
Value between 0-100%. Approximates quality

#### setRateControlMode(self, mode: depthai.VideoEncoderProperties.RateControlMode)

Kind: Method

Set rate control mode Applicable only to H264 and H265 profiles

#### bitstream

Kind: Property

Outputs ImgFrame message that carries BITSTREAM encoded (MJPEG, H264 or H265)
frame data. Mutually exclusive with out.

#### input

Kind: Property

Input for NV12 ImgFrame to be encoded Default queue is blocking with size set by
'setNumFramesPool' (4).

#### out

Kind: Property

Outputs EncodedFrame message that carries encoded (MJPEG, H264 or H265) frame
data. Mutually exclusive with bitstream.

### Need assistance?

Head over to [Discussion Forum](https://discuss.luxonis.com/) for technical support or any other questions you might have.
