Ejemplo n.º 1
0
 /// <summary>
 /// Sanitizes an audio bitrate given the output codec, sample rate and mixdown.
 /// </summary>
 /// <param name="audioBitrate">The desired audio bitrate.</param>
 /// <param name="encoder">The output encoder to be used.</param>
 /// <param name="sampleRate">The output sample rate to be used.</param>
 /// <param name="mixdown">The mixdown to be used.</param>
 /// <returns>A sanitized audio bitrate.</returns>
 public static int SanitizeAudioBitrate(int audioBitrate, HBAudioEncoder encoder, int sampleRate, HBMixdown mixdown)
 {
     return(HBFunctions.hb_audio_bitrate_get_best((uint)encoder.Id, audioBitrate, sampleRate, mixdown.Id));
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Gets the default audio bitrate for the given parameters.
 /// </summary>
 /// <param name="encoder">The encoder to use.</param>
 /// <param name="sampleRate">The sample rate to use.</param>
 /// <param name="mixdown">The mixdown to use.</param>
 /// <returns>The default bitrate for these parameters.</returns>
 public static int GetDefaultBitrate(HBAudioEncoder encoder, int sampleRate, HBMixdown mixdown)
 {
     return(HBFunctions.hb_audio_bitrate_get_default((uint)encoder.Id, sampleRate, mixdown.Id));
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Sanitizes a mixdown given the output codec and input channel layout.
        /// </summary>
        /// <param name="mixdown">The desired mixdown.</param>
        /// <param name="encoder">The output encoder to be used.</param>
        /// <param name="layout">The input channel layout.</param>
        /// <returns>A sanitized mixdown value.</returns>
        public static HBMixdown SanitizeMixdown(HBMixdown mixdown, HBAudioEncoder encoder, ulong layout)
        {
            int sanitizedMixdown = HBFunctions.hb_mixdown_get_best((uint)encoder.Id, layout, mixdown.Id);

            return(Mixdowns.Single(m => m.Id == sanitizedMixdown));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets the bitrate limits for the given audio codec, sample rate and mixdown.
        /// </summary>
        /// <param name="encoder">The audio encoder used.</param>
        /// <param name="sampleRate">The sample rate used (Hz).</param>
        /// <param name="mixdown">The mixdown used.</param>
        /// <returns>Limits on the audio bitrate for the given settings.</returns>
        public static BitrateLimits GetBitrateLimits(HBAudioEncoder encoder, int sampleRate, HBMixdown mixdown)
        {
            int low  = 0;
            int high = 0;

            HBFunctions.hb_audio_bitrate_get_limits((uint)encoder.Id, sampleRate, mixdown.Id, ref low, ref high);

            return(new BitrateLimits {
                Low = low, High = high
            });
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Determines if the given mixdown supports the given channel layout.
 /// </summary>
 /// <param name="mixdown">The mixdown to evaluate.</param>
 /// <param name="layout">The channel layout to evaluate.</param>
 /// <returns>True if the mixdown supports the given channel layout.</returns>
 public static bool MixdownHasRemixSupport(HBMixdown mixdown, ulong layout)
 {
     return(HBFunctions.hb_mixdown_has_remix_support(mixdown.Id, layout) > 0);
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Determines if the given encoder supports the given mixdown.
 /// </summary>
 /// <param name="mixdown">The mixdown to evaluate.</param>
 /// <param name="encoder">The encoder to evaluate.</param>
 /// <returns>True if the encoder supports the mixdown.</returns>
 public static bool MixdownHasCodecSupport(HBMixdown mixdown, HBAudioEncoder encoder)
 {
     return(HBFunctions.hb_mixdown_has_codec_support(mixdown.Id, (uint)encoder.Id) > 0);
 }
Ejemplo n.º 7
0
        /// <summary>
        /// The create audio.
        /// </summary>
        /// <param name="job">
        /// The job.
        /// </param>
        /// <returns>
        /// The <see cref="Audio"/>.
        /// </returns>
        private static Audio CreateAudio(EncodeTask job)
        {
            Audio audio = new Audio();

            List <uint> copyMaskList = new List <uint>();

            if (job.AllowedPassthruOptions.AudioAllowAACPass)
            {
                copyMaskList.Add(NativeConstants.HB_ACODEC_AAC_PASS);
            }
            if (job.AllowedPassthruOptions.AudioAllowAC3Pass)
            {
                copyMaskList.Add(NativeConstants.HB_ACODEC_AC3_PASS);
            }
            if (job.AllowedPassthruOptions.AudioAllowDTSHDPass)
            {
                copyMaskList.Add(NativeConstants.HB_ACODEC_DCA_HD_PASS);
            }
            if (job.AllowedPassthruOptions.AudioAllowDTSPass)
            {
                copyMaskList.Add(NativeConstants.HB_ACODEC_DCA_PASS);
            }
            if (job.AllowedPassthruOptions.AudioAllowEAC3Pass)
            {
                copyMaskList.Add(NativeConstants.HB_ACODEC_EAC3_PASS);
            }
            if (job.AllowedPassthruOptions.AudioAllowFlacPass)
            {
                copyMaskList.Add(NativeConstants.HB_ACODEC_FLAC_PASS);
            }
            if (job.AllowedPassthruOptions.AudioAllowMP3Pass)
            {
                copyMaskList.Add(NativeConstants.HB_ACODEC_MP3_PASS);
            }
            if (job.AllowedPassthruOptions.AudioAllowTrueHDPass)
            {
                copyMaskList.Add(NativeConstants.HB_ACODEC_TRUEHD_PASS);
            }
            audio.CopyMask = copyMaskList.ToArray();

            HBAudioEncoder audioEncoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper <AudioEncoder> .GetShortName(job.AllowedPassthruOptions.AudioEncoderFallback));

            audio.FallbackEncoder = audioEncoder.Id;

            audio.AudioList = new List <Interop.Json.Encode.AudioTrack>();
            foreach (AudioTrack item in job.AudioTracks)
            {
                HBAudioEncoder encoder = HandBrakeEncoderHelpers.GetAudioEncoder(ApplicationServices.Utilities.Converters.GetCliAudioEncoder(item.Encoder));
                Validate.NotNull(encoder, "Unrecognized audio encoder:" + item.Encoder);

                HBMixdown mixdown = HandBrakeEncoderHelpers.GetMixdown(EnumHelper <Mixdown> .GetShortName(item.MixDown));
                Validate.NotNull(mixdown, "Unrecognized audio mixdown:" + item.MixDown);

                HBRate sampleRate = HandBrakeEncoderHelpers.AudioSampleRates.FirstOrDefault(s => s.Name == item.SampleRate.ToString(CultureInfo.InvariantCulture));

                HandBrake.ApplicationServices.Interop.Json.Encode.AudioTrack audioTrack = new HandBrake.ApplicationServices.Interop.Json.Encode.AudioTrack
                {
                    Track             = (item.Track.HasValue ? item.Track.Value : 0) - 1,
                    DRC               = item.DRC,
                    Encoder           = encoder.Id,
                    Gain              = item.Gain,
                    Mixdown           = mixdown.Id,
                    NormalizeMixLevel = false,
                    Samplerate        = sampleRate != null ? sampleRate.Rate : 0,
                    Name              = item.TrackName,
                };

                if (!item.IsPassthru)
                {
                    if (item.EncoderRateType == AudioEncoderRateType.Quality)
                    {
                        audioTrack.Quality = item.Quality;
                    }

                    if (item.EncoderRateType == AudioEncoderRateType.Bitrate)
                    {
                        audioTrack.Bitrate = item.Bitrate;
                    }
                }

                audio.AudioList.Add(audioTrack);
            }

            return(audio);
        }
Ejemplo n.º 8
0
        private Audio CreateAudio(EncodeTask job)
        {
            Audio audio = new Audio();

            List <string> copyMaskList = new List <string>();

            if (job.AudioPassthruOptions.AudioAllowAACPass)
            {
                copyMaskList.Add(EnumHelper <AudioEncoder> .GetShortName(AudioEncoder.AacPassthru));
            }
            if (job.AudioPassthruOptions.AudioAllowAC3Pass)
            {
                copyMaskList.Add(EnumHelper <AudioEncoder> .GetShortName(AudioEncoder.Ac3Passthrough));
            }
            if (job.AudioPassthruOptions.AudioAllowDTSHDPass)
            {
                copyMaskList.Add(EnumHelper <AudioEncoder> .GetShortName(AudioEncoder.DtsHDPassthrough));
            }
            if (job.AudioPassthruOptions.AudioAllowDTSPass)
            {
                copyMaskList.Add(EnumHelper <AudioEncoder> .GetShortName(AudioEncoder.DtsPassthrough));
            }
            if (job.AudioPassthruOptions.AudioAllowEAC3Pass)
            {
                copyMaskList.Add(EnumHelper <AudioEncoder> .GetShortName(AudioEncoder.EAc3Passthrough));
            }
            if (job.AudioPassthruOptions.AudioAllowFlacPass)
            {
                copyMaskList.Add(EnumHelper <AudioEncoder> .GetShortName(AudioEncoder.FlacPassthru));
            }
            if (job.AudioPassthruOptions.AudioAllowMP3Pass)
            {
                copyMaskList.Add(EnumHelper <AudioEncoder> .GetShortName(AudioEncoder.Mp3Passthru));
            }
            if (job.AudioPassthruOptions.AudioAllowTrueHDPass)
            {
                copyMaskList.Add(EnumHelper <AudioEncoder> .GetShortName(AudioEncoder.TrueHDPassthrough));
            }
            if (job.AudioPassthruOptions.AudioAllowMP2Pass)
            {
                copyMaskList.Add(EnumHelper <AudioEncoder> .GetShortName(AudioEncoder.Mp2Passthru));
            }

            audio.CopyMask = copyMaskList.ToArray();

            HBAudioEncoder audioEncoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper <AudioEncoder> .GetShortName(job.AudioPassthruOptions.AudioEncoderFallback));

            audio.FallbackEncoder = audioEncoder?.ShortName;

            Validate.NotNull(audio.FallbackEncoder, string.Format("Unrecognized audio encoder: {0} \n", job.AudioPassthruOptions.AudioEncoderFallback));

            audio.AudioList = new List <HandBrake.Interop.Interop.Json.Encode.AudioTrack>();
            foreach (AudioTrack item in job.AudioTracks)
            {
                HBAudioEncoder encoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper <AudioEncoder> .GetShortName(item.Encoder));
                Validate.NotNull(encoder, "Unrecognized audio encoder:" + item.Encoder);

                if (item.IsPassthru && (item.ScannedTrack.Codec & encoder.Id) == 0)
                {
                    // We have an unsupported passthru. Rather than let libhb drop the track, switch it to the fallback.
                    encoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper <AudioEncoder> .GetShortName(job.AudioPassthruOptions.AudioEncoderFallback));
                }

                HBMixdown mixdown = HandBrakeEncoderHelpers.GetMixdown(item.MixDown);

                HBRate sampleRate = HandBrakeEncoderHelpers.AudioSampleRates.FirstOrDefault(s => s.Name == item.SampleRate.ToString(CultureInfo.InvariantCulture));

                HandBrake.Interop.Interop.Json.Encode.AudioTrack audioTrack = new HandBrake.Interop.Interop.Json.Encode.AudioTrack
                {
                    Track             = (item.Track.HasValue ? item.Track.Value : 0) - 1,
                    DRC               = item.DRC,
                    Encoder           = encoder.ShortName,
                    Gain              = item.Gain,
                    Mixdown           = mixdown != null ? mixdown.Id : -1,
                    NormalizeMixLevel = false,
                    Samplerate        = sampleRate != null ? sampleRate.Rate : 0,
                    Name              = !string.IsNullOrEmpty(item.TrackName) ? item.TrackName : null,
                };

                if (!item.IsPassthru)
                {
                    if (item.EncoderRateType == AudioEncoderRateType.Quality)
                    {
                        audioTrack.Quality = item.Quality;
                    }

                    if (item.EncoderRateType == AudioEncoderRateType.Bitrate)
                    {
                        audioTrack.Bitrate = item.Bitrate;
                    }
                }

                audio.AudioList.Add(audioTrack);
            }

            return(audio);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Determines if a mixdown is available for a given track and encoder.
 /// </summary>
 /// <param name="mixdown">
 /// The mixdown to evaluate.
 /// </param>
 /// <param name="encoder">
 /// The encoder to evaluate.
 /// </param>
 /// <param name="channelLayout">channel layout of the source track</param>
 /// <returns>True if available.</returns>
 public static bool MixdownIsSupported(HBMixdown mixdown, HBAudioEncoder encoder, long channelLayout)
 {
     return(HBFunctions.hb_mixdown_is_supported(mixdown.Id, (uint)encoder.Id, (uint)channelLayout) > 0);
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AudioTrack"/> class.
        /// Create a track from a behaviour track.
        /// </summary>
        /// <param name="track">
        /// The Behavior track
        /// </param>
        /// <param name="sourceTrack">
        /// The source track we are dealing with.
        /// </param>
        /// <param name="fallback">
        /// An encoder to fall back to.
        /// </param>
        public AudioTrack(AudioBehaviourTrack track, Audio sourceTrack, AllowedPassthru fallback, OutputFormat container)
        {
            AudioEncoder   chosenEncoder = track.Encoder;
            HBAudioEncoder encoderInfo   = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper <AudioEncoder> .GetShortName(track.Encoder));

            if (track.IsPassthru && (sourceTrack.Codec & encoderInfo.Id) == 0)
            {
                chosenEncoder = fallback.AudioEncoderFallback;
            }

            if (track.IsPassthru && chosenEncoder == AudioEncoder.Passthrough)
            {
                HBAudioEncoder fallbackEncoderInfo = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper <AudioEncoder> .GetShortName(fallback.AudioEncoderFallback));

                if (fallbackEncoderInfo != null)
                {
                    int format   = HandBrakeEncoderHelpers.GetContainer(EnumHelper <OutputFormat> .GetShortName(container)).Id;
                    int copyMask = checked ((int)HandBrakeEncoderHelpers.BuildCopyMask(
                                                fallback.AudioAllowMP3Pass,
                                                fallback.AudioAllowAACPass,
                                                fallback.AudioAllowAC3Pass,
                                                fallback.AudioAllowDTSPass,
                                                fallback.AudioAllowDTSHDPass,
                                                fallback.AudioAllowEAC3Pass,
                                                fallback.AudioAllowFlacPass,
                                                fallback.AudioAllowTrueHDPass));

                    HBAudioEncoder autoPassthruEncoderOption = HandBrakeEncoderHelpers.GetAutoPassthruEncoder(sourceTrack.Codec, copyMask, fallbackEncoderInfo.Id, format);
                    AudioEncoder   autoPassthru = EnumHelper <AudioEncoder> .GetValue(autoPassthruEncoderOption.ShortName);

                    chosenEncoder = autoPassthru;
                }
            }

            encoderInfo = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper <AudioEncoder> .GetShortName(chosenEncoder));

            this.scannedTrack = sourceTrack;
            this.drc          = track.DRC;
            this.encoder      = chosenEncoder;
            this.gain         = track.Gain;
            this.mixDown      = track.MixDown != null ? track.MixDown.ShortName : "dpl2";

            // If the mixdown isn't supported, downgrade it.
            if (track.IsPassthru && track.MixDown != null && encoderInfo != null && !HandBrakeEncoderHelpers.MixdownIsSupported(track.MixDown, encoderInfo, sourceTrack.ChannelLayout))
            {
                HBMixdown changedMixdown = HandBrakeEncoderHelpers.GetDefaultMixdown(encoderInfo, (ulong)sourceTrack.ChannelLayout);
                if (changedMixdown != null)
                {
                    this.mixDown = changedMixdown.ShortName;
                }
            }

            this.sampleRate      = track.SampleRate;
            this.encoderRateType = track.EncoderRateType;
            this.quality         = track.Quality;
            this.bitrate         = track.Bitrate;

            if (!string.IsNullOrEmpty(this.scannedTrack?.Name))
            {
                this.TrackName = this.scannedTrack.Name;
            }

            this.SetupLimits();
        }
