diff options
author | jstebbins <[email protected]> | 2011-06-12 18:05:20 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2011-06-12 18:05:20 +0000 |
commit | 991912416a55dfcf100591f31e6e72f3f2f5275d (patch) | |
tree | 0ed644ee9ba9d05e20e30de2a0805aa27802405c | |
parent | e36c5d5cc69a207b088a0c92c8c6cb7a3f50ba21 (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.c | 1 | ||||
-rw-r--r-- | libhb/common.h | 9 | ||||
-rw-r--r-- | libhb/deca52.c | 3 | ||||
-rw-r--r-- | libhb/decavcodec.c | 62 | ||||
-rw-r--r-- | libhb/decdca.c | 4 | ||||
-rw-r--r-- | libhb/declpcm.c | 2 | ||||
-rw-r--r-- | libhb/encavcodecaudio.c | 14 | ||||
-rw-r--r-- | libhb/encfaac.c | 33 | ||||
-rw-r--r-- | libhb/encvorbis.c | 15 | ||||
-rw-r--r-- | libhb/platform/macosx/encca_aac.c | 17 | ||||
-rw-r--r-- | libhb/scan.c | 1 | ||||
-rw-r--r-- | libhb/stream.c | 1 |
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 ); |