diff options
-rw-r--r-- | contrib/ffmpeg/module.defs | 1 | ||||
-rw-r--r-- | libhb/bd.c | 4 | ||||
-rw-r--r-- | libhb/common.c | 51 | ||||
-rw-r--r-- | libhb/common.h | 27 | ||||
-rw-r--r-- | libhb/decavcodec.c | 23 | ||||
-rw-r--r-- | libhb/declpcm.c | 1 | ||||
-rw-r--r-- | libhb/encavcodecaudio.c | 6 | ||||
-rw-r--r-- | libhb/muxavformat.c | 6 | ||||
-rw-r--r-- | libhb/scan.c | 13 | ||||
-rw-r--r-- | libhb/stream.c | 24 | ||||
-rw-r--r-- | libhb/sync.c | 96 |
11 files changed, 214 insertions, 38 deletions
diff --git a/contrib/ffmpeg/module.defs b/contrib/ffmpeg/module.defs index 49dd3e1eb..1ca9957c6 100644 --- a/contrib/ffmpeg/module.defs +++ b/contrib/ffmpeg/module.defs @@ -30,6 +30,7 @@ FFMPEG.CONFIGURE.extra = \ --disable-encoders \ --enable-encoder=aac \ --enable-encoder=ac3 \ + --enable-encoder=eac3 \ --enable-encoder=flac \ --enable-encoder=mpeg2video \ --enable-encoder=mpeg4 \ 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 |