# `Media` Module API Manual

```{attention}
This module has undergone significant changes since firmware version V0.7. If you are using firmware before V0.7, please refer to the old version documentation.
```

## Overview

The media module of the CanMV K230 platform is a software abstraction layer mainly used to encapsulate the media data link and media buffer operations of the CanMV K230 platform.

The VB buffer system is automatically initialized at system startup. Users do not need to call `init` / `deinit` manually.

## API Introduction

The media module of the CanMV K230 platform provides a static `MediaManager` class, which contains the methods described in the following sections.

### link

**Description**

This method establishes connections between channels of different modules to achieve automatic data flow. The `Display` module can automatically create a `link` through `bind_layer`.

**Syntax**

```python
MediaManager.link(src=(mod, dev, chn), dst=(mod, dev, chn))
```

**Parameters**

| Parameter Name | Description                                     | Input / Output |
|----------------|-------------------------------------------------|----------------|
| src            | Source channel tuple `(mod_id, dev_id, chn_id)`  | Input          |
| dst            | Destination channel tuple `(mod_id, dev_id, chn_id)` | Input     |

**Return Values**

| Return Value          | Description                           |
|-----------------------|---------------------------------------|
| `MediaManager.linker` | Link object, can be used to destroy   |

**Example**

```python
# Connect Sensor channel 0 to video encoder channel 0
link = MediaManager.link(
    src=(CAMERA_MOD_ID, CAM_DEV_ID_0, CAM_CHN_ID_0),
    dst=(VIDEO_ENCODE_MOD_ID, VENC_DEV_ID, VENC_CHN_ID_0)
)
# Destroy the link
link.destroy()
```

> **Note**: Use `Display.bind_layer()` instead of `MediaManager.link()` to connect Sensor to Display.

### Buffer Class

`MediaManager.Buffer` provides methods for acquiring and managing VB buffers.

#### Buffer.get

**Description**

Acquires a buffer of the specified size from a VB pool.

**Syntax**

```python
MediaManager.Buffer.get(size, poolid=VB_INVALID_POOLID)
```

**Parameters**

| Parameter Name | Description                                                          | Input / Output |
|----------------|----------------------------------------------------------------------|----------------|
| size           | Requested buffer size (in bytes)                                     | Input          |
| poolid         | Pool ID; `VB_INVALID_POOLID` means acquire from any pool (optional)  | Input          |

**Return Values**

| Return Value              | Description |
|---------------------------|-------------|
| `MediaManager.Buffer` object | Success     |

#### Buffer.alloc

**Description**

Allocates a buffer directly via MMZ (does not depend on a VB pool).

**Syntax**

```python
MediaManager.Buffer.alloc(size)
```

**Parameters**

| Parameter Name | Description                      | Input / Output |
|----------------|----------------------------------|----------------|
| size           | Requested buffer size (in bytes) | Input          |

**Return Values**

| Return Value              | Description |
|---------------------------|-------------|
| `MediaManager.Buffer` object | Success     |

#### Buffer.destroy / Buffer.free

**Description**

Releases the resources of an acquired or allocated `buffer`.

**Syntax**

```python
buffer.destroy()
# or
buffer.free()
```

**Parameters**

| Parameter Name | Description | Input / Output |
|----------------|-------------|----------------|
| None           |             |                |

**Return Values**

| Return Value | Description           |
|--------------|-----------------------|
| `bool`       | `True` on success     |

#### Buffer.flush_cache

**Description**

Flushes the buffer cache to ensure data consistency.

**Syntax**

```python
buffer.flush_cache()
```

**Return Values**

| Return Value | Description           |
|--------------|-----------------------|
| `bool`       | `True` on success     |

#### Buffer Properties

| Property    | Type | Description               |
|-------------|------|---------------------------|
| `handle`    | int  | VB block handle           |
| `pool_id`   | int  | Owning VB pool ID         |
| `phys_addr` | int  | Physical address          |
| `virt_addr` | int  | Virtual address           |
| `size`      | int  | Buffer size (in bytes)    |

### VBPool Class

`MediaManager.VBPool` is used to manually create and manage VB buffer pools.

#### VBPool.create

**Description**

Creates a VB buffer pool.

**Syntax**

```python
MediaManager.VBPool.create(blk_size, blk_cnt, mode=VB_REMAP_MODE_NOCACHE)
```

**Parameters**

| Parameter Name | Description                                                 | Input / Output |
|----------------|-------------------------------------------------------------|----------------|
| blk_size       | Size of each buffer block (in bytes)                        | Input          |
| blk_cnt        | Number of buffer blocks                                     | Input          |
| mode           | Remap mode, default `VB_REMAP_MODE_NOCACHE` (optional)      | Input          |

**Return Values**

| Return Value            | Description |
|--------------------------|-------------|
| `MediaManager.VBPool` object | Success     |

#### VBPool.destroy

**Description**

Destroys the VB pool and releases all associated resources.

**Syntax**

```python
pool.destroy()
```

**Return Values**

| Return Value | Description           |
|--------------|-----------------------|
| `bool`       | `True` on success     |

#### VBPool Properties

| Property   | Type | Description            |
|------------|------|------------------------|
| `pool_id`  | int  | Pool ID                |
| `blk_size` | int  | Block size (in bytes)  |
| `blk_cnt`  | int  | Number of blocks       |
| `mode`     | int  | Remap mode             |

### Deprecated Methods

The following methods have been deprecated since firmware version V0.7. Calling them will print a deprecation message or raise an exception:

| Method                           | Status                      |
|----------------------------------|-----------------------------|
| `MediaManager.init()`            | Deprecated (prints message) |
| `MediaManager.deinit()`          | Deprecated (prints message) |
| `MediaManager._config()`         | Deprecated (raises error)   |
| `MediaManager.config_comm_pool()` | Deprecated (raises error)  |

## Data Structure Description

The media module of the CanMV K230 platform includes the following data definitions.

### Media Module ID

**Description**

The currently defined media module IDs of the CanMV K230 platform. Users need to set the corresponding module ID when creating media links.

**Definition**

```python
# CanMV K230 Media Module Definitions
AUDIO_IN_MOD_ID = K_ID_AI          # Audio input device module
AUDIO_OUT_MOD_ID = K_ID_AO         # Audio output device module
AUDIO_ENCODE_MOD_ID = K_ID_AENC    # Audio encoding device module
AUDIO_DECODE_MOD_ID = K_ID_ADEC    # Audio decoding device module
CAMERA_MOD_ID = K_ID_VI            # Camera device module
DISPLAY_MOD_ID = K_ID_VO           # Display device module
DMA_MOD_ID = K_ID_DMA              # DMA device module
DPU_MOD_ID = K_ID_DPU              # DPU device module
VIDEO_ENCODE_MOD_ID = K_ID_VENC    # Video encoding device module
VIDEO_DECODE_MOD_ID = K_ID_VDEC    # Video decoding device module
NONAI_2D_CSC_MOD_ID = K_ID_NONAI_2D  # Hardware color space conversion module
```

### Media Device ID

**Description**

The currently defined media device IDs of the CanMV K230 platform. Users need to set the corresponding device ID when creating media links.

**Definition**

```python
# Audio Device ID Definitions
# TODO

# Camera Device ID Definitions
CAM_DEV_ID_0 = VICAP_DEV_ID_0
CAM_DEV_ID_1 = VICAP_DEV_ID_1
CAM_DEV_ID_2 = VICAP_DEV_ID_2
CAM_DEV_ID_MAX = VICAP_DEV_ID_MAX

# Display Device ID Definitions
DISPLAY_DEV_ID = 0

# DMA Device ID Definitions
# TODO

# DPU Device ID Definitions
# TODO

# Video Encoding Device ID Definitions
VENC_DEV_ID = const(0)

# Video Decoding Device ID Definitions
VDEC_DEV_ID = const(0)
```

### Media Device Channel ID

**Description**

The currently defined media device channel IDs of the CanMV K230 platform. Users need to set the corresponding device channel ID when creating media links.

**Definition**

```python
# Audio Channel ID Definitions
# TODO

# Camera Channel ID Definitions
CAM_CHN_ID_0 = VICAP_CHN_ID_0
CAM_CHN_ID_1 = VICAP_CHN_ID_1
CAM_CHN_ID_2 = VICAP_CHN_ID_2
CAM_CHN_ID_MAX = VICAP_CHN_ID_MAX

# Video Encoding Channel ID Definitions
VENC_CHN_ID_0 = const(0)
VENC_CHN_ID_1 = const(1)
VENC_CHN_ID_2 = const(2)
VENC_CHN_ID_3 = const(3)
VENC_CHN_ID_MAX = VENC_MAX_CHN_NUMS

# Video Decoding Channel ID Definitions
VDEC_CHN_ID_0 = const(0)
VDEC_CHN_ID_1 = const(1)
VDEC_CHN_ID_2 = const(2)
VDEC_CHN_ID_3 = const(3)
VDEC_CHN_ID_MAX = VDEC_MAX_CHN_NUMS
```

### General Constants

| Constant Name            | Value         | Description                              |
|--------------------------|---------------|------------------------------------------|
| `MAX_MEDIA_BUFFER_POOLS` | `16`          | Maximum number of media buffer pools     |
| `MAX_MEDIA_LINK_COUNT`   | `8`           | Maximum number of media links            |
| `VENC_PACK_CNT_MAX`      | `const(12)`   | Maximum packets per frame for VENC       |
| `VB_INVALID_POOLID`      | `0xFFFFFFFF`  | Invalid VB pool ID                       |
| `VB_INVALID_HANDLE`      | `0xFFFFFFFF`  | Invalid VB block handle                  |
| `ALIGN_UP`               | (function)    | Address/size alignment utility           |

## Example Programs

### Example 1: Using VBPool and Buffer

```python
from media.media import *

# Create a VB buffer pool
pool = MediaManager.VBPool.create(blk_size=4096, blk_cnt=4, mode=VB_REMAP_MODE_NOCACHE)

# Get a buffer from the specified pool
buffer = MediaManager.Buffer.get(1024, poolid=pool.pool_id)
print(buffer)

# Inspect buffer properties
print(f"phys_addr: 0x{buffer.phys_addr:x}, size: {buffer.size}")

# Release the buffer
buffer.destroy()

# Destroy the pool
pool.destroy()
```

### Example 2: Using Buffer.alloc for direct allocation

```python
from media.media import *

# Allocate buffer directly via MMZ
buffer = MediaManager.Buffer.alloc(4096)
print(buffer)

# Flush cache
buffer.flush_cache()

# Free
buffer.free()
```
