# Writing camera data

The dv-processing library provides a convenient way of recording camera data into AEDAT4 files. These files can record
multiple data-types and can be read using existing tools in the library. The DV GUI software also provides ways to play
back these recordings.

## Writing a file

Files can be written using the {cpp:class}`dv::io::MonoCameraWriter` class. Since the writer supports multiple data type
configuration, it needs to know apriori what data streams are needed for writing. They are declared using a
{cpp:class}`dv::io::MonoCameraWriter::Config` structure and is passed to the constructor of the writer class to
correctly initialize the required streams in the file header.

### Defining output streams from an existing camera reader handle

As mentioned in the previous paragraph, the number of output streams and their data-types needs to be known for the
writer. Output streams definitions can be generated by an input camera capture. In this case, the writer class will
inspect what streams the capture can output and will create output streams for them. Following is an example on how to
initialize a writer with a camera capture class:

`````{tabs}
````{group-tab} C++
```{literalinclude} assets/code_samples/c++/writing_data/sample2.cpp
:language: c++
:linenos:
:tab-width: 4
```
````

````{group-tab} Python
```{literalinclude} assets/code_samples/python/writing_data/sample2.py
:language: python
:linenos:
:tab-width: 4
```
````
`````

### Defining output streams manually

Output streams definition can be manually defined in the config structure, following is a sample that manually defines
event, frame, IMU, and trigger data-type streams and creates a writer instance:

`````{tabs}
````{group-tab} C++
```{literalinclude} assets/code_samples/c++/writing_data/sample0.cpp
:language: c++
:linenos:
:tab-width: 4
```
````
````{group-tab} Python
```{literalinclude} assets/code_samples/python/writing_data/sample0.py
:language: python
:linenos:
:tab-width: 4
```
````
`````

### Defining output streams using predefined templates

The {cpp:class}`dv::io::MonoCameraWriter` class provides some templates for configuration to reduce the code lines.
Following is a sample how to use a named method that generates a config for writing data:

`````{tabs}
````{group-tab} C++
```{literalinclude} assets/code_samples/c++/writing_data/sample1.cpp
:language: c++
:linenos:
:tab-width: 4
```
````

````{group-tab} Python
```{literalinclude} assets/code_samples/python/writing_data/sample1.py
:language: python
:linenos:
:tab-width: 4
```
````
`````

A list of available output stream configurations is available under the {cpp:class}`dv::io::MonoCameraWriter` class:

- `EventOnlyConfig` - a single output stream "events"
- `FrameOnlyConfig` - a single output stream "frames"
- `DVSConfig` - three output streams: "events", "imu", and "trigger"
- `DAVISConfig` - four output streams: "events", "frames", "imu", and "trigger"

## Writing data to the file

The writer instance can be used to write data with the output streams configured. The following sections provide sample
code on how to write individual data types using the writer class.

### Writing events

The following sample shows an example on how to write event data using the {cpp:class}`dv::io::MonoCameraWriter` class:

`````{tabs}
````{group-tab} C++
```{literalinclude} assets/code_samples/c++/writing_data/sample3.cpp
:language: c++
:linenos:
:tab-width: 4
```
````

````{group-tab} Python
```{literalinclude} assets/code_samples/python/writing_data/sample3.py
:language: python
:linenos:
:tab-width: 4
```
````
`````

### Writing frames

The following sample shows an example on how to write image frames using the {cpp:class}`dv::io::MonoCameraWriter`
class:

`````{tabs}
````{group-tab} C++
```{literalinclude} assets/code_samples/c++/writing_data/sample4.cpp
:language: c++
:linenos:
:tab-width: 4
```
````

````{group-tab} Python
```{literalinclude} assets/code_samples/python/writing_data/sample4.py
:language: python
:linenos:
:tab-width: 4
```
````
`````

### Writing IMU data

The following sample shows an example on how to write IMU measurement data using the
{cpp:class}`dv::io::MonoCameraWriter` class:

`````{tabs}
````{group-tab} C++
```{literalinclude} assets/code_samples/c++/writing_data/sample5.cpp
:language: c++
:linenos:
:tab-width: 4
```
````

````{group-tab} Python
```{literalinclude} assets/code_samples/python/writing_data/sample5.py
:language: python
:linenos:
:tab-width: 4
```
````
`````

### Writing trigger data

The following sample shows an example on how to write triggers using the {cpp:class}`dv::io::MonoCameraWriter` class:

`````{tabs}
````{group-tab} C++
```{literalinclude} assets/code_samples/c++/writing_data/sample6.cpp
:language: c++
:linenos:
:tab-width: 4
```
````

````{group-tab} Python
```{literalinclude} assets/code_samples/python/writing_data/sample6.py
:language: python
:linenos:
:tab-width: 4
```
````
`````

### [Advanced] Writing custom data types

The previous samples show how to use named functions for writing different data types into a file. C++ API provides
templated methods to write any type of data. Below is sample that shows how to write data using the generic templated
API:

```{note}
Since templated methods are only available in C++, the generic writing methods are only available in the C++ API.
```

```{literalinclude} assets/code_samples/c++/writing_data/sample7.cpp
---
language: c++
linenos:
tab-width: 4
---
```

### Sample application - recording data from live camera

An application writing multiple types of data from a live camera can be found among the code samples in the source code
repository of the dv-processing library:

- [Camera writer in C++](https://gitlab.com/inivation/dv/dv-processing/-/blob/master/samples/io/mono-live-writer)
- [Camera capture in Python](https://gitlab.com/inivation/dv/dv-processing/-/blob/master/python/samples/writer_mono_dvs.py)
