Update source to Armbian-dev-202610.A311Y3
This commit is contained in:
@@ -92,6 +92,7 @@ GST_DEBUG_CATEGORY (gst_aml_hal_asink_debug_category);
|
||||
#define GST_AUDIO_FORMAT_TYPE_TRUE_HD 105
|
||||
#define GST_AUDIO_FORMAT_TYPE_MPEGH 106
|
||||
#define GST_AUDIO_FORMAT_TYPE_IAMF 107
|
||||
#define GST_AUDIO_FORMAT_TYPE_AAC_XHE 108
|
||||
|
||||
#define MAX_COMMIT_BYTES 30*1024
|
||||
#define MAX_COMMIT_COUNT 70
|
||||
@@ -206,6 +207,10 @@ struct _GstAmlHalAsinkPrivate
|
||||
gboolean xrun_paused;
|
||||
gboolean disable_xrun;
|
||||
|
||||
/* metrics info thread */
|
||||
GThread *metrics_thread;
|
||||
gboolean quit_metrics_thread;
|
||||
|
||||
#ifdef ESSOS_RM
|
||||
GMutex ess_lock;
|
||||
EssRMgr *rm;
|
||||
@@ -223,6 +228,8 @@ struct _GstAmlHalAsinkPrivate
|
||||
int64_t gap_start_pts;
|
||||
int32_t gap_duration;
|
||||
uint64_t gap_offset;
|
||||
int64_t drop_start_pts;
|
||||
int32_t drop_duration;
|
||||
|
||||
/* avsync */
|
||||
void * avsync;
|
||||
@@ -255,9 +262,6 @@ struct _GstAmlHalAsinkPrivate
|
||||
|
||||
guint64 clip_front;
|
||||
guint64 clip_back;
|
||||
/*audio metric info*/
|
||||
gint64 drop_start;
|
||||
gint64 drop_duration;
|
||||
int decoder_id;
|
||||
gboolean re_set_decoder_id;
|
||||
guint8 * codec_data;
|
||||
@@ -336,6 +340,7 @@ enum
|
||||
SIGNAL_XRUN,
|
||||
SIGNAL_AUDSWITCH,
|
||||
SIGNAL_DROPPTS,
|
||||
SIGNAL_METRICS,
|
||||
MAX_SIGNAL
|
||||
};
|
||||
|
||||
@@ -483,8 +488,10 @@ static void vol_ramp(guchar * data, gint size, gint ch_num, int dir);
|
||||
static void hal_set_player_overwrite (GstAmlHalAsink * sink, gboolean defaults);
|
||||
#endif
|
||||
static void hal_get_metric_info (GstAmlHalAsink * sink);
|
||||
static void check_drop_pts (GstAmlHalAsink *sink);
|
||||
static void check_metrics_info (GstAmlHalAsink *sink);
|
||||
static void set_decoder_id (GstAmlHalAsink *sink);
|
||||
static gpointer metrics_thread(gpointer para);
|
||||
|
||||
static void
|
||||
gst_aml_hal_asink_class_init (GstAmlHalAsinkClass * klass)
|
||||
{
|
||||
@@ -744,6 +751,17 @@ gst_aml_hal_asink_class_init (GstAmlHalAsinkClass * klass)
|
||||
G_TYPE_INT64,
|
||||
G_TYPE_INT64);
|
||||
|
||||
g_signals[SIGNAL_METRICS]= g_signal_new( "audio-metrics",
|
||||
G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)),
|
||||
(GSignalFlags) (G_SIGNAL_RUN_LAST),
|
||||
0, /* class offset */
|
||||
NULL, /* accumulator */
|
||||
NULL, /* accu data */
|
||||
g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_POINTER);
|
||||
|
||||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_aml_hal_asink_change_state);
|
||||
gstelement_class->provide_clock =
|
||||
@@ -824,7 +842,9 @@ gst_aml_hal_asink_init (GstAmlHalAsink* sink)
|
||||
priv->aligned_timeout = -1;
|
||||
priv->clip_front = 0;
|
||||
priv->clip_back = 0;
|
||||
priv->drop_start = -1;
|
||||
priv->gap_start_pts = -1;
|
||||
priv->gap_duration = -1;
|
||||
priv->drop_start_pts = -1;
|
||||
priv->drop_duration = -1;
|
||||
priv->decoder_id = 0;
|
||||
priv->re_set_decoder_id = false;
|
||||
@@ -1874,21 +1894,28 @@ parse_caps (GstAmlHalAsink* sink, GstAudioRingBufferSpec * spec, GstCaps * caps)
|
||||
if (codec_data_val) {
|
||||
GstBuffer *buf = gst_value_get_buffer(codec_data_val);
|
||||
GstMapInfo map;
|
||||
gst_buffer_map(buf, &map, GST_MAP_READ);
|
||||
|
||||
priv->codec_data = g_malloc0(map.size);
|
||||
if (priv->codec_data) {
|
||||
memcpy(priv->codec_data, map.data, map.size);
|
||||
priv->codec_data_size = map.size;
|
||||
GST_DEBUG_OBJECT (sink, "got code data %d bytes", priv->codec_data_size);
|
||||
} else {
|
||||
GST_ERROR_OBJECT (sink, "malloc fail!!");
|
||||
if (buf && gst_buffer_map(buf, &map, GST_MAP_READ)) {
|
||||
g_free (priv->codec_data);
|
||||
priv->codec_data = g_malloc0(map.size);
|
||||
if (priv->codec_data) {
|
||||
memcpy(priv->codec_data, map.data, map.size);
|
||||
priv->codec_data_size = map.size;
|
||||
priv->b_send_codec_data = FALSE;
|
||||
GST_DEBUG_OBJECT (sink, "got code data %d bytes", priv->codec_data_size);
|
||||
} else {
|
||||
priv->codec_data_size = 0;
|
||||
GST_ERROR_OBJECT (sink, "malloc fail!!");
|
||||
}
|
||||
gst_buffer_unmap(buf, &map);
|
||||
}
|
||||
gst_buffer_unmap(buf, &map);
|
||||
}
|
||||
}
|
||||
spec->type = GST_AUDIO_FORMAT_TYPE_AAC_XHE;
|
||||
GST_DEBUG_OBJECT (sink, "USAC profile, use AUDIO_FORMAT_AAC_XHE");
|
||||
} else {
|
||||
spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC;
|
||||
}
|
||||
spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC;
|
||||
info.bpf = 1;
|
||||
} else if (g_str_equal (mimetype, "audio/x-dts")
|
||||
|| g_str_equal (mimetype, "audio/x-gst-fourcc-dtse")
|
||||
@@ -3994,6 +4021,9 @@ hal_parse_spec (GstAmlHalAsink * sink, GstAudioRingBufferSpec * spec)
|
||||
case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC:
|
||||
priv->format_ = AUDIO_FORMAT_HE_AAC_V2;
|
||||
break;
|
||||
case GST_AUDIO_FORMAT_TYPE_AAC_XHE:
|
||||
priv->format_ = AUDIO_FORMAT_AAC_XHE;
|
||||
break;
|
||||
case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_DTS:
|
||||
priv->format_ = AUDIO_FORMAT_DTS;
|
||||
break;
|
||||
@@ -4168,6 +4198,49 @@ aml_open_output_stream (GstAmlHalAsink * sink, GstAudioRingBufferSpec * spec)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gpointer metrics_thread(gpointer para)
|
||||
{
|
||||
GstAmlHalAsink *sink = (GstAmlHalAsink *)para;
|
||||
GstAmlHalAsinkPrivate *priv = sink->priv;
|
||||
|
||||
GST_INFO_OBJECT (sink, "enter");
|
||||
while (!priv->quit_metrics_thread) {
|
||||
check_metrics_info(sink);
|
||||
/* Sleep for 100ms */
|
||||
g_usleep(100000);
|
||||
}
|
||||
GST_INFO_OBJECT (sink, "exit");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean start_metrics_thread(GstAmlHalAsink * sink)
|
||||
{
|
||||
GstAmlHalAsinkPrivate *priv = sink->priv;
|
||||
|
||||
priv->quit_metrics_thread = FALSE;
|
||||
priv->metrics_thread = g_thread_new("aml-asink-metrics", metrics_thread, sink);
|
||||
if (!priv->metrics_thread) {
|
||||
GST_ERROR_OBJECT(sink, "Failed to create metrics thread");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_INFO_OBJECT(sink, "metrics thread started");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void stop_metrics_thread(GstAmlHalAsink * sink)
|
||||
{
|
||||
GstAmlHalAsinkPrivate *priv = sink->priv;
|
||||
|
||||
if (priv->metrics_thread) {
|
||||
GST_INFO_OBJECT(sink, "stopping metrics thread");
|
||||
priv->quit_metrics_thread = TRUE;
|
||||
g_thread_join(priv->metrics_thread);
|
||||
priv->metrics_thread = NULL;
|
||||
GST_INFO_OBJECT(sink, "metrics thread stopped");
|
||||
}
|
||||
}
|
||||
|
||||
/* This method should create a new stream of the given @spec. No playback should
|
||||
* start yet so we start in the corked state. */
|
||||
static gboolean hal_acquire (GstAmlHalAsink * sink,
|
||||
@@ -4177,6 +4250,11 @@ static gboolean hal_acquire (GstAmlHalAsink * sink,
|
||||
if (!aml_open_output_stream (sink, spec))
|
||||
return FALSE;
|
||||
|
||||
/* Start metrics thread after stream is successfully opened */
|
||||
if (!start_metrics_thread(sink)) {
|
||||
GST_ERROR_OBJECT(sink, "Failed to start metrics thread");
|
||||
}
|
||||
|
||||
/* TODO:: configure volume when we changed it, else we leave the default */
|
||||
GST_DEBUG_OBJECT(sink, "done");
|
||||
return TRUE;
|
||||
@@ -4188,6 +4266,9 @@ static gboolean hal_release (GstAmlHalAsink * sink)
|
||||
GstAmlHalAsinkPrivate *priv = sink->priv;
|
||||
GST_INFO_OBJECT (sink, "enter");
|
||||
|
||||
/* Stop metrics thread before releasing the stream */
|
||||
stop_metrics_thread(sink);
|
||||
|
||||
hal_stop(sink);
|
||||
|
||||
g_mutex_lock(&priv->feed_lock);
|
||||
@@ -4798,7 +4879,8 @@ static guint hal_commit (GstAmlHalAsink * sink, guchar * data,
|
||||
// -----------------------------------------------------------------------
|
||||
//| 'A' | 'S' | 'C' | asc size | asc data | ES data |
|
||||
// -----------------------------------------------------------------------
|
||||
if (AUDIO_FORMAT_HE_AAC_V2 == priv->format_) {
|
||||
if (AUDIO_FORMAT_HE_AAC_V2 == priv->format_ ||
|
||||
AUDIO_FORMAT_AAC_XHE == priv->format_) {
|
||||
uint8_t aac_header[4] = {'A','S','C'};
|
||||
if (priv->codec_data_size > 255) {
|
||||
GST_ERROR_OBJECT(sink, "codec_data_size(%d) is too large", priv->codec_data_size);
|
||||
@@ -4891,7 +4973,6 @@ static guint hal_commit (GstAmlHalAsink * sink, guchar * data,
|
||||
|
||||
}
|
||||
|
||||
check_drop_pts(sink);
|
||||
if (!raw_data)
|
||||
priv->frame_sent++;
|
||||
|
||||
@@ -4917,41 +4998,48 @@ static uint32_t hal_get_latency (GstAmlHalAsink * sink)
|
||||
return latency;
|
||||
}
|
||||
|
||||
static void hal_get_metric_info (GstAmlHalAsink * sink)
|
||||
static void hal_get_metrics_info (GstAmlHalAsink * sink)
|
||||
{
|
||||
GstAmlHalAsinkPrivate *priv = sink->priv;
|
||||
char *metric = NULL;
|
||||
char *metrics_info = NULL;
|
||||
|
||||
GST_DEBUG_OBJECT (sink, "enter");
|
||||
g_mutex_lock(&priv->feed_lock);
|
||||
if (!priv->stream_) {
|
||||
g_mutex_unlock(&priv->feed_lock);
|
||||
GST_ERROR_OBJECT (sink, "null pointer");
|
||||
return;
|
||||
}
|
||||
|
||||
metric = priv->stream_->common.get_parameters((const struct audio_stream *)priv->stream_, "get_metric_info");
|
||||
if (NULL != metric) {
|
||||
sscanf(metric, "drop_start=%"PRId64",drop_duration=%"PRId64"", &priv->drop_start, &priv->drop_duration);
|
||||
free (metric);
|
||||
metrics_info = priv->stream_->common.get_parameters((struct audio_stream *)priv->stream_, "get_metrics_info");
|
||||
if (NULL != metrics_info) {
|
||||
sscanf(metrics_info, "drop_start_pts=%"PRId64",drop_duration=%"PRId32",gap_start_pts=%"PRId64",gap_duration=%"PRId32"",
|
||||
&priv->drop_start_pts, &priv->drop_duration, &priv->gap_start_pts, &priv->gap_duration);
|
||||
free(metrics_info);
|
||||
}
|
||||
GST_DEBUG_OBJECT (sink, " drop_start=%" PRId64 ", drop_duration=%" PRId64 "", priv->drop_start, priv->drop_duration);
|
||||
g_mutex_unlock(&priv->feed_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
static void check_drop_pts (GstAmlHalAsink *sink)
|
||||
static void check_metrics_info (GstAmlHalAsink *sink)
|
||||
{
|
||||
GstAmlHalAsinkPrivate *priv = sink->priv;
|
||||
|
||||
//get metric info
|
||||
hal_get_metric_info(sink);
|
||||
hal_get_metrics_info(sink);
|
||||
|
||||
if (-1 == priv->drop_duration) {
|
||||
return;
|
||||
if (priv->drop_duration > 0 || priv->gap_duration > 0) {
|
||||
GST_WARNING_OBJECT (sink, "emit metrics info signal, drop start:%" PRId64 ", drop duration:%" PRId32 ", gap start:%" PRId64 ", gap duration:%" PRId32"",
|
||||
priv->drop_start_pts, priv->drop_duration, priv->gap_start_pts, priv->gap_duration);
|
||||
GstMetricsInfo info;
|
||||
info.drop_start_pts = priv->drop_start_pts;
|
||||
info.drop_duration = priv->drop_duration;
|
||||
info.gap_start_pts = priv->gap_start_pts;
|
||||
info.gap_duration = priv->gap_duration;
|
||||
g_signal_emit (G_OBJECT (sink), g_signals[SIGNAL_METRICS], 0, &info);
|
||||
priv->drop_start_pts = -1;
|
||||
priv->drop_duration = -1;
|
||||
priv->gap_start_pts = -1;
|
||||
priv->gap_duration = -1;
|
||||
}
|
||||
|
||||
GST_WARNING_OBJECT (sink, "emit drop pts signal start:%" PRId64 ", duration:%" PRId64 "", priv->drop_start, priv->drop_duration);
|
||||
g_signal_emit (G_OBJECT (sink), g_signals[SIGNAL_DROPPTS], 0, priv->drop_start, priv->drop_duration, NULL);
|
||||
priv->drop_duration = -1;
|
||||
priv->drop_start = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,15 @@ typedef struct {
|
||||
gboolean enable;
|
||||
} TlvInfo;
|
||||
|
||||
|
||||
typedef struct {
|
||||
gint64 drop_start_pts;
|
||||
gint32 drop_duration;
|
||||
|
||||
gint64 gap_start_pts;
|
||||
gint32 gap_duration;
|
||||
} GstMetricsInfo;
|
||||
|
||||
GType gst_aml_hal_asink_get_type (void);
|
||||
|
||||
GstClock *gst_aml_hal_asink_get_clock (GstElement *element);
|
||||
|
||||
Reference in New Issue
Block a user