mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
rtpg729pay: properly support perfect-rtptime
This commit is contained in:
parent
713719f705
commit
d1974e386a
2 changed files with 62 additions and 21 deletions
|
@ -136,6 +136,9 @@ gst_rtp_g729_pay_reset (GstRTPG729Pay * pay)
|
||||||
{
|
{
|
||||||
gst_adapter_clear (pay->adapter);
|
gst_adapter_clear (pay->adapter);
|
||||||
pay->discont = FALSE;
|
pay->discont = FALSE;
|
||||||
|
pay->next_rtp_time = 0;
|
||||||
|
pay->first_ts = GST_CLOCK_TIME_NONE;
|
||||||
|
pay->first_rtp_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -159,10 +162,11 @@ gst_rtp_g729_pay_set_caps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtp_g729_pay_push (GstRTPG729Pay * rtpg729pay,
|
gst_rtp_g729_pay_push (GstRTPG729Pay * rtpg729pay,
|
||||||
const guint8 * data, guint payload_len, GstClockTime timestamp,
|
const guint8 * data, guint payload_len)
|
||||||
GstClockTime duration)
|
|
||||||
{
|
{
|
||||||
GstBaseRTPPayload *basepayload;
|
GstBaseRTPPayload *basepayload;
|
||||||
|
GstClockTime duration;
|
||||||
|
guint frames;
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
guint8 *payload;
|
guint8 *payload;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
@ -170,7 +174,7 @@ gst_rtp_g729_pay_push (GstRTPG729Pay * rtpg729pay,
|
||||||
basepayload = GST_BASE_RTP_PAYLOAD (rtpg729pay);
|
basepayload = GST_BASE_RTP_PAYLOAD (rtpg729pay);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rtpg729pay, "Pushing %d bytes ts %" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (rtpg729pay, "Pushing %d bytes ts %" GST_TIME_FORMAT,
|
||||||
payload_len, GST_TIME_ARGS (timestamp));
|
payload_len, GST_TIME_ARGS (rtpg729pay->next_ts));
|
||||||
|
|
||||||
/* create buffer to hold the payload */
|
/* create buffer to hold the payload */
|
||||||
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
|
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
|
||||||
|
@ -180,8 +184,14 @@ gst_rtp_g729_pay_push (GstRTPG729Pay * rtpg729pay,
|
||||||
memcpy (payload, data, payload_len);
|
memcpy (payload, data, payload_len);
|
||||||
|
|
||||||
/* set metadata */
|
/* set metadata */
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
frames =
|
||||||
|
(payload_len / G729_FRAME_SIZE) + ((payload_len % G729_FRAME_SIZE) >> 1);
|
||||||
|
duration = frames * G729_FRAME_DURATION;
|
||||||
|
GST_BUFFER_TIMESTAMP (outbuf) = rtpg729pay->next_ts;
|
||||||
GST_BUFFER_DURATION (outbuf) = duration;
|
GST_BUFFER_DURATION (outbuf) = duration;
|
||||||
|
GST_BUFFER_OFFSET (outbuf) = rtpg729pay->next_rtp_time;
|
||||||
|
rtpg729pay->next_ts += duration;
|
||||||
|
rtpg729pay->next_rtp_time += frames * 80;
|
||||||
|
|
||||||
if (G_UNLIKELY (rtpg729pay->discont)) {
|
if (G_UNLIKELY (rtpg729pay->discont)) {
|
||||||
GST_DEBUG_OBJECT (basepayload, "discont, setting marker bit");
|
GST_DEBUG_OBJECT (basepayload, "discont, setting marker bit");
|
||||||
|
@ -195,6 +205,24 @@ gst_rtp_g729_pay_push (GstRTPG729Pay * rtpg729pay,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_rtp_g729_pay_recalc_rtp_time (GstRTPG729Pay * rtpg729pay, GstClockTime time)
|
||||||
|
{
|
||||||
|
if (GST_CLOCK_TIME_IS_VALID (rtpg729pay->first_ts)
|
||||||
|
&& GST_CLOCK_TIME_IS_VALID (time) && time >= rtpg729pay->first_ts) {
|
||||||
|
GstClockTime diff;
|
||||||
|
guint32 rtpdiff;
|
||||||
|
|
||||||
|
diff = time - rtpg729pay->first_ts;
|
||||||
|
rtpdiff = (diff / GST_MSECOND) * 8;
|
||||||
|
rtpg729pay->next_rtp_time = rtpg729pay->first_rtp_time + rtpdiff;
|
||||||
|
GST_DEBUG_OBJECT (rtpg729pay,
|
||||||
|
"elapsed time %" GST_TIME_FORMAT ", rtp %d, "
|
||||||
|
"new offset %" G_GUINT64_FORMAT, GST_TIME_ARGS (diff), rtpdiff,
|
||||||
|
rtpg729pay->next_rtp_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtp_g729_pay_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buf)
|
gst_rtp_g729_pay_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
@ -271,34 +299,49 @@ gst_rtp_g729_pay_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buf)
|
||||||
"Calculated min_payload_len %u and max_payload_len %u",
|
"Calculated min_payload_len %u and max_payload_len %u",
|
||||||
min_payload_len, max_payload_len);
|
min_payload_len, max_payload_len);
|
||||||
|
|
||||||
if (GST_BUFFER_IS_DISCONT (buf))
|
|
||||||
rtpg729pay->discont = TRUE;
|
|
||||||
|
|
||||||
adapter = rtpg729pay->adapter;
|
adapter = rtpg729pay->adapter;
|
||||||
|
available = gst_adapter_available (adapter);
|
||||||
|
|
||||||
|
/* resync rtp time on discont or a discontinuous cn packet */
|
||||||
|
if (GST_BUFFER_IS_DISCONT (buf)) {
|
||||||
|
/* flush remainder */
|
||||||
|
if (available > 0) {
|
||||||
|
gst_rtp_g729_pay_push (rtpg729pay,
|
||||||
|
gst_adapter_take (adapter, available), available);
|
||||||
|
available = 0;
|
||||||
|
}
|
||||||
|
rtpg729pay->discont = TRUE;
|
||||||
|
gst_rtp_g729_pay_recalc_rtp_time (rtpg729pay, GST_BUFFER_TIMESTAMP (buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GST_BUFFER_SIZE (buf) < G729_FRAME_SIZE)
|
||||||
|
gst_rtp_g729_pay_recalc_rtp_time (rtpg729pay, GST_BUFFER_TIMESTAMP (buf));
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (rtpg729pay->first_ts))) {
|
||||||
|
rtpg729pay->first_ts = GST_BUFFER_TIMESTAMP (buf);
|
||||||
|
rtpg729pay->first_rtp_time = rtpg729pay->next_rtp_time;
|
||||||
|
}
|
||||||
|
|
||||||
/* let's reset the base timestamp when the adapter is empty */
|
/* let's reset the base timestamp when the adapter is empty */
|
||||||
if (gst_adapter_available (adapter) == 0)
|
if (available == 0)
|
||||||
rtpg729pay->next_ts = GST_BUFFER_TIMESTAMP (buf);
|
rtpg729pay->next_ts = GST_BUFFER_TIMESTAMP (buf);
|
||||||
|
|
||||||
if (gst_adapter_available (adapter) == 0 &&
|
if (available == 0 &&
|
||||||
GST_BUFFER_SIZE (buf) >= min_payload_len &&
|
GST_BUFFER_SIZE (buf) >= min_payload_len &&
|
||||||
GST_BUFFER_SIZE (buf) <= max_payload_len) {
|
GST_BUFFER_SIZE (buf) <= max_payload_len) {
|
||||||
ret = gst_rtp_g729_pay_push (rtpg729pay,
|
ret = gst_rtp_g729_pay_push (rtpg729pay,
|
||||||
GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf),
|
GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
|
||||||
GST_BUFFER_TIMESTAMP (buf), GST_BUFFER_DURATION (buf));
|
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_adapter_push (adapter, buf);
|
gst_adapter_push (adapter, buf);
|
||||||
|
|
||||||
available = gst_adapter_available (adapter);
|
available = gst_adapter_available (adapter);
|
||||||
|
|
||||||
/* as long as we have full frames */
|
/* as long as we have full frames */
|
||||||
/* this loop will push all available buffers till the last frame */
|
/* this loop will push all available buffers till the last frame */
|
||||||
while (available >= min_payload_len ||
|
while (available >= min_payload_len ||
|
||||||
available % G729_FRAME_SIZE == G729B_CN_FRAME_SIZE) {
|
available % G729_FRAME_SIZE == G729B_CN_FRAME_SIZE) {
|
||||||
GstClockTime duration;
|
|
||||||
|
|
||||||
/* We send as much as we can */
|
/* We send as much as we can */
|
||||||
if (available <= max_payload_len) {
|
if (available <= max_payload_len) {
|
||||||
payload_len = available;
|
payload_len = available;
|
||||||
|
@ -307,14 +350,9 @@ gst_rtp_g729_pay_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buf)
|
||||||
(available / G729_FRAME_SIZE) * G729_FRAME_SIZE);
|
(available / G729_FRAME_SIZE) * G729_FRAME_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
duration = (payload_len / G729_FRAME_SIZE) * G729_FRAME_DURATION;
|
|
||||||
rtpg729pay->next_ts += duration;
|
|
||||||
|
|
||||||
ret = gst_rtp_g729_pay_push (rtpg729pay,
|
ret = gst_rtp_g729_pay_push (rtpg729pay,
|
||||||
gst_adapter_take (adapter, payload_len), payload_len,
|
gst_adapter_take (adapter, payload_len), payload_len);
|
||||||
rtpg729pay->next_ts, duration);
|
available -= payload_len;
|
||||||
|
|
||||||
available = gst_adapter_available (adapter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -46,6 +46,9 @@ struct _GstRTPG729Pay
|
||||||
|
|
||||||
GstAdapter *adapter;
|
GstAdapter *adapter;
|
||||||
GstClockTime next_ts;
|
GstClockTime next_ts;
|
||||||
|
guint32 next_rtp_time;
|
||||||
|
GstClockTime first_ts;
|
||||||
|
guint32 first_rtp_time;
|
||||||
gboolean discont;
|
gboolean discont;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue