Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python/example: add st20p_tx support #655

Merged
merged 1 commit into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions include/mtl_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -755,14 +755,21 @@ static inline void mtl_para_pmd_set(struct mtl_init_params* p, enum mtl_port por
p->pmd[port] = pmd;
}

/** Helper to get the port from struct mtl_init_params */
static inline char* mtl_para_port_get(struct mtl_init_params* p, enum mtl_port port) {
return p->port[port];
}

/**
* Inline function returning primary port pointer from mtl_init_params
* @param p
* The pointer to the init parameters.
* @return
* Primary port name pointer
*/
static inline char* mtl_p_port(struct mtl_init_params* p) { return p->port[MTL_PORT_P]; }
static inline char* mtl_p_port(struct mtl_init_params* p) {
return mtl_para_port_get(p, MTL_PORT_P);
}

/**
* Inline function returning redundant port pointer from mtl_init_params
Expand All @@ -771,7 +778,9 @@ static inline char* mtl_p_port(struct mtl_init_params* p) { return p->port[MTL_P
* @return
* Redundant port name pointer
*/
static inline char* mtl_r_port(struct mtl_init_params* p) { return p->port[MTL_PORT_R]; }
static inline char* mtl_r_port(struct mtl_init_params* p) {
return mtl_para_port_get(p, MTL_PORT_R);
}

/**
* Inline helper function returning primary port source IP address pointer
Expand Down Expand Up @@ -1459,6 +1468,18 @@ static inline size_t mtl_size_page_align(size_t sz, size_t pg_sz) {
return sz;
}

/** Helper struct to perform mtl_memcpy with mtl_cpuva_t */
struct mtl_memcpy_ops {
mtl_cpuva_t dst;
mtl_cpuva_t src;
size_t sz;
};
/** Helper function to perform mtl_memcpy with mtl_cpuva_t */
static inline int mtl_memcpy_action(struct mtl_memcpy_ops* ops) {
mtl_memcpy((void*)ops->dst, (const void*)ops->src, ops->sz);
return 0;
}

#if defined(__cplusplus)
}
#endif
Expand Down
16 changes: 15 additions & 1 deletion include/st_pipeline_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -1934,8 +1934,22 @@ static inline void st_rxp_para_udp_port_set(struct st_rx_port* p, enum mtl_port
p->udp_port[port] = udp_port;
}

/** Helper to set the port for struct st_tx_port */
int st_txp_para_port_set(struct st_tx_port* p, enum mtl_session_port port, char* name);
/** Helper to set the dip for struct st_tx_port */
int st_txp_para_dip_set(struct st_tx_port* p, enum mtl_port port, char* ip);
/** Helper to set the udp port number for struct st_tx_port */
static inline void st_txp_para_udp_port_set(struct st_tx_port* p, enum mtl_port port,
uint16_t udp_port) {
p->udp_port[port] = udp_port;
}

