vorbis: Port to the new multichannel caps

This commit is contained in:
Sebastian Dröge 2011-12-20 12:08:53 +01:00
parent 2fc75efdce
commit 9c60505900
5 changed files with 118 additions and 42 deletions

View file

@ -26,7 +26,7 @@
/* http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9 */
const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = {
{ /* Mono */
GST_AUDIO_CHANNEL_POSITION_FRONT_MONO},
GST_AUDIO_CHANNEL_POSITION_MONO},
{ /* Stereo */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
@ -53,7 +53,7 @@ const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = {
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
GST_AUDIO_CHANNEL_POSITION_LFE,
GST_AUDIO_CHANNEL_POSITION_LFE1,
},
{ /* 6.1 Surround, in Vorbis spec since 2010-01-13 */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
@ -62,7 +62,7 @@ const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = {
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
GST_AUDIO_CHANNEL_POSITION_LFE},
GST_AUDIO_CHANNEL_POSITION_LFE1},
{ /* 7.1 Surround, in Vorbis spec since 2010-01-13 */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
@ -71,5 +71,71 @@ const GstAudioChannelPosition gst_vorbis_channel_positions[][8] = {
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
GST_AUDIO_CHANNEL_POSITION_LFE},
GST_AUDIO_CHANNEL_POSITION_LFE1},
};
const GstAudioChannelPosition gst_vorbis_default_channel_positions[][8] = {
{ /* Mono */
GST_AUDIO_CHANNEL_POSITION_MONO},
{ /* Stereo */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
{ /* Stereo + Centre */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER},
{ /* Quadraphonic */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
},
{ /* Stereo + Centre + rear stereo */
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,
},
{ /* Full 5.1 Surround */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_LFE1,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
},
{ /* 6.1 Surround, in Vorbis spec since 2010-01-13 */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_LFE1,
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
},
{ /* 7.1 Surround, in Vorbis spec since 2010-01-13 */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_LFE1,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
},
};
#ifndef USE_TREMOLO
/* gst[i] = vorbis[reorder_map[i]] */
const gint gst_vorbis_reorder_map[][8] = {
{0},
{0, 1},
{0, 2, 1},
{0, 1, 2, 3},
{0, 2, 1, 3, 4},
{0, 2, 1, 4, 5, 3},
{0, 2, 1, 5, 6, 4, 3},
{0, 2, 1, 6, 7, 4, 5, 3}
};
#endif

View file

@ -21,8 +21,13 @@
#define __GST_VORBIS_COMMON_H__
#include <gst/gst.h>
#include <gst/audio/multichannel.h>
#include <gst/audio/audio.h>
extern const GstAudioChannelPosition gst_vorbis_channel_positions[][8];
extern const GstAudioChannelPosition gst_vorbis_default_channel_positions[][8];
#ifndef USE_TREMOLO
extern const gint gst_vorbis_reorder_map[][8];
#endif
#endif /* __GST_VORBIS_COMMON_H__ */

View file

@ -44,7 +44,6 @@
#include <string.h>
#include <gst/audio/audio.h>
#include <gst/tag/tag.h>
#include <gst/audio/multichannel.h>
#include "gstvorbiscommon.h"
@ -230,14 +229,9 @@ vorbis_handle_identification_packet (GstVorbisDec * vd)
GstCaps *caps;
GstAudioInfo info;
gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate,
vd->vi.channels);
switch (info.channels) {
case 1:
case 2:
/* nothing */
break;
case 3:
case 4:
case 5:
@ -246,20 +240,22 @@ vorbis_handle_identification_packet (GstVorbisDec * vd)
case 8:
{
const GstAudioChannelPosition *pos;
gint i;
pos = gst_vorbis_channel_positions[info.channels - 1];
for (i = 0; i < info.channels; i++)
info.position[i] = pos[i];
pos = gst_vorbis_default_channel_positions[info.channels - 1];
gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate,
vd->vi.channels, pos);
break;
}
default:{
GstAudioChannelPosition position[64];
gint i, max_pos = MAX (info.channels, 64);
GST_ELEMENT_WARNING (vd, STREAM, DECODE,
(NULL), ("Using NONE channel layout for more than 8 channels"));
for (i = 0; i < max_pos; i++)
info.position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate,
vd->vi.channels, position);
break;
}
}
@ -577,7 +573,12 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
#endif
goto wrong_samples;
#ifndef USE_TREMOLO
#ifdef USE_TREMOLO
if (vd->info.channels < 9)
gst_audio_reorder_channels (data, size, GST_VORBIS_AUDIO_FORMAT,
vd->info.channels, gst_vorbis_channel_positions[vd->info.channels - 1],
gst_vorbis_default_channel_positions[vd->info.channels - 1]);
#else
/* copy samples in buffer */
vd->copy_samples ((vorbis_sample_t *) data, pcm,
sample_count, vd->info.channels);

View file

@ -28,6 +28,7 @@
#include <string.h>
#include "gstvorbisdeclib.h"
#include "gstvorbiscommon.h"
#ifndef TREMOR
/* These samples can be outside of the float -1.0 -- 1.0 range, this
@ -65,7 +66,8 @@ copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
gint i;
for (i = 0; i < channels; i++) {
memcpy (out, in[i], samples * sizeof (float));
memcpy (out, in[gst_vorbis_reorder_map[channels - 1][i]],
samples * sizeof (float));
out += samples;
}
#else
@ -73,7 +75,7 @@ copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
for (j = 0; j < samples; j++) {
for (i = 0; i < channels; i++) {
*out++ = in[i][j];
*out++ = in[gst_vorbis_reorder_map[channels - 1][i]][j];
}
}
#endif
@ -165,7 +167,7 @@ copy_samples_16 (vorbis_sample_t * _out, vorbis_sample_t ** _in, guint samples,
for (j = 0; j < samples; j++) {
for (i = 0; i < channels; i++) {
*out++ = CLIP_TO_15 (in[i][j] >> 9);
*out++ = CLIP_TO_15 (in[gst_vorbis_reorder_map[channels - 1][i]][j] >> 9);
}
}
}

View file

@ -50,7 +50,6 @@
#include <gst/gsttagsetter.h>
#include <gst/tag/tag.h>
#include <gst/audio/multichannel.h>
#include <gst/audio/audio.h>
#include "gstvorbisenc.h"
@ -264,30 +263,19 @@ gst_vorbis_enc_generate_sink_caps (void)
"rate", GST_TYPE_INT_RANGE, 1, 200000,
"channels", G_TYPE_INT, 1, NULL));
gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
"format", G_TYPE_STRING, GST_AUDIO_NE (F32),
"rate", GST_TYPE_INT_RANGE, 1, 200000,
"channels", G_TYPE_INT, 2, NULL));
for (i = 3; i <= 8; i++) {
GValue chanpos = { 0 };
GValue pos = { 0 };
for (i = 2; i <= 8; i++) {
GstStructure *structure;
g_value_init (&chanpos, GST_TYPE_ARRAY);
g_value_init (&pos, GST_TYPE_AUDIO_CHANNEL_POSITION);
guint64 channel_mask = 0;
const GstAudioChannelPosition *pos = gst_vorbis_channel_positions[i - 1];
for (c = 0; c < i; c++) {
g_value_set_enum (&pos, gst_vorbis_channel_positions[i - 1][c]);
gst_value_array_append_value (&chanpos, &pos);
channel_mask |= pos[i];
}
g_value_unset (&pos);
structure = gst_structure_new ("audio/x-raw",
"format", G_TYPE_STRING, GST_AUDIO_NE (F32),
"rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i, NULL);
gst_structure_set_value (structure, "channel-positions", &chanpos);
g_value_unset (&chanpos);
"rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i,
"channel-mask", GST_TYPE_BITMASK, channel_mask, NULL);
gst_caps_append_structure (caps, structure);
}
@ -295,7 +283,8 @@ gst_vorbis_enc_generate_sink_caps (void)
gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
"format", G_TYPE_STRING, GST_AUDIO_NE (F32),
"rate", GST_TYPE_INT_RANGE, 1, 200000,
"channels", GST_TYPE_INT_RANGE, 9, 255, NULL));
"channels", GST_TYPE_INT_RANGE, 9, 255,
"channel-mask", GST_TYPE_BITMASK, G_GUINT64_CONSTANT (0), NULL));
return caps;
}
@ -765,9 +754,22 @@ gst_vorbis_enc_handle_frame (GstAudioEncoder * enc, GstBuffer * buffer)
vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
/* deinterleave samples, write the buffer data */
for (i = 0; i < size; i++) {
for (j = 0; j < vorbisenc->channels; j++) {
vorbis_buffer[j][i] = *ptr++;
if (vorbisenc->channels < 2 || vorbisenc->channels > 8) {
for (i = 0; i < size; i++) {
for (j = 0; j < vorbisenc->channels; j++) {
vorbis_buffer[j][i] = *ptr++;
}
}
} else {
gint i, j;
/* Reorder */
for (i = 0; i < size; i++) {
for (j = 0; j < vorbisenc->channels; j++) {
vorbis_buffer[gst_vorbis_reorder_map[vorbisenc->channels - 1][j]][i] =
ptr[j];
}
ptr += vorbisenc->channels;
}
}