From 6c739b3d32c875b14ad09ab97fe17b1b1e932f52 Mon Sep 17 00:00:00 2001 From: Sergey Khripchenko Date: Mon, 25 Feb 2019 06:49:43 -0800 Subject: [PATCH] FS-11468 Try to split payload to packets evenly(with largest at the end) up to vpx_globals.rtp_slice_size, (assume hdrlen constant across all packets of the same picture). It keeps packets being transmitted in order. Without it last (and thus the smallest one) packet usually arrive out of order (before the previous one) --- src/switch_vpx.c | 67 ++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/src/switch_vpx.c b/src/switch_vpx.c index df3464115f..5191027638 100644 --- a/src/switch_vpx.c +++ b/src/switch_vpx.c @@ -699,7 +699,11 @@ static switch_status_t switch_vpx_init(switch_codec_t *codec, switch_codec_flag_ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "VPX VER:%s VPX_IMAGE_ABI_VERSION:%d VPX_CODEC_ABI_VERSION:%d\n", vpx_codec_version_str(), VPX_IMAGE_ABI_VERSION, VPX_CODEC_ABI_VERSION); - context->picture_id = 13; // picture Id may start from random value and must be incremented on each frame + if (!context->is_vp9) { + context->picture_id = 13; // picture Id may start from random value and must be incremented on each frame + } else { + context->vp9.picture_id = 13; + } return SWITCH_STATUS_SUCCESS; } @@ -708,7 +712,7 @@ static switch_status_t consume_partition(vpx_context_t *context, switch_frame_t { vpx_payload_descriptor_t *payload_descriptor; uint8_t *body, *c = NULL; - uint32_t hdrlen = 0, payload_size = 0, packet_size = 0, start = 0, key = 0; + uint32_t hdrlen = 0, payload_size = 0, max_payload_size = 0, start = 0, key = 0; switch_size_t remaining_bytes = 0; switch_status_t status; @@ -755,11 +759,6 @@ static switch_status_t consume_partition(vpx_context_t *context, switch_frame_t } body = ((uint8_t *)frame->data) + hdrlen; - packet_size = vpx_globals.rtp_slice_size; - payload_size = packet_size - hdrlen; - // else add extended TBD - - frame->datalen = hdrlen; if (context->is_vp9) { payload_descriptor->vp9.start = start; @@ -769,28 +768,14 @@ static switch_status_t consume_partition(vpx_context_t *context, switch_frame_t payload_descriptor->vp9.have_pid = 1; if (payload_descriptor->vp9.have_pid) { - - if (context->vp9.picture_id < 0) context->vp9.picture_id = 0; - if (context->vp9.picture_id > 0x7f) { *body++ = (context->vp9.picture_id >> 8) | 0x80; *body++ = context->vp9.picture_id & 0xff; - payload_size--; - frame->datalen++; + hdrlen += 2; } else { *body++ = context->vp9.picture_id; + hdrlen++; } - - - payload_size--; - frame->datalen++; - } - - if (start) { - context->vp9.picture_id++; -#ifdef DEBUG_VP9 - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sending pid: %d\n", context->vp9.picture_id); -#endif } if (key) { @@ -803,8 +788,7 @@ static switch_status_t consume_partition(vpx_context_t *context, switch_frame_t ss->y = 0; ss->zero = 0; body++; - payload_size--; - frame->datalen++; + hdrlen++; if (0) { // y ? uint16_t *w; @@ -820,19 +804,16 @@ static switch_status_t consume_partition(vpx_context_t *context, switch_frame_t *w = (uint16_t)context->codec_settings.video.width; *h = (uint16_t)context->codec_settings.video.height; - payload_size-= (ss->n_s + 1) * 4; - frame->datalen+= (ss->n_s + 1) * 4; + hdrlen += (ss->n_s + 1) * 4; } } else { payload_descriptor->vp9.have_p_layer = 1; } } - - } else { - payload_descriptor->vp8.start = start; } if (!context->is_vp9) { + payload_descriptor->vp8.start = start; payload_descriptor->vp8.extended = 1; /* REQUIRED header. */ @@ -853,21 +834,39 @@ static switch_status_t consume_partition(vpx_context_t *context, switch_frame_t payload_descriptor->vp8.KEYIDX = 0; } + /* + Try to split payload to packets evenly(with largest at the end) up to vpx_globals.rtp_slice_size, + (assume hdrlen constant across all packets of the same picture). + It keeps packets being transmitted in order. + Without it last (and thus the smallest one) packet usually arrive out of order + (before the previous one) + */ + max_payload_size = vpx_globals.rtp_slice_size - hdrlen; + payload_size = remaining_bytes / ((remaining_bytes + max_payload_size - 1) / max_payload_size); + if (remaining_bytes <= payload_size) { switch_buffer_read(context->pbuffer, body, remaining_bytes); context->pkt = NULL; - frame->datalen += remaining_bytes; + frame->datalen = hdrlen + remaining_bytes; frame->m = 1; - if (!context->is_vp9) { + + // increment and wrap picture_id (if needed) after the last picture's packet + if (context->is_vp9) { + context->vp9.picture_id++; + if ((uint16_t)context->vp9.picture_id > 0x7fff) { + context->vp9.picture_id = 0; + } + } else { context->picture_id++; - if (context->picture_id > 0x7fff) { + if ((uint16_t)context->picture_id > 0x7fff) { context->picture_id = 0; } } + status = SWITCH_STATUS_SUCCESS; } else { switch_buffer_read(context->pbuffer, body, payload_size); - frame->datalen += payload_size; + frame->datalen = hdrlen + payload_size; frame->m = 0; status = SWITCH_STATUS_MORE_DATA; }