diff --git a/lib/micro-rtsp-server/include/micro_rtp_structs.h b/lib/micro-rtsp-server/include/micro_rtp_structs.h new file mode 100644 index 0000000..9c8b215 --- /dev/null +++ b/lib/micro-rtsp-server/include/micro_rtp_structs.h @@ -0,0 +1,51 @@ +#pragma once + +#include + +// https://www.ietf.org/rfc/rfc2326#section-10.12 +typedef struct __attribute__((packed)) +{ + char magic; // Magic encapsulation ASCII dollar sign (24 hexadecimal) + uint8_t channel; // Channel identifier + uint16_t length; // Network order +} rtp_over_tcp_hdr_t; + +// RTP data header - http://www.ietf.org/rfc/rfc3550.txt +typedef struct __attribute__((packed)) +{ + uint16_t version : 2; // protocol version + uint16_t padding : 1; // padding flag + uint16_t extension : 1; // header extension flag + uint16_t cc : 4; // CSRC count + uint16_t marker : 1; // marker bit + uint16_t pt : 7; // payload type + uint16_t seq : 16; // sequence number + uint32_t ts; // timestamp + uint32_t ssrc; // synchronization source +} rtp_hdr_t; + +// https://datatracker.ietf.org/doc/html/rfc2435 +typedef struct __attribute__((packed)) +{ + uint32_t tspec : 8; // type-specific field + uint32_t off : 24; // fragment byte offset + uint8_t type; // id of jpeg decoder params + uint8_t q; // Q values 0-127 indicate the quantization tables. JPEG types 0 and 1 (and their corresponding types 64 and 65) + uint8_t width; // frame width in 8 pixel blocks + uint8_t height; // frame height in 8 pixel blocks +} jpeg_hdr_t; + +typedef struct __attribute__((packed)) +{ + uint16_t dri; + uint16_t f : 1; + uint16_t l : 1; + uint16_t count : 14; +} jpeg_hdr_rst_t; + +typedef struct __attribute__((packed)) +{ + uint8_t mbz; + uint8_t precision; + uint16_t length; +} jpeg_hdr_qtable_t; diff --git a/lib/micro-rtsp-server/include/micro_rtsp_streamer.h b/lib/micro-rtsp-server/include/micro_rtsp_streamer.h index 465162f..16d3f64 100644 --- a/lib/micro-rtsp-server/include/micro_rtsp_streamer.h +++ b/lib/micro-rtsp-server/include/micro_rtsp_streamer.h @@ -1,5 +1,7 @@ #pragma once +#include + // https://en.wikipedia.org/wiki/Maximum_transmission_unit constexpr size_t max_wifi_mtu = 2304; // Payload JPG - https://www.ietf.org/rfc/rfc1890.txt @@ -8,17 +10,30 @@ constexpr uint8_t RTP_PAYLOAD_JPG = 26; constexpr size_t jpeg_luminance_table_length = 64; constexpr size_t jpeg_chrominance_table_length = 64; +// One of the types below will be returned, the jpeg_packet_with_quantization_t for the first packet, then the jpeg_packet_t + +typedef struct __attribute__((packed)) +{ + rtp_over_tcp_hdr_t rtp_over_tcp_hdr; + rtp_hdr_t rtp_hdr; + jpeg_hdr_t jpeg_hdr; + jpeg_hdr_qtable_t jpeg_hdr_qtable; + uint8_t quantization_table_luminance[jpeg_luminance_table_length]; + uint8_t quantization_table_chrominance[jpeg_chrominance_table_length]; + uint8_t jpeg_data[]; +} jpeg_packet_with_quantization_t; + +typedef struct __attribute__((packed)) +{ + rtp_over_tcp_hdr_t rtp_over_tcp_hdr; + rtp_hdr_t rtp_hdr; + jpeg_hdr_t jpeg_hdr; + uint8_t jpeg_data[]; +} jpeg_packet_t; + class micro_rtsp_streamer { public: - // https://www.ietf.org/rfc/rfc2326#section-10.12 - typedef struct __attribute__((packed)) - { - char magic; // Magic encapsulation ASCII dollar sign (24 hexadecimal) - uint8_t channel; // Channel identifier - uint16_t length; // Network order - } rtp_over_tcp_hdr_t; - micro_rtsp_streamer(const uint16_t width, const uint16_t height); rtp_over_tcp_hdr_t *create_jpg_packet(const uint8_t *jpg_scan, const uint8_t *jpg_scan_end, uint8_t **jpg_offset, const uint32_t timestamp, const uint8_t *quantization_table_luminance, const uint8_t *quantization_table_chrominance); @@ -26,65 +41,4 @@ private: uint16_t width_, height_; uint32_t ssrc_; uint16_t sequence_number_; - - // RTP data header - http://www.ietf.org/rfc/rfc3550.txt - typedef struct __attribute__((packed)) - { - uint16_t version : 2; // protocol version - uint16_t padding : 1; // padding flag - uint16_t extension : 1; // header extension flag - uint16_t cc : 4; // CSRC count - uint16_t marker : 1; // marker bit - uint16_t pt : 7; // payload type - uint16_t seq : 16; // sequence number - uint32_t ts; // timestamp - uint32_t ssrc; // synchronization source - } rtp_hdr_t; - - // https://datatracker.ietf.org/doc/html/rfc2435 - typedef struct __attribute__((packed)) - { - uint32_t tspec : 8; // type-specific field - uint32_t off : 24; // fragment byte offset - uint8_t type; // id of jpeg decoder params - uint8_t q; // Q values 0-127 indicate the quantization tables. JPEG types 0 and 1 (and their corresponding types 64 and 65) - uint8_t width; // frame width in 8 pixel blocks - uint8_t height; // frame height in 8 pixel blocks - } jpeg_hdr_t; - - typedef struct __attribute__((packed)) - { - uint16_t dri; - uint16_t f : 1; - uint16_t l : 1; - uint16_t count : 14; - } jpeg_hdr_rst_t; - - typedef struct __attribute__((packed)) - { - uint8_t mbz; - uint8_t precision; - uint16_t length; - } jpeg_hdr_qtable_t; - - // The types below will be returned, the jpeg_packet_with_quantization_t for the first packet, then the jpeg_packet_t - - typedef struct __attribute__((packed)) - { - rtp_over_tcp_hdr_t rtp_over_tcp_hdr; - rtp_hdr_t rtp_hdr; - jpeg_hdr_t jpeg_hdr; - jpeg_hdr_qtable_t jpeg_hdr_qtable; - uint8_t quantization_table_luminance[jpeg_luminance_table_length]; - uint8_t quantization_table_chrominance[jpeg_chrominance_table_length]; - uint8_t jpeg_data[]; - } jpeg_packet_with_quantization_t; - - typedef struct __attribute__((packed)) - { - rtp_over_tcp_hdr_t rtp_over_tcp_hdr; - rtp_hdr_t rtp_hdr; - jpeg_hdr_t jpeg_hdr; - uint8_t jpeg_data[]; - } jpeg_packet_t; }; \ No newline at end of file diff --git a/lib/micro-rtsp-server/src/micro_rtsp_server.cpp b/lib/micro-rtsp-server/src/micro_rtsp_server.cpp index 9d38ce7..0b5ef5e 100644 --- a/lib/micro-rtsp-server/src/micro_rtsp_server.cpp +++ b/lib/micro-rtsp-server/src/micro_rtsp_server.cpp @@ -72,7 +72,7 @@ void micro_rtsp_server::loop() { log_v("Stream frame to client: 0x%08x", client); // RTP over TCP encapsulates in a $ - client.write((const uint8_t *)packet, packet->length + sizeof(micro_rtsp_streamer::rtp_over_tcp_hdr_t)); + client.write((const uint8_t *)packet, packet->length + sizeof(rtp_over_tcp_hdr_t)); // TODO: UDP } free(packet); diff --git a/lib/micro-rtsp-server/src/micro_rtsp_streamer.cpp b/lib/micro-rtsp-server/src/micro_rtsp_streamer.cpp index 4ffa206..93a748e 100644 --- a/lib/micro-rtsp-server/src/micro_rtsp_streamer.cpp +++ b/lib/micro-rtsp-server/src/micro_rtsp_streamer.cpp @@ -15,7 +15,7 @@ micro_rtsp_streamer::micro_rtsp_streamer(const uint16_t width, const uint16_t he sequence_number_ = 0; } -micro_rtsp_streamer::rtp_over_tcp_hdr_t *micro_rtsp_streamer::create_jpg_packet(const uint8_t *jpg_scan, const uint8_t *jpg_scan_end, uint8_t **jpg_offset, const uint32_t timestamp, const uint8_t *quantization_table_luminance, const uint8_t *quantization_table_chrominance) +rtp_over_tcp_hdr_t *micro_rtsp_streamer::create_jpg_packet(const uint8_t *jpg_scan, const uint8_t *jpg_scan_end, uint8_t **jpg_offset, const uint32_t timestamp, const uint8_t *quantization_table_luminance, const uint8_t *quantization_table_chrominance) { log_v("jpg_scan:0x%08x, jpg_scan_end:0x%08x, jpg_offset:0x%08x, timestamp:%d, quantization_table_luminance:0x%08x, quantization_table_chrominance:0x%08x", jpg_scan, jpg_scan_end, jpg_offset, timestamp, quantization_table_luminance, quantization_table_chrominance); diff --git a/test/test_main.cpp b/test/test_main.cpp index f1c75e1..5fd8164 100644 --- a/test/test_main.cpp +++ b/test/test_main.cpp @@ -84,11 +84,11 @@ void test_jpg_decode() void test_struct_sizes() { - TEST_ASSERT_EQUAL(4, sizeof(micro_rtsp_streamer::rtp_over_tcp_hdr_t)); -// TEST_ASSERT_EQUAL(12, sizeof(micro_rtsp_streamer::rtp_hdr_t)); -// TEST_ASSERT_EQUAL(8, sizeof(micro_rtsp_streamer::jpeg_hdr_t)); -// TEST_ASSERT_EQUAL(4, sizeof(micro_rtsp_streamer::jpeg_hdr_qtable_t)); -// TEST_ASSERT_EQUAL(24, sizeof(micro_rtsp_streamer::jpeg_packet_t)); + TEST_ASSERT_EQUAL(4, sizeof(rtp_over_tcp_hdr_t)); + TEST_ASSERT_EQUAL(12, sizeof(rtp_hdr_t)); + TEST_ASSERT_EQUAL(8, sizeof(jpeg_hdr_t)); + TEST_ASSERT_EQUAL(4, sizeof(jpeg_hdr_qtable_t)); + TEST_ASSERT_EQUAL(24, sizeof(jpeg_packet_t)); } void setup()