예제 #1
0
        /// <summary>
        /// The calculate bitrate limits.
        /// </summary>
        private void SetupBitrateLimits()
        {
            // Base set of bitrates available.
            List <int> audioBitrates = HandBrakeEncoderHelpers.AudioBitrates;

            // Defaults
            int max = 256;
            int low = 32;

            // Based on the users settings, find the high and low bitrates.
            HBAudioEncoder hbaenc  = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper <AudioEncoder> .GetShortName(this.Encoder));
            HBRate         rate    = HandBrakeEncoderHelpers.AudioSampleRates.FirstOrDefault(t => t.Name == this.SampleRate.ToString(CultureInfo.InvariantCulture));
            HBMixdown      mixdown = this.mixDown ?? HandBrakeEncoderHelpers.GetMixdown("dpl2");

            BitrateLimits limits = HandBrakeEncoderHelpers.GetBitrateLimits(hbaenc, rate != null ? rate.Rate : 48000, mixdown);

            if (limits != null)
            {
                max = limits.High;
                low = limits.Low;
            }

            // Return the subset of available bitrates.
            List <int> subsetBitrates = audioBitrates.Where(b => b <= max && b >= low).ToList();

            this.bitrates = subsetBitrates;
            this.NotifyOfPropertyChange(() => this.Bitrates);

            // If the subset does not contain the current bitrate, request the default.
            if (!subsetBitrates.Contains(this.Bitrate))
            {
                this.Bitrate = HandBrakeEncoderHelpers.GetDefaultBitrate(hbaenc, rate != null ? rate.Rate : 48000, mixdown);
            }
        }
예제 #2
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 = Encoders.SanitizeMixdown(mixdownLimits, this.HBAudioEncoder, track.ChannelLayout);
                    }

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

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

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

            foreach (int bitrateChoice in Encoders.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(() => this.BitrateChoices);

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

            //this.selectedBitrate = this.BitrateChoices.Single(b => b.Bitrate == oldBitrate);
            this.RaisePropertyChanged(() => this.SelectedBitrate);
        }
