From 63957bf43719bd8fd8de0946c7b6deb40f84ee06 Mon Sep 17 00:00:00 2001 From: Daniel Callander Date: Tue, 11 Apr 2023 00:33:53 +0100 Subject: [PATCH 1/2] Drop frames after 50ms --- src/main.c | 4 ++++ src/video/dji_net.c | 48 ++++++++++++++++++++++++++++++++++++++------- src/video/dji_usb.c | 42 ++++++++++++++++++++++++++++++++------- 3 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/main.c b/src/main.c index adfe6cd..de8b4b9 100644 --- a/src/main.c +++ b/src/main.c @@ -253,6 +253,10 @@ static void pair_check(PSERVER_DATA server) int main(int argc, char *argv[]) { + // force line buffered mode + setvbuf(stdout, NULL, _IOLBF, 0); + setvbuf(stderr, NULL, _IOLBF, 0); + CONFIGURATION config; config_parse(argc, argv, &config); diff --git a/src/video/dji_net.c b/src/video/dji_net.c index c41e862..6c285f5 100644 --- a/src/video/dji_net.c +++ b/src/video/dji_net.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -11,8 +12,13 @@ #include "dji.h" #include "video.h" -int sockfd = -1; -int frame_counter = 0; +#define ACCEPTABLE_FRAME_TIME 50000000 + +static int sockfd = -1; +static struct timespec last_frame_time = {0, 0}; +// static struct timespec last_key_time = {0, 0}; + +static uint8_t buf[1000000]; static int dji_net_setup(int videoFormat, int width, int height, int redrawRate, void *context, int drFlags) @@ -54,26 +60,54 @@ dji_net_setup(int videoFormat, int width, int height, int redrawRate, void *cont send(sockfd, &header, sizeof(header), 0); + clock_gettime(CLOCK_MONOTONIC, &last_frame_time); + // last_key_time = last_frame_time; + return 0; } static int dji_net_submit_decode_unit(PDECODE_UNIT decodeUnit) { - uint8_t *buf = malloc(decodeUnit->fullLength); - PLENTRY entry = decodeUnit->bufferList; uint32_t length = 0; while (entry != NULL) { + if (length + entry->length > sizeof(buf)) + { + printf("dji_net: Frame too large: %d >= 1Mb\n", length + entry->length); + return DR_NEED_IDR; + } + memcpy(buf + length, entry->data, entry->length); length += entry->length; entry = entry->next; } - send(sockfd, &length, sizeof(length), 0); - send(sockfd, buf, length, 0); + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + uint64_t diff = (now.tv_sec - last_frame_time.tv_sec) * 1000000000 + + (now.tv_nsec - last_frame_time.tv_nsec); + last_frame_time = now; + + if (diff >= ACCEPTABLE_FRAME_TIME && decodeUnit->frameType != FRAME_TYPE_IDR) + { + printf("dji_net: Dropping frame: %llums >= 50ms\n", diff / 1000000); + } + else + { + uint8_t frame_type = decodeUnit->frameType; + send(sockfd, &length, sizeof(length), 0); + send(sockfd, &frame_type, sizeof(frame_type), 0); + send(sockfd, buf, length, 0); + } - free(buf); + // diff = (now.tv_sec - last_key_time.tv_sec) * 1000000000 + + // (now.tv_nsec - last_key_time.tv_nsec); + // if (diff >= 1000000000) + // { + // last_key_time = now; + // return DR_NEED_IDR; + // } return DR_OK; } diff --git a/src/video/dji_usb.c b/src/video/dji_usb.c index cbcd42f..9ee6e75 100644 --- a/src/video/dji_usb.c +++ b/src/video/dji_usb.c @@ -2,11 +2,12 @@ #include #include #include +#include #include #include #include -#include co +#include #include #include "dji.h" @@ -18,7 +19,14 @@ #define USB_INTERFACE 3 #define USB_ENDPOINT_OUT 0x03 -libusb_device_handle *dev = NULL; +#define ACCEPTABLE_FRAME_TIME 50000000 + +static libusb_device_handle *dev = NULL; + +static struct timespec last_frame_time = {0, 0}; +// static struct timespec last_key_time = {0, 0}; + +static uint8_t buf[1000000]; static int dji_usb_setup(int videoFormat, int width, int height, int redrawRate, void *context, int drFlags) @@ -79,6 +87,9 @@ dji_usb_setup(int videoFormat, int width, int height, int redrawRate, void *cont exit(1); } + clock_gettime(CLOCK_MONOTONIC, &last_frame_time); + // last_key_time = last_frame_time; + return 0; } @@ -91,21 +102,38 @@ static void dji_usb_cleanup(void) static int dji_usb_submit_decode_unit(PDECODE_UNIT decodeUnit) { - uint8_t *buf = malloc(decodeUnit->fullLength); - PLENTRY entry = decodeUnit->bufferList; uint32_t length = 0; while (entry != NULL) { + if (length + entry->length > sizeof(buf)) + { + printf("dji_net: Frame too large: %d >= 1Mb\n", length + entry->length); + return DR_NEED_IDR; + } + memcpy(buf + length, entry->data, entry->length); length += entry->length; entry = entry->next; } - libusb_bulk_transfer(dev, USB_ENDPOINT_OUT, &length, sizeof(length), NULL, 0); - libusb_bulk_transfer(dev, USB_ENDPOINT_OUT, buf, length, NULL, 0); + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + uint64_t diff = (now.tv_sec - last_frame_time.tv_sec) * 1000000000 + + (now.tv_nsec - last_frame_time.tv_nsec); + last_frame_time = now; - free(buf); + if (diff >= ACCEPTABLE_FRAME_TIME && decodeUnit->frameType != FRAME_TYPE_IDR) + { + printf("dji_net: Dropping frame: %lums >= 50ms\n", diff / 1000000); + } + else + { + uint8_t frame_type = decodeUnit->frameType; + libusb_bulk_transfer(dev, USB_ENDPOINT_OUT, &length, sizeof(length), NULL, 0); + libusb_bulk_transfer(dev, USB_ENDPOINT_OUT, &frame_type, sizeof(frame_type), NULL, 0); + libusb_bulk_transfer(dev, USB_ENDPOINT_OUT, buf, length, NULL, 0); + } return DR_OK; } From 584ebc10ddd6cd9975f005ddd6d9785de44ee4a9 Mon Sep 17 00:00:00 2001 From: Dan Date: Tue, 11 Apr 2023 00:41:30 +0100 Subject: [PATCH 2/2] Update src/video/dji_usb.c --- src/video/dji_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/dji_usb.c b/src/video/dji_usb.c index 9ee6e75..051d49c 100644 --- a/src/video/dji_usb.c +++ b/src/video/dji_usb.c @@ -108,7 +108,7 @@ static int dji_usb_submit_decode_unit(PDECODE_UNIT decodeUnit) { if (length + entry->length > sizeof(buf)) { - printf("dji_net: Frame too large: %d >= 1Mb\n", length + entry->length); + printf("dji_usb: Frame too large: %d >= 1Mb\n", length + entry->length); return DR_NEED_IDR; }