formats: Modify RCE_FRAGMENT_GENERIC to follow existing definitions
I noticed that H263 uses a very similar fragmentation as RCE_FRAGMENT_GENERIC and this commit modifies the implementation to use the exactly same scheme in case we want to support H263 at some point.
This commit is contained in:
parent
f55c4578a8
commit
d359371040
|
@ -166,18 +166,11 @@ enum RTP_CTX_ENABLE_FLAGS {
|
|||
arrived. Does not work if the dependencies are not in monotonic order. */
|
||||
RCE_H26X_DEPENDENCY_ENFORCEMENT = 1 << 4,
|
||||
|
||||
/** Fragment generic frames into RTP packets of 1500 bytes.
|
||||
/** Fragment frames into RTP packets of MTU size (1500 bytes).
|
||||
*
|
||||
* If RCE_FRAGMENT_GENERIC is given to create_stream(), uvgRTP will split frames
|
||||
* of type RTP_FORMAT_GENERIC into packets of 1500 bytes automatically and reconstruct
|
||||
* the full frame from the fragments in the receiver
|
||||
*
|
||||
* This behavior is not from any specification and only supported by uvgRTP so it
|
||||
* will break interoperability between libraries if enabled.
|
||||
*
|
||||
* RCE_FRAGMENT_GENERIC can be used, for example, when you're using uvgRTP for
|
||||
* both sender and receiver and the media stream you wish to stream is not supported
|
||||
* by uvgRTP but requires packetization because MEDIA_FRAME_SIZE > MTU */
|
||||
* Some RTP profiles define fragmentation with marker bit indicating the end of frame.
|
||||
* You can enable this functionality using this flag at both sender and receiver.
|
||||
*/
|
||||
RCE_FRAGMENT_GENERIC = 1 << 5,
|
||||
|
||||
/** If SRTP is enabled and RCE_INPLACE_ENCRYPTION flag is *not* given,
|
||||
|
|
|
@ -49,14 +49,22 @@ rtp_error_t uvgrtp::formats::media::push_media_frame(uint8_t *data, size_t data_
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (!(rce_flags_ & RCE_FRAGMENT_GENERIC) || data_len <= rtp_ctx_->get_payload_size()) {
|
||||
// TODO: Some RTP formats use this fragmentation, enable it if support for those formats is added
|
||||
|
||||
bool fragmentation = (rce_flags_ & RCE_FRAGMENT_GENERIC);
|
||||
bool set_marker = false;
|
||||
|
||||
if (!fragmentation || data_len <= rtp_ctx_->get_payload_size()) {
|
||||
|
||||
set_marker = fragmentation;
|
||||
|
||||
if (data_len > rtp_ctx_->get_payload_size()) {
|
||||
UVG_LOG_WARN("Packet is larger (%zu bytes) than maximum payload size (%zu bytes)",
|
||||
data_len, rtp_ctx_->get_payload_size());
|
||||
UVG_LOG_WARN("Consider using RCE_FRAGMENT_GENERIC!");
|
||||
}
|
||||
|
||||
if ((ret = fqueue_->enqueue_message(data, data_len)) != RTP_OK) {
|
||||
if ((ret = fqueue_->enqueue_message(data, data_len, set_marker)) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to enqueue message: %d", ret);
|
||||
(void)fqueue_->deinit_transaction();
|
||||
return ret;
|
||||
|
@ -68,7 +76,6 @@ rtp_error_t uvgrtp::formats::media::push_media_frame(uint8_t *data, size_t data_
|
|||
size_t payload_size = rtp_ctx_->get_payload_size();
|
||||
ssize_t data_left = data_len;
|
||||
ssize_t data_pos = 0;
|
||||
bool set_marker = true;
|
||||
|
||||
while (data_left > (ssize_t)payload_size) {
|
||||
if ((ret = fqueue_->enqueue_message(data + data_pos, payload_size, set_marker)) != RTP_OK) {
|
||||
|
@ -102,10 +109,14 @@ rtp_error_t uvgrtp::formats::media::packet_handler(void *arg, int rce_flags, uvg
|
|||
uint32_t seq = frame->header.seq;
|
||||
uint32_t recv = 0;
|
||||
|
||||
bool fragmentation = (rce_flags & RCE_FRAGMENT_GENERIC);
|
||||
|
||||
/* If fragmentation of generic frame has not been enabled, we can just return the frame
|
||||
* in "out" because RTP packet handler has done all the necessasry stuff for small RTP packets */
|
||||
if (!(rce_flags & RCE_FRAGMENT_GENERIC))
|
||||
if (!fragmentation)
|
||||
{
|
||||
return RTP_PKT_READY;
|
||||
}
|
||||
|
||||
if (minfo->frames.find(ts) != minfo->frames.end()) {
|
||||
minfo->frames[ts].npkts++;
|
||||
|
@ -119,7 +130,14 @@ rtp_error_t uvgrtp::formats::media::packet_handler(void *arg, int rce_flags, uvg
|
|||
*out = nullptr;
|
||||
|
||||
if (frame->header.marker)
|
||||
{
|
||||
minfo->frames[ts].e_seq = seq;
|
||||
}
|
||||
else if (seq == minfo->frames[ts].s_seq - 1)
|
||||
{
|
||||
// try to detect if the start seq was ordered wrong
|
||||
minfo->frames[ts].s_seq = seq;
|
||||
}
|
||||
|
||||
if (minfo->frames[ts].e_seq != INVALID_SEQ && minfo->frames[ts].s_seq != INVALID_SEQ) {
|
||||
if (minfo->frames[ts].s_seq > minfo->frames[ts].e_seq)
|
||||
|
@ -154,7 +172,7 @@ rtp_error_t uvgrtp::formats::media::packet_handler(void *arg, int rce_flags, uvg
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (frame->header.marker) {
|
||||
if (!(frame->header.marker)) {
|
||||
minfo->frames[ts].npkts = 1;
|
||||
minfo->frames[ts].s_seq = seq;
|
||||
minfo->frames[ts].e_seq = INVALID_SEQ;
|
||||
|
@ -162,7 +180,7 @@ rtp_error_t uvgrtp::formats::media::packet_handler(void *arg, int rce_flags, uvg
|
|||
minfo->frames[ts].size = frame->payload_len;
|
||||
*out = nullptr;
|
||||
} else {
|
||||
return RTP_PKT_READY;
|
||||
return RTP_PKT_READY; // fragmentation is used, but there was only one packet for this frame
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue