This commit is contained in:
Rene Zeldenthuis
2024-04-01 19:58:44 +02:00
parent f59fb8bb9a
commit 5117f0d21a
9 changed files with 90 additions and 64 deletions

View File

@@ -7,6 +7,7 @@
micro_rtsp_streamer::micro_rtsp_streamer(const uint16_t width, const uint16_t height)
{
log_v("width:%d, height:%d", width, height);
width_ = width;
height_ = height;
// Random number
@@ -14,8 +15,10 @@ micro_rtsp_streamer::micro_rtsp_streamer(const uint16_t width, const uint16_t he
sequence_number_ = 0;
}
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)
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)
{
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);
// The MTU of wireless networks is 2,312 bytes. This size includes the packet headers.
const auto isFirstFragment = jpg_scan == *jpg_offset;
const auto include_quantization_tables = isFirstFragment && quantization_table_luminance != nullptr && quantization_table_chrominance != nullptr;
@@ -31,44 +34,37 @@ rtp_over_tcp_hdr_t *micro_rtsp_streamer::create_jpg_packet(const uint8_t *jpg_sc
const auto packet = (jpeg_packet_t *)calloc(1, packet_size);
// 4 bytes RTP over TCP header
assert(4 == sizeof(rtp_over_tcp_hdr_t));
packet->rtp_over_tcp_hdr.magic = '$'; // encapsulation
packet->rtp_over_tcp_hdr.channel = 0; // number of multiplexed sub-channel on RTPS connection - here the RTP channel
packet->rtp_over_tcp_hdr.length = packet_size;
log_v("rtp_over_tcp_hdr_t={.magic=%c,.channel=%i,.length=%i}", packet->rtp_over_tcp_hdr.magic, packet->rtp_over_tcp_hdr.channel, packet->rtp_over_tcp_hdr.length);
log_v("rtp_over_tcp_hdr_t={.magic=%c,.channel=%u,.length=%u}", packet->rtp_over_tcp_hdr.magic, packet->rtp_over_tcp_hdr.channel, packet->rtp_over_tcp_hdr.length);
// 12 bytes RTP header
assert(12 == sizeof(rtp_hdr_t));
packet->rtp_hdr.version = 2;
packet->rtp_hdr.marker = isLastFragment;
packet->rtp_hdr.pt = RTP_PAYLOAD_JPG;
packet->rtp_hdr.seq = sequence_number_;
packet->rtp_hdr.ts = timestamp;
packet->rtp_hdr.ssrc = ssrc_;
log_v("rtp_hdr={.version:%i,.padding:%i,.extension:%i,.cc:%i,.marker:%i,.pt:%i,.seq:%i,.ts:%u,.ssrc:%u}", packet->rtp_hdr.version, packet->rtp_hdr.padding, packet->rtp_hdr.extension, packet->rtp_hdr.cc, packet->rtp_hdr.marker, packet->rtp_hdr.pt, packet->rtp_hdr.seq, packet->rtp_hdr.ts, packet->rtp_hdr.ssrc);
log_v("rtp_hdr={.version:%u,.padding:%u,.extension:%u,.cc:%u,.marker:%u,.pt:%u,.seq:%u,.ts:%u,.ssrc:%u}", packet->rtp_hdr.version, packet->rtp_hdr.padding, packet->rtp_hdr.extension, packet->rtp_hdr.cc, packet->rtp_hdr.marker, packet->rtp_hdr.pt, packet->rtp_hdr.seq, packet->rtp_hdr.ts, packet->rtp_hdr.ssrc);
// 8 bytes JPEG payload header
assert(8 == sizeof(jpeg_hdr_t));
packet->jpeg_hdr.tspec = 0; // type-specific field
packet->jpeg_hdr.off = (uint32_t)(*jpg_offset - jpg_scan); // fragment byte offset (24 bits in jpg)
packet->jpeg_hdr.type = 0; // id of jpeg decoder params
packet->jpeg_hdr.q = (uint8_t)(include_quantization_tables ? 0x80 : 0x5e); // quantization factor (or table id) 5eh=94d
packet->jpeg_hdr.width = (uint8_t)(width_ >> 3); // frame width in 8 pixel blocks
packet->jpeg_hdr.height = (uint8_t)(height_ >> 3); // frame height in 8 pixel blocks
log_v("jpeg_hdr={.tspec:%i,.off:0x%6x,.type:0x2%x,.q:%i,.width:%i.height:%i}", packet->jpeg_hdr.tspec, packet->jpeg_hdr.off, packet->jpeg_hdr.type, packet->jpeg_hdr.q, packet->jpeg_hdr.width, packet->jpeg_hdr.height);
// length so far should be 24 bytes
assert(24 == sizeof(jpeg_packet_t));
log_v("jpeg_hdr={.tspec:%u,.off:0x%6x,.type:0x2%x,.q:%u,.width:%u.height:%u}", packet->jpeg_hdr.tspec, packet->jpeg_hdr.off, packet->jpeg_hdr.type, packet->jpeg_hdr.q, packet->jpeg_hdr.width, packet->jpeg_hdr.height);
if (include_quantization_tables)
{
const auto packet_with_quantization = (jpeg_packet_with_quantization_t *)packet;
assert(4 == sizeof(jpeg_hdr_qtable_t));
// Only in first packet of the frame
packet_with_quantization->jpeg_hdr_qtable.mbz = 0;
packet_with_quantization->jpeg_hdr_qtable.precision = 0; // 8 bit precision
packet_with_quantization->jpeg_hdr_qtable.length = jpeg_luminance_table_length + jpeg_chrominance_table_length;
log_v("jpeg_hdr_qtable={.mbz:%i,.precision:%i,.length:%d}", packet_with_quantization->jpeg_hdr_qtable.mbz, packet_with_quantization->jpeg_hdr_qtable.precision, packet_with_quantization->jpeg_hdr_qtable.length);
log_v("jpeg_hdr_qtable={.mbz:%u,.precision:%u,.length:%u}", packet_with_quantization->jpeg_hdr_qtable.mbz, packet_with_quantization->jpeg_hdr_qtable.precision, packet_with_quantization->jpeg_hdr_qtable.length);
memcpy(packet_with_quantization->quantization_table_luminance, quantization_table_luminance, jpeg_luminance_table_length);
memcpy(packet_with_quantization->quantization_table_chrominance, quantization_table_chrominance, jpeg_chrominance_table_length);
// Copy JPG data
@@ -85,5 +81,5 @@ rtp_over_tcp_hdr_t *micro_rtsp_streamer::create_jpg_packet(const uint8_t *jpg_sc
// Update sequence number
sequence_number_++;
return (rtp_over_tcp_hdr_t*)packet;
return (rtp_over_tcp_hdr_t *)packet;
}