faac: Port to the new raw audio caps

This commit is contained in:
Sebastian Dröge 2012-01-05 09:52:16 +01:00
parent 1cb6e68cd0
commit ad63a0c6e3
2 changed files with 39 additions and 45 deletions

View file

@ -38,7 +38,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <gst/audio/multichannel.h> #include <gst/audio/audio.h>
#include <gst/pbutils/codec-utils.h> #include <gst/pbutils/codec-utils.h>
#include "gstfaac.h" #include "gstfaac.h"
@ -58,6 +58,7 @@
#define SINK_CAPS \ #define SINK_CAPS \
"audio/x-raw, " \ "audio/x-raw, " \
"format = (string) "GST_AUDIO_NE (S16) ", " \ "format = (string) "GST_AUDIO_NE (S16) ", " \
"layout = (string) interleaved, " \
"rate = (int) {" SAMPLE_RATES "}, " \ "rate = (int) {" SAMPLE_RATES "}, " \
"channels = (int) [ 1, 6 ] " "channels = (int) [ 1, 6 ] "
@ -277,7 +278,7 @@ gst_faac_stop (GstAudioEncoder * enc)
} }
static const GstAudioChannelPosition aac_channel_positions[][8] = { static const GstAudioChannelPosition aac_channel_positions[][8] = {
{GST_AUDIO_CHANNEL_POSITION_FRONT_MONO}, {GST_AUDIO_CHANNEL_POSITION_MONO},
{GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
{ {
@ -302,7 +303,7 @@ static const GstAudioChannelPosition aac_channel_positions[][8] = {
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
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_LFE1}
}; };
static GstCaps * static GstCaps *
@ -334,24 +335,19 @@ gst_faac_getcaps (GstAudioEncoder * enc, GstCaps * filter)
gst_structure_set_value (s, "rate", &rates_arr); gst_structure_set_value (s, "rate", &rates_arr);
for (i = 1; i <= 6; i++) { for (i = 1; i <= 6; i++) {
GValue chanpos = { 0 }; guint64 channel_mask = 0;
GValue pos = { 0 };
t = gst_structure_copy (s); t = gst_structure_copy (s);
gst_structure_set (t, "channels", G_TYPE_INT, i, NULL); gst_structure_set (t, "channels", G_TYPE_INT, i, NULL);
if (i == 1)
continue;
g_value_init (&chanpos, GST_TYPE_ARRAY); for (c = 0; c < i; c++)
g_value_init (&pos, GST_TYPE_AUDIO_CHANNEL_POSITION); channel_mask |=
G_GUINT64_CONSTANT (1) << aac_channel_positions[i - 1][c];
for (c = 0; c < i; c++) { gst_structure_set (t, "channel-mask", GST_TYPE_BITMASK, channel_mask,
g_value_set_enum (&pos, aac_channel_positions[i - 1][c]); NULL);
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_caps_append_structure (tmp, t);
} }
gst_structure_free (s); gst_structure_free (s);
@ -369,39 +365,30 @@ static gboolean
gst_faac_set_format (GstAudioEncoder * enc, GstAudioInfo * info) gst_faac_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
{ {
GstFaac *faac = GST_FAAC (enc); GstFaac *faac = GST_FAAC (enc);
gint channels, samplerate, width; gint width;
gulong fmt = 0, bps = 0; gulong fmt = 0;
gboolean result = FALSE; gboolean result = FALSE;
/* base class takes care */ /* base class takes care */
channels = GST_AUDIO_INFO_CHANNELS (info);
samplerate = GST_AUDIO_INFO_RATE (info);
width = GST_AUDIO_INFO_WIDTH (info); width = GST_AUDIO_INFO_WIDTH (info);
if (GST_AUDIO_INFO_IS_INTEGER (info)) { if (GST_AUDIO_INFO_IS_INTEGER (info)) {
switch (width) { switch (width) {
case 16: case 16:
fmt = FAAC_INPUT_16BIT; fmt = FAAC_INPUT_16BIT;
bps = 2;
break; break;
case 24: case 24:
case 32: case 32:
fmt = FAAC_INPUT_32BIT; fmt = FAAC_INPUT_32BIT;
bps = 4;
break; break;
default: default:
g_return_val_if_reached (FALSE); g_return_val_if_reached (FALSE);
} }
} else { } else {
fmt = FAAC_INPUT_FLOAT; fmt = FAAC_INPUT_FLOAT;
bps = 4;
} }
/* ok, record and set up */
faac->format = fmt; faac->format = fmt;
faac->bps = bps;
faac->channels = channels;
faac->samplerate = samplerate;
/* finish up */ /* finish up */
result = gst_faac_configure_source_pad (faac); result = gst_faac_configure_source_pad (faac);
@ -482,18 +469,19 @@ gst_faac_open_encoder (GstFaac * faac)
faacEncConfiguration *conf; faacEncConfiguration *conf;
guint maxbitrate; guint maxbitrate;
gulong samples, bytes; gulong samples, bytes;
GstAudioInfo *info =
gst_audio_encoder_get_audio_info (GST_AUDIO_ENCODER (faac));
g_return_val_if_fail (faac->samplerate != 0 && faac->channels != 0, FALSE); g_return_val_if_fail (info->rate != 0 && info->channels != 0, FALSE);
/* clean up in case of re-configure */ /* clean up in case of re-configure */
gst_faac_close_encoder (faac); gst_faac_close_encoder (faac);
if (!(handle = faacEncOpen (faac->samplerate, faac->channels, if (!(handle = faacEncOpen (info->rate, info->channels, &samples, &bytes)))
&samples, &bytes)))
goto setup_failed; goto setup_failed;
/* mind channel count */ /* mind channel count */
samples /= faac->channels; samples /= info->channels;
/* record */ /* record */
faac->handle = handle; faac->handle = handle;
@ -514,7 +502,7 @@ gst_faac_open_encoder (GstFaac * faac)
if (faac->brtype == VBR) { if (faac->brtype == VBR) {
conf->quantqual = faac->quality; conf->quantqual = faac->quality;
} else if (faac->brtype == ABR) { } else if (faac->brtype == ABR) {
conf->bitRate = faac->bitrate / faac->channels; conf->bitRate = faac->bitrate / info->channels;
} }
conf->inputFormat = faac->format; conf->inputFormat = faac->format;
@ -524,13 +512,12 @@ gst_faac_open_encoder (GstFaac * faac)
/* check, warn and correct if the max bitrate for the given samplerate is /* check, warn and correct if the max bitrate for the given samplerate is
* exceeded. Maximum of 6144 bit for a channel */ * exceeded. Maximum of 6144 bit for a channel */
maxbitrate = maxbitrate =
(unsigned int) (6144.0 * (double) faac->samplerate / (double) 1024.0 + (unsigned int) (6144.0 * (double) info->rate / (double) 1024.0 + .5);
.5);
if (conf->bitRate > maxbitrate) { if (conf->bitRate > maxbitrate) {
GST_ELEMENT_WARNING (faac, RESOURCE, SETTINGS, (NULL), GST_ELEMENT_WARNING (faac, RESOURCE, SETTINGS, (NULL),
("bitrate %lu exceeds maximum allowed bitrate of %u for samplerate %d. " ("bitrate %lu exceeds maximum allowed bitrate of %u for samplerate %d. "
"Setting bitrate to %u", conf->bitRate, maxbitrate, "Setting bitrate to %u", conf->bitRate, maxbitrate,
faac->samplerate, maxbitrate)); info->rate, maxbitrate));
conf->bitRate = maxbitrate; conf->bitRate = maxbitrate;
} }
@ -543,7 +530,7 @@ gst_faac_open_encoder (GstFaac * faac)
/* let's see what really happened, /* let's see what really happened,
* note that this may not really match desired rate */ * note that this may not really match desired rate */
GST_DEBUG_OBJECT (faac, "average bitrate: %lu kbps", GST_DEBUG_OBJECT (faac, "average bitrate: %lu kbps",
(conf->bitRate + 500) / 1000 * faac->channels); (conf->bitRate + 500) / 1000 * info->channels);
GST_DEBUG_OBJECT (faac, "quantization quality: %ld", conf->quantqual); GST_DEBUG_OBJECT (faac, "quantization quality: %ld", conf->quantqual);
GST_DEBUG_OBJECT (faac, "bandwidth: %d Hz", conf->bandWidth); GST_DEBUG_OBJECT (faac, "bandwidth: %d Hz", conf->bandWidth);
@ -562,6 +549,8 @@ gst_faac_configure_source_pad (GstFaac * faac)
{ {
GstCaps *srccaps; GstCaps *srccaps;
gboolean ret; gboolean ret;
GstAudioInfo *info =
gst_audio_encoder_get_audio_info (GST_AUDIO_ENCODER (faac));
/* negotiate stream format */ /* negotiate stream format */
gst_faac_negotiate (faac); gst_faac_negotiate (faac);
@ -572,8 +561,8 @@ gst_faac_configure_source_pad (GstFaac * faac)
/* now create a caps for it all */ /* now create a caps for it all */
srccaps = gst_caps_new_simple ("audio/mpeg", srccaps = gst_caps_new_simple ("audio/mpeg",
"mpegversion", G_TYPE_INT, faac->mpegversion, "mpegversion", G_TYPE_INT, faac->mpegversion,
"channels", G_TYPE_INT, faac->channels, "channels", G_TYPE_INT, info->channels,
"rate", G_TYPE_INT, faac->samplerate, "rate", G_TYPE_INT, info->rate,
"stream-format", G_TYPE_STRING, (faac->outputformat ? "adts" : "raw"), "stream-format", G_TYPE_STRING, (faac->outputformat ? "adts" : "raw"),
NULL); NULL);
@ -661,11 +650,20 @@ gst_faac_handle_frame (GstAudioEncoder * enc, GstBuffer * in_buf)
guint8 *data; guint8 *data;
guint8 *out_data; guint8 *out_data;
gsize out_size; gsize out_size;
GstAudioInfo *info =
gst_audio_encoder_get_audio_info (GST_AUDIO_ENCODER (faac));
out_buf = gst_buffer_new_and_alloc (faac->bytes); out_buf = gst_buffer_new_and_alloc (faac->bytes);
out_data = gst_buffer_map (out_buf, &out_size, NULL, GST_MAP_WRITE); out_data = gst_buffer_map (out_buf, &out_size, NULL, GST_MAP_WRITE);
if (G_LIKELY (in_buf)) { if (G_LIKELY (in_buf)) {
if (memcmp (info->position, aac_channel_positions[info->channels - 1],
sizeof (GstAudioChannelPosition) * info->channels) != 0) {
in_buf = gst_buffer_make_writable (in_buf);
gst_audio_buffer_reorder_channels (in_buf, info->finfo->format,
info->channels, info->position,
aac_channel_positions[info->channels - 1]);
}
data = gst_buffer_map (in_buf, &size, NULL, GST_MAP_READ); data = gst_buffer_map (in_buf, &size, NULL, GST_MAP_READ);
} else { } else {
data = NULL; data = NULL;
@ -673,7 +671,7 @@ gst_faac_handle_frame (GstAudioEncoder * enc, GstBuffer * in_buf)
} }
if (G_UNLIKELY ((ret_size = faacEncEncode (faac->handle, (gint32 *) data, if (G_UNLIKELY ((ret_size = faacEncEncode (faac->handle, (gint32 *) data,
size / faac->bps, out_data, out_size)) < 0)) size / (info->finfo->width / 8), out_data, out_size)) < 0))
goto encode_failed; goto encode_failed;
gst_buffer_unmap (in_buf, data, size); gst_buffer_unmap (in_buf, data, size);

View file

@ -44,12 +44,8 @@ typedef struct _GstFaacClass GstFaacClass;
struct _GstFaac { struct _GstFaac {
GstAudioEncoder element; GstAudioEncoder element;
/* stream properties */ /* input format */
gint samplerate, gint format;
channels,
format,
bps;
/* input frame size */ /* input frame size */
gint samples; gint samples;
/* required output buffer size */ /* required output buffer size */