Ejemplo n.º 11
0
        private void RefreshBitrateChoices()
        {
            if (this.SelectedAudioEncoder == null || this.SelectedMixdown == null)
            {
                return;
            }

            int oldBitrate = 0;

            if (this.SelectedBitrate != null)
            {
                oldBitrate = this.SelectedBitrate.Bitrate;
            }

            this.bitrateChoices = new List <BitrateChoiceViewModel>();
            BitrateLimits bitrateLimits = null;

            // Determine if we should gray out "out of range" bitrates
            // Can only do this if a source is loaded
            if (this.main.HasVideoSource)
            {
                // Find if we're encoding a single track
                var track = this.GetTargetAudioTrack();

                // Can only gray out bitrates if we're encoding exactly one track
                if (track != null)
                {
                    int sampleRateLimits = this.SampleRate;
                    if (sampleRateLimits == 0)
                    {
                        sampleRateLimits = track.SampleRate;
                    }

                    HBMixdown mixdownLimits = this.SelectedMixdown.Mixdown;
                    if (mixdownLimits.ShortName == "none" || string.IsNullOrEmpty(mixdownLimits.ShortName))
                    {
                        mixdownLimits = HandBrakeEncoderHelpers.SanitizeMixdown(mixdownLimits, this.HBAudioEncoder, (ulong)track.ChannelLayout);
                    }

                    bitrateLimits = HandBrakeEncoderHelpers.GetBitrateLimits(this.HBAudioEncoder, sampleRateLimits, mixdownLimits);
                }
            }

            BitrateLimits encoderBitrateLimits = CodecUtilities.GetAudioEncoderLimits(this.HBAudioEncoder);

            this.bitrateChoices.Add(new BitrateChoiceViewModel
            {
                Bitrate      = 0,
                IsCompatible = true
            });

            foreach (int bitrateChoice in HandBrakeEncoderHelpers.AudioBitrates)
            {
                if (bitrateChoice >= encoderBitrateLimits.Low && bitrateChoice <= encoderBitrateLimits.High)
                {
                    bool isCompatible = bitrateLimits == null || bitrateChoice >= bitrateLimits.Low && bitrateChoice <= bitrateLimits.High;

                    this.bitrateChoices.Add(new BitrateChoiceViewModel
                    {
                        Bitrate      = bitrateChoice,
                        IsCompatible = isCompatible
                    });
                }
            }

            this.RaisePropertyChanged(nameof(this.BitrateChoices));

            this.selectedBitrate = this.BitrateChoices.SingleOrDefault(b => b.Bitrate == oldBitrate);
            if (this.selectedBitrate == null)
            {
                this.selectedBitrate = this.BitrateChoices[0];
            }

            this.RaisePropertyChanged(nameof(this.SelectedBitrate));
        }