# Disparity encoding

This example encodes disparity output of the
[StereoDepth](https://docs.luxonis.com/software/depthai-components/nodes/stereo_depth.md). Note that you shouldn't enable subpixel
mode, as UINT16 isn't supported by the
[VideoEncoder](https://docs.luxonis.com/software/depthai-components/nodes/video_encoder.md).

Pressing Ctrl+C will stop the recording and then convert it using ffmpeg into an mp4 to make it playable. Note that ffmpeg will
need to be installed and runnable for the conversion to mp4 to succeed.

Be careful, this example saves encoded video to your host storage. So if you leave it running, you could fill up your storage on
your host.

### Similar samples:

 * [RGB Encoding](https://docs.luxonis.com/software/depthai/examples/rgb_encoding.md)
 * [RGB & Mono Encoding](https://docs.luxonis.com/software/depthai/examples/rgb_mono_encoding.md)

## Demo

## Setup

Please run the [install script](https://github.com/luxonis/depthai-python/blob/main/examples/install_requirements.py) to download
all required dependencies. Please note that this script must be ran from git context, so you have to download the
[depthai-python](https://github.com/luxonis/depthai-python) repository first and then run the script

```bash
git clone https://github.com/luxonis/depthai-python.git
cd depthai-python/examples
python3 install_requirements.py
```

For additional information, please follow the [installation guide](https://docs.luxonis.com/software/depthai/manual-install.md).

## Source code

#### Python

```python
#!/usr/bin/env python3

import depthai as dai

# NOTE Because we are encoding disparity values, output video will be a gray, and won't have many pixel levels - either 0..95 or 0..190

# Create pipeline
pipeline = dai.Pipeline()

# Create left/right mono cameras for Stereo depth
monoLeft = pipeline.create(dai.node.MonoCamera)
monoLeft.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
monoLeft.setCamera("left")

monoRight = pipeline.create(dai.node.MonoCamera)
monoRight.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
monoRight.setCamera("right")

# Create a node that will produce the depth map
depth = pipeline.create(dai.node.StereoDepth)
depth.setDefaultProfilePreset(dai.node.StereoDepth.PresetMode.HIGH_DENSITY)
depth.initialConfig.setMedianFilter(dai.MedianFilter.KERNEL_7x7)
depth.setLeftRightCheck(False)
depth.setExtendedDisparity(False)
# Subpixel disparity is of UINT16 format, which is unsupported by VideoEncoder
depth.setSubpixel(False)
monoLeft.out.link(depth.left)
monoRight.out.link(depth.right)

videoEnc = pipeline.create(dai.node.VideoEncoder)
# Depth resolution/FPS will be the same as mono resolution/FPS
videoEnc.setDefaultProfilePreset(monoLeft.getFps(), dai.VideoEncoderProperties.Profile.MJPEG)
depth.disparity.link(videoEnc.input)

xout = pipeline.create(dai.node.XLinkOut)
xout.setStreamName("enc")
videoEnc.bitstream.link(xout.input)

# Connect to device and start pipeline
with dai.Device(pipeline) as device:

    # Output queue will be used to get the encoded data from the output defined above
    q = device.getOutputQueue(name="enc")

    # The .h265 file is a raw stream file (not playable yet)
    with open('disparity.mjpeg', 'wb') as videoFile:
        print("Press Ctrl+C to stop encoding...")
        try:
            while True:
                videoFile.write(q.get().getData())
        except KeyboardInterrupt:
            # Keyboard interrupt (Ctrl + C) detected
            pass

    print("To view the encoded data, convert the stream file (.mjpeg) into a video file (.mp4) using a command below:")
    print("ffmpeg -framerate 30 -i disparity.mjpeg -c copy video.mp4")
```

#### C++

```cpp
#include <csignal>
#include <iostream>

// Includes common necessary includes for development using depthai library
#include "depthai/depthai.hpp"

static std::atomic<bool> alive{true};
static void sigintHandler(int signum) {
    alive = false;
}

int main() {
    using namespace std;
    std::signal(SIGINT, &sigintHandler);

    // Create pipeline
    dai::Pipeline pipeline;

    // Define sources and outputs
    auto monoLeft = pipeline.create<dai::node::MonoCamera>();
    monoLeft->setResolution(dai::MonoCameraProperties::SensorResolution::THE_400_P);
    monoLeft->setCamera("left");

    auto monoRight = pipeline.create<dai::node::MonoCamera>();
    monoRight->setResolution(dai::MonoCameraProperties::SensorResolution::THE_400_P);
    monoRight->setCamera("right");

    auto stereo = pipeline.create<dai::node::StereoDepth>();
    stereo->setDefaultProfilePreset(dai::node::StereoDepth::PresetMode::HIGH_DENSITY);
    stereo->initialConfig.setMedianFilter(dai::MedianFilter::KERNEL_7x7);
    stereo->setLeftRightCheck(false);
    stereo->setExtendedDisparity(false);
    // Subpixel disparity is of UINT16 format, which is unsupported by VideoEncoder
    stereo->setSubpixel(false);
    monoLeft->out.link(stereo->left);
    monoRight->out.link(stereo->right);

    auto videoEnc = pipeline.create<dai::node::VideoEncoder>();
    videoEnc->setDefaultProfilePreset(monoLeft->getFps(), dai::VideoEncoderProperties::Profile::MJPEG);
    stereo->disparity.link(videoEnc->input);

    auto xout = pipeline.create<dai::node::XLinkOut>();
    xout->setStreamName("disparity");
    videoEnc->bitstream.link(xout->input);

    // Connect to device and start pipeline
    dai::Device device(pipeline);

    // Output queue will be used to get the disparity frames from the outputs defined above
    auto q = device.getOutputQueue("disparity");

    auto videoFile = std::ofstream("disparity.mjpeg", std::ios::binary);
    cout << "Press Ctrl+C to stop encoding..." << endl;

    while(alive) {
        auto h265Packet = q->get<dai::ImgFrame>();
        videoFile.write((char*)(h265Packet->getData().data()), h265Packet->getData().size());
    }

    cout << "To view the encoded data, convert the stream file (.mjpeg) into a video file (.mp4) using a command below:" << endl;
    cout << "ffmpeg -framerate 30 -i disparity.mjpeg -c copy video.mp4" << endl;
    return 0;
}
```

## Pipeline

### Need assistance?

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