diff options
author | sr55 <[email protected]> | 2012-09-08 17:46:28 +0000 |
---|---|---|
committer | sr55 <[email protected]> | 2012-09-08 17:46:28 +0000 |
commit | d5bcce8f440245352742d35422fe913eb013bbbd (patch) | |
tree | 680afc2f050b871c7cc46eda241169118362c024 /win | |
parent | da4318f07c23f6755b1b21845b7336990ebabcd4 (diff) |
WinGui: Implement hb_get_audio_bitrate_limits() in the Windows UI to provide only valid bitrate options. Also disabled the bitrate selection control for flac.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4938 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'win')
3 files changed, 177 insertions, 39 deletions
diff --git a/win/CS/HandBrake.ApplicationServices/Model/Encoding/AudioTrack.cs b/win/CS/HandBrake.ApplicationServices/Model/Encoding/AudioTrack.cs index ac4b95e32..fedeb275f 100644 --- a/win/CS/HandBrake.ApplicationServices/Model/Encoding/AudioTrack.cs +++ b/win/CS/HandBrake.ApplicationServices/Model/Encoding/AudioTrack.cs @@ -198,6 +198,7 @@ namespace HandBrake.ApplicationServices.Model.Encoding this.encoder = value;
this.NotifyOfPropertyChange(() => this.Encoder);
this.NotifyOfPropertyChange("IsPassthru");
+ this.NotifyOfPropertyChange("CanSetBitrate");
this.NotifyOfPropertyChange("TrackReference");
}
}
@@ -335,6 +336,17 @@ namespace HandBrake.ApplicationServices.Model.Encoding }
/// <summary>
+ /// Gets a value indicating whether can set bitrate.
+ /// </summary>
+ public bool CanSetBitrate
+ {
+ get
+ {
+ return this.IsPassthru || this.Encoder == AudioEncoder.ffflac;
+ }
+ }
+
+ /// <summary>
/// Gets a value indicating whether IsLossless.
/// </summary>
public bool IsLossless
diff --git a/win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs b/win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs index 89016071e..28bbf81ac 100644 --- a/win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs @@ -23,6 +23,22 @@ namespace HandBrakeWPF.Converters.Audio public class AudioBitrateConverter : IValueConverter
{
/// <summary>
+ /// The samplerates.
+ /// </summary>
+ readonly Dictionary<double, int> samplerates = new Dictionary<double, int>
+ {
+ { 8, 8000 },
+ { 11.025, 11025 },
+ { 12, 12000 },
+ { 16, 16000 },
+ { 22.05, 22050 },
+ { 24, 24000 },
+ { 32, 32000 },
+ { 44.1, 44100 },
+ { 48, 48000 }
+ };
+
+ /// <summary>
/// Converts source values to a value for the binding target. The data binding engine calls this method when it propagates the values from source bindings to the binding target.
/// </summary>
/// <returns>
@@ -43,58 +59,46 @@ namespace HandBrakeWPF.Converters.Audio public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// Base set of bitrates available.
- List<int> bitrates = new List<int> { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 640, 768 };
+ List<int> bitrates = new List<int> { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 640, 768, 960, 1152, 1344, 1536 };
int max = 160;
+ int low = 32;
AudioTrack track = value as AudioTrack;
if (track != null)
{
- int channels = this.GetChannelCount(track.MixDown);
+ int samplerate = this.GetBestSampleRate(track);
+ int srShift = this.GetSamplerateShift(samplerate);
+ int lfeCount = this.GetLowFreqChannelCount(track.MixDown);
+ int channels = this.GetChannelCount(track.MixDown) - lfeCount;
- double samplerate = 48; // Default
-
- if (!track.SampleRate.Equals(0.0d))
- {
- samplerate = track.SampleRate;
- }
- else if (track.ScannedTrack != null && track.ScannedTrack.SampleRate != 0)
- {
- samplerate = track.ScannedTrack.SampleRate / 1000d;
- }
-
switch (track.Encoder)
{
case AudioEncoder.Faac:
+ low = (channels + lfeCount) * 32;
+ max = (channels + lfeCount) * (192 >> srShift);
+ break;
case AudioEncoder.ffaac:
- if (samplerate > 24)
- {
- max = 160 * channels;
- if (max > 768)
- {
- max = 768;
- }
- }
- else
- {
- max = 96 * channels;
- if (max > 480)
- {
- max = 480;
- }
- }
+ low = ((channels + lfeCount) * 32);
+ max = ((channels + lfeCount) *
+ ((192 + (64 * ((samplerate << srShift) >= 44100 ? 1 : 0)))
+ >> srShift));
break;
case AudioEncoder.Lame:
- max = samplerate > 24 ? 320 : 160;
+ low = 8 + (24 * (srShift < 1 ? 1 : 0) );
+ max = 64 + (96 * (srShift < 2 ? 1 : 0)) + (160 * (srShift < 1 ? 1 : 0));
break;
case AudioEncoder.Vorbis:
- max = samplerate > 24
- ? (channels > 2
- ? 128 * channels
- : (track.SampleRate > 32 ? 224 * channels : 160 * channels))
- : 80 * this.GetChannelCount(track.MixDown);
+ low = (channels + lfeCount) * (14 +
+ (8 * (srShift < 2 ? 1 : 0)) +
+ (6 * (srShift < 1 ? 1 : 0)));
+ max = (channels + lfeCount) * (32 +
+ (54 * (srShift < 2 ? 1 : 0)) +
+ (104 * (srShift < 1 ? 1 : 0)) +
+ (50 * (samplerate >= 44100 ? 1 : 0)));
break;
case AudioEncoder.Ac3:
+ low = 224 * channels / 5;
max = samplerate > 24 ? 640 : 320;
break;
case AudioEncoder.Ac3Passthrough:
@@ -104,7 +108,7 @@ namespace HandBrakeWPF.Converters.Audio case AudioEncoder.Mp3Passthru:
case AudioEncoder.Passthrough:
case AudioEncoder.ffflac:
- max = 768; // Since we don't care, just set it to the max.
+ max = 1536; // Since we don't care, just set it to the max.
break;
default:
max = 768;
@@ -112,13 +116,18 @@ namespace HandBrakeWPF.Converters.Audio }
// Bring the bitrate down in-line with the max.
+ if (track.Bitrate < low)
+ {
+ track.Bitrate = low;
+ }
+
if (track.Bitrate > max)
{
track.Bitrate = max;
}
}
- return bitrates.Where(bitrate => bitrate <= max);
+ return bitrates.Where(bitrate => bitrate <= max && bitrate >= low);
}
/// <summary>
@@ -152,7 +161,124 @@ namespace HandBrakeWPF.Converters.Audio }
}
+ /// <summary>
+ /// The get low freq channel count.
+ /// </summary>
+ /// <param name="mixdown">
+ /// The mixdown.
+ /// </param>
+ /// <returns>
+ /// The System.Int32.
+ /// </returns>
+ private int GetLowFreqChannelCount(Mixdown mixdown)
+ {
+ switch (mixdown)
+ {
+ case Mixdown.FivePoint1Channels:
+ case Mixdown.SixPoint1Channels:
+ case Mixdown.SevenPoint1Channels:
+ case Mixdown.Five_2_LFE:
+ return 1;
+ default:
+ return 0;
+ }
+ }
+
+ /// <summary>
+ /// The get samplerate shift.
+ /// </summary>
+ /// <param name="samplerate">
+ /// The samplerate.
+ /// </param>
+ /// <returns>
+ /// The System.Int32.
+ /// </returns>
+ private int GetSamplerateShift(int samplerate)
+ {
+ /* sr_shift: 0 -> 48000, 44100, 32000 Hz
+ * 1 -> 24000, 22050, 16000 Hz
+ * 2 -> 12000, 11025, 8000 Hz
+ *
+ * also, since samplerates are sanitized downwards:
+ *
+ * (samplerate < 32000) implies (samplerate <= 24000)
+ */
+ return ((samplerate < 16000) ? 2 : (samplerate < 32000) ? 1 : 0);
+ }
+
+ /// <summary>
+ /// The get best sample rate.
+ /// </summary>
+ /// <param name="track">
+ /// The track.
+ /// </param>
+ /// <returns>
+ /// The System.Double.
+ /// </returns>
+ private int GetBestSampleRate(AudioTrack track)
+ {
+ int samplerate = 48000; // Default to 48
+
+ // Try get the users selected sample rate
+ if (!track.SampleRate.Equals(0.0d))
+ {
+ samplerate = this.samplerates[track.SampleRate];
+ }
+ else if (track.ScannedTrack != null && track.ScannedTrack.SampleRate != 0) // If it's auto, try get the source
+ {
+ samplerate = track.ScannedTrack.SampleRate;
+ }
+
+ // THen Sanitize to make sure it's valid
+ int bestSamplerate;
+ if ((samplerate < 32000) && (track.Encoder == AudioEncoder.Ac3))
+ {
+ // AC-3 < 32 kHz suffers from poor hardware compatibility
+ bestSamplerate = 32000;
+ }
+ else
+ {
+ bestSamplerate = samplerate;
+ foreach (KeyValuePair<double, int> item in this.samplerates)
+ {
+ // valid samplerate
+ if (bestSamplerate.Equals(item.Value))
+ break;
+ // samplerate is higher than the next valid samplerate,
+ // or lower than the lowest valid samplerate
+ if (bestSamplerate > item.Value && bestSamplerate < this.samplerates.First().Value)
+ {
+ bestSamplerate = item.Value;
+ break;
+ }
+ }
+ }
+
+ return bestSamplerate;
+ }
+
+ /// <summary>
+ /// The convert back.
+ /// </summary>
+ /// <param name="value">
+ /// The value.
+ /// </param>
+ /// <param name="targetType">
+ /// The target type.
+ /// </param>
+ /// <param name="parameter">
+ /// The parameter.
+ /// </param>
+ /// <param name="culture">
+ /// The culture.
+ /// </param>
+ /// <returns>
+ /// The System.Object.
+ /// </returns>
+ /// <exception cref="NotImplementedException">
+ /// We don't use this.
+ /// </exception>
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
diff --git a/win/CS/HandBrakeWPF/Views/AudioView.xaml b/win/CS/HandBrakeWPF/Views/AudioView.xaml index 4e9c6d92f..2f8d0d8e3 100644 --- a/win/CS/HandBrakeWPF/Views/AudioView.xaml +++ b/win/CS/HandBrakeWPF/Views/AudioView.xaml @@ -200,7 +200,7 @@ VerticalAlignment="Center"
FontWeight="Bold"
Text="Bitrate"
- Visibility="{Binding IsPassthru,
+ Visibility="{Binding CanSetBitrate,
Converter={StaticResource boolToVisConverter},
ConverterParameter=true}" />
<ComboBox Grid.Column="5"
@@ -210,7 +210,7 @@ ItemsSource="{Binding TrackReference,
Converter={StaticResource audioBitrateConverter}}"
SelectedItem="{Binding Bitrate}"
- Visibility="{Binding IsPassthru,
+ Visibility="{Binding CanSetBitrate,
Converter={StaticResource boolToVisConverter},
ConverterParameter=true}" />
|