예제 #1
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);
		}
예제 #2
0
		public AudioEncodingViewModel(AudioEncoding audioEncoding, Title selectedTitle, List<int> chosenAudioTracks, string containerName, 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.containerName = containerName;
			this.RefreshEncoderChoices();

			HBAudioEncoder hbAudioEncoder = Encoders.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(Encoders.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;

			Messenger.Default.Register<SelectedTitleChangedMessage>(
				this,
				message =>
					{
						this.RefreshMixdownChoices();
						this.RefreshBitrateChoices();
						this.RefreshDrc();
					});

			Messenger.Default.Register<AudioInputChangedMessage>(
				this,
				message =>
					{
						this.RefreshMixdownChoices();
						this.RefreshBitrateChoices();
						this.RefreshDrc();
					});

			Messenger.Default.Register<OptionsChangedMessage>(
				this,
				message =>
					{
						this.RaisePropertyChanged(() => this.NameVisible);
					});

			Messenger.Default.Register<ContainerChangedMessage>(
				this,
				message =>
					{
						this.containerName = message.ContainerName;
						this.RefreshEncoderChoices();
					});

			this.initializing = false;
		}
예제 #3
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);
        }
예제 #4
0
        public AudioEncodingViewModel(AudioEncoding audioEncoding, Title selectedTitle, List <int> chosenAudioTracks, string containerName, 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.containerName = containerName;
            this.RefreshEncoderChoices();

            HBAudioEncoder hbAudioEncoder = Encoders.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(Encoders.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;

            Messenger.Default.Register <SelectedTitleChangedMessage>(
                this,
                message =>
            {
                this.RefreshMixdownChoices();
                this.RefreshBitrateChoices();
                this.RefreshDrc();
            });

            Messenger.Default.Register <AudioInputChangedMessage>(
                this,
                message =>
            {
                this.RefreshMixdownChoices();
                this.RefreshBitrateChoices();
                this.RefreshDrc();
            });

            Messenger.Default.Register <OptionsChangedMessage>(
                this,
                message =>
            {
                this.RaisePropertyChanged(() => this.NameVisible);
            });

            Messenger.Default.Register <ContainerChangedMessage>(
                this,
                message =>
            {
                this.containerName = message.ContainerName;
                this.RefreshEncoderChoices();
            });

            this.initializing = false;
        }
예제 #5
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;
        }