/** Helper to get the frame addr from struct st_frame */
static inline mtl_cpuva_t st_frame_addr(struct st_frame* frame, uint8_t plane) {
static inline void* st_frame_addr(struct st_frame* frame, uint8_t plane) {
return frame->addr[plane];
}
/** Helper to get the frame addr(mtl_cpuva_t) from struct st_frame */
static inline mtl_cpuva_t st_frame_addr_cpuva(struct st_frame* frame, uint8_t plane) {
return (mtl_cpuva_t)frame->addr[plane];
}
/** Helper to get the frame iova from struct st_frame */
Expand Down
3 changes: 1 addition & 2 deletions lib/src/st2110/pipeline/st20_pipeline_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -636,8 +636,7 @@ st20p_tx_handle st20p_tx_create(mtl_handle mt, struct st20p_tx_ops* ops) {
}

if (!ops->notify_frame_available) {
err("%s, pls set notify_frame_available\n", __func__);
return NULL;
warn("%s, pls set notify_frame_available\n", __func__);
}

src_size = st_frame_size(ops->input_fmt, ops->width, ops->height, ops->interlaced);
Expand Down
11 changes: 11 additions & 0 deletions lib/src/st2110/st_fmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1250,3 +1250,14 @@ int st_rxp_para_sip_set(struct st_rx_port* p, enum mtl_port port, char* ip) {
err("%s, fail to inet_pton for %s\n", __func__, ip);
return -EIO;
}

int st_txp_para_port_set(struct st_tx_port* p, enum mtl_session_port port, char* name) {
return snprintf(p->port[port], MTL_PORT_MAX_LEN, "%s", name);
}

int st_txp_para_dip_set(struct st_tx_port* p, enum mtl_port port, char* ip) {
int ret = inet_pton(AF_INET, ip, p->dip_addr[port]);
if (ret == 1) return 0;
err("%s, fail to inet_pton for %s\n", __func__, ip);
return -EIO;
}
40 changes: 30 additions & 10 deletions python/example/cv2_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# opencv2 utils

import ctypes
import sys

import cv2
import numpy as np
Expand Down Expand Up @@ -67,7 +68,7 @@ def display_yuv422(y, u, v):

yuv = cv2.merge([y, u, v])
display_img = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR)
cv2.imshow("st20p_rx_python", display_img)
cv2.imshow(sys.argv[0], display_img)
cv2.waitKey(1)


Expand All @@ -77,7 +78,9 @@ def destroy():

def frame_display_yuv422p8(frame, display_scale_factor):
# Pack frame pointer from frame addr
ptr = (ctypes.c_ubyte * (frame.data_size)).from_address(mtl.st_frame_addr(frame, 0))
ptr = (ctypes.c_ubyte * (frame.data_size)).from_address(
mtl.st_frame_addr_cpuva(frame, 0)
)
width = frame.width
height = frame.height

Expand All @@ -91,7 +94,9 @@ def frame_display_yuv422p8(frame, display_scale_factor):

def frame_display_yuv422p10le(frame, display_scale_factor):
# Pack frame pointer from frame addr
ptr = (ctypes.c_ubyte * (frame.data_size)).from_address(mtl.st_frame_addr(frame, 0))
ptr = (ctypes.c_ubyte * (frame.data_size)).from_address(
mtl.st_frame_addr_cpuva(frame, 0)
)
width = frame.width
height = frame.height

Expand All @@ -106,7 +111,9 @@ def frame_display_yuv422p10le(frame, display_scale_factor):

def frame_display_uyvy(frame, display_scale_factor):
# Pack frame pointer from frame addr
ptr = (ctypes.c_ubyte * (frame.data_size)).from_address(mtl.st_frame_addr(frame, 0))
ptr = (ctypes.c_ubyte * (frame.data_size)).from_address(
mtl.st_frame_addr_cpuva(frame, 0)
)
width = frame.width
height = frame.height
downscaled_width = width // display_scale_factor
Expand All @@ -122,14 +129,27 @@ def frame_display_uyvy(frame, display_scale_factor):


