# VideoEncoder

VideoEncoder node is used to encode
[ImgFrame](https://docs.luxonis.com/software-v3/depthai/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.

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) 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.

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

## Examples of functionality

 * [Video Encode](https://docs.luxonis.com/software-v3/depthai/examples/video_encoder/video_encode.md) - Encode video stream from
   ColorCamera to H264/H265/MJPEG
 * [RGB Encoding & YOLO](https://docs.luxonis.com/software-v3/depthai/examples/detection_network/detection_network.md) - Run a
   YOLOv6n object detection model and display results (bounding boxes) on a video stream, while simultaneously encoding the video
   stream to H264.

## Reference

### dai::node::VideoEncoder

Kind: class

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

#### Input input

Kind: variable

Input for NV12 ImgFrame to be encoded

#### Output bitstream

Kind: variable

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

#### Output out

Kind: variable

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

#### std::shared_ptr< VideoEncoder > build(Node::Output & input)

Kind: function

#### void setDefaultProfilePreset(float fps, Properties::Profile profile)

Kind: function

Sets a default preset based on specified frame rate and profile parameters: fps: Frame rate in frames per second; profile:
Encoding profile

#### void setNumFramesPool(int frames)

Kind: function

Set number of frames in pool parameters: frames: Number of pool frames

#### int getNumFramesPool()

Kind: function

Get number of frames in pool return: Number of pool frames

#### void setRateControlMode(Properties::RateControlMode mode)

Kind: function

Set rate control mode.

#### void setProfile(Properties::Profile profile)

Kind: function

Set encoding profile.

#### void setBitrate(int bitrate)

Kind: function

Set output bitrate in bps, for CBR rate control mode. 0 for auto (based on frame size and FPS)

#### void setBitrateKbps(int bitrateKbps)

Kind: function

Set output bitrate in kbps, for CBR rate control mode. 0 for auto (based on frame size and FPS)

#### void setKeyframeFrequency(int freq)

Kind: function

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

#### void setNumBFrames(int numBFrames)

Kind: function

Set number of B frames to be inserted.

#### void setQuality(int quality)

Kind: function

Set quality parameters: quality: Value between 0-100%. Approximates quality

#### void setLossless(bool lossless)

Kind: function

Set lossless mode. Applies only to [M]JPEG profile parameters: lossless: True to enable lossless jpeg encoding, false otherwise

#### void setFrameRate(float frameRate)

Kind: function

Sets expected frame rate parameters: frameRate: Frame rate in frames per second

#### void setMaxOutputFrameSize(int maxFrameSize)

Kind: function

Specifies maximum output encoded frame size

#### Properties::RateControlMode getRateControlMode()

Kind: function

Get rate control mode.

#### Properties::Profile getProfile()

Kind: function

Get profile.

#### int getBitrate()

Kind: function

Get bitrate in bps.

#### int getBitrateKbps()

Kind: function

Get bitrate in kbps.

#### int getKeyframeFrequency()

Kind: function

Get keyframe frequency.

#### int getNumBFrames()

Kind: function

Get number of B frames.

#### int getQuality()

Kind: function

Get quality.

#### float getFrameRate()

Kind: function

Get frame rate.

#### bool getLossless()

Kind: function

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

#### int getMaxOutputFrameSize()

Kind: function

#### DeviceNodeCRTP()

Kind: function

#### DeviceNodeCRTP(const std::shared_ptr< Device > & device)

Kind: function

#### DeviceNodeCRTP(std::unique_ptr< Properties > props)

Kind: function

#### DeviceNodeCRTP(std::unique_ptr< Properties > props, bool confMode)

Kind: function

#### DeviceNodeCRTP(const std::shared_ptr< Device > & device, std::unique_ptr< Properties > props, bool confMode)

Kind: function

### Need assistance?

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