From a1e06be84bfc52bc4f08a9a1da9c70e406c1c68e Mon Sep 17 00:00:00 2001 From: Aaro Altonen Date: Tue, 4 Aug 2020 12:06:41 +0300 Subject: [PATCH] Implement push_frame() for generic media formats --- src/formats/media.cc | 52 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/formats/media.cc b/src/formats/media.cc index 36b38b1..87d2b9e 100644 --- a/src/formats/media.cc +++ b/src/formats/media.cc @@ -31,8 +31,56 @@ rtp_error_t uvg_rtp::formats::media::push_frame(std::unique_ptr data, rtp_error_t uvg_rtp::formats::media::__push_frame(uint8_t *data, size_t data_len, int flags) { - (void)data, (void)data_len, (void)flags; - return RTP_GENERIC_ERROR; + std::vector> buffers; + size_t payload_size = rtp_ctx_->get_payload_size(); + uint8_t header[uvg_rtp::frame::HEADER_SIZE_RTP]; + + /* fill RTP header with our session's values + * and push the header to the buffer vector to use vectored I/O */ + rtp_ctx_->fill_header(header); + buffers.push_back(std::make_pair(sizeof(header), header)); + buffers.push_back(std::make_pair(data_len, data)); + + if (data_len > payload_size) { + if (flags_ & RCE_FRAGMENT_GENERIC) { + + rtp_error_t ret = RTP_OK; + ssize_t data_left = data_len; + ssize_t data_pos = 0; + + /* set marker bit for the first fragment */ + header[1] |= (1 << 7); + + while (data_left > (ssize_t)payload_size) { + buffers.at(1).first = payload_size; + buffers.at(1).second = data + data_pos; + + if ((ret = socket_->sendto(buffers, 0)) != RTP_OK) + return ret; + + rtp_ctx_->update_sequence(header); + + data_pos += payload_size; + data_left -= payload_size; + + /* clear marker bit for middle fragments */ + header[1] &= 0x7f; + } + + /* set marker bit for the last frame */ + header[1] |= (1 << 7); + + buffers.at(1).first = data_left; + buffers.at(1).second = data + data_pos; + + return socket_->sendto(buffers, 0); + + } else { + LOG_WARN("Packet is larger (%zu bytes) than payload_size (%zu bytes)", data_len, payload_size); + } + } + + return socket_->sendto(buffers, 0); } static rtp_error_t packet_handler(ssize_t size, void *packet, uvg_rtp::frame::rtp_frame **out)