예제 #3
0
        public AudioEncodingViewModel(AudioEncoding audioEncoding, SourceTitle selectedTitle, List <int> chosenAudioTracks, AudioPanelViewModel audioPanelVM)
        {
            this.initializing = true;
            this.audioPanelVM = audioPanelVM;

            this.targetStreams     = new ObservableCollection <TargetStreamViewModel>();
            this.targetStreamIndex = audioEncoding.InputNumber;

            this.SetChosenTracks(chosenAudioTracks, selectedTitle);

            this.audioEncoders  = new List <AudioEncoderViewModel>();
            this.mixdownChoices = new List <MixdownViewModel>();

            this.RefreshEncoderChoices();

            this.presetChangeSubscription = this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile)
                                            .Subscribe(profile =>
            {
                this.containerSubscription?.Dispose();

                this.containerSubscription = profile.WhenAnyValue(x => x.ContainerName)
                                             .Skip(1)
                                             .Subscribe(_ =>
                {
                    this.RefreshEncoderChoices(isContainerChange: true);
                });

                this.audioPanelVM.SuppressProfileEdits = true;
                this.RefreshEncoderChoices();
                this.audioPanelVM.SuppressProfileEdits = false;
            });

            HBAudioEncoder hbAudioEncoder = HandBrakeEncoderHelpers.GetAudioEncoder(audioEncoding.Encoder);

            if (hbAudioEncoder.IsPassthrough)
            {
                this.selectedAudioEncoder = this.audioEncoders[0];
                this.selectedPassthrough  = audioEncoding.Encoder;
            }
            else
            {
                this.selectedAudioEncoder = this.audioEncoders.Skip(1).FirstOrDefault(e => e.Encoder.ShortName == audioEncoding.Encoder);
                this.selectedPassthrough  = "copy";
            }

            if (this.selectedAudioEncoder == null)
            {
                this.selectedAudioEncoder = this.audioEncoders[1];
            }

            this.RefreshMixdownChoices();
            this.RefreshBitrateChoices();
            this.RefreshSampleRateChoices();

            this.SelectMixdown(HandBrakeEncoderHelpers.GetMixdown(audioEncoding.Mixdown));

            this.sampleRate = audioEncoding.SampleRateRaw;

            if (!this.HBAudioEncoder.SupportsQuality)
            {
                this.encodeRateType = AudioEncodeRateType.Bitrate;
            }
            else
            {
                this.encodeRateType = audioEncoding.EncodeRateType;
            }

            this.audioQuality = audioEncoding.Quality;

            if (audioEncoding.Compression >= 0)
            {
                this.audioCompression = audioEncoding.Compression;
            }
            else
            {
                this.audioCompression = this.HBAudioEncoder.DefaultCompression;
            }

            this.selectedBitrate = this.BitrateChoices.SingleOrDefault(b => b.Bitrate == audioEncoding.Bitrate);
            if (this.selectedBitrate == null)
            {
                this.selectedBitrate = this.BitrateChoices.First();
            }

            this.gain = audioEncoding.Gain;
            this.drc  = audioEncoding.Drc;
            this.passthroughIfPossible = audioEncoding.PassthroughIfPossible;
            this.name = audioEncoding.Name;

            // EncoderSettingsVisible
            this.WhenAnyValue(x => x.SelectedAudioEncoder, x => x.SelectedPassthrough, (audioEncoder, passthrough) =>
            {
                if (audioEncoder == null)
                {
                    return(false);
                }

                if (passthrough == null)
                {
                    return(false);
                }

                return(!GetHBAudioEncoder(audioEncoder, passthrough).IsPassthrough);
            }).ToProperty(this, x => x.EncoderSettingsVisible, out this.encoderSettingsVisible);

            // AudioCompressionVisible
            this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder =>
            {
                return(!audioEncoder.IsPassthrough && audioEncoder.Encoder.SupportsCompression);
            }).ToProperty(this, x => x.AudioCompressionVisible, out this.audioCompressionVisible);

            // PassthroughIfPossibleVisible
            this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder =>
            {
                if (audioEncoder.IsPassthrough)
                {
                    return(false);
                }

                if (HandBrakeEncoderHelpers.AudioEncoders.Any(e => e.Id == (NativeConstants.HB_ACODEC_PASS_FLAG | audioEncoder.Encoder.Id)))
                {
                    return(true);
                }

                return(audioEncoder.Encoder.ShortName.ToLowerInvariant().Contains("aac") || audioEncoder.Encoder.ShortName.ToLowerInvariant().Contains("mp3"));
            }).ToProperty(this, x => x.PassthroughIfPossibleVisible, out this.passthroughIfPossibleVisible);

            // BitrateVisible
            this.WhenAnyValue(
                x => x.SelectedAudioEncoder,
                x => x.EncoderSettingsVisible,
                x => x.SelectedMixdown,
                x => x.EncodeRateType,
                (audioEncoder, encoderSettingsVisible, mixdown, encodeRateType) =>
            {
                if (audioEncoder.IsPassthrough)
                {
                    return(false);
                }

                if (encoderSettingsVisible && mixdown != null && encodeRateType == AudioEncodeRateType.Bitrate)
                {
                    // We only need to find out if the bitrate limits exist, so pass in some normal values for sample rate and mixdown.
                    BitrateLimits bitrateLimits = HandBrakeEncoderHelpers.GetBitrateLimits(audioEncoder.Encoder, 48000, HandBrakeEncoderHelpers.GetMixdown("dpl2"));
                    return(bitrateLimits.High > 0);
                }

                return(false);
            }).ToProperty(this, x => x.BitrateVisible, out this.bitrateVisible);

            // BitrateLabelVisible
            this.WhenAnyValue(x => x.BitrateVisible, x => x.SelectedAudioEncoder, (bitrateVisible, audioEncoder) =>
            {
                return(!audioEncoder.IsPassthrough && bitrateVisible && !audioEncoder.Encoder.SupportsQuality);
            }).ToProperty(this, x => x.BitrateLabelVisible, out this.bitrateLabelVisible);

            // AudioQualityVisible
            this.WhenAnyValue(x => x.SelectedAudioEncoder, x => x.EncodeRateType, (audioEncoder, encodeRateType) =>
            {
                return(!audioEncoder.IsPassthrough &&
                       audioEncoder.Encoder.SupportsQuality &&
                       encodeRateType == AudioEncodeRateType.Quality);
            }).ToProperty(this, x => x.AudioQualityVisible, out this.audioQualityVisible);

            // AudioQualityRadioVisible
            this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder =>
            {
                return(!audioEncoder.IsPassthrough && audioEncoder.Encoder.SupportsQuality);
            }).ToProperty(this, x => x.AudioQualityRadioVisible, out this.audioQualityRadioVisible);

            // AudioQualityMinimum
            this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder =>
            {
                if (audioEncoder.IsPassthrough)
                {
                    return(0);
                }

                return(Math.Round(audioEncoder.Encoder.QualityLimits.Low, RangeRoundDigits));
            }).ToProperty(this, x => x.AudioQualityMinimum, out this.audioQualityMinimum);

            // AudioQualityMaximum
            this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder =>
            {
                if (audioEncoder.IsPassthrough)
                {
                    return(0);
                }

                return(Math.Round(audioEncoder.Encoder.QualityLimits.High, RangeRoundDigits));
            }).ToProperty(this, x => x.AudioQualityMaximum, out this.audioQualityMaximum);

            // AudioQualityGranularity
            this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder =>
            {
                if (audioEncoder.IsPassthrough)
                {
                    return(0);
                }

                return(Math.Round(audioEncoder.Encoder.QualityLimits.Granularity, RangeRoundDigits));
            }).ToProperty(this, x => x.AudioQualityGranularity, out this.audioQualityGranularity);

            // AudioQualityToolTip
            this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder =>
            {
                if (audioEncoder.IsPassthrough)
                {
                    return(string.Empty);
                }

                string directionSentence;
                if (audioEncoder.Encoder.QualityLimits.Ascending)
                {
                    directionSentence = EncodingRes.AscendingQualityToolTip;
                }
                else
                {
                    directionSentence = EncodingRes.DescendingQualityToolTip;
                }

                return(string.Format(
                           EncodingRes.AudioQualityToolTip,
                           directionSentence,
                           audioEncoder.Encoder.QualityLimits.Low,
                           audioEncoder.Encoder.QualityLimits.High));
            }).ToProperty(this, x => x.AudioQualityToolTip, out this.audioQualityToolTip);

            // AudioCompressionMinimum
            this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder =>
            {
                if (audioEncoder.IsPassthrough)
                {
                    return(0);
                }

                return(Math.Round(audioEncoder.Encoder.CompressionLimits.Low, RangeRoundDigits));
            }).ToProperty(this, x => x.AudioCompressionMinimum, out this.audioCompressionMinimum);

            // AudioCompressionMaximum
            this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder =>
            {
                if (audioEncoder.IsPassthrough)
                {
                    return(0);
                }

                return(Math.Round(audioEncoder.Encoder.CompressionLimits.High, RangeRoundDigits));
            }).ToProperty(this, x => x.AudioCompressionMaximum, out this.audioCompressionMaximum);

            // AudioCompressionGranularity
            this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder =>
            {
                if (audioEncoder.IsPassthrough)
                {
                    return(0);
                }

                return(Math.Round(audioEncoder.Encoder.CompressionLimits.Granularity, RangeRoundDigits));
            }).ToProperty(this, x => x.AudioCompressionGranularity, out this.audioCompressionGranularity);

            // AudioCompressionToolTip
            this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder =>
            {
                if (audioEncoder.IsPassthrough)
                {
                    return(string.Empty);
                }

                string directionSentence;
                if (audioEncoder.Encoder.QualityLimits.Ascending)
                {
                    directionSentence = EncodingRes.AscendingCompressionToolTip;
                }
                else
                {
                    directionSentence = EncodingRes.DescendingCompressionToolTip;
                }

                return(string.Format(
                           EncodingRes.AudioCompressionToolTip,
                           directionSentence,
                           audioEncoder.Encoder.CompressionLimits.Low,
                           audioEncoder.Encoder.CompressionLimits.High));
            }).ToProperty(this, x => x.AudioCompressionToolTip, out this.audioCompressionToolTip);

            // PassthroughChoicesVisible
            this.WhenAnyValue(x => x.SelectedAudioEncoder, audioEncoder =>
            {
                return(audioEncoder.IsPassthrough);
            }).ToProperty(this, x => x.PassthroughChoicesVisible, out this.passthroughChoicesVisible);

            this.selectedTitleSubscription = this.main.WhenAnyValue(x => x.SelectedTitle)
                                             .Skip(1)
                                             .Subscribe(_ =>
            {
                this.RefreshFromNewInput();
            });

            this.audioTrackChangedSubscription = this.main.AudioTracks.Connect().WhenAnyPropertyChanged().Subscribe(_ =>
            {
                this.RefreshFromNewInput();
            });

            Config.Observables.ShowAudioTrackNameField.ToProperty(this, x => x.NameVisible, out this.nameVisible);

            this.initializing = false;
        }