summaryrefslogtreecommitdiffstats
path: root/libhb
diff options
context:
space:
mode:
authorRodeo <[email protected]>2015-02-15 22:48:46 +0000
committerRodeo <[email protected]>2015-02-15 22:48:46 +0000
commit3adcd92b35be6fb8940c5f249112a263c7ec0ed9 (patch)
tree49dfe2e1b269be7a0238fa3c5367899da783451a /libhb
parent901d81b2b980c3afa7e14f434cc8ffd092cc750e (diff)
New audio output options.
Dolby Digital Plus (E-AC-3), Dolby TrueHD and FLAC can now be passed through without re-encoding. They aren't covered by Auto Passthru yet, however. In addition, encoding to E-AC-3 is now possible. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6908 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb')
-rw-r--r--libhb/bd.c4
-rw-r--r--libhb/common.c51
-rw-r--r--libhb/common.h27
-rw-r--r--libhb/decavcodec.c23
-rw-r--r--libhb/declpcm.c1
-rw-r--r--libhb/encavcodecaudio.c6
-rw-r--r--libhb/muxavformat.c6
-rw-r--r--libhb/scan.c13
-rw-r--r--libhb/stream.c24
-rw-r--r--libhb/sync.c96
10 files changed, 213 insertions, 38 deletions
diff --git a/libhb/bd.c b/libhb/bd.c
index 59a801594..b44d665ad 100644
--- a/libhb/bd.c
+++ b/libhb/bd.c
@@ -425,7 +425,7 @@ hb_title_t * hb_bd_title_scan( hb_bd_t * d, int tt, uint64_t min_duration )
add_audio(ii, title->list_audio, bdaudio, HB_SUBSTREAM_BD_AC3,
HB_ACODEC_AC3, AV_CODEC_ID_AC3);
add_audio(ii, title->list_audio, bdaudio, HB_SUBSTREAM_BD_TRUEHD,
- HB_ACODEC_FFMPEG, AV_CODEC_ID_TRUEHD);
+ HB_ACODEC_FFTRUEHD, AV_CODEC_ID_TRUEHD);
break;
case BLURAY_STREAM_TYPE_AUDIO_DTS:
@@ -441,7 +441,7 @@ hb_title_t * hb_bd_title_scan( hb_bd_t * d, int tt, uint64_t min_duration )
case BLURAY_STREAM_TYPE_AUDIO_AC3PLUS:
add_audio(ii, title->list_audio, bdaudio, 0,
- HB_ACODEC_FFMPEG, AV_CODEC_ID_EAC3);
+ HB_ACODEC_FFEAC3, AV_CODEC_ID_EAC3);
break;
case BLURAY_STREAM_TYPE_AUDIO_LPCM:
diff --git a/libhb/common.c b/libhb/common.c
index 3476dbf7a..78b4437c6 100644
--- a/libhb/common.c
+++ b/libhb/common.c
@@ -53,9 +53,13 @@ enum
HB_GID_ACODEC_AUTO_PASS,
HB_GID_ACODEC_DTS_PASS,
HB_GID_ACODEC_DTSHD_PASS,
+ HB_GID_ACODEC_EAC3,
+ HB_GID_ACODEC_EAC3_PASS,
HB_GID_ACODEC_FLAC,
+ HB_GID_ACODEC_FLAC_PASS,
HB_GID_ACODEC_MP3,
HB_GID_ACODEC_MP3_PASS,
+ HB_GID_ACODEC_TRUEHD_PASS,
HB_GID_ACODEC_VORBIS,
HB_GID_MUX_MKV,
HB_GID_MUX_MP4,
@@ -137,6 +141,10 @@ hb_rate_internal_t hb_audio_bitrates[] =
{ { "1152", 1152, }, NULL, 1, },
{ { "1344", 1344, }, NULL, 1, },
{ { "1536", 1536, }, NULL, 1, },
+ { { "2304", 2304, }, NULL, 1, },
+ { { "3072", 3072, }, NULL, 1, },
+ { { "4608", 4608, }, NULL, 1, },
+ { { "6144", 6144, }, NULL, 1, },
};
int hb_audio_bitrates_count = sizeof(hb_audio_bitrates) / sizeof(hb_audio_bitrates[0]);
@@ -263,6 +271,9 @@ hb_encoder_internal_t hb_audio_encoders[] =
{ { "AAC Passthru", "copy:aac", "AAC Passthru", HB_ACODEC_AAC_PASS, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_ACODEC_AAC_PASS, },
{ { "AC3", "ac3", "AC3 (libavcodec)", HB_ACODEC_AC3, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_ACODEC_AC3, },
{ { "AC3 Passthru", "copy:ac3", "AC3 Passthru", HB_ACODEC_AC3_PASS, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_ACODEC_AC3_PASS, },
+ { { "E-AC3", "eac3", "E-AC3 (libavcodec)", HB_ACODEC_FFEAC3, HB_MUX_AV_MKV, }, NULL, 1, HB_GID_ACODEC_EAC3, },
+ { { "E-AC3 Passthru", "copy:eac3", "E-AC3 Passthru", HB_ACODEC_EAC3_PASS, HB_MUX_AV_MKV, }, NULL, 1, HB_GID_ACODEC_EAC3_PASS, },
+ { { "TrueHD Passthru", "copy:truehd","TrueHD Passthru", HB_ACODEC_TRUEHD_PASS, HB_MUX_AV_MKV, }, NULL, 1, HB_GID_ACODEC_TRUEHD_PASS,},
{ { "DTS Passthru", "copy:dts", "DTS Passthru", HB_ACODEC_DCA_PASS, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_ACODEC_DTS_PASS, },
{ { "DTS-HD Passthru", "copy:dtshd", "DTS-HD Passthru", HB_ACODEC_DCA_HD_PASS, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_ACODEC_DTSHD_PASS, },
{ { "MP3", "mp3", "MP3 (libmp3lame)", HB_ACODEC_LAME, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_ACODEC_MP3, },
@@ -270,6 +281,7 @@ hb_encoder_internal_t hb_audio_encoders[] =
{ { "Vorbis", "vorbis", "Vorbis (libvorbis)", HB_ACODEC_VORBIS, HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_ACODEC_VORBIS, },
{ { "FLAC 16-bit", "flac16", "FLAC 16-bit (libavcodec)", HB_ACODEC_FFFLAC, HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_ACODEC_FLAC, },
{ { "FLAC 24-bit", "flac24", "FLAC 24-bit (libavcodec)", HB_ACODEC_FFFLAC24, HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_ACODEC_FLAC, },
+ { { "FLAC Passthru", "copy:flac", "FLAC Passthru", HB_ACODEC_FLAC_PASS, HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_ACODEC_FLAC_PASS, },
{ { "Auto Passthru", "copy", "Auto Passthru", HB_ACODEC_AUTO_PASS, HB_MUX_MASK_MP4|HB_MUX_MASK_MKV, }, NULL, 1, HB_GID_ACODEC_AUTO_PASS, },
};
int hb_audio_encoders_count = sizeof(hb_audio_encoders) / sizeof(hb_audio_encoders[0]);
@@ -300,6 +312,9 @@ static int hb_audio_encoder_is_enabled(int encoder)
case HB_ACODEC_AC3:
return avcodec_find_encoder(AV_CODEC_ID_AC3) != NULL;
+ case HB_ACODEC_FFEAC3:
+ return avcodec_find_encoder(AV_CODEC_ID_EAC3) != NULL;
+
case HB_ACODEC_FFFLAC:
case HB_ACODEC_FFFLAC24:
return avcodec_find_encoder(AV_CODEC_ID_FLAC) != NULL;
@@ -662,10 +677,12 @@ const hb_rate_t* hb_video_framerate_get_next(const hb_rate_t *last)
int hb_audio_samplerate_get_best(uint32_t codec, int samplerate, int *sr_shift)
{
int best_samplerate;
- if (samplerate < 32000 && (codec == HB_ACODEC_AC3 ||
+ if (samplerate < 32000 && (codec == HB_ACODEC_AC3 ||
+ codec == HB_ACODEC_FFEAC3 ||
codec == HB_ACODEC_CA_HAAC))
{
// ca_haac can't do samplerates < 32 kHz
+ // libav's E-AC-3 encoder can't do samplerates < 32 kHz
// AC-3 < 32 kHz suffers from poor hardware compatibility
best_samplerate = 32000;
}
@@ -826,6 +843,14 @@ int hb_audio_bitrate_get_default(uint32_t codec, int samplerate, int mixdown)
bitrate = (nchannels * 128) - (32 * (nchannels < 5));
break;
+ // Our E-AC-3 encoder is pretty similar to our AC-3 encoder but it does
+ // allow for higher bitrates, should some users want a bit more quality
+ // at the expense of compression efficiency - still, let's remain
+ // compatible with passthru over S/PDIF by default: 384, 768, 1536 Kbps
+ case HB_ACODEC_FFEAC3:
+ bitrate = (nchannels * 384) - (128 * (nchannels - 2) * (nchannels > 2));
+ break;
+
case HB_ACODEC_CA_HAAC:
case HB_ACODEC_FDK_HAAC:
bitrate = nchannels * 32;
@@ -893,6 +918,14 @@ fail:
* The maximum AC3 bitrate is 640 Kbps
* Limits: minimum of 224/5 Kbps per full-bandwidth channel, maximum of 640 Kbps
*
+ * ffeac3
+ * ------
+ * supported samplerates: 32 - 48 kHz (< 32 kHz not supported by libav encoder)
+ * Dolby's encoder has a min. of 224 Kbps for 5 full-bandwidth channels (5.0, 5.1)
+ * The maximum bitrate is 128 bits per sample per second
+ * Limits: minimum of 224/5 Kbps per full-bandwidth channel
+ * maximum of 128/1000 * samplerate Kbps
+ *
* ca_aac
* ------
* supported samplerates: 8 - 48 kHz
@@ -975,6 +1008,11 @@ void hb_audio_bitrate_get_limits(uint32_t codec, int samplerate, int mixdown,
*high = 640;
break;
+ case HB_ACODEC_FFEAC3:
+ *low = 224 * nchannels / 5;
+ *high = 128 * samplerate / 1000;
+ break;
+
case HB_ACODEC_CA_AAC:
{
switch (samplerate)
@@ -1617,8 +1655,9 @@ int hb_mixdown_get_default(uint32_t codec, uint64_t layout)
mixdown = HB_AMIXDOWN_7POINT1;
break;
- // the AC3 encoder defaults to the best mixdown up to 5.1
+ // the (E-)AC-3 encoder defaults to the best mixdown up to 5.1
case HB_ACODEC_AC3:
+ case HB_ACODEC_FFEAC3:
mixdown = HB_AMIXDOWN_5POINT1;
break;
@@ -1824,6 +1863,13 @@ int hb_audio_encoder_get_fallback_for_passthru(int passthru)
gid = HB_GID_ACODEC_AC3;
break;
+ case HB_ACODEC_EAC3_PASS:
+ gid = HB_GID_ACODEC_EAC3;
+ break;
+
+ case HB_ACODEC_FLAC_PASS:
+ gid = HB_GID_ACODEC_FLAC;
+
case HB_ACODEC_MP3_PASS:
gid = HB_GID_ACODEC_MP3;
break;
@@ -3481,6 +3527,7 @@ void hb_audio_config_init(hb_audio_config_t * audiocfg)
audiocfg->in.flags = 0;
audiocfg->in.mode = 0;
audiocfg->in.samplerate = -1;
+ audiocfg->in.sample_bit_depth = 0;
audiocfg->in.samples_per_frame = -1;
audiocfg->in.bitrate = -1;
audiocfg->in.matrix_encoding = AV_MATRIX_ENCODING_NONE;
diff --git a/libhb/common.h b/libhb/common.h
index 813bfb9d3..41c5dd822 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -629,7 +629,7 @@ struct hb_job_s
/* Audio starts here */
/* Audio Codecs: Update win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/NativeConstants.cs when changing these consts */
-#define HB_ACODEC_MASK 0x00FFFF00
+#define HB_ACODEC_MASK 0x03FFFF00
#define HB_ACODEC_LAME 0x00000200
#define HB_ACODEC_VORBIS 0x00000400
#define HB_ACODEC_AC3 0x00000800
@@ -645,16 +645,21 @@ struct hb_job_s
#define HB_ACODEC_FFFLAC24 0x00200000
#define HB_ACODEC_FDK_AAC 0x00400000
#define HB_ACODEC_FDK_HAAC 0x00800000
-#define HB_ACODEC_FF_MASK 0x00FF2800
+#define HB_ACODEC_FFEAC3 0x01000000
+#define HB_ACODEC_FFTRUEHD 0x02000000
+#define HB_ACODEC_FF_MASK 0x03FF2800
#define HB_ACODEC_PASS_FLAG 0x40000000
-#define HB_ACODEC_PASS_MASK (HB_ACODEC_MP3 | HB_ACODEC_FFAAC | HB_ACODEC_DCA_HD | HB_ACODEC_AC3 | HB_ACODEC_DCA)
-#define HB_ACODEC_AUTO_PASS (HB_ACODEC_PASS_MASK | HB_ACODEC_PASS_FLAG)
-#define HB_ACODEC_MP3_PASS (HB_ACODEC_MP3 | HB_ACODEC_PASS_FLAG)
-#define HB_ACODEC_AAC_PASS (HB_ACODEC_FFAAC | HB_ACODEC_PASS_FLAG)
-#define HB_ACODEC_AC3_PASS (HB_ACODEC_AC3 | HB_ACODEC_PASS_FLAG)
-#define HB_ACODEC_DCA_PASS (HB_ACODEC_DCA | HB_ACODEC_PASS_FLAG)
-#define HB_ACODEC_DCA_HD_PASS (HB_ACODEC_DCA_HD | HB_ACODEC_PASS_FLAG)
-#define HB_ACODEC_ANY (HB_ACODEC_MASK | HB_ACODEC_PASS_FLAG)
+#define HB_ACODEC_PASS_MASK (HB_ACODEC_AC3 | HB_ACODEC_DCA | HB_ACODEC_DCA_HD | HB_ACODEC_FFAAC | HB_ACODEC_FFEAC3 | HB_ACODEC_FFFLAC | HB_ACODEC_MP3 | HB_ACODEC_FFTRUEHD)
+#define HB_ACODEC_AUTO_PASS (HB_ACODEC_PASS_FLAG | HB_ACODEC_PASS_MASK)
+#define HB_ACODEC_ANY (HB_ACODEC_PASS_FLAG | HB_ACODEC_MASK)
+#define HB_ACODEC_AAC_PASS (HB_ACODEC_PASS_FLAG | HB_ACODEC_FFAAC)
+#define HB_ACODEC_AC3_PASS (HB_ACODEC_PASS_FLAG | HB_ACODEC_AC3)
+#define HB_ACODEC_DCA_PASS (HB_ACODEC_PASS_FLAG | HB_ACODEC_DCA)
+#define HB_ACODEC_DCA_HD_PASS (HB_ACODEC_PASS_FLAG | HB_ACODEC_DCA_HD)
+#define HB_ACODEC_EAC3_PASS (HB_ACODEC_PASS_FLAG | HB_ACODEC_FFEAC3)
+#define HB_ACODEC_FLAC_PASS (HB_ACODEC_PASS_FLAG | HB_ACODEC_FFFLAC)
+#define HB_ACODEC_MP3_PASS (HB_ACODEC_PASS_FLAG | HB_ACODEC_MP3)
+#define HB_ACODEC_TRUEHD_PASS (HB_ACODEC_PASS_FLAG | HB_ACODEC_FFTRUEHD)
#define HB_SUBSTREAM_BD_TRUEHD 0x72
#define HB_SUBSTREAM_BD_AC3 0x76
@@ -714,6 +719,7 @@ struct hb_audio_config_s
PRIVATE uint32_t flags; /* Bitstream flags, codec-specific */
PRIVATE uint32_t mode; /* Bitstream mode, codec-specific */
PRIVATE int samplerate; /* Input sample rate (Hz) */
+ PRIVATE int sample_bit_depth; /* Input samples' bit depth (0 if unknown) */
PRIVATE int samples_per_frame; /* Number of samples per frame */
PRIVATE int bitrate; /* Input bitrate (bps) */
PRIVATE int matrix_encoding; /* Source matrix encoding mode, set by the audio decoder */
@@ -1037,6 +1043,7 @@ typedef struct hb_work_info_s
uint64_t channel_layout;
hb_chan_map_t * channel_map;
int samples_per_frame;
+ int sample_bit_depth;
int matrix_encoding;
};
};
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index fef5dd89d..dffb23a84 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -333,16 +333,6 @@ static int decavcodecaInit( hb_work_object_t * w, hb_job_t * job )
{
switch (w->audio->config.out.mixdown)
{
- case HB_AMIXDOWN_MONO:
- if (w->codec_param == AV_CODEC_ID_TRUEHD)
- {
- // libavcodec can't decode TrueHD Mono (bug #356)
- // work around it by requesting Stereo and downmixing
- pv->context->request_channel_layout = AV_CH_LAYOUT_STEREO;
- break;
- }
- pv->context->request_channel_layout = AV_CH_LAYOUT_MONO;
- break;
// request 5.1 before downmixing to dpl1/dpl2
case HB_AMIXDOWN_DOLBY:
case HB_AMIXDOWN_DOLBYPLII:
@@ -357,6 +347,14 @@ static int decavcodecaInit( hb_work_object_t * w, hb_job_t * job )
}
}
+ // libavcodec can't decode TrueHD Mono (bug #356)
+ // work around it by requesting Stereo and downmixing
+ if (w->codec_param == AV_CODEC_ID_TRUEHD &&
+ w->audio->config.in.channel_layout == AV_CH_LAYOUT_MONO)
+ {
+ pv->context->request_channel_layout = AV_CH_LAYOUT_STEREO;
+ }
+
// Set decoder opts...
AVDictionary * av_opts = NULL;
av_dict_set( &av_opts, "refcounted_frames", "1", 0 );
@@ -711,7 +709,6 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
}
if (dec_len > 0 && got_frame)
{
- info->rate.den = 1;
// libavcoded doesn't consistently set frame->sample_rate
if (frame->sample_rate != 0)
{
@@ -722,7 +719,9 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
info->rate.num = context->sample_rate;
hb_log("decavcodecaBSInfo: warning: invalid frame sample_rate! Using context sample_rate.");
}
- info->samples_per_frame = frame->nb_samples;
+ info->rate.den = 1;
+ info->samples_per_frame = frame->nb_samples;
+ info->sample_bit_depth = context->bits_per_raw_sample;
int bps = av_get_bits_per_sample(context->codec_id);
int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
diff --git a/libhb/declpcm.c b/libhb/declpcm.c
index 4688dfdbb..42cc13e50 100644
--- a/libhb/declpcm.c
+++ b/libhb/declpcm.c
@@ -381,6 +381,7 @@ static int declpcmBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
info->matrix_encoding = AV_MATRIX_ENCODING_NONE;
info->channel_layout = hdr2layout[nchannels - 1];
info->channel_map = &hb_libav_chan_map;
+ info->sample_bit_depth = sample_size;
info->samples_per_frame = ( duration * rate ) / 90000;
return 1;
diff --git a/libhb/encavcodecaudio.c b/libhb/encavcodecaudio.c
index 7242867fd..784ba5e2f 100644
--- a/libhb/encavcodecaudio.c
+++ b/libhb/encavcodecaudio.c
@@ -74,6 +74,12 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job)
av_dict_set(&av_opts, "dsur_mode", "on", 0);
break;
+ case HB_ACODEC_FFEAC3:
+ codec_id = AV_CODEC_ID_EAC3;
+ if (matrix_encoding != AV_MATRIX_ENCODING_NONE)
+ av_dict_set(&av_opts, "dsur_mode", "on", 0);
+ break;
+
case HB_ACODEC_FDK_AAC:
case HB_ACODEC_FDK_HAAC:
codec_name = "libfdk_aac";
diff --git a/libhb/muxavformat.c b/libhb/muxavformat.c
index f0b62bddc..13f9e9832 100644
--- a/libhb/muxavformat.c
+++ b/libhb/muxavformat.c
@@ -441,6 +441,12 @@ static int avformatInit( hb_mux_object_t * m )
case HB_ACODEC_AC3:
track->st->codec->codec_id = AV_CODEC_ID_AC3;
break;
+ case HB_ACODEC_FFEAC3:
+ track->st->codec->codec_id = AV_CODEC_ID_EAC3;
+ break;
+ case HB_ACODEC_FFTRUEHD:
+ track->st->codec->codec_id = AV_CODEC_ID_TRUEHD;
+ break;
case HB_ACODEC_LAME:
case HB_ACODEC_MP3:
track->st->codec->codec_id = AV_CODEC_ID_MP3;
diff --git a/libhb/scan.c b/libhb/scan.c
index d116f6815..55c9bfc90 100644
--- a/libhb/scan.c
+++ b/libhb/scan.c
@@ -1121,6 +1121,7 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b )
hb_fifo_close( &audio->priv.scan_cache );
audio->config.in.samplerate = info.rate.num;
+ audio->config.in.sample_bit_depth = info.sample_bit_depth;
audio->config.in.samples_per_frame = info.samples_per_frame;
audio->config.in.bitrate = info.bitrate;
audio->config.in.matrix_encoding = info.matrix_encoding;
@@ -1189,6 +1190,15 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b )
{
switch (audio->config.in.codec)
{
+ case HB_ACODEC_AC3:
+ codec_name = "AC3";
+ break;
+ case HB_ACODEC_FFEAC3:
+ codec_name = "E-AC3";
+ break;
+ case HB_ACODEC_FFTRUEHD:
+ codec_name = "TrueHD";
+ break;
case HB_ACODEC_DCA:
codec_name = "DTS";
break;
@@ -1198,6 +1208,9 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b )
case HB_ACODEC_FFAAC:
codec_name = "AAC";
break;
+ case HB_ACODEC_FFFLAC:
+ codec_name = "FLAC";
+ break;
case HB_ACODEC_MP3:
codec_name = "MP3";
break;
diff --git a/libhb/stream.c b/libhb/stream.c
index b34fa029c..c21a04e95 100644
--- a/libhb/stream.c
+++ b/libhb/stream.c
@@ -81,7 +81,7 @@ static const stream2codec_t st2codec[256] = {
st(0x85, U, 0, 0, "ATSC Program ID"),
// 0x86 can be BD DTS-HD/DTS. Set to 'unknown' till we know more.
st(0x86, U, HB_ACODEC_DCA_HD, AV_CODEC_ID_DTS, "DTS-HD MA"),
- st(0x87, A, HB_ACODEC_FFMPEG, AV_CODEC_ID_EAC3, "E-AC3"),
+ st(0x87, A, HB_ACODEC_FFEAC3, AV_CODEC_ID_EAC3, "E-AC3"),
st(0x8a, A, HB_ACODEC_DCA, AV_CODEC_ID_DTS, "DTS"),
@@ -3847,7 +3847,7 @@ static void hb_ps_stream_find_streams(hb_stream_t *stream)
// HD-DVD TrueHD
int idx = update_ps_streams( stream, pes_info.stream_id,
pes_info.bd_substream_id, 0, A );
- stream->pes.list[idx].codec = HB_ACODEC_FFMPEG;
+ stream->pes.list[idx].codec = HB_ACODEC_FFTRUEHD;
stream->pes.list[idx].codec_param = AV_CODEC_ID_TRUEHD;
continue;
}
@@ -4151,7 +4151,7 @@ static void hb_ts_resolve_pid_types(hb_stream_t *stream)
update_ts_streams( stream, pid, HB_SUBSTREAM_BD_TRUEHD,
stype, A, &pes_idx );
- stream->pes.list[pes_idx].codec = HB_ACODEC_FFMPEG;
+ stream->pes.list[pes_idx].codec = HB_ACODEC_FFTRUEHD;
stream->pes.list[pes_idx].codec_param = AV_CODEC_ID_TRUEHD;
continue;
}
@@ -4162,7 +4162,7 @@ static void hb_ts_resolve_pid_types(hb_stream_t *stream)
// which conflicts with SDDS
// To distinguish, Bluray streams have a reg_desc of HDMV
update_ts_streams( stream, pid, 0, stype, A, &pes_idx );
- stream->pes.list[pes_idx].codec = HB_ACODEC_FFMPEG;
+ stream->pes.list[pes_idx].codec = HB_ACODEC_FFEAC3;
stream->pes.list[pes_idx].codec_param = AV_CODEC_ID_EAC3;
continue;
}
@@ -5058,6 +5058,14 @@ static void add_ffmpeg_audio(hb_title_t *title, hb_stream_t *stream, int id)
audio->config.in.codec = HB_ACODEC_AC3;
break;
+ case AV_CODEC_ID_EAC3:
+ audio->config.in.codec = HB_ACODEC_FFEAC3;
+ break;
+
+ case AV_CODEC_ID_TRUEHD:
+ audio->config.in.codec = HB_ACODEC_FFTRUEHD;
+ break;
+
case AV_CODEC_ID_DTS:
{
switch (codec->profile)
@@ -5078,6 +5086,14 @@ static void add_ffmpeg_audio(hb_title_t *title, hb_stream_t *stream, int id)
}
} break;
+ case AV_CODEC_ID_FLAC:
+ {
+ int len = MIN(codec->extradata_size, HB_CONFIG_MAX_SIZE);
+ memcpy(audio->priv.config.extradata.bytes, codec->extradata, len);
+ audio->priv.config.extradata.length = len;
+ audio->config.in.codec = HB_ACODEC_FFFLAC;
+ } break;
+
case AV_CODEC_ID_MP3:
audio->config.in.codec = HB_ACODEC_MP3;
break;
diff --git a/libhb/sync.c b/libhb/sync.c
index d2c7b94f1..21fe8c2ae 100644
--- a/libhb/sync.c
+++ b/libhb/sync.c
@@ -1260,13 +1260,15 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
w->fifo_out = w->audio->priv.fifo_sync;
}
- if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS ||
- w->audio->config.out.codec == HB_ACODEC_AAC_PASS )
+ if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS ||
+ w->audio->config.out.codec == HB_ACODEC_AAC_PASS ||
+ w->audio->config.out.codec == HB_ACODEC_EAC3_PASS ||
+ w->audio->config.out.codec == HB_ACODEC_FLAC_PASS )
{
- /* Have a silent AC-3/AAC frame ready in case we have to fill a
- gap */
- AVCodec * codec;
- AVCodecContext * c;
+ /* Have a silent frame ready in case we have to fill a gap */
+ AVDictionary *av_opts = NULL;
+ AVCodec *codec;
+ AVCodecContext *c;
switch ( w->audio->config.out.codec )
{
@@ -1274,10 +1276,18 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
{
codec = avcodec_find_encoder( AV_CODEC_ID_AC3 );
} break;
+ case HB_ACODEC_EAC3_PASS:
+ {
+ codec = avcodec_find_encoder( AV_CODEC_ID_EAC3 );
+ } break;
case HB_ACODEC_AAC_PASS:
{
codec = avcodec_find_encoder_by_name("aac");
} break;
+ case HB_ACODEC_FLAC_PASS:
+ {
+ codec = avcodec_find_encoder( AV_CODEC_ID_FLAC );
+ } break;
default:
{
// Never gets here
@@ -1290,7 +1300,71 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
c->sample_rate = w->audio->config.in.samplerate;
c->channels =
av_get_channel_layout_nb_channels(w->audio->config.in.channel_layout);
- hb_ff_set_sample_fmt(c, codec, AV_SAMPLE_FMT_FLT);
+
+ /*
+ * lossless codecs may encode differently depending on the bit depth, so
+ * we need to set it correctly if we want the bitstream to be as close
+ * as possible to what we're passing through
+ */
+ if (w->audio->config.out.codec == HB_ACODEC_FLAC_PASS)
+ {
+ if (w->audio->config.in.sample_bit_depth <= 16)
+ {
+ hb_ff_set_sample_fmt(c, codec, AV_SAMPLE_FMT_S16);
+ }
+ else
+ {
+ hb_ff_set_sample_fmt(c, codec, AV_SAMPLE_FMT_S32);
+ }
+ c->bits_per_raw_sample = w->audio->config.in.sample_bit_depth;
+ }
+ else
+ {
+ hb_ff_set_sample_fmt(c, codec, AV_SAMPLE_FMT_FLTP);
+ }
+
+ /*
+ * the default frame size selected by the encoder may not match
+ * that of the input stream, but the FLAC encoder will honor whatever
+ * frame size we set as long as it's a valid FLAC block size.
+ *
+ * for AC-3, the frame size is the same for all streams.
+ *
+ * for E-AC-3, using the same bitrate and sample rate as the input
+ * should result in the frame size being the same as the source's.
+ */
+ if (w->audio->config.out.codec == HB_ACODEC_FLAC_PASS)
+ {
+ c->frame_size = w->audio->config.in.samples_per_frame;
+ }
+
+ /*
+ * we want the output to be as close as possible to what we're passing
+ * through, and we do have access to the source's matrix encoding mode.
+ */
+ if (w->audio->config.out.codec == HB_ACODEC_AC3_PASS ||
+ w->audio->config.out.codec == HB_ACODEC_EAC3_PASS)
+ {
+ switch (w->audio->config.in.matrix_encoding)
+ {
+ case AV_MATRIX_ENCODING_DOLBY:
+ case AV_MATRIX_ENCODING_DPLII:
+ av_dict_set(&av_opts, "dsur_mode", "on", 0);
+ break;
+ case AV_MATRIX_ENCODING_DPLIIX:
+ case AV_MATRIX_ENCODING_DOLBYEX:
+ av_dict_set(&av_opts, "dsurex_mode", "on", 0);
+ break;
+ case AV_MATRIX_ENCODING_DPLIIZ:
+ av_dict_set(&av_opts, "dsurex_mode", "dpliiz", 0);
+ break;
+ case AV_MATRIX_ENCODING_DOLBYHEADPHONE:
+ av_dict_set(&av_opts, "dheadphone_mode", "on", 0);
+ break;
+ default:
+ break;
+ }
+ }
if (w->audio->config.in.channel_layout == AV_CH_LAYOUT_STEREO_DOWNMIX)
{
@@ -1301,7 +1375,7 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
c->channel_layout = w->audio->config.in.channel_layout;
}
- if (hb_avcodec_open(c, codec, NULL, 0) < 0)
+ if (hb_avcodec_open(c, codec, &av_opts, 0) < 0)
{
hb_log("sync: track %d, hb_avcodec_open() failed, dropping video to sync",
w->audio->config.out.track);
@@ -1358,6 +1432,12 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
free( zeros );
hb_avcodec_close( c );
}
+ AVDictionaryEntry *opt = NULL;
+ while ((opt = av_dict_get(av_opts, "", opt, AV_DICT_IGNORE_SUFFIX)) != NULL)
+ {
+ hb_log("InitAudio: unknown option '%s'", opt->key);
+ }
+ av_dict_free( &av_opts );
av_free( c );
}
else