def frame_display_rfc4175be10(mtl_handle, frame, display_scale_factor):
yuv422p10le_frame = mtl.st_frame_create(
yuv422p8_frame = mtl.st_frame_create(
mtl_handle,
mtl.ST_FRAME_FMT_YUV422PLANAR10LE,
mtl.ST_FRAME_FMT_YUV422PLANAR8,
frame.width,
frame.height,
frame.interlaced,
)
if yuv422p10le_frame:
mtl.st_frame_convert(frame, yuv422p10le_frame)
frame_display_yuv422p10le(yuv422p10le_frame, display_scale_factor)
mtl.st_frame_free(yuv422p10le_frame)
if yuv422p8_frame:
mtl.st_frame_convert(frame, yuv422p8_frame)
frame_display_yuv422p8(yuv422p8_frame, display_scale_factor)
mtl.st_frame_free(yuv422p8_frame)


def frame_display(mtl_handle, frame, display_scale_factor):
if frame.fmt == mtl.ST_FRAME_FMT_YUV422PLANAR10LE:
frame_display_yuv422p10le(frame, display_scale_factor)
elif frame.fmt == mtl.ST_FRAME_FMT_UYVY:
frame_display_uyvy(frame, display_scale_factor)
elif frame.fmt == mtl.ST_FRAME_FMT_YUV422PLANAR8:
frame_display_yuv422p8(frame, display_scale_factor)
elif frame.fmt == mtl.ST_FRAME_FMT_YUV422RFC4175PG2BE10:
frame_display_rfc4175be10(mtl_handle, frame, display_scale_factor)
else:
print(f"Unknown fmt: {mtl.st_frame_fmt_name(frame.fmt)}")
33 changes: 15 additions & 18 deletions python/example/st20p_rx.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2023 Intel Corporation

from pickle import TRUE
import sys

import cv2_util
import pymtl as mtl


def main():
display = TRUE
display = True
display_scale_factor = 2
# ST_FRAME_FMT_YUV422PLANAR10LE, mtl.ST_FRAME_FMT_UYVY
# or ST_FRAME_FMT_YUV422RFC4175PG2BE10, ST_FRAME_FMT_YUV422PLANAR8
Expand All @@ -25,6 +25,9 @@ def main():

# Create MTL instance
mtl_handle = mtl.mtl_init(init_para)
if not mtl_handle:
print("mtl_init fail")
sys.exit(1)

# Create st20p rx session
rx_para = mtl.st20p_rx_ops()
Expand All @@ -37,38 +40,32 @@ def main():
rx_para.output_fmt = output_fmt
# rx port
rx_port = mtl.st_rx_port()
mtl.st_rxp_para_port_set(rx_port, mtl.MTL_SESSION_PORT_P, "0000:af:01.0")
mtl.st_rxp_para_port_set(
rx_port,
mtl.MTL_SESSION_PORT_P,
mtl.mtl_para_port_get(init_para, mtl.MTL_SESSION_PORT_P),
)
rx_port.num_port = 1
mtl.st_rxp_para_sip_set(rx_port, mtl.MTL_SESSION_PORT_P, "239.168.85.20")
mtl.st_rxp_para_udp_port_set(rx_port, mtl.MTL_SESSION_PORT_P, 20000)
rx_port.payload_type = 112
rx_para.port = rx_port
# create st20p_rx session
st20p_rx = mtl.st20p_rx_create(mtl_handle, rx_para)
if not st20p_rx:
print("st20p_rx_create fail")
sys.exit(1)

# loop until ctrl-c
try:
while True:
frame = mtl.st20p_rx_get_frame(st20p_rx)
if frame:
# print(f"frame addr: {hex(mtl.st_frame_addr(frame, 0))}")
# print(f"frame addr: {hex(mtl.st_frame_addr_cpuva(frame, 0))}")
# print(f"frame iova: {hex(mtl.st_frame_iova(frame, 0))}")
# print(f"pkts_total: {frame.pkts_total}")
if display:
if output_fmt == mtl.ST_FRAME_FMT_YUV422PLANAR10LE:
cv2_util.frame_display_yuv422p10le(frame, display_scale_factor)
elif output_fmt == mtl.ST_FRAME_FMT_UYVY:
cv2_util.frame_display_uyvy(frame, display_scale_factor)
elif output_fmt == mtl.ST_FRAME_FMT_YUV422PLANAR8:
cv2_util.frame_display_yuv422p8(frame, display_scale_factor)
elif output_fmt == mtl.ST_FRAME_FMT_YUV422RFC4175PG2BE10:
cv2_util.frame_display_rfc4175be10(
mtl_handle, frame, display_scale_factor
)
else:
print(
f"Unknown output_fmt: {mtl.st_frame_fmt_name(output_fmt)}"
)
cv2_util.frame_display(mtl_handle, frame, display_scale_factor)
# return the frame
mtl.st20p_rx_put_frame(st20p_rx, frame)

Expand Down
112 changes: 112 additions & 0 deletions python/example/st20p_tx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2023 Intel Corporation

import ctypes
import sys

import cv2_util
import pymtl as mtl


def main():
display = False
display_scale_factor = 2
# ST_FRAME_FMT_YUV422PLANAR10LE or ST_FRAME_FMT_YUV422RFC4175PG2BE10
input_fmt = mtl.ST_FRAME_FMT_YUV422PLANAR10LE
# yuv422p10le_1080p.yuv or yuv422rfc4175be10_1080p.yuv
yuv_file_path = "yuv422p10le_1080p.yuv"

yuv_file = open(yuv_file_path, "rb")
if not yuv_file:
print(f"Open {yuv_file_path} fail")
sys.exit(1)

# Init para
init_para = mtl.mtl_init_params()
mtl.mtl_para_port_set(init_para, mtl.MTL_PORT_P, "0000:af:01.1")
init_para.num_ports = 1
mtl.mtl_para_sip_set(init_para, mtl.MTL_PORT_P, "192.168.108.101")
init_para.flags = mtl.MTL_FLAG_BIND_NUMA | mtl.MTL_FLAG_DEV_AUTO_START_STOP
mtl.mtl_para_tx_queues_cnt_set(init_para, mtl.MTL_PORT_P, 1)
mtl.mtl_para_rx_queues_cnt_set(init_para, mtl.MTL_PORT_P, 0)

# Create MTL instance
mtl_handle = mtl.mtl_init(init_para)
if not mtl_handle:
print("mtl_init fail")
sys.exit(1)

# Create st20p tx session
tx_para = mtl.st20p_tx_ops()
tx_para.name = "st20p_tx_python"
tx_para.width = 1920
tx_para.height = 1080
tx_para.fps = mtl.ST_FPS_P59_94
tx_para.framebuff_cnt = 3
tx_para.transport_fmt = mtl.ST20_FMT_YUV_422_10BIT
tx_para.input_fmt = input_fmt
# tx port
tx_port = mtl.st_tx_port()
mtl.st_txp_para_port_set(
tx_port,
mtl.MTL_SESSION_PORT_P,
mtl.mtl_para_port_get(init_para, mtl.MTL_SESSION_PORT_P),
)
tx_port.num_port = 1
mtl.st_txp_para_dip_set(tx_port, mtl.MTL_SESSION_PORT_P, "239.168.85.20")
mtl.st_txp_para_udp_port_set(tx_port, mtl.MTL_SESSION_PORT_P, 20000)
tx_port.payload_type = 112
tx_para.port = tx_port
# create st20p_tx session
st20p_tx = mtl.st20p_tx_create(mtl_handle, tx_para)
if not st20p_tx:
print("st20p_tx_create fail")
sys.exit(1)
frame_sz = mtl.st20p_tx_frame_size(st20p_tx)
print(f"frame_sz: {hex(frame_sz)}")

# loop until ctrl-c
try:
while True:
frame = mtl.st20p_tx_get_frame(st20p_tx)
if frame:
# print(f"frame addr: {hex(mtl.st_frame_addr_cpuva(frame, 0))}")
# print(f"frame iova: {hex(mtl.st_frame_iova(frame, 0))}")
yuv_frame = yuv_file.read(frame_sz)
if not yuv_frame:
yuv_file.seek(0)
# print("EOF")
yuv_frame = yuv_file.read(frame_sz)
if yuv_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_sz
mtl.mtl_memcpy_action(memcpy_ops)
if display:
cv2_util.frame_display(mtl_handle, frame, display_scale_factor)
else:
print(f"Fail to read {hex(frame_sz)} from {yuv_file_path}")
mtl.st20p_tx_put_frame(st20p_tx, frame)

except KeyboardInterrupt:
print("KeyboardInterrupt")

# Free st20p_tx session
mtl.st20p_tx_free(st20p_tx)

# Close file
yuv_file.close()

# Free MTL instance
mtl.mtl_uninit(mtl_handle)

print("Everything fine, bye")


if __name__ == "__main__":
main()