// --------------------------------------------------------------------------------------------------------------------
//
// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
//
//
// The encoders.
//
// --------------------------------------------------------------------------------------------------------------------
namespace HandBrake.Interop.Interop
{
using System.Collections.Generic;
using System.Linq;
using HandBrake.Interop.Interop.HbLib;
using HandBrake.Interop.Interop.Helpers;
using HandBrake.Interop.Interop.Model;
using HandBrake.Interop.Interop.Model.Encoding;
///
/// The encoders.
///
public static class HandBrakeEncoderHelpers
{
///
/// The audio encoders.
///
private static List audioEncoders;
///
/// The video encoders.
///
private static List videoEncoders;
///
/// Video framerates in pts.
///
private static List videoFramerates;
///
/// List of HandBrake mixdowns.
///
private static List mixdowns;
///
/// List of HandBrake containers.
///
private static List containers;
///
/// The audio bitrates.
///
private static List audioBitrates;
///
/// Audio sample rates in Hz.
///
private static List audioSampleRates;
///
/// Initializes static members of the HandBrakeEncoderHelpers class.
///
static HandBrakeEncoderHelpers()
{
HandBrakeUtils.EnsureGlobalInit();
}
///
/// Gets a list of supported audio encoders.
///
public static List AudioEncoders
{
get
{
if (audioEncoders == null)
{
audioEncoders = InteropUtilities.ToListFromIterator(HBFunctions.hb_audio_encoder_get_next, HandBrakeUnitConversionHelpers.NativeToAudioEncoder);
}
return audioEncoders;
}
}
///
/// Gets a list of supported video encoders.
///
public static List VideoEncoders
{
get
{
if (videoEncoders == null)
{
videoEncoders = InteropUtilities.ToListFromIterator(HBFunctions.hb_video_encoder_get_next, HandBrakeUnitConversionHelpers.NativeToVideoEncoder);
}
return videoEncoders;
}
}
///
/// Gets a list of supported video framerates (in pts).
///
public static List VideoFramerates
{
get
{
if (videoFramerates == null)
{
videoFramerates = InteropUtilities.ToListFromIterator(HBFunctions.hb_video_framerate_get_next, HandBrakeUnitConversionHelpers.NativeToRate);
}
return videoFramerates;
}
}
///
/// Gets a list of supported mixdowns.
///
public static List Mixdowns
{
get
{
if (mixdowns == null)
{
mixdowns = InteropUtilities.ToListFromIterator(HBFunctions.hb_mixdown_get_next, HandBrakeUnitConversionHelpers.NativeToMixdown);
}
return mixdowns;
}
}
///
/// Gets a list of supported audio bitrates.
///
public static List AudioBitrates
{
get
{
if (audioBitrates == null)
{
audioBitrates = InteropUtilities.ToListFromIterator(HBFunctions.hb_audio_bitrate_get_next, b => b.rate);
}
return audioBitrates;
}
}
///
/// Gets a list of supported audio sample rates (in Hz).
///
public static List AudioSampleRates
{
get
{
if (audioSampleRates == null)
{
audioSampleRates = InteropUtilities.ToListFromIterator(HBFunctions.hb_audio_samplerate_get_next, HandBrakeUnitConversionHelpers.NativeToRate);
}
return audioSampleRates;
}
}
///
/// Gets a list of supported containers.
///
public static List Containers
{
get
{
if (containers == null)
{
containers = InteropUtilities.ToListFromIterator(HBFunctions.hb_container_get_next, HandBrakeUnitConversionHelpers.NativeToContainer);
}
return containers;
}
}
///
/// Gets a value indicating whether SRT subtitles can be burnt in.
///
public static bool CanBurnSrt
{
get
{
return HBFunctions.hb_subtitle_can_burn((int)hb_subtitle_s_subsource.SRTSUB) > 0;
}
}
///
/// Gets the audio encoder with the specified short name.
///
///
/// The name of the audio encoder.
///
///
/// The requested audio encoder.
///
public static HBAudioEncoder GetAudioEncoder(string shortName)
{
return AudioEncoders.SingleOrDefault(e => e.ShortName == shortName);
}
///
/// Gets the audio encoder with the specified codec ID.
///
///
/// The ID of the audio encoder.
///
///
/// The requested audio encoder.
///
public static HBAudioEncoder GetAudioEncoder(int codecId)
{
return AudioEncoders.SingleOrDefault(e => e.Id == codecId);
}
///
/// Gets the video encoder with the specified short name.
///
///
/// The name of the video encoder.
///
///
/// The requested video encoder.
///
public static HBVideoEncoder GetVideoEncoder(string shortName)
{
return VideoEncoders.SingleOrDefault(e => e.ShortName == shortName);
}
///
/// Gets the mixdown with the specified short name.
///
///
/// The name of the mixdown.
///
///
/// The requested mixdown.
///
public static HBMixdown GetMixdown(string shortName)
{
return Mixdowns.SingleOrDefault(m => m.ShortName == shortName);
}
///
/// Gets the mixdown with the specified ID.
///
/// The mixdown ID.
/// The requested mixdown.
public static HBMixdown GetMixdown(int id)
{
return Mixdowns.SingleOrDefault(m => m.Id == id);
}
///
/// Gets the container with the specified short name.
///
///
/// The name of the container.
///
///
/// The requested container.
///
public static HBContainer GetContainer(string shortName)
{
return Containers.SingleOrDefault(c => c.ShortName == shortName);
}
///
/// Returns true if the subtitle source type can be set to forced only.
///
///
/// The subtitle source type (SSA, VobSub, etc)
///
///
/// True if the subtitle source type can be set to forced only.
///
public static bool SubtitleCanSetForcedOnly(int source)
{
return HBFunctions.hb_subtitle_can_force(source) > 0;
}
///
/// Returns true if the subtitle source type can be burned in.
///
///
/// The subtitle source type (SSA, VobSub, etc)
///
///
/// True if the subtitle source type can be burned in.
///
public static bool SubtitleCanBurn(int source)
{
return HBFunctions.hb_subtitle_can_burn(source) > 0;
}
///
/// Returns true if the subtitle type can be passed through using the given muxer.
///
///
/// The subtitle source type (SSA, VobSub, etc)
///
///
/// The ID of the muxer.
///
///
/// True if the subtitle type can be passed through with the given muxer.
///
public static bool SubtitleCanPassthrough(int subtitleSourceType, int muxer)
{
return HBFunctions.hb_subtitle_can_pass(subtitleSourceType, muxer) > 0;
}
///
/// Gets the subtitle source type's name.
///
///
/// The subtitle source type (SSA, VobSub, etc).
///
///
/// The name of the subtitle source.
///
public static string GetSubtitleSourceName(int source)
{
switch ((hb_subtitle_s_subsource)source)
{
case hb_subtitle_s_subsource.CC608SUB:
return "CC608";
case hb_subtitle_s_subsource.CC708SUB:
return "CC708";
case hb_subtitle_s_subsource.SRTSUB:
return "SRT";
case hb_subtitle_s_subsource.SSASUB:
return "SSA";
case hb_subtitle_s_subsource.TX3GSUB:
return "TX3G";
case hb_subtitle_s_subsource.UTF8SUB:
return "UTF8";
case hb_subtitle_s_subsource.VOBSUB:
return "VobSub";
case hb_subtitle_s_subsource.PGSSUB:
return "PGS";
default:
return string.Empty;
}
}
///
/// Determines if the given encoder is compatible with the given track.
///
///
/// The codec Id.
///
///
/// The encoder to examine.
///
///
/// True if the given encoder is comatible with the given audio track.
///
///
/// Only works with passthrough encoders.
///
public static bool AudioEncoderIsCompatible(int codecId, HBAudioEncoder encoder)
{
return (codecId & encoder.Id) > 0;
}
///
/// Determines if the given mixdown supports the given channel layout.
///
///
/// The mixdown to evaluate.
///
///
/// The channel layout to evaluate.
///
///
/// True if the mixdown supports the given channel layout.
///
public static bool MixdownHasRemixSupport(HBMixdown mixdown, ulong layout)
{
return HBFunctions.hb_mixdown_has_remix_support(mixdown.Id, layout) > 0;
}
///
/// Determines if the given encoder supports the given mixdown.
///
///
/// The mixdown to evaluate.
///
///
/// The encoder to evaluate.
///
///
/// True if the encoder supports the mixdown.
///
public static bool MixdownHasCodecSupport(HBMixdown mixdown, HBAudioEncoder encoder)
{
return HBFunctions.hb_mixdown_has_codec_support(mixdown.Id, (uint)encoder.Id) > 0;
}
///
/// Determines if a mixdown is available for a given track and encoder.
///
///
/// The mixdown to evaluate.
///
///
/// The encoder to evaluate.
///
/// channel layout of the source track
/// True if available.
public static bool MixdownIsSupported(HBMixdown mixdown, HBAudioEncoder encoder, long channelLayout)
{
return HBFunctions.hb_mixdown_is_supported(mixdown.Id, (uint)encoder.Id, (uint)channelLayout) > 0;
}
///
/// Determines if DRC can be applied to the given track with the given encoder.
///
///
/// The track Number.
///
///
/// The encoder to use for DRC.
///
///
/// The title.
///
///
/// True if DRC can be applied to the track with the given encoder.
///
public static bool CanApplyDrc(int trackNumber, HBAudioEncoder encoder, int title)
{
return HBFunctions.hb_audio_can_apply_drc2(HandBrakeInstanceManager.LastScanHandle, title, trackNumber, encoder.Id) > 0;
}
///
/// Determines if the given input audio codec can be passed through.
///
///
/// The input codec to consider.
///
///
/// True if the codec can be passed through.
///
public static bool CanPassthroughAudio(int codecId)
{
return (codecId & NativeConstants.HB_ACODEC_PASS_MASK) > 0;
}
///
/// Sanitizes a mixdown given the output codec and input channel layout.
///
///
/// The desired mixdown.
///
///
/// The output encoder to be used.
///
///
/// The input channel layout.
///
///
/// A sanitized mixdown value.
///
public static HBMixdown SanitizeMixdown(HBMixdown mixdown, HBAudioEncoder encoder, ulong layout)
{
if (mixdown == null)
{
return null;
}
int sanitizedMixdown = HBFunctions.hb_mixdown_get_best((uint)encoder.Id, layout, mixdown.Id);
if (sanitizedMixdown != -1)
{
return Mixdowns.Single(m => m.Id == sanitizedMixdown);
}
return Mixdowns.FirstOrDefault(); // "none"
}
///
/// Gets the default mixdown for the given audio encoder and channel layout.
///
///
/// The output codec to be used.
///
///
/// The input channel layout.
///
///
/// The default mixdown for the given codec and channel layout.
///
public static HBMixdown GetDefaultMixdown(HBAudioEncoder encoder, ulong layout)
{
int defaultMixdown = HBFunctions.hb_mixdown_get_default((uint)encoder.Id, layout);
return Mixdowns.Single(m => m.Id == defaultMixdown);
}
///
/// Sanitizes the given sample rate for the given encoder.
///
/// The encoder.
/// The sample rate to sanitize.
/// The sanitized sample rate.
public static int SanitizeSampleRate(HBAudioEncoder encoder, int sampleRate)
{
return HBFunctions.hb_audio_samplerate_find_closest(sampleRate, (uint)encoder.Id);
}
///
/// Gets the bitrate limits for the given audio codec, sample rate and mixdown.
///
///
/// The audio encoder used.
///
///
/// The sample rate used (Hz).
///
///
/// The mixdown used.
///
///
/// Limits on the audio bitrate for the given settings.
///
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, high);
}
///
/// Gets the video quality limits for the given video codec.
///
///
/// The video encoder to check.
///
///
/// Limits on the video quality for the encoder.
///
public static VideoQualityLimits GetVideoQualityLimits(HBVideoEncoder encoder)
{
float low = 0;
float high = 0;
float granularity = 0;
int direction = 0;
HBFunctions.hb_video_quality_get_limits((uint)encoder.Id, ref low, ref high, ref granularity, ref direction);
return new VideoQualityLimits(low, high, granularity, direction == 0);
}
///
/// Sanitizes an audio bitrate given the output codec, sample rate and mixdown.
///
///
/// The desired audio bitrate.
///
///
/// The output encoder to be used.
///
///
/// The output sample rate to be used.
///
///
/// The mixdown to be used.
///
///
/// A sanitized audio bitrate.
///
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);
}
///
/// Gets the default audio bitrate for the given parameters.
///
///
/// The encoder to use.
///
///
/// The sample rate to use.
///
///
/// The mixdown to use.
///
///
/// The default bitrate for these parameters.
///
public static int GetDefaultBitrate(HBAudioEncoder encoder, int sampleRate, HBMixdown mixdown)
{
return HBFunctions.hb_audio_bitrate_get_default((uint)encoder.Id, sampleRate, mixdown.Id);
}
///
/// Gets limits on audio quality for a given encoder.
///
///
/// The audio encoder ID.
///
///
/// Limits on the audio quality for the given encoder.
///
public static RangeLimits GetAudioQualityLimits(int encoderId)
{
float low = 0, high = 0, granularity = 0;
int direction = 0;
HBFunctions.hb_audio_quality_get_limits((uint)encoderId, ref low, ref high, ref granularity, ref direction);
return new RangeLimits(direction == 0, granularity, high, low);
}
///
/// Gets limits on audio compression for a given encoder.
///
///
/// The audio encoder ID.
///
///
/// Limits on the audio compression for the given encoder.
///
public static RangeLimits GetAudioCompressionLimits(int encoderId)
{
float low = 0, high = 0, granularity = 0;
int direction = 0;
HBFunctions.hb_audio_compression_get_limits((uint)encoderId, ref low, ref high, ref granularity, ref direction);
return new RangeLimits(direction == 0, granularity, high, low);
}
///
/// The get default quality.
///
///
/// The encoder.
///
///
/// The .
///
public static double GetDefaultQuality(HBAudioEncoder encoder)
{
return HBFunctions.hb_audio_quality_get_default((uint)encoder.Id);
}
///
/// The get default audio compression.
///
///
/// The encoder.
///
///
/// The .
///
public static double GetDefaultAudioCompression(HBAudioEncoder encoder)
{
return HBFunctions.hb_audio_compression_get_default((uint)encoder.Id);
}
}
}