summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2011-06-12 18:05:20 +0000
committerjstebbins <[email protected]>2011-06-12 18:05:20 +0000
commit991912416a55dfcf100591f31e6e72f3f2f5275d (patch)
tree0ed644ee9ba9d05e20e30de2a0805aa27802405c
parente36c5d5cc69a207b088a0c92c8c6cb7a3f50ba21 (diff)
libhb: generalize channel remapping between decoders and encoders
Decoders set the channel map of their output in hb_audio_config_t. Encoders use this information to remap while encoding. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4052 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/common.c1
-rw-r--r--libhb/common.h9
-rw-r--r--libhb/deca52.c3
-rw-r--r--libhb/decavcodec.c62
-rw-r--r--libhb/decdca.c4
-rw-r--r--libhb/declpcm.c2
-rw-r--r--libhb/encavcodecaudio.c14
-rw-r--r--libhb/encfaac.c33
-rw-r--r--libhb/encvorbis.c15
-rw-r--r--libhb/platform/macosx/encca_aac.c17
-rw-r--r--libhb/scan.c1
-rw-r--r--libhb/stream.c1
12 files changed, 71 insertions, 91 deletions
diff --git a/libhb/common.c b/libhb/common.c
index cc4f5ec0c..2d5963d76 100644
--- a/libhb/common.c
+++ b/libhb/common.c
@@ -1178,6 +1178,7 @@ void hb_audio_config_init(hb_audio_config_t * audiocfg)
audiocfg->in.bitrate = -1;
audiocfg->in.samplerate = -1;
audiocfg->in.channel_layout = 0;
+ audiocfg->in.channel_map = NULL;
audiocfg->in.version = 0;
audiocfg->in.mode = 0;
audiocfg->flags.ac3 = 0;
diff --git a/libhb/common.h b/libhb/common.h
index ee3bc3b98..492e39750 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -82,6 +82,7 @@ typedef struct hb_lock_s hb_lock_t;
#else
#define PRIVATE const
#endif
+#include "downmix.h"
hb_list_t * hb_list_init();
int hb_list_count( hb_list_t * );
@@ -423,10 +424,9 @@ struct hb_audio_config_s
PRIVATE uint32_t mode; /* Bitstream mode, codec dependent encoding */
PRIVATE int samplerate; /* Input sample rate (Hz) */
PRIVATE int bitrate; /* Input bitrate (kbps) */
- PRIVATE int channel_layout;
- /* channel_layout is the channel layout of this audio this is used to
- * provide a common way of describing the source audio
- */
+ PRIVATE int channel_layout; /* channel_layout is the channel layout of this audio this is used to
+ * provide a common way of describing the source audio */
+ PRIVATE hb_chan_map_t * channel_map; /* source channel map, set by the audio decoder */
} in;
/* Misc. */
@@ -715,6 +715,7 @@ typedef struct hb_work_info_s
};
struct { // info only valid for audio decoders
int channel_layout;
+ hb_chan_map_t * channel_map;
};
};
} hb_work_info_t;
diff --git a/libhb/deca52.c b/libhb/deca52.c
index 3148bc672..2771eda55 100644
--- a/libhb/deca52.c
+++ b/libhb/deca52.c
@@ -5,6 +5,7 @@
It may be used under the terms of the GNU General Public License. */
#include "hb.h"
+#include "downmix.h"
#include "a52dec/a52.h"
#include "libavutil/crc.h"
@@ -464,5 +465,7 @@ static int deca52BSInfo( hb_work_object_t *w, const hb_buffer_t *b,
info->channel_layout |= HB_INPUT_CH_LAYOUT_HAS_LFE;
}
+ info->channel_map = &hb_ac3_chan_map;
+
return 1;
}
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index 770a7914e..610ec1120 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -112,7 +112,6 @@ struct hb_work_private_s
struct SwsContext *sws_context; // if we have to rescale or convert color space
hb_downmix_t *downmix;
int cadence[12];
- hb_chan_map_t *out_map;
};
static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *data, int size, int64_t pts );
@@ -209,22 +208,12 @@ static int decavcodecInit( hb_work_object_t * w, hb_job_t * job )
if ( w->audio != NULL )
{
- if ( w->audio->config.out.codec == HB_ACODEC_AC3 )
- {
- // ffmpegs audio encoder expect an smpte chan map as input.
- // So we need to map the decoders output to smpte.
- pv->out_map = &hb_smpte_chan_map;
- }
- else
- {
- pv->out_map = &hb_qt_chan_map;
- }
if ( hb_need_downmix( w->audio->config.in.channel_layout,
w->audio->config.out.mixdown) )
{
pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout,
w->audio->config.out.mixdown);
- hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, pv->out_map );
+ hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, &hb_smpte_chan_map );
}
pv->ff_audio_list = hb_list_init();
@@ -238,22 +227,12 @@ static int decavcodecInit( hb_work_object_t * w, hb_job_t * job )
ff_pv->list = hb_list_init();
ff_pv->job = job;
- if ( audio->config.out.codec == HB_ACODEC_AC3 )
- {
- // ffmpegs audio encoder expect an smpte chan map as input.
- // So we need to map the decoders output to smpte.
- ff_pv->out_map = &hb_smpte_chan_map;
- }
- else
- {
- ff_pv->out_map = &hb_qt_chan_map;
- }
if ( hb_need_downmix( audio->config.in.channel_layout,
audio->config.out.mixdown) )
{
ff_pv->downmix = hb_downmix_init(audio->config.in.channel_layout,
audio->config.out.mixdown);
- hb_downmix_set_chan_map( ff_pv->downmix, &hb_smpte_chan_map, ff_pv->out_map );
+ hb_downmix_set_chan_map( ff_pv->downmix, &hb_smpte_chan_map, &hb_smpte_chan_map );
}
}
}
@@ -574,6 +553,8 @@ static int decavcodecBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
buf = buf->next;
}
+ info->channel_map = &hb_smpte_chan_map;
+
av_free( buffer );
if ( parser != NULL )
av_parser_close( parser );
@@ -1375,22 +1356,12 @@ static int decavcodecviInit( hb_work_object_t * w, hb_job_t * job )
if ( w->audio != NULL )
{
- if ( w->audio->config.out.codec == HB_ACODEC_AC3 )
- {
- // ffmpegs audio encoder expect an smpte chan map as input.
- // So we need to map the decoders output to smpte.
- pv->out_map = &hb_smpte_chan_map;
- }
- else
- {
- pv->out_map = &hb_qt_chan_map;
- }
if ( hb_need_downmix( w->audio->config.in.channel_layout,
w->audio->config.out.mixdown) )
{
pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout,
w->audio->config.out.mixdown);
- hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, pv->out_map );
+ hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, &hb_smpte_chan_map );
}
pv->ff_audio_list = hb_list_init();
@@ -1405,22 +1376,12 @@ static int decavcodecviInit( hb_work_object_t * w, hb_job_t * job )
ff_pv->job = job;
ff_pv->pts_next = -1;
- if ( audio->config.out.codec == HB_ACODEC_AC3 )
- {
- // ffmpegs audio encoder expect an smpte chan map as input.
- // So we need to map the decoders output to smpte.
- ff_pv->out_map = &hb_smpte_chan_map;
- }
- else
- {
- ff_pv->out_map = &hb_qt_chan_map;
- }
if ( hb_need_downmix( audio->config.in.channel_layout,
audio->config.out.mixdown) )
{
ff_pv->downmix = hb_downmix_init(audio->config.in.channel_layout,
audio->config.out.mixdown);
- hb_downmix_set_chan_map( ff_pv->downmix, &hb_smpte_chan_map, ff_pv->out_map );
+ hb_downmix_set_chan_map( ff_pv->downmix, &hb_smpte_chan_map, &hb_smpte_chan_map );
}
}
}
@@ -1514,16 +1475,7 @@ static hb_buffer_t * downmixAudio(
else
{
buf = hb_buffer_init( nsamples * sizeof(float) );
- float *fl32 = (float *)buf->data;
- int i;
- for( i = 0; i < nsamples; ++i )
- {
- fl32[i] = buffer[i];
- }
- int n_ch_samples = nsamples / channels;
- hb_layout_remap( &hb_smpte_chan_map, pv->out_map,
- audio->config.in.channel_layout,
- fl32, n_ch_samples );
+ memcpy(buf->data, buffer, nsamples * sizeof(float) );
}
return buf;
diff --git a/libhb/decdca.c b/libhb/decdca.c
index 62f460915..ed86be4b7 100644
--- a/libhb/decdca.c
+++ b/libhb/decdca.c
@@ -5,6 +5,8 @@
It may be used under the terms of the GNU General Public License. */
#include "hb.h"
+#include "downmix.h"
+
#include "dca.h"
struct hb_work_private_s
@@ -358,5 +360,7 @@ static int decdcaBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
info->channel_layout |= HB_INPUT_CH_LAYOUT_HAS_LFE;
}
+ info->channel_map = &hb_qt_chan_map;
+
return 1;
}
diff --git a/libhb/declpcm.c b/libhb/declpcm.c
index fc120a333..3dd1f7366 100644
--- a/libhb/declpcm.c
+++ b/libhb/declpcm.c
@@ -5,6 +5,7 @@
It may be used under the terms of the GNU General Public License. */
#include "hb.h"
+#include "downmix.h"
struct hb_work_private_s
{
@@ -267,6 +268,7 @@ static int declpcmBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
info->bitrate = bitrate;
info->flags = ( b->data[3] << 16 ) | ( b->data[4] << 8 ) | b->data[5];
info->channel_layout = hdr2layout[nchannels - 1];
+ info->channel_map = &hb_qt_chan_map;
return 1;
}
diff --git a/libhb/encavcodecaudio.c b/libhb/encavcodecaudio.c
index 7c0a51971..78d1a0565 100644
--- a/libhb/encavcodecaudio.c
+++ b/libhb/encavcodecaudio.c
@@ -168,17 +168,7 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
hb_list_getbytes( pv->list, pv->buf, pv->input_samples * sizeof( float ),
&pts, &pos);
- hb_chan_map_t *map = NULL;
- if ( audio->config.in.codec == HB_ACODEC_AC3 )
- {
- map = &hb_ac3_chan_map;
- }
- else if ( audio->config.in.codec == HB_ACODEC_DCA ||
- audio->config.in.codec == HB_ACODEC_LPCM )
- {
- map = &hb_qt_chan_map;
- }
- if ( map )
+ if ( audio->config.in.channel_map != &hb_smpte_chan_map )
{
int layout;
switch (audio->config.out.mixdown)
@@ -196,7 +186,7 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
layout = HB_INPUT_CH_LAYOUT_3F2R | HB_INPUT_CH_LAYOUT_HAS_LFE;
break;
}
- hb_layout_remap( map, &hb_smpte_chan_map, layout,
+ hb_layout_remap( audio->config.in.channel_map, &hb_smpte_chan_map, layout,
(float*)pv->buf, pv->samples_per_frame);
}
diff --git a/libhb/encfaac.c b/libhb/encfaac.c
index b8ff8347c..fe1a1f55b 100644
--- a/libhb/encfaac.c
+++ b/libhb/encfaac.c
@@ -119,20 +119,27 @@ int encfaacInit( hb_work_object_t * w, hb_job_t * job )
cfg->outputFormat = 0;
cfg->inputFormat = FAAC_INPUT_FLOAT;
- if (audio->config.out.mixdown == HB_AMIXDOWN_6CH && audio->config.in.codec == HB_ACODEC_AC3)
+ if( ( audio->config.out.mixdown == HB_AMIXDOWN_6CH ) && ( audio->config.in.channel_map != &hb_qt_chan_map ) )
{
- /* we are preserving 5.1 AC-3 audio into 6-channel AAC, and need to
- re-map the output of deca52 into our own mapping - the mapping
- below is the default mapping expected by QuickTime */
- /* DTS output from libdca is already in the right mapping for QuickTime */
- /* This doesn't seem to be correct for VLC on Linux */
- cfg->channel_map[0] = 2;
- cfg->channel_map[1] = 1;
- cfg->channel_map[2] = 3;
- cfg->channel_map[3] = 4;
- cfg->channel_map[4] = 5;
- cfg->channel_map[5] = 0;
- }
+ if( audio->config.in.channel_map == &hb_ac3_chan_map )
+ {
+ cfg->channel_map[0] = 2;
+ cfg->channel_map[1] = 1;
+ cfg->channel_map[2] = 3;
+ cfg->channel_map[3] = 4;
+ cfg->channel_map[4] = 5;
+ cfg->channel_map[5] = 0;
+ }
+ else if( audio->config.in.channel_map == &hb_smpte_chan_map )
+ {
+ cfg->channel_map[0] = 2;
+ cfg->channel_map[1] = 0;
+ cfg->channel_map[2] = 1;
+ cfg->channel_map[3] = 4;
+ cfg->channel_map[4] = 5;
+ cfg->channel_map[5] = 3;
+ }
+ }
if( !faacEncSetConfiguration( pv->faac, cfg ) )
{
diff --git a/libhb/encvorbis.c b/libhb/encvorbis.c
index 1c7e323ba..01bd216e8 100644
--- a/libhb/encvorbis.c
+++ b/libhb/encvorbis.c
@@ -120,8 +120,8 @@ int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
pv->channel_map[0] = 0;
break;
case 6:
- // Vorbis use the following channels map = L C R Ls Rs Lfe
- if( audio->config.in.codec == HB_ACODEC_AC3 )
+ // Vorbis uses the following channel map = L C R Ls Rs Lfe
+ if( audio->config.in.channel_map == &hb_ac3_chan_map )
{
pv->channel_map[0] = 1;
pv->channel_map[1] = 2;
@@ -130,7 +130,16 @@ int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
pv->channel_map[4] = 5;
pv->channel_map[5] = 0;
}
- else
+ else if( audio->config.in.channel_map == &hb_smpte_chan_map )
+ {
+ pv->channel_map[0] = 0;
+ pv->channel_map[1] = 2;
+ pv->channel_map[2] = 1;
+ pv->channel_map[3] = 4;
+ pv->channel_map[4] = 5;
+ pv->channel_map[5] = 3;
+ }
+ else // &hb_qt_chan_map
{
pv->channel_map[0] = 1;
pv->channel_map[1] = 0;
diff --git a/libhb/platform/macosx/encca_aac.c b/libhb/platform/macosx/encca_aac.c
index 85c9c2d88..97f802208 100644
--- a/libhb/platform/macosx/encca_aac.c
+++ b/libhb/platform/macosx/encca_aac.c
@@ -192,11 +192,20 @@ int encCoreAudioInit( hb_work_object_t * w, hb_job_t * job, enum AAC_MODE mode )
}
}
- if( ( audio->config.out.mixdown == HB_AMIXDOWN_6CH ) && ( audio->config.in.codec == HB_ACODEC_AC3) )
+ if( ( audio->config.out.mixdown == HB_AMIXDOWN_6CH ) && ( audio->config.in.channel_map != &hb_qt_chan_map ) )
{
- SInt32 channelMap[6] = { 2, 1, 3, 4, 5, 0 };
- AudioConverterSetProperty( pv->converter, kAudioConverterChannelMap,
- sizeof( channelMap ), channelMap );
+ if( audio->config.in.channel_map == &hb_ac3_chan_map )
+ {
+ SInt32 channelMap[6] = { 2, 1, 3, 4, 5, 0 };
+ AudioConverterSetProperty( pv->converter, kAudioConverterChannelMap,
+ sizeof( channelMap ), channelMap );
+ }
+ else if( audio->config.in.channel_map == &hb_smpte_chan_map )
+ {
+ SInt32 channelMap[6] = { 2, 0, 1, 4, 5, 3 };
+ AudioConverterSetProperty( pv->converter, kAudioConverterChannelMap,
+ sizeof( channelMap ), channelMap );
+ }
}
// set encoder quality to maximum
diff --git a/libhb/scan.c b/libhb/scan.c
index 247e25028..afc650911 100644
--- a/libhb/scan.c
+++ b/libhb/scan.c
@@ -1003,6 +1003,7 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b )
audio->config.in.samplerate = info.rate;
audio->config.in.bitrate = info.bitrate;
audio->config.in.channel_layout = info.channel_layout;
+ audio->config.in.channel_map = info.channel_map;
audio->config.in.version = info.version;
audio->config.in.mode = info.mode;
audio->config.flags.ac3 = info.flags;
diff --git a/libhb/stream.c b/libhb/stream.c
index f48b61923..fdfc8b6a7 100644
--- a/libhb/stream.c
+++ b/libhb/stream.c
@@ -3336,6 +3336,7 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
audio->config.in.bitrate = codec->bit_rate? codec->bit_rate : 1;
audio->config.in.samplerate = codec->sample_rate;
audio->config.in.channel_layout = layout;
+ audio->config.in.channel_map = &hb_smpte_chan_map;
}
tag = av_metadata_get( st->metadata, "language", NULL, 0 );