Skip to content

Commit

Permalink
python/example: add st22 support (#690)
Browse files Browse the repository at this point in the history
Signed-off-by: Frank Du <frank.du@intel.com>
  • Loading branch information
frankdjx authored Jan 5, 2024
1 parent f4a85c5 commit 05a99e3
Show file tree
Hide file tree
Showing 15 changed files with 510 additions and 154 deletions.
8 changes: 4 additions & 4 deletions include/st_pipeline_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ enum st22p_tx_flag {
* st22p_tx_put_ext_frame.
*/
ST22P_TX_FLAG_EXT_FRAME = (MTL_BIT32(8)),
/** Enable the st22p_tx_get_frame block behavier to wait until a frame becomes
/** Enable the st22p_tx_get_frame block behavior to wait until a frame becomes
available or timeout(1s) */
ST22P_TX_FLAG_BLOCK_GET = (MTL_BIT32(15)),
};
Expand Down Expand Up @@ -434,7 +434,7 @@ enum st20p_tx_flag {
* performance since the object enqueue/dequeue will be acted one by one.
*/
ST20P_TX_FLAG_DISABLE_BULK = (MTL_BIT32(10)),
/** Enable the st20p_tx_get_frame block behavier to wait until a frame becomes
/** Enable the st20p_tx_get_frame block behavior to wait until a frame becomes
available or timeout(1s) */
ST20P_TX_FLAG_BLOCK_GET = (MTL_BIT32(15)),
};
Expand Down Expand Up @@ -465,7 +465,7 @@ enum st22p_rx_flag {
*/
ST22P_RX_FLAG_EXT_FRAME = (MTL_BIT32(4)),

/** Enable the st22p_rx_get_frame block behavier to wait until a frame becomes
/** Enable the st22p_rx_get_frame block behavior to wait until a frame becomes
available or timeout(1s) */
ST22P_RX_FLAG_BLOCK_GET = (MTL_BIT32(15)),
/**
Expand Down Expand Up @@ -509,7 +509,7 @@ enum st20p_rx_flag {
*/
ST20P_RX_FLAG_SIMULATE_PKT_LOSS = (MTL_BIT32(5)),

/** Enable the st20p_rx_get_frame block behavier to wait until a frame becomes
/** Enable the st20p_rx_get_frame block behavior to wait until a frame becomes
available or timeout(1s) */
ST20P_RX_FLAG_BLOCK_GET = (MTL_BIT32(15)),
/**
Expand Down
5 changes: 5 additions & 0 deletions lib/src/mt_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1526,6 +1526,11 @@ int mt_ptp_wait_stable(struct mtl_main_impl* impl, enum mtl_port port, int timeo
if (!ptp->active) return 0;

while (ptp->delta_result_cnt <= 5) {
if (mt_aborted(impl)) {
err("%s, fail as user aborted\n", __func__);
return -EIO;
}

if (timeout_ms >= 0) {
int ms = (mt_get_tsc(impl) - start_ts) / NS_PER_MS;
if (ms > timeout_ms) {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/st2110/pipeline/st22_pipeline_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ st22p_rx_handle st22p_rx_create(mtl_handle mt, struct st22p_rx_ops* ops) {
mt_pthread_mutex_init(&ctx->lock, NULL);

mt_pthread_mutex_init(&ctx->block_wake_mutex, NULL);
mt_pthread_cond_init(&ctx->block_wake_cond, NULL);
mt_pthread_cond_wait_init(&ctx->block_wake_cond);
if (ops->flags & ST22P_RX_FLAG_BLOCK_GET) ctx->block_get = true;

/* copy ops */
Expand Down
4 changes: 2 additions & 2 deletions lib/src/st2110/pipeline/st22_pipeline_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ static int tx_st22p_encode_put_frame(void* priv, struct st22_encode_frame_meta*
dbg("%s(%d), frame %u result %d data_size %" PRIu64 "\n", __func__, idx, encode_idx,
result, data_size);
if ((result < 0) || (data_size <= ST22_ENCODE_MIN_FRAME_SZ) || (data_size > max_size)) {
info("%s(%d), invalid frame %u result %d data_size %" PRIu64
warn("%s(%d), invalid frame %u result %d data_size %" PRIu64
", allowed min %u max %" PRIu64 "\n",
__func__, idx, encode_idx, result, data_size, ST22_ENCODE_MIN_FRAME_SZ,
max_size);
Expand Down Expand Up @@ -609,7 +609,7 @@ st22p_tx_handle st22p_tx_create(mtl_handle mt, struct st22p_tx_ops* ops) {
mt_pthread_mutex_init(&ctx->lock, NULL);

mt_pthread_mutex_init(&ctx->block_wake_mutex, NULL);
mt_pthread_cond_init(&ctx->block_wake_cond, NULL);
mt_pthread_cond_wait_init(&ctx->block_wake_cond);
if (ops->flags & ST22P_TX_FLAG_BLOCK_GET) ctx->block_get = true;

/* copy ops */
Expand Down
3 changes: 2 additions & 1 deletion lib/src/st2110/st_tx_video_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,8 @@ static int tv_train_pacing(struct mtl_main_impl* impl, struct st_tx_video_sessio
}

/* wait ptp and tsc calibrate done */
mt_ptp_wait_stable(impl, MTL_PORT_P, 60 * 3 * MS_PER_S);
ret = mt_ptp_wait_stable(impl, MTL_PORT_P, 60 * 3 * MS_PER_S);
if (ret < 0) return ret;
mt_wait_tsc_stable(impl);

train_start_time = mt_get_tsc(impl);
Expand Down
10 changes: 6 additions & 4 deletions plugins/st22_ffmpeg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ Follow the guide in ffmpeg site.

```bash
wget https://www.larmoire.info/jellyfish/media/jellyfish-3-mbps-hd-hevc.mkv
ffmpeg -i jellyfish-3-mbps-hd-hevc.mkv -vframes 3 -c:v rawvideo yuv420p8le.yuv
ffmpeg -s 1920x1080 -pix_fmt yuv420p -i yuv420p8le.yuv -pix_fmt yuv422p test_planar8.yuv
ffmpeg -i jellyfish-3-mbps-hd-hevc.mkv -vframes 8 -c:v rawvideo yuv420p8le_1080p.yuv
ffmpeg -s 1920x1080 -pix_fmt yuv420p -i yuv420p8le_1080p.yuv -pix_fmt yuv422p yuv422p8le_1080p.yuv
```

### 3.2 Edit kahawai.json to enable the st22 ffmpeg plugin
Expand All @@ -51,14 +51,16 @@ ffmpeg -s 1920x1080 -pix_fmt yuv420p -i yuv420p8le.yuv -pix_fmt yuv422p test_pla

### 3.3 Run the sample with tx and rx based on h264 CBR

Customize the p_port as the setup.

Tx run:

```bash
./build/app/TxSt22PipelineSample --st22_codec h264_cbr --pipeline_fmt YUV422PLANAR8 --tx_url test_planar8.yuv
./build/app/TxSt22PipelineSample --p_port 0000:ac:01.0 --st22_codec h264_cbr --pipeline_fmt YUV422PLANAR8 --tx_url yuv422p8le_1080p.yuv
```

Rx run:

```bash
./build/app/RxSt22PipelineSample --st22_codec h264_cbr --pipeline_fmt YUV422PLANAR8 --rx_url out_planar8.yuv
./build/app/RxSt22PipelineSample --p_port 0000:ac:01.1 --st22_codec h264_cbr --pipeline_fmt YUV422PLANAR8 --rx_url out_yuv422p8le_1080p.yuv
```
66 changes: 56 additions & 10 deletions python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,34 +81,80 @@ sudo pip3 install opencv-python
sudo pip3 install av
```

### 3.1 st20p_rx.py
### 3.1 st20p_tx.py

Run the `st20p_tx.py`, which reads YUV video data from a file and transmits it over the network as a ST2110 ST_FRAME_FMT_YUV422RFC4175PG2BE10 stream.

```bash
python3 python/example/st20p_tx.py --p_port 0000:ac:01.0 --p_sip 192.168.108.101 --p_tx_ip 239.168.85.20 --tx_url yuv422p10le_1080p.yuv --pipeline_fmt YUV422PLANAR10LE --width 1920 --height 1080 --udp_port 20000 --payload_type 112
```

### 3.2 st20p_rx.py

Execute the `st20p_rx.py` to receive a ST2110 ST_FRAME_FMT_YUV422RFC4175PG2BE10 stream and display it.

```bash
python3 python/example/st20p_rx.py --p_port 0000:ac:01.1 --p_sip 192.168.108.102 --p_rx_ip 239.168.85.20
python3 python/example/st20p_rx.py --p_port 0000:ac:01.1 --p_sip 192.168.108.102 --p_rx_ip 239.168.85.20 --pipeline_fmt YUV422PLANAR10LE --width 1920 --height 1080 --udp_port 20000 --payload_type 112 --display
```

### 3.2 st20p_tx.py
### 3.3 st20p_tx_decode.py

Run the `st20p_tx.py`, which reads YUV video data from a file(default: yuv422p10le_1080p.yuv) and transmits it over the network as a ST2110 ST_FRAME_FMT_YUV422RFC4175PG2BE10 stream.
Use `st20p_tx_decode.py` to decode YUV video from an encoded file `jellyfish-3-mbps-hd-hevc-10bit.mkv` and transmit it as a ST2110 ST_FRAME_FMT_YUV422RFC4175PG2BE10 stream across the network.

```bash
python3 python/example/st20p_tx.py --p_port 0000:ac:01.0 --p_sip 192.168.108.101 --p_tx_ip 239.168.85.20
python3 python/example/st20p_tx_decode.py --p_port 0000:ac:01.0 --p_sip 192.168.108.101 --p_tx_ip 239.168.85.20 --tx_url jellyfish-3-mbps-hd-hevc-10bit.mkv --udp_port 20000 --payload_type 112
```

### 3.3 st20p_rx_encode.py
### 3.4 st20p_rx_encode.py

Run the `st20p_rx_encode.py` to receive a ST2110 ST_FRAME_FMT_YUV422RFC4175PG2BE10 stream and encode it to a `.mp4` encoder file.

```bash
python3 python/example/st20p_rx_encode.py --p_port 0000:ac:01.1 --p_sip 192.168.108.102 --p_rx_ip 239.168.85.20
python3 python/example/st20p_rx_encode.py --p_port 0000:ac:01.1 --p_sip 192.168.108.102 --p_rx_ip 239.168.85.20 --rx_url test.mp4 --width 1920 --height 1080 --udp_port 20000 --payload_type 112
```

### 3.4 st20p_tx_decode.py
### 3.5 st22p_tx.py

Use `st20p_tx_decode.py` to decode YUV video from an encoded file `jellyfish-3-mbps-hd-hevc-10bit.mkv` and transmit it as a ST2110 ST_FRAME_FMT_YUV422RFC4175PG2BE10 stream across the network.
Run the `st22p_tx.py`, which reads YUV video data from a file and transmits it over the network as a compressed ST2110-22 stream.

```bash
python3 python/example/st22p_tx.py --p_port 0000:ac:01.0 --p_sip 192.168.108.101 --p_tx_ip 239.168.85.20 --tx_url yuv422p10le_1080p.yuv --pipeline_fmt YUV422PLANAR10LE --st22_codec jpegxs --width 1920 --height 1080 --udp_port 20000 --payload_type 112
```

### 3.6 st22p_rx.py

Execute the `st22p_rx.py` to receive a compressed ST2110-22 stream stream and display it.

```bash
python3 python/example/st22p_rx.py --p_port 0000:ac:01.1 --p_sip 192.168.108.102 --p_rx_ip 239.168.85.20 --pipeline_fmt YUV422PLANAR10LE --st22_codec jpegxs --width 1920 --height 1080 --udp_port 20000 --payload_type 112 --display
```

### 3.7 interlaced

For TX, interlaced yuv file is used and `--interlaced` is enabled.

st20p_tx:

```bash
python3 python/example/st20p_tx.py --p_port 0000:ac:01.0 --p_sip 192.168.108.101 --p_tx_ip 239.168.85.20 --tx_url yuv422p10le_1080i.yuv --pipeline_fmt YUV422PLANAR10LE --width 1920 --height 1080 --udp_port 20000 --payload_type 112 --interlaced
```

st22p_tx:

```bash
python3 python/example/st22p_tx.py --p_port 0000:ac:01.0 --p_sip 192.168.108.101 --p_tx_ip 239.168.85.20 --tx_url yuv422p10le_1080i.yuv --pipeline_fmt YUV422PLANAR10LE --st22_codec jpegxs --width 1920 --height 1080 --udp_port 20000 --payload_type 112 --interlaced
```

For RX, `--interlaced` is enabled.

st20p_rx:

```bash
python3 python/example/st20p_rx.py --p_port 0000:ac:01.1 --p_sip 192.168.108.102 --p_rx_ip 239.168.85.20 --pipeline_fmt YUV422PLANAR10LE --width 1920 --height 1080 --udp_port 20000 --payload_type 112 --interlaced --display
```

st22p_rx:

```bash
python3 python/example/st20p_tx_decode.py --p_port 0000:ac:01.0 --p_sip 192.168.108.101 --p_tx_ip 239.168.85.20
python3 python/example/st22p_rx.py --p_port 0000:ac:01.1 --p_sip 192.168.108.102 --p_rx_ip 239.168.85.20 --pipeline_fmt YUV422PLANAR10LE --st22_codec jpegxs --width 1920 --height 1080 --udp_port 20000 --payload_type 112 --interlaced --display
```
38 changes: 0 additions & 38 deletions python/example/arg_util.py

This file was deleted.

104 changes: 103 additions & 1 deletion python/example/cv2_util.py → python/example/misc_util.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2023 Intel Corporation
# opencv2 utils
# misc utils

import argparse
import ctypes
import sys

Expand All @@ -10,6 +11,95 @@
import pymtl as mtl


def parse_pipeline_fmt(name):
fmt = mtl.st_frame_name_to_fmt(name)
if fmt >= mtl.ST_FRAME_FMT_MAX:
raise argparse.ArgumentTypeError(f"{name} is not a valid fmt name")
return fmt


def parse_st22_codec(name):
if name == "jpegxs":
return mtl.ST22_CODEC_JPEGXS
if name == "h264_cbr":
return mtl.ST22_CODEC_H264_CBR

raise argparse.ArgumentTypeError(f"{name} is not a valid codec name")


def parse_args(is_tx):
parser = argparse.ArgumentParser(description="Argument util for MTL example")
if is_tx:
p_port_default = "0000:af:01.1"
else:
p_port_default = "0000:af:01.0"
parser.add_argument(
"--p_port", type=str, default=p_port_default, help="primary port name"
)
if is_tx:
p_sip_default = "192.168.108.101"
else:
p_sip_default = "192.168.108.102"
parser.add_argument(
"--p_sip", type=str, default=p_sip_default, help="primary local IP address"
)
# p_tx_ip
parser.add_argument(
"--p_tx_ip",
type=str,
default="239.168.85.20",
help="primary TX dest IP address",
)
# p_rx_ip
parser.add_argument(
"--p_rx_ip",
type=str,
default="239.168.85.20",
help="primary RX source IP address",
)
# pipeline_fmt
parser.add_argument(
"--pipeline_fmt",
type=parse_pipeline_fmt,
default=mtl.ST_FRAME_FMT_YUV422PLANAR10LE,
help="pipeline_fmt",
)
# display
parser.add_argument("--display", action="store_true", help="enable display option")
parser.add_argument(
"--display_scale_factor", type=int, default=2, help="display scale factor"
)
# tx_url
parser.add_argument(
"--tx_url", type=str, default="yuv422p10le_1080p.yuv", help="tx url file path"
)
# rx_url
parser.add_argument(
"--rx_url", type=str, default="test.mp4", help="rx url file path"
)
# width & height
parser.add_argument("--width", type=int, default=1920, help="width")
parser.add_argument("--height", type=int, default=1080, help="height")
# interlaced
parser.add_argument(
"--interlaced", action="store_true", help="Enable interlaced option"
)
# udp_port
parser.add_argument("--udp_port", type=int, default=20000, help="udp port")
# payload_type
parser.add_argument("--payload_type", type=int, default=112, help="payload type")
# ptp
parser.add_argument("--ptp", action="store_true", help="Enable built-in PTP option")
# st22_codec
parser.add_argument(
"--st22_codec",
type=parse_st22_codec,
default=mtl.ST22_CODEC_JPEGXS,
help="st22_codec",
)
return parser.parse_args()


def ptr_to_yuv422p8(ptr, width, height):
y_size = width * height
u_size = width * height // 2
Expand Down Expand Up @@ -167,3 +257,15 @@ def field_display(mtl_handle, first, second, display_scale_factor):
mtl.st_field_merge(first, second, frame)
frame_display(mtl_handle, frame, display_scale_factor)
mtl.st_frame_free(frame)


def copy_to_st_frame(yuv_frame, frame):
src_p = ctypes.c_char_p(yuv_frame)
src_address = ctypes.cast(src_p, ctypes.c_void_p).value
src_address_uint64 = ctypes.c_uint64(src_address).value
# mtl_memcpy_action
memcpy_ops = mtl.mtl_memcpy_ops()
memcpy_ops.dst = mtl.st_frame_addr_cpuva(frame, 0)
memcpy_ops.src = src_address_uint64
memcpy_ops.sz = frame.data_size
mtl.mtl_memcpy_action(memcpy_ops)
Loading

0 comments on commit 05a99e3

Please sign in to comment.