Update source to Armbian-dev-202610.A311Y3

This commit is contained in:
2026-11-11 08:50:43 +08:00
parent 3428a94f6b
commit f459ef6a9e
12514 changed files with 2264376 additions and 468481 deletions
@@ -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);