Merge branch 'gst-plugins-bad-avtp_crf_align_with_packet_interval' into 'main'

avtp: crf: sync: Align to AAF/CVF packet interval

See merge request gstreamer/gstreamer!1071
This commit is contained in:
twischer 2024-05-03 17:19:44 +00:00
commit 65a3a6ce28
3 changed files with 68 additions and 14 deletions

View file

@ -182,13 +182,7 @@ gst_avtp_crf_sync_transform_ip (GstBaseTransform * parent, GstBuffer * buffer)
if (h264_time < current_ts)
h264_time += (1ULL << 32);
/*
* float typecasted to guint64 truncates the decimal part. So, round() it
* before casting.
*/
adjusted_h264_time =
(GstClockTime) roundl (current_ts + ceill (((gdouble) h264_time -
current_ts) / avg_period) * avg_period);
adjusted_h264_time = gst_avtp_crf_adjust_ts (avtpcrfbase, pdu, h264_time);
res =
avtp_cvf_pdu_set (pdu, AVTP_CVF_FIELD_H264_TIMESTAMP,
adjusted_h264_time);
@ -212,13 +206,7 @@ gst_avtp_crf_sync_transform_ip (GstBaseTransform * parent, GstBuffer * buffer)
if (tstamp < current_ts)
tstamp += (1ULL << 32);
/*
* float typecasted to guint64 truncates the decimal part. So, round() it
* before casting.
*/
adjusted_tstamp =
(GstClockTime) roundl (current_ts + ceill ((tstamp -
current_ts) / avg_period) * avg_period);
adjusted_tstamp = gst_avtp_crf_adjust_ts (avtpcrfbase, pdu, tstamp);
set_avtp_tstamp (avtpcrfsync, pdu, adjusted_tstamp);
set_avtp_mr_bit (avtpcrfsync, pdu, thread_data->mr);
GST_LOG_OBJECT (avtpcrfsync,

View file

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <math.h>
#include <avtp.h>
#include <avtp_aaf.h>
#include <avtp_cvf.h>
@ -115,3 +116,66 @@ h264_tstamp_valid (struct avtp_stream_pdu *pdu)
}
return FALSE;
}
/* Returns only valid values when the AVTP timestamp is valid
* In case of CVF a single video frame might be fragmented but only the last
* fragment/PDU contains the valid timestamp.
*/
static guint
get_events_per_ts (const GstAvtpCrfBase * const avtpcrfbase,
const struct avtp_stream_pdu *const pdu)
{
guint32 type;
guint64 len;
guint64 channels;
guint64 bit_depth;
int res;
res =
avtp_pdu_get ((struct avtp_common_pdu *) pdu, AVTP_FIELD_SUBTYPE, &type);
g_assert (res == 0);
switch (type) {
case AVTP_SUBTYPE_AAF:
res = avtp_aaf_pdu_get (pdu, AVTP_AAF_FIELD_STREAM_DATA_LEN, &len);
g_assert (res == 0);
res = avtp_aaf_pdu_get (pdu, AVTP_AAF_FIELD_CHAN_PER_FRAME, &channels);
g_assert (res == 0);
res = avtp_aaf_pdu_get (pdu, AVTP_AAF_FIELD_BIT_DEPTH, &bit_depth);
g_assert (res == 0);
/* calculate audio samples/events per PDU */
return (len * 8) / (channels * bit_depth);
break;
case AVTP_SUBTYPE_CVF:
// TODO expects that one video frame is between valid timestamps and
// avtpcrfbase->thread_data.average_period is calculated from CRF video
// frame sync type
return 1;
default:
GST_INFO_OBJECT (avtpcrfbase, "type 0x%x not supported.\n", type);
break;
}
return 1;
}
GstClockTime
gst_avtp_crf_adjust_ts (GstAvtpCrfBase * const avtpcrfbase,
const struct avtp_stream_pdu * const pdu, GstClockTime tstamp)
{
const GstAvtpCrfThreadData *const thread_data = &avtpcrfbase->thread_data;
const GstClockTime current_ts = thread_data->current_ts;
const guint events_per_ts = get_events_per_ts (avtpcrfbase, pdu);
const gdouble avg_period = thread_data->average_period * events_per_ts;
GstClockTime adjusted_tstamp;
/*
* float typecasted to guint64 truncates the decimal part. So, round() it
* before casting.
*/
adjusted_tstamp =
(GstClockTime) roundl (current_ts + ceill (((gdouble) tstamp -
current_ts) / avg_period) * avg_period);
return adjusted_tstamp;
}

View file

@ -28,5 +28,7 @@ gboolean buffer_size_valid (GstMapInfo * info);
GstClockTime get_avtp_tstamp (GstAvtpCrfBase * avtpcrfbase,
struct avtp_stream_pdu * pdu);
gboolean h264_tstamp_valid (struct avtp_stream_pdu * pdu);
GstClockTime gst_avtp_crf_adjust_ts (GstAvtpCrfBase * const avtpcrfbase,
const struct avtp_stream_pdu * const pdu, GstClockTime tstamp);
#endif /* __GST_AVTP_CRF_UTILS_H__ */