flac: report latency in flacenc and flacdec

The FLAC specification states that the data is processed in blocks, regardless of the number of channels. Thus, The latency can be calculated using the blocksize and rate. For example a 1 second block sampled at 44.1KHz has a blocksize of 44100
This commit is contained in:
Julian Bouzas 2019-03-22 12:01:01 +01:00
parent d682c74c1e
commit 2ebdd70c21
2 changed files with 54 additions and 1 deletions

View file

@ -238,6 +238,22 @@ gst_flac_dec_stop (GstAudioDecoder * dec)
return TRUE;
}
static gint64
gst_flac_dec_get_latency (GstFlacDec * flacdec)
{
/* The FLAC specification states that the data is processed in blocks,
* regardless of the number of channels. Thus, The latency can be calculated
* using the blocksize and rate. For example a 1 second block sampled at
* 44.1KHz has a blocksize of 44100 */
/* Make sure the rate is valid */
if (!flacdec->info.rate)
return 0;
/* Calculate the latecy */
return (flacdec->max_blocksize * GST_SECOND) / flacdec->info.rate;
}
static gboolean
gst_flac_dec_set_format (GstAudioDecoder * dec, GstCaps * caps)
{
@ -294,6 +310,7 @@ gst_flac_dec_set_format (GstAudioDecoder * dec, GstCaps * caps)
}
}
GST_INFO_OBJECT (dec, "headers and metadata are now processed");
return TRUE;
}
@ -450,7 +467,9 @@ gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
const FLAC__StreamMetadata * metadata, void *client_data)
{
GstFlacDec *flacdec = GST_FLAC_DEC (client_data);
GstAudioDecoder *dec = GST_AUDIO_DECODER (client_data);
GstAudioChannelPosition position[8];
guint64 curr_latency = 0, old_latency = gst_flac_dec_get_latency (flacdec);
GST_LOG_OBJECT (flacdec, "metadata type: %d", metadata->type);
@ -507,6 +526,11 @@ gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
default:
break;
}
/* Update the latency if it has changed */
curr_latency = gst_flac_dec_get_latency (flacdec);
if (old_latency != curr_latency)
gst_audio_decoder_set_latency (dec, curr_latency, curr_latency);
}
static void

View file

@ -841,6 +841,26 @@ done:
return duration;
}
static gint64
gst_flac_enc_get_latency (GstFlacEnc * flacenc)
{
/* The FLAC specification states that the data is processed in blocks,
* regardless of the number of channels. Thus, The latency can be calculated
* using the blocksize and rate. For example a 1 second block sampled at
* 44.1KHz has a blocksize of 44100 */
/* Get the blocksize */
const guint blocksize = FLAC__stream_encoder_get_blocksize (flacenc->encoder);
/* Get the sample rate in KHz */
const guint rate = FLAC__stream_encoder_get_sample_rate (flacenc->encoder);
if (!rate)
return 0;
/* Calculate the latecy */
return (blocksize * GST_SECOND) / rate;
}
static gboolean
gst_flac_enc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
{
@ -887,7 +907,9 @@ gst_flac_enc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
if (init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK)
goto failed_to_initialize;
/* no special feedback to base class; should provide all available samples */
/* feedback to base class */
gst_audio_encoder_set_latency (enc,
gst_flac_enc_get_latency (flacenc), gst_flac_enc_get_latency (flacenc));
return TRUE;
@ -1440,6 +1462,8 @@ gst_flac_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstFlacEnc *this = GST_FLAC_ENC (object);
GstAudioEncoder *enc = GST_AUDIO_ENCODER (object);
guint64 curr_latency = 0, old_latency = gst_flac_enc_get_latency (this);
GST_OBJECT_LOCK (this);
@ -1507,6 +1531,11 @@ gst_flac_enc_set_property (GObject * object, guint prop_id,
}
GST_OBJECT_UNLOCK (this);
/* Update latency if it has changed */
curr_latency = gst_flac_enc_get_latency (this);
if (old_latency != curr_latency)
gst_audio_encoder_set_latency (enc, curr_latency, curr_latency);
}
static void