mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
faac: Only accept specific channel layouts as required by AAC
Fixes bug #607105.
This commit is contained in:
parent
be9ca4d5e1
commit
007b667366
1 changed files with 75 additions and 0 deletions
|
@ -48,6 +48,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gst/audio/multichannel.h>
|
||||
|
||||
#include "gstfaac.h"
|
||||
|
||||
#define SINK_CAPS \
|
||||
|
@ -120,6 +122,7 @@ static void gst_faac_get_property (GObject * object,
|
|||
static gboolean gst_faac_sink_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_faac_configure_source_pad (GstFaac * faac);
|
||||
static gboolean gst_faac_sink_setcaps (GstPad * pad, GstCaps * caps);
|
||||
static GstCaps *gst_faac_sink_getcaps (GstPad * pad);
|
||||
static GstFlowReturn gst_faac_push_buffers (GstFaac * faac, gboolean force);
|
||||
static GstFlowReturn gst_faac_chain (GstPad * pad, GstBuffer * data);
|
||||
static GstStateChangeReturn gst_faac_change_state (GstElement * element,
|
||||
|
@ -296,6 +299,8 @@ gst_faac_init (GstFaac * faac)
|
|||
GST_DEBUG_FUNCPTR (gst_faac_chain));
|
||||
gst_pad_set_setcaps_function (faac->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_faac_sink_setcaps));
|
||||
gst_pad_set_getcaps_function (faac->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_faac_sink_getcaps));
|
||||
gst_pad_set_event_function (faac->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_faac_sink_event));
|
||||
gst_element_add_pad (GST_ELEMENT (faac), faac->sinkpad);
|
||||
|
@ -347,6 +352,76 @@ gst_faac_close_encoder (GstFaac * faac)
|
|||
faac->offset = 0;
|
||||
}
|
||||
|
||||
static const GstAudioChannelPosition aac_channel_positions[][8] = {
|
||||
{GST_AUDIO_CHANNEL_POSITION_FRONT_MONO},
|
||||
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
|
||||
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER},
|
||||
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER},
|
||||
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT},
|
||||
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_LFE,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}
|
||||
};
|
||||
|
||||
static GstCaps *
|
||||
gst_faac_sink_getcaps (GstPad * pad)
|
||||
{
|
||||
static volatile gsize sinkcaps = 0;
|
||||
|
||||
if (g_once_init_enter (&sinkcaps)) {
|
||||
GstCaps *tmp = gst_caps_new_empty ();
|
||||
GstStructure *s, *t;
|
||||
gint i, c;
|
||||
|
||||
s = gst_structure_new ("audio/x-raw-int",
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
||||
"width", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16, "rate", GST_TYPE_INT_RANGE, 8000, 96000, NULL);
|
||||
|
||||
for (i = 1; i <= 6; i++) {
|
||||
GValue chanpos = { 0 };
|
||||
GValue pos = { 0 };
|
||||
|
||||
t = gst_structure_copy (s);
|
||||
|
||||
gst_structure_set (t, "channels", G_TYPE_INT, i, NULL);
|
||||
|
||||
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, aac_channel_positions[i - 1][c]);
|
||||
gst_value_array_append_value (&chanpos, &pos);
|
||||
}
|
||||
g_value_unset (&pos);
|
||||
|
||||
gst_structure_set_value (t, "channel-positions", &chanpos);
|
||||
g_value_unset (&chanpos);
|
||||
gst_caps_append_structure (tmp, t);
|
||||
}
|
||||
gst_structure_free (s);
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "Generated sinkcaps: %" GST_PTR_FORMAT, tmp);
|
||||
|
||||
g_once_init_leave (&sinkcaps, (gsize) tmp);
|
||||
}
|
||||
|
||||
return gst_caps_ref ((GstCaps *) sinkcaps);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_faac_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue