voaacenc: Only generate sinkcaps once and in a threadsafe way

This commit is contained in:
Sebastian Dröge 2011-04-19 09:49:08 +02:00
parent adb3ac9237
commit dc7f93c05b
2 changed files with 81 additions and 89 deletions

View file

@ -89,10 +89,12 @@ static GstCaps *gst_voaacenc_getcaps (GstPad * pad);
static GstCaps *gst_voaacenc_create_source_pad_caps (GstVoAacEnc * voaacenc); static GstCaps *gst_voaacenc_create_source_pad_caps (GstVoAacEnc * voaacenc);
static gint voaacenc_get_rate_index (gint rate); static gint voaacenc_get_rate_index (gint rate);
static gpointer
gst_voaacenc_generate_sink_caps (gpointer data)
{
#define VOAAC_ENC_MAX_CHANNELS 6 #define VOAAC_ENC_MAX_CHANNELS 6
/* describe the channels position */ /* describe the channels position */
const GstAudioChannelPosition static const GstAudioChannelPosition
gst_voaacenc_channel_position[][VOAAC_ENC_MAX_CHANNELS] = { gst_voaacenc_channel_position[][VOAAC_ENC_MAX_CHANNELS] = {
{ /* 1 ch: Mono */ { /* 1 ch: Mono */
GST_AUDIO_CHANNEL_POSITION_FRONT_MONO}, GST_AUDIO_CHANNEL_POSITION_FRONT_MONO},
@ -121,7 +123,54 @@ const GstAudioChannelPosition
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
GST_AUDIO_CHANNEL_POSITION_LFE} GST_AUDIO_CHANNEL_POSITION_LFE}
}; };
GstCaps *caps = gst_caps_new_empty ();
gint i, c;
for (i = 0; i < VOAAC_ENC_MAX_CHANNELS; i++) {
GValue chanpos = { 0 };
GValue pos = { 0 };
GstStructure *structure;
g_value_init (&chanpos, GST_TYPE_ARRAY);
g_value_init (&pos, GST_TYPE_AUDIO_CHANNEL_POSITION);
for (c = 0; c <= i; c++) {
g_value_set_enum (&pos, gst_voaacenc_channel_position[i][c]);
gst_value_array_append_value (&chanpos, &pos);
}
g_value_unset (&pos);
structure = gst_structure_new ("audio/x-raw-int",
"width", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"signed", G_TYPE_BOOLEAN, TRUE,
"endianness", G_TYPE_INT, G_BYTE_ORDER,
"rate", GST_TYPE_INT_RANGE, 8000, 96000, "channels", G_TYPE_INT, i + 1,
NULL);
gst_structure_set_value (structure, "channel-positions", &chanpos);
g_value_unset (&chanpos);
gst_caps_append_structure (caps, structure);
}
GST_DEBUG ("generated sink caps: %" GST_PTR_FORMAT, caps);
return caps;
}
static GstCaps *
gst_voaacenc_get_sink_caps (void)
{
static GOnce g_once = G_ONCE_INIT;
GstCaps *caps;
g_once (&g_once, gst_voaacenc_generate_sink_caps, NULL);
caps = g_once.retval;
return gst_caps_ref (caps);
}
static void static void
_do_init (GType object_type) _do_init (GType object_type)
@ -235,7 +284,6 @@ gst_voaacenc_init (GstVoAacEnc * voaacenc, GstVoAacEncClass * klass)
/* init rest */ /* init rest */
voaacenc->handle = NULL; voaacenc->handle = NULL;
voaacenc->sinkcaps = NULL;
} }
static void static void
@ -245,11 +293,6 @@ gst_voaacenc_finalize (GObject * object)
voaacenc = GST_VOAACENC (object); voaacenc = GST_VOAACENC (object);
if (voaacenc->sinkcaps) {
gst_caps_unref (voaacenc->sinkcaps);
voaacenc->sinkcaps = NULL;
}
g_object_unref (G_OBJECT (voaacenc->adapter)); g_object_unref (G_OBJECT (voaacenc->adapter));
voaacenc->adapter = NULL; voaacenc->adapter = NULL;
@ -288,58 +331,10 @@ gst_voaacenc_negotiate (GstVoAacEnc * voaacenc)
gst_caps_unref (caps); gst_caps_unref (caps);
} }
static GstCaps *
gst_voaacenc_generate_sink_caps (void)
{
GstCaps *caps = gst_caps_new_empty ();
gint i, c;
for (i = 0; i < VOAAC_ENC_MAX_CHANNELS; i++) {
GValue chanpos = { 0 };
GValue pos = { 0 };
GstStructure *structure;
g_value_init (&chanpos, GST_TYPE_ARRAY);
g_value_init (&pos, GST_TYPE_AUDIO_CHANNEL_POSITION);
for (c = 0; c <= i; c++) {
g_value_set_enum (&pos, gst_voaacenc_channel_position[i][c]);
gst_value_array_append_value (&chanpos, &pos);
}
g_value_unset (&pos);
structure = gst_structure_new ("audio/x-raw-int",
"width", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"signed", G_TYPE_BOOLEAN, TRUE,
"endianness", G_TYPE_INT, G_BYTE_ORDER,
"rate", GST_TYPE_INT_RANGE, 8000, 96000, "channels", G_TYPE_INT, i + 1,
NULL);
gst_structure_set_value (structure, "channel-positions", &chanpos);
g_value_unset (&chanpos);
gst_caps_append_structure (caps, structure);
}
return caps;
}
static GstCaps * static GstCaps *
gst_voaacenc_getcaps (GstPad * pad) gst_voaacenc_getcaps (GstPad * pad)
{ {
GstVoAacEnc *voaacenc = GST_VOAACENC (GST_PAD_PARENT (pad)); return gst_voaacenc_get_sink_caps ();
if (voaacenc->sinkcaps == NULL) {
voaacenc->sinkcaps = gst_voaacenc_generate_sink_caps ();
}
GST_DEBUG_OBJECT (voaacenc, "generated sink caps: %" GST_PTR_FORMAT,
voaacenc->sinkcaps);
return gst_caps_ref (voaacenc->sinkcaps);
} }
@ -549,8 +544,6 @@ gst_voaacenc_create_source_pad_caps (GstVoAacEnc * voaacenc)
return caps; return caps;
} }
static VO_U32 static VO_U32
voaacenc_core_mem_alloc (VO_S32 uID, VO_MEM_INFO * pMemInfo) voaacenc_core_mem_alloc (VO_S32 uID, VO_MEM_INFO * pMemInfo)
{ {

View file

@ -47,7 +47,6 @@ struct _GstVoAacEnc {
/* pads */ /* pads */
GstPad *sinkpad, *srcpad; GstPad *sinkpad, *srcpad;
GstCaps *sinkcaps;
gboolean discont; gboolean discont;
GstAdapter *adapter; GstAdapter *adapter;