Skip to content

Commit

Permalink
app: add video check sha option (#539)
Browse files Browse the repository at this point in the history
Enabled by "--video_sha_check", the sha digest is carried by the user
meta.

Signed-off-by: Frank Du <[email protected]>
  • Loading branch information
frankdjx authored Oct 19, 2023
1 parent fdabaa4 commit 50b2ee7
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 14 deletions.
12 changes: 9 additions & 3 deletions app/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ libm = cc.find_library('m', required : true)
libpthread = cc.find_library('pthread', required : true)
libjson_c = dependency('json-c', required : true)
libpcap = dependency('pcap', required: true)

libsdl2 = dependency('sdl2', required: false)
if libsdl2.found()
add_global_arguments('-DAPP_HAS_SDL2', language : 'c')
Expand All @@ -33,8 +34,13 @@ if libsdl2_ttf.found()
else
message('SDL2_ttf not found')
endif
libopenssl = dependency('openssl', required : true)
dpdk_dep = dependency('libdpdk', required : true)

libopenssl = dependency('openssl', required : false)
if libopenssl.found()
add_global_arguments('-DAPP_HAS_SSL', language : 'c')
else
message('openssl not found')
endif

# add source file
subdir('src')
Expand Down Expand Up @@ -94,7 +100,7 @@ executable('RxTxApp', sources,
c_args : app_c_args,
link_args: app_ld_args,
# asan should be always the first dep
dependencies: [asan_dep, mtl, libjson_c, libpcap, libsdl2, libsdl2_ttf, libm, libpthread, ws2_32_dep, mman_dep]
dependencies: [asan_dep, mtl, libjson_c, libpcap, libsdl2, libsdl2_ttf, libm, libpthread, ws2_32_dep, mman_dep, libopenssl]
)

# Color convert tool for raw yuv file
Expand Down
8 changes: 4 additions & 4 deletions app/sample/dma/dma_sample.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static int dma_copy_sample(mtl_handle st) {
}
fb_src_iova = mtl_hp_virt2iova(st, fb_src);
rand_data((uint8_t*)fb_src, fb_size, 0);
SHA256((unsigned char*)fb_src, fb_size, fb_src_shas);
st_sha256((unsigned char*)fb_src, fb_size, fb_src_shas);

uint64_t start_ns = mtl_ptp_read_time(st);
while (fb_dst_iova_off < fb_size) {
Expand All @@ -72,7 +72,7 @@ static int dma_copy_sample(mtl_handle st) {
uint64_t end_ns = mtl_ptp_read_time(st);

/* all copy completed, check sha */
SHA256((unsigned char*)fb_dst, fb_size, fb_dst_shas);
st_sha256((unsigned char*)fb_dst, fb_size, fb_dst_shas);
ret = memcmp(fb_dst_shas, fb_src_shas, SHA256_DIGEST_LENGTH);
if (ret != 0) {
err("sha check fail\n");
Expand Down Expand Up @@ -142,7 +142,7 @@ static int dma_map_copy_sample(mtl_handle st) {
}

rand_data((uint8_t*)fb_src, fb_size, 0);
SHA256((unsigned char*)fb_src, fb_size, fb_src_shas);
st_sha256((unsigned char*)fb_src, fb_size, fb_src_shas);

uint64_t start_ns = mtl_ptp_read_time(st);
while (fb_dst_iova_off < fb_size) {
Expand All @@ -165,7 +165,7 @@ static int dma_map_copy_sample(mtl_handle st) {
uint64_t end_ns = mtl_ptp_read_time(st);

/* all copy completed, check sha */
SHA256((unsigned char*)fb_dst, fb_size, fb_dst_shas);
st_sha256((unsigned char*)fb_dst, fb_size, fb_dst_shas);
ret = memcmp(fb_dst_shas, fb_src_shas, SHA256_DIGEST_LENGTH);
if (ret != 0) {
err("%s: sha check fail\n", __func__);
Expand Down
7 changes: 7 additions & 0 deletions app/src/app_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ struct st_app_tx_video_session {
uint16_t framebuff_producer_idx;
uint16_t framebuff_consumer_idx;
struct st_tx_frame* framebuffs;
bool sha_check;

pcap_t* st20_pcap;
bool st20_pcap_input;
Expand Down Expand Up @@ -231,6 +232,7 @@ struct st_app_rx_video_session {
bool slice;
uint8_t num_port;
uint64_t last_stat_time_ns;
bool sha_check;

char st20_dst_url[ST_APP_URL_MAX_LEN];
int st20_dst_fb_cnt; /* the count of received fbs will be saved to file */
Expand Down Expand Up @@ -432,6 +434,7 @@ struct st_app_tx_st20p_session {
int height;
uint8_t num_port;
uint64_t last_stat_time_ns;
bool sha_check;

char st20p_source_url[ST_APP_URL_MAX_LEN];
uint8_t* st20p_source_begin;
Expand All @@ -458,6 +461,7 @@ struct st_app_rx_st20p_session {
int height;
uint8_t num_port;
uint64_t last_stat_time_ns;
bool sha_check;

/* stat */
int stat_frame_received;
Expand Down Expand Up @@ -521,6 +525,7 @@ struct st_app_context {
int32_t tx_ts_delta_us;
enum st21_pacing tx_pacing_type;
bool tx_no_bulk;
bool video_sha_check;

struct st_app_tx_audio_session* tx_audio_sessions;
char tx_audio_url[ST_APP_URL_MAX_LEN];
Expand Down Expand Up @@ -614,4 +619,6 @@ uint8_t* st_json_ip(struct st_app_context* ctx, st_json_session_base_t* base,

int st_set_mtl_log_file(struct st_app_context* ctx, const char* file);

void st_sha_dump(const char* tag, const unsigned char* sha);

#endif
25 changes: 25 additions & 0 deletions app/src/app_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
#include <signal.h>
#include <stdio.h>

#ifdef APP_HAS_SSL
#include <openssl/sha.h>
#endif

#ifndef __FAVOR_BSD
#define __FAVOR_BSD
#endif
Expand Down Expand Up @@ -61,17 +65,23 @@ enum st_tx_frame_status {
ST_TX_FRAME_STATUS_MAX,
};

#ifndef SHA256_DIGEST_LENGTH
#define SHA256_DIGEST_LENGTH 32
#endif

struct st_tx_frame {
enum st_tx_frame_status stat;
size_t size;
bool second_field; /* for interlaced mode */
bool slice_trigger; /* for slice */
uint16_t lines_ready; /* for slice */
uint8_t shas[SHA256_DIGEST_LENGTH];
};

struct st_rx_frame {
void* frame;
size_t size;
uint8_t shas[SHA256_DIGEST_LENGTH];
};

static inline int st_pthread_mutex_init(pthread_mutex_t* mutex,
Expand Down Expand Up @@ -195,4 +205,19 @@ static inline int st_set_real_time(struct timespec* ts) {
#endif
}

#ifdef APP_HAS_SSL
static inline unsigned char* st_sha256(const unsigned char* d, size_t n,
unsigned char* md) {
return SHA256(d, n, md);
}
#else
static inline unsigned char* st_sha256(const unsigned char* d, size_t n,
unsigned char* md) {
MTL_MAY_UNUSED(d);
MTL_MAY_UNUSED(n);
md[0] = rand();
return NULL;
}
#endif

#endif
5 changes: 5 additions & 0 deletions app/src/args.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ enum st_args_cmd {
ST_ARG_SHARED_RX_QUEUES,
ST_ARG_RX_USE_CNI,
ST_ARG_VIRTIO_USER,
ST_ARG_VIDEO_SHA_CHECK,
ST_ARG_MAX,
};

Expand Down Expand Up @@ -227,6 +228,7 @@ static struct option st_app_args_options[] = {
{"shared_rx_queues", no_argument, 0, ST_ARG_SHARED_RX_QUEUES},
{"rx_use_cni", no_argument, 0, ST_ARG_RX_USE_CNI},
{"virtio_user", no_argument, 0, ST_ARG_VIRTIO_USER},
{"video_sha_check", no_argument, 0, ST_ARG_VIDEO_SHA_CHECK},

{0, 0, 0, 0}};

Expand Down Expand Up @@ -691,6 +693,9 @@ int st_app_parse_args(struct st_app_context* ctx, struct mtl_init_params* p, int
case ST_ARG_VIRTIO_USER:
p->flags |= MTL_FLAG_VIRTIO_USER;
break;
case ST_ARG_VIDEO_SHA_CHECK:
ctx->video_sha_check = true;
break;
case '?':
break;
default:
Expand Down
16 changes: 16 additions & 0 deletions app/src/rx_st20p_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ static void app_rx_st20p_consume_frame(struct st_app_rx_st20p_session* s,
static void* app_rx_st20p_frame_thread(void* arg) {
struct st_app_rx_st20p_session* s = arg;
struct st_frame* frame;
uint8_t shas[SHA256_DIGEST_LENGTH];
int idx = s->idx;

info("%s(%d), start\n", __func__, s->idx);
while (!s->st20p_app_thread_stop) {
Expand Down Expand Up @@ -70,6 +72,19 @@ static void* app_rx_st20p_frame_thread(void* arg) {
}

app_rx_st20p_consume_frame(s, frame);
if (s->sha_check) {
if (frame->user_meta_size != sizeof(shas)) {
err("%s(%d), invalid user meta size %" PRId64 "\n", __func__, idx,
frame->user_meta_size);
} else {
st_sha256((unsigned char*)frame->addr[0], st_frame_plane_size(frame, 0), shas);
if (memcmp(shas, frame->user_meta, sizeof(shas))) {
err("%s(%d), sha check fail for frame %p\n", __func__, idx, frame->addr);
st_sha_dump("user meta sha:", frame->user_meta);
st_sha_dump("frame sha:", shas);
}
}
}
s->stat_frame_total_received++;
if (!s->stat_frame_first_rx_time)
s->stat_frame_first_rx_time = st_app_get_monotonic_time();
Expand Down Expand Up @@ -157,6 +172,7 @@ static int app_rx_st20p_init(struct st_app_context* ctx,
memset(&ops, 0, sizeof(ops));

s->last_stat_time_ns = st_app_get_monotonic_time();
s->sha_check = ctx->video_sha_check;

snprintf(name, 32, "app_rx_st20p_%d", idx);
ops.name = name;
Expand Down
33 changes: 26 additions & 7 deletions app/src/rx_video_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,26 @@ static inline bool app_rx_video_is_frame_type(enum st20_type type) {
}

static int app_rx_video_enqueue_frame(struct st_app_rx_video_session* s, void* frame,
size_t size) {
struct st20_rx_frame_meta* meta) {
uint16_t producer_idx = s->framebuff_producer_idx;
struct st_rx_frame* framebuff = &s->framebuffs[producer_idx];

if (framebuff->frame) {
return -EBUSY;
}

if (s->sha_check) {
if (meta->user_meta_size != sizeof(framebuff->shas)) {
err("%s(%d), invalid user meta size %" PRId64 "\n", __func__, s->idx,
meta->user_meta_size);
return -EIO;
}
memcpy(framebuff->shas, meta->user_meta, sizeof(framebuff->shas));
}

dbg("%s(%d), frame idx %d\n", __func__, s->idx, producer_idx);
framebuff->frame = frame;
framebuff->size = size;
framebuff->size = meta->frame_total_size;
/* point to next */
producer_idx++;
if (producer_idx >= s->framebuff_cnt) producer_idx = 0;
Expand Down Expand Up @@ -62,7 +71,7 @@ static void app_rx_video_consume_frame(struct st_app_rx_video_session* s, void*
st_pthread_cond_signal(&d->display_wake_cond);
st_pthread_mutex_unlock(&d->display_wake_mutex);
}
} else {
} else if (s->st20_dst_fd > 0) {
if (s->st20_dst_cursor + frame_size > s->st20_dst_end)
s->st20_dst_cursor = s->st20_dst_begin;
dbg("%s(%d), dst %p src %p size %" PRIu64 "\n", __func__, s->idx, s->st20_dst_cursor,
Expand Down Expand Up @@ -94,6 +103,15 @@ static void* app_rx_video_frame_thread(void* arg) {

dbg("%s(%d), frame idx %d\n", __func__, idx, consumer_idx);
app_rx_video_consume_frame(s, framebuff->frame, framebuff->size);
if (s->sha_check) {
uint8_t shas[SHA256_DIGEST_LENGTH];
st_sha256((unsigned char*)framebuff->frame, framebuff->size, shas);
if (memcmp(shas, framebuff->shas, sizeof(shas))) {
err("%s(%d), sha check fail for frame idx %d\n", __func__, idx, consumer_idx);
st_sha_dump("user meta sha:", framebuff->shas);
st_sha_dump("frame sha:", shas);
}
}
st20_rx_put_framebuff(s->handle, framebuff->frame);
/* point to next */
st_pthread_mutex_lock(&s->st20_wake_mutex);
Expand Down Expand Up @@ -267,7 +285,7 @@ static int app_rx_video_init_frame_thread(struct st_app_rx_video_session* s) {
int ret, idx = s->idx;

/* user do not require fb save to file or display */
if (s->st20_dst_fb_cnt < 1 && s->display == NULL) return 0;
if (s->st20_dst_fb_cnt < 1 && !s->display && !s->sha_check) return 0;

ret = pthread_create(&s->st20_app_thread, NULL, app_rx_video_frame_thread, s);
if (ret < 0) {
Expand Down Expand Up @@ -323,19 +341,19 @@ static int app_rx_video_frame_ready(void* priv, void* frame,
if (!s->stat_frame_first_rx_time)
s->stat_frame_first_rx_time = st_app_get_monotonic_time();

if (s->st20_dst_fd < 0 && s->display == NULL) {
if (!s->st20_app_thread) {
/* free the queue directly as no read thread is running */
st20_rx_put_framebuff(s->handle, frame);
return 0;
}

st_pthread_mutex_lock(&s->st20_wake_mutex);
ret = app_rx_video_enqueue_frame(s, frame, meta->frame_total_size);
ret = app_rx_video_enqueue_frame(s, frame, meta);
if (ret < 0) {
/* free the queue */
st20_rx_put_framebuff(s->handle, frame);
st_pthread_mutex_unlock(&s->st20_wake_mutex);
return ret;
return 0;
}
st_pthread_cond_signal(&s->st20_wake_cond);
st_pthread_mutex_unlock(&s->st20_wake_mutex);
Expand Down Expand Up @@ -458,6 +476,7 @@ static int app_rx_video_init(struct st_app_context* ctx, st_json_video_session_t
memset(&ops, 0, sizeof(ops));

s->last_stat_time_ns = st_app_get_monotonic_time();
s->sha_check = ctx->video_sha_check;

snprintf(name, 32, "app_rx_video_%d", idx);
ops.name = name;
Expand Down
8 changes: 8 additions & 0 deletions app/src/rxtx_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -586,3 +586,11 @@ int st_set_mtl_log_file(struct st_app_context* ctx, const char* file) {
info("%s, succ to %s\n", __func__, file);
return 0;
}

void st_sha_dump(const char* tag, const unsigned char* sha) {
if (tag) info("%s, ", tag);
for (size_t i = 0; i < SHA256_DIGEST_LENGTH; i++) {
info("0x%02x ", sha[i]);
}
info("\n");
}
7 changes: 7 additions & 0 deletions app/src/tx_st20p_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ static void* app_tx_st20p_frame_thread(void* arg) {
st20p_tx_handle handle = s->handle;
int idx = s->idx;
struct st_frame* frame;
uint8_t shas[SHA256_DIGEST_LENGTH];

info("%s(%d), start\n", __func__, idx);
while (!s->st20p_app_thread_stop) {
Expand All @@ -82,6 +83,11 @@ static void* app_tx_st20p_frame_thread(void* arg) {
continue;
}
app_tx_st20p_build_frame(s, frame);
if (s->sha_check) {
st_sha256((unsigned char*)frame->addr[0], st_frame_plane_size(frame, 0), shas);
frame->user_meta = shas;
frame->user_meta_size = sizeof(shas);
}
st20p_tx_put_frame(handle, frame);
}
info("%s(%d), stop\n", __func__, idx);
Expand Down Expand Up @@ -236,6 +242,7 @@ static int app_tx_st20p_init(struct st_app_context* ctx, st_json_st20p_session_t
memset(&ops, 0, sizeof(ops));

s->last_stat_time_ns = st_app_get_monotonic_time();
s->sha_check = ctx->video_sha_check;

snprintf(name, 32, "app_tx_st20p_%d", idx);
ops.name = name;
Expand Down
9 changes: 9 additions & 0 deletions app/src/tx_video_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ static int app_tx_video_next_frame(void* priv, uint16_t* next_frame_idx,
framebuff->stat = ST_TX_FRAME_IN_TRANSMITTING;
*next_frame_idx = consumer_idx;
meta->second_field = framebuff->second_field;
if (s->sha_check) {
meta->user_meta = framebuff->shas;
meta->user_meta_size = sizeof(framebuff->shas);
}
/* point to next */
consumer_idx++;
if (consumer_idx >= s->framebuff_cnt) consumer_idx = 0;
Expand Down Expand Up @@ -234,6 +238,10 @@ static void* app_tx_video_frame_thread(void* arg) {
/* interlaced use different layout? */
app_tx_video_build_frame(s, frame_addr, s->st20_frame_size);
}
if (s->sha_check) {
st_sha256((unsigned char*)frame_addr, s->st20_frame_size, framebuff->shas);
// st_sha_dump("frame sha:", framebuff->shas);
}

st_pthread_mutex_lock(&s->st20_wake_mutex);
framebuff->size = s->st20_frame_size;
Expand Down Expand Up @@ -710,6 +718,7 @@ static int app_tx_video_init(struct st_app_context* ctx, st_json_video_session_t
s->ctx = ctx;
s->enable_vsync = false;
s->last_stat_time_ns = st_app_get_monotonic_time();
s->sha_check = ctx->video_sha_check;

snprintf(name, 32, "app_tx_video_%d", idx);
ops.name = name;
Expand Down

0 comments on commit 50b2ee7

Please sign in to comment.