Create new send API
This API is used to send small messages. The message may consist of several smaller buffers or it may just be one buffer containing all the data. The total size of buffers must not exceed the MAX_PAYLOAD limit
This commit is contained in:
parent
9484444699
commit
6b89c779d7
|
@ -16,7 +16,7 @@
|
|||
#include "writer.hh"
|
||||
|
||||
// TODO implement frame splitting if data_len > MTU
|
||||
rtp_error_t kvz_rtp::generic::push_generic_frame(connection *conn, uint8_t *data, size_t data_len, uint32_t timestamp)
|
||||
rtp_error_t kvz_rtp::generic::push_generic_frame(kvz_rtp::connection *conn, uint8_t *data, size_t data_len, uint32_t timestamp)
|
||||
{
|
||||
if (data_len > MAX_PAYLOAD) {
|
||||
LOG_WARN("packet is larger (%zu bytes) than MAX_PAYLOAD (%u bytes)", data_len, MAX_PAYLOAD);
|
||||
|
@ -25,7 +25,7 @@ rtp_error_t kvz_rtp::generic::push_generic_frame(connection *conn, uint8_t *data
|
|||
uint8_t header[kvz_rtp::frame::HEADER_SIZE_RTP];
|
||||
conn->fill_rtp_header(header, timestamp);
|
||||
|
||||
return kvz_rtp::sender::write_frame(conn, header, sizeof(header), data, data_len);
|
||||
return kvz_rtp::send::send_frame(conn, header, sizeof(header), data, data_len);
|
||||
}
|
||||
|
||||
kvz_rtp::frame::rtp_frame *kvz_rtp::generic::process_generic_frame(
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
/* Validity of arguments is checked by kvz_rtp::sender. We just need to relay them there */
|
||||
rtp_error_t kvz_rtp::opus::push_opus_frame(connection *conn, uint8_t *data, uint32_t data_len, uint32_t timestamp)
|
||||
{
|
||||
return kvz_rtp::generic::push_generic_frame(conn, data, data_len, timestamp);
|
||||
|
||||
#if 0
|
||||
rtp_error_t ret;
|
||||
|
||||
if ((ret = kvz_rtp::sender::write_rtp_header(conn, timestamp)) != RTP_OK) {
|
||||
|
@ -18,7 +21,6 @@ rtp_error_t kvz_rtp::opus::push_opus_frame(connection *conn, uint8_t *data, uint
|
|||
|
||||
return kvz_rtp::sender::write_payload(conn, data, data_len);
|
||||
|
||||
#if 0
|
||||
uint8_t buffer[MAX_PACKET] = { 0 };
|
||||
RTPOpus::OpusConfig *config = (RTPOpus::OpusConfig *)conn->getConfig();
|
||||
|
||||
|
|
83
src/send.cc
83
src/send.cc
|
@ -16,76 +16,49 @@
|
|||
#include "util.hh"
|
||||
#include "writer.hh"
|
||||
|
||||
rtp_error_t kvz_rtp::sender::write_payload(kvz_rtp::connection *conn, uint8_t *payload, size_t payload_len)
|
||||
rtp_error_t kvz_rtp::send::send_frame(
|
||||
kvz_rtp::connection *conn,
|
||||
uint8_t *frame, size_t frame_len
|
||||
)
|
||||
{
|
||||
if (!conn)
|
||||
if (!conn || !frame || frame_len == 0)
|
||||
return RTP_INVALID_VALUE;
|
||||
|
||||
conn->inc_sent_bytes(payload_len);
|
||||
if (frame_len >= MAX_PAYLOAD) {
|
||||
LOG_WARN("Frame length (%lu) is larger than MAX_PAYLOAD (%u)", frame_len, MAX_PAYLOAD);
|
||||
}
|
||||
|
||||
conn->inc_sent_bytes(frame_len);
|
||||
conn->inc_sent_pkts();
|
||||
conn->inc_rtp_sequence();
|
||||
|
||||
return conn->get_socket().sendto(payload, payload_len, 0, NULL);
|
||||
return conn->get_socket().sendto(frame, frame_len, 0, NULL);
|
||||
}
|
||||
|
||||
rtp_error_t kvz_rtp::sender::write_generic_header(kvz_rtp::connection *conn, uint8_t *header, size_t header_len)
|
||||
{
|
||||
if (!conn)
|
||||
return RTP_INVALID_VALUE;
|
||||
|
||||
#ifdef __linux__
|
||||
return conn->get_socket().sendto(header, header_len, MSG_MORE, NULL);
|
||||
#else
|
||||
return conn->get_socket().sendto(header, header_len, MSG_PARTIAL, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
rtp_error_t kvz_rtp::sender::write_rtp_header(kvz_rtp::connection *conn, uint32_t timestamp)
|
||||
{
|
||||
if (!conn)
|
||||
return RTP_INVALID_VALUE;
|
||||
|
||||
uint8_t header[kvz_rtp::frame::HEADER_SIZE_RTP] = { 0 };
|
||||
conn->fill_rtp_header(header, timestamp);
|
||||
|
||||
return kvz_rtp::sender::write_generic_header(conn, header, kvz_rtp::frame::HEADER_SIZE_RTP);
|
||||
}
|
||||
|
||||
rtp_error_t kvz_rtp::sender::write_generic_frame(kvz_rtp::connection *conn, kvz_rtp::frame::rtp_frame *frame)
|
||||
{
|
||||
if (!frame)
|
||||
return RTP_INVALID_VALUE;
|
||||
|
||||
rtp_error_t ret;
|
||||
|
||||
if ((ret = kvz_rtp::sender::write_payload(conn, frame->data, frame->total_len)) != RTP_OK) {
|
||||
LOG_ERROR("Failed to send payload! Size %zu, Type %d", frame->total_len, frame->type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return RTP_OK;
|
||||
}
|
||||
|
||||
rtp_error_t kvz_rtp::sender::write_frame(
|
||||
rtp_error_t kvz_rtp::send::send_frame(
|
||||
kvz_rtp::connection *conn,
|
||||
uint8_t *header, size_t header_len,
|
||||
uint8_t *payload, size_t payload_len
|
||||
)
|
||||
{
|
||||
if (!conn || !header || !payload || header_len == 0 || payload_len == 0)
|
||||
if (!conn || !header || header_len == 0 || !payload || payload_len == 0)
|
||||
return RTP_INVALID_VALUE;
|
||||
|
||||
rtp_error_t ret;
|
||||
std::vector<std::pair<size_t, uint8_t *>> buffers;
|
||||
|
||||
if ((ret = kvz_rtp::sender::write_generic_header(conn, header, header_len)) != RTP_OK) {
|
||||
LOG_ERROR("Failed to write generic header, length: %zu", header_len);
|
||||
return ret;
|
||||
}
|
||||
buffers.push_back(std::make_pair(header_len, header));
|
||||
buffers.push_back(std::make_pair(payload_len, payload));
|
||||
|
||||
if ((ret = kvz_rtp::sender::write_payload(conn, payload, payload_len)) != RTP_OK) {
|
||||
LOG_ERROR("Failed to write payload, length: %zu", payload_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return conn->get_socket().sendto(buffers, 0);
|
||||
}
|
||||
|
||||
rtp_error_t kvz_rtp::send::send_frame(
|
||||
kvz_rtp::connection *conn,
|
||||
std::vector<std::pair<size_t, uint8_t *>>& buffers
|
||||
)
|
||||
{
|
||||
if (!conn)
|
||||
return RTP_INVALID_VALUE;
|
||||
|
||||
return conn->get_socket().sendto(buffers, 0);
|
||||
}
|
||||
|
|
76
src/send.hh
76
src/send.hh
|
@ -7,43 +7,59 @@
|
|||
namespace kvz_rtp {
|
||||
class connection;
|
||||
|
||||
namespace sender {
|
||||
namespace send {
|
||||
/* Send RTP Frame to remote
|
||||
*
|
||||
* This functions assumes "frame_len" is smaller than MAX_PAYLOAD
|
||||
* No measures are taken (apart from print a warning) if it's larger
|
||||
* TODO: should it split the frame?
|
||||
*
|
||||
* send_frame() assumes that "frame" starts with a valid RTP header
|
||||
*
|
||||
* Return RTP_OK on success
|
||||
* Return RTP_INVALID_VALUE if one of the values are invalid
|
||||
* Return RTP_SEND_ERROR if sending the frame failed */
|
||||
rtp_error_t send_frame(
|
||||
kvz_rtp::connection *conn,
|
||||
uint8_t *frame, size_t frame_len
|
||||
);
|
||||
|
||||
/* Write RTP Header to OS buffers. This should be called first when sending new RTP packet.
|
||||
/* Send RTP Frame to remote
|
||||
*
|
||||
* Return RTP_OK on success and RTP_ERROR on error */
|
||||
rtp_error_t write_rtp_header(kvz_rtp::connection *conn, uint32_t timestamp);
|
||||
|
||||
/* To minimize the amount of copying, write all headers directly to operating system's buffers
|
||||
* This function uses MSG_MORE/MSG_PARTIAL to prevent the actual sending.
|
||||
* This functions assumes "frame_len" + "header_len" is smaller than MAX_PAYLOAD
|
||||
* No measures are taken (apart from print a warning) if it's larger
|
||||
* TODO: should it split the frame?
|
||||
*
|
||||
* Return RTP_OK on success and RTP_ERROR on error */
|
||||
rtp_error_t write_generic_header(kvz_rtp::connection *conn, uint8_t *header, size_t header_len);
|
||||
|
||||
/* Write the actual data payload and send the full datagram to remote
|
||||
* send_frame() assumes that "header" points to a valid RTP header
|
||||
*
|
||||
* Caller should first write the RTP and all other necessary headers by calling
|
||||
* write_*_header() and then finalize the send by calling writePayload()
|
||||
*
|
||||
* return RTP_OK on success and RTP_ERROR on error */
|
||||
rtp_error_t write_payload(kvz_rtp::connection *conn, uint8_t *payload, size_t payload_len);
|
||||
|
||||
/* Write a generic frame
|
||||
* This function sends the datagram immediately,
|
||||
*
|
||||
* Return RTP_OK on success and RTP_ERROR on error */
|
||||
rtp_error_t write_generic_frame(kvz_rtp::connection *conn, kvz_rtp::frame::rtp_frame *frame);
|
||||
|
||||
/* If the header and payload of RTP messages are separate, the can be combined and sent
|
||||
* using write_frame()
|
||||
*
|
||||
* This function will send the message right away.
|
||||
*
|
||||
* return RTP_OK on success and RTP_ERROR on error */
|
||||
rtp_error_t write_frame(
|
||||
* Return RTP_OK on success
|
||||
* Return RTP_INVALID_VALUE if one of the values are invalid
|
||||
* Return RTP_SEND_ERROR if sending the frame failed */
|
||||
rtp_error_t send_frame(
|
||||
kvz_rtp::connection *conn,
|
||||
uint8_t *header, size_t header_len,
|
||||
uint8_t *payload, size_t payload_len
|
||||
);
|
||||
|
||||
/* Send RTP Frame to remote
|
||||
*
|
||||
* This functions assumes "frame_len" is smaller than MAX_PAYLOAD
|
||||
* No measures are taken (apart from print a warning) if it's larger
|
||||
* TODO: should it split the frame?
|
||||
*
|
||||
* send_frame() assumes that "buffers" contains at least two buffers:
|
||||
* - RTP header
|
||||
* - RTP payload
|
||||
*
|
||||
* RTP header must be the first buffer of the "buffers" vector
|
||||
*
|
||||
* Return RTP_OK on success
|
||||
* Return RTP_INVALID_VALUE if one of the values are invalid
|
||||
* Return RTP_SEND_ERROR if sending the frame failed */
|
||||
rtp_error_t send_frame(
|
||||
kvz_rtp::connection *conn,
|
||||
std::vector<std::pair<size_t, uint8_t *>>& buffers
|
||||
);
|
||||
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue