/// <summary>\r
/// Video Frame Rates\r
/// </summary>\r
- private static readonly Dictionary<double, int> VideoRates = new Dictionary<double, int>\r
+ private static readonly Dictionary<double, int> VideoRates;\r
+\r
+ /// <summary>\r
+ /// Initializes static members of the Converters class.\r
+ /// </summary>\r
+ static Converters()\r
{\r
- {5, 5400000},\r
- {10, 2700000},\r
- {12, 2250000},\r
- {15, 1800000},\r
- {23.976, 1126125},\r
- {24, 1125000},\r
- {25, 1080000},\r
- {29.97, 900900},\r
- {30, 900000},\r
- {50, 540000},\r
- {59.94, 450450},\r
- {60, 450000}\r
- };\r
+ HandBrakeUtils.EnsureGlobalInit();\r
+\r
+ VideoRates = new Dictionary<double, int>();\r
+ foreach (var framerate in Encoders.VideoFramerates)\r
+ {\r
+ VideoRates.Add(double.Parse(framerate.Name), framerate.Rate);\r
+ }\r
+ }\r
\r
/// <summary>\r
/// Convert Framerate to Video Rates\r
return NativeConstants.HB_ACODEC_AC3;\r
case AudioEncoder.ffaac:\r
return NativeConstants.HB_ACODEC_FFAAC;\r
- case AudioEncoder.fdkaac:\r
- return NativeConstants.HB_ACODEC_FDK_AAC;\r
- case AudioEncoder.fdkheaac:\r
- return NativeConstants.HB_ACODEC_FDK_HAAC;\r
+ case AudioEncoder.fdkaac:\r
+ return NativeConstants.HB_ACODEC_FDK_AAC;\r
+ case AudioEncoder.fdkheaac:\r
+ return NativeConstants.HB_ACODEC_FDK_HAAC;\r
case AudioEncoder.AacPassthru:\r
return NativeConstants.HB_ACODEC_AAC_PASS;\r
case AudioEncoder.Lame:\r
case NativeConstants.HB_ACODEC_FFAAC:\r
case NativeConstants.HB_ACODEC_CA_AAC:\r
case NativeConstants.HB_ACODEC_CA_HAAC:\r
- case NativeConstants.HB_ACODEC_FDK_HAAC: // TODO Check this is correct\r
- case NativeConstants.HB_ACODEC_FDK_AAC: // TODO Check this is correct\r
+ case NativeConstants.HB_ACODEC_FDK_HAAC: // TODO Check this is correct\r
+ case NativeConstants.HB_ACODEC_FDK_AAC: // TODO Check this is correct\r
return AudioCodec.Aac;\r
case NativeConstants.HB_ACODEC_FFFLAC:\r
return AudioCodec.Flac;\r
{\r
var result = new HBVideoEncoder\r
{\r
- Id = encoder.encoder,\r
+ Id = encoder.codec,\r
ShortName = encoder.short_name,\r
- DisplayName = encoder.human_readable_name,\r
+ DisplayName = encoder.name,\r
CompatibleContainers = Container.None\r
};\r
\r
{\r
var result = new HBAudioEncoder\r
{\r
- Id = encoder.encoder,\r
+ Id = encoder.codec,\r
ShortName = encoder.short_name,\r
- DisplayName = encoder.human_readable_name,\r
+ DisplayName = encoder.name,\r
CompatibleContainers = Container.None\r
};\r
\r
result.CompatibleContainers = result.CompatibleContainers | Container.Mp4;\r
}\r
\r
- result.QualityLimits = Encoders.GetAudioQualityLimits(encoder.encoder);\r
- result.DefaultQuality = HBFunctions.hb_get_default_audio_quality((uint)encoder.encoder);\r
- result.CompressionLimits = Encoders.GetAudioCompressionLimits(encoder.encoder);\r
- result.DefaultCompression = HBFunctions.hb_get_default_audio_compression((uint) encoder.encoder);\r
+ result.QualityLimits = Encoders.GetAudioQualityLimits(encoder.codec);\r
+ result.DefaultQuality = HBFunctions.hb_audio_quality_get_default((uint)encoder.codec);\r
+ result.CompressionLimits = Encoders.GetAudioCompressionLimits(encoder.codec);\r
+ result.DefaultCompression = HBFunctions.hb_audio_compression_get_default((uint)encoder.codec);\r
\r
return result;\r
}\r
\r
+ /// <summary>\r
+ /// Converts a native HB rate structure to an HBRate object.\r
+ /// </summary>\r
+ /// <param name="rate">The structure to convert.</param>\r
+ /// <returns>The converted rate object.</returns>\r
+ public static HBRate NativeToRate(hb_rate_s rate)\r
+ {\r
+ return new HBRate\r
+ {\r
+ Name = rate.name,\r
+ Rate = rate.rate\r
+ };\r
+ }\r
+\r
/// <summary>\r
/// Converts a native HB mixdown structure to a Mixdown model.\r
/// </summary>\r
{\r
Id = mixdown.amixdown,\r
ShortName = mixdown.short_name,\r
- DisplayName = mixdown.human_readable_name\r
+ DisplayName = mixdown.name\r
};\r
}\r
\r
/// </summary>\r
private const string TurboX264Opts = "ref=1:subme=2:me=dia:analyse=none:trellis=0:no-fast-pskip=0:8x8dct=0:weightb=0";\r
\r
- /// <summary>\r
- /// Lock for creation of handbrake instances;\r
- /// </summary>\r
- private static object instanceCreationLock = new object();\r
-\r
- /// <summary>\r
- /// True if a handbrake instance has been created.\r
- /// </summary>\r
- private static bool globalInitialized;\r
-\r
/// <summary>\r
/// The native handle to the HandBrake instance.\r
/// </summary>\r
/// <param name="verbosity">The code for the logging verbosity to use.</param>\r
public void Initialize(int verbosity)\r
{\r
- lock (instanceCreationLock)\r
- {\r
- if (!globalInitialized)\r
- {\r
- globalInitialized = true;\r
- }\r
- }\r
+ HandBrakeUtils.EnsureGlobalInit();\r
\r
HandBrakeUtils.RegisterLogger();\r
this.hbHandle = HBFunctions.hb_init(verbosity, update_check: 0);\r
public void StartEncode(EncodeJob job, bool preview, int previewNumber, int previewSeconds, double overallSelectedLengthSeconds)\r
{\r
EncodingProfile profile = job.EncodingProfile;\r
+ if (job.ChosenAudioTracks == null)\r
+ {\r
+ throw new ArgumentException("job.ChosenAudioTracks cannot be null.");\r
+ }\r
+\r
this.currentJob = job;\r
\r
IntPtr nativeJobPtr = HBFunctions.hb_job_init_by_index(this.hbHandle, this.GetTitleIndex(job.Title));\r
this.encodeAllocatedMemory = this.ApplyJob(ref nativeJob, job, preview, previewNumber, previewSeconds, overallSelectedLengthSeconds);\r
\r
this.subtitleScan = false;\r
- if (job.Subtitles.SourceSubtitles != null)\r
+ if (job.Subtitles != null && job.Subtitles.SourceSubtitles != null)\r
{\r
foreach (SourceSubtitle subtitle in job.Subtitles.SourceSubtitles)\r
{\r
}\r
else\r
{\r
- displayWidth = (int)((double)cropHeight * displayAspect);\r
+ displayWidth = (int)((double)height * displayAspect);\r
}\r
\r
nativeJob.anamorphic.dar_width = displayWidth;\r
}\r
}\r
\r
- bool hasBurnedSubtitle = job.Subtitles.SourceSubtitles.Any(s => s.BurnedIn);\r
+ bool hasBurnedSubtitle = job.Subtitles.SourceSubtitles != null && job.Subtitles.SourceSubtitles.Any(s => s.BurnedIn);\r
if (hasBurnedSubtitle)\r
{\r
this.AddFilter(filterList, (int)hb_filter_ids.HB_FILTER_RENDER_SUB, string.Format(CultureInfo.InvariantCulture, "{0}:{1}:{2}:{3}", crop.Top, crop.Bottom, crop.Left, crop.Right), allocatedMemory);\r
if (encoding.Bitrate == 0)\r
{\r
// Bitrate of 0 means auto: choose the default for this codec, sample rate and mixdown.\r
- nativeAudio.config.output.bitrate = HBFunctions.hb_get_default_audio_bitrate(\r
+ nativeAudio.config.output.bitrate = HBFunctions.hb_audio_bitrate_get_default(\r
nativeAudio.config.output.codec,\r
nativeAudio.config.output.samplerate,\r
nativeAudio.config.output.mixdown);\r
<Compile Include="Model\Encoding\Detelecine.cs" />\r
<Compile Include="Model\Encoding\EncodingProfile.cs" />\r
<Compile Include="Model\Encoding\HBMixdown.cs" />\r
+ <Compile Include="Model\Encoding\HBRate.cs" />\r
<Compile Include="Model\Encoding\HBVideoEncoder.cs" />\r
<Compile Include="Model\Encoding\Mixdown.cs" />\r
<Compile Include="Model\Encoding\OutputExtension.cs" />\r
/// </summary>\r
private static LoggingCallback errorCallback;\r
\r
+ /// <summary>\r
+ /// True if the global initialize function has been called.\r
+ /// </summary>\r
+ private static bool globalInitialized;\r
+\r
/// <summary>\r
/// Fires when HandBrake has logged a message.\r
/// </summary>\r
/// </summary>\r
public static event EventHandler<MessageLoggedEventArgs> ErrorLogged;\r
\r
+ /// <summary>\r
+ /// Initializes static members of the HandBrakeUtils class.\r
+ /// </summary>\r
+ static HandBrakeUtils()\r
+ {\r
+ if (!globalInitialized)\r
+ {\r
+ if (HBFunctions.hb_global_init() == -1)\r
+ {\r
+ throw new InvalidOperationException("HB global init failed.");\r
+ }\r
+\r
+ globalInitialized = true;\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Ensures the HB global initialize method has been called.\r
+ /// </summary>\r
+ public static void EnsureGlobalInit()\r
+ {\r
+ // Does nothing, but invokes static ctor.\r
+ }\r
+\r
/// <summary>\r
/// Enables or disables LibDVDNav. If disabled libdvdread will be used instead.\r
/// </summary>\r
\r
if (messageParts.Length > 0)\r
{\r
- if (MessageLogged != null)\r
+ message = messageParts[0];\r
+\r
+ // When MP4 muxing fails (for example when the file is too big without Large File Size)\r
+ // a message is logged but it isn't marked as an error.\r
+ if (message.StartsWith("MP4ERROR", StringComparison.Ordinal))\r
{\r
- MessageLogged(null, new MessageLoggedEventArgs { Message = messageParts[0] });\r
+ SendErrorEvent(message);\r
+ return;\r
}\r
\r
- System.Diagnostics.Debug.WriteLine(messageParts[0]);\r
+ SendMessageEvent(message);\r
}\r
}\r
}\r
// This error happens in normal operations. Log it as a message.\r
if (message == "dvd: ifoOpen failed")\r
{\r
- if (MessageLogged != null)\r
- {\r
- MessageLogged(null, new MessageLoggedEventArgs { Message = message });\r
- }\r
-\r
+ SendMessageEvent(message);\r
return;\r
}\r
\r
- if (ErrorLogged != null)\r
- {\r
- ErrorLogged(null, new MessageLoggedEventArgs { Message = message });\r
- }\r
-\r
- System.Diagnostics.Debug.WriteLine("ERROR: " + message);\r
+ SendErrorEvent(message);\r
}\r
}\r
\r
throw new ArgumentException("height must be positive.");\r
}\r
\r
- HBFunctions.hb_init(0, 0);\r
- IntPtr ptr = HBFunctions.hb_x264_param_unparse(\r
+ HBFunctions.hb_init(0, 0);\r
+ IntPtr ptr = HBFunctions.hb_x264_param_unparse(\r
preset,\r
string.Join(",", tunes),\r
extraOptions,\r
width,\r
height);\r
\r
- string x264Settings = Marshal.PtrToStringAnsi(ptr);\r
+ string x264Settings = Marshal.PtrToStringAnsi(ptr);\r
\r
\r
- return x264Settings;\r
+ return x264Settings;\r
}\r
\r
/// <summary>\r
\r
return audioBytes;\r
}\r
+\r
+ /// <summary>\r
+ /// Sends the message logged event to any registered listeners.\r
+ /// </summary>\r
+ /// <param name="message">The message to send.</param>\r
+ private static void SendMessageEvent(string message)\r
+ {\r
+ if (MessageLogged != null)\r
+ {\r
+ MessageLogged(null, new MessageLoggedEventArgs { Message = message });\r
+ }\r
+\r
+ System.Diagnostics.Debug.WriteLine(message);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Sends the error logged event to any registered listeners.\r
+ /// </summary>\r
+ /// <param name="message">The message to send</param>\r
+ private static void SendErrorEvent(string message)\r
+ {\r
+ if (ErrorLogged != null)\r
+ {\r
+ ErrorLogged(null, new MessageLoggedEventArgs { Message = message });\r
+ }\r
+\r
+ System.Diagnostics.Debug.WriteLine("ERROR: " + message);\r
+ }\r
}\r
}\r
[DllImport("hb.dll", EntryPoint = "hb_register_error_handler", CallingConvention = CallingConvention.Cdecl)]\r
public static extern void hb_register_error_handler(LoggingCallback callback);\r
\r
+ [DllImport("hb.dll", EntryPoint = "hb_global_init", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern int hb_global_init();\r
+\r
/// Return Type: hb_handle_t*\r
///verbose: int\r
///update_check: int\r
public static extern int hb_srt_add(ref hb_job_s job, ref hb_subtitle_config_s subtitleConfig, string lang);\r
\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_mixdown_is_supported", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_mixdown_is_supported(int mixdown, uint codec, ulong layout);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_mixdown_has_remix_support", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_mixdown_has_remix_support(int mixdown, ulong layout);\r
+//int hb_video_framerate_get_from_name(const char *name);\r
+//const char* hb_video_framerate_get_name(int framerate);\r
+//const char* hb_video_framerate_sanitize_name(const char *name);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_mixdown_has_codec_support", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_mixdown_has_codec_support(int mixdown, uint codec);\r
+ // returns hb_rate_s\r
+ [DllImport("hb.dll", EntryPoint = "hb_video_framerate_get_next", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern IntPtr hb_video_framerate_get_next(IntPtr last);\r
+\r
+\r
+//int hb_audio_samplerate_get_best(uint32_t codec, int samplerate, int *sr_shift);\r
+//int hb_audio_samplerate_get_from_name(const char *name);\r
+//const char* hb_audio_samplerate_get_name(int samplerate);\r
+\r
+ // returns hb_rate_s\r
+ [DllImport("hb.dll", EntryPoint = "hb_audio_samplerate_get_next", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern IntPtr hb_audio_samplerate_get_next(IntPtr last);\r
+\r
+\r
+ [DllImport("hb.dll", EntryPoint = "hb_audio_bitrate_get_best", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern int hb_audio_bitrate_get_best(uint codec, int bitrate, int samplerate, int mixdown);\r
+\r
+ [DllImport("hb.dll", EntryPoint = "hb_audio_bitrate_get_default", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern int hb_audio_bitrate_get_default(uint codec, int samplerate, int mixdown);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_default_mixdown", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_get_default_mixdown(uint codec, ulong layout);\r
+ [DllImport("hb.dll", EntryPoint = "hb_audio_bitrate_get_limits", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern int hb_audio_bitrate_get_limits(uint codec, int samplerate, int mixdown, ref int low, ref int high);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_best_mixdown", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_get_best_mixdown(uint codec, ulong layout, int mixdown);\r
+ [DllImport("hb.dll", EntryPoint = "hb_audio_bitrate_get_next", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern IntPtr hb_audio_bitrate_get_next(IntPtr last);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_best_audio_bitrate", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_get_best_audio_bitrate(uint codec, int bitrate, int samplerate, int mixdown);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_default_audio_bitrate", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_get_default_audio_bitrate(uint codec, int samplerate, int mixdown);\r
+ [DllImport("hb.dll", EntryPoint = "hb_audio_quality_get_limits", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern void hb_audio_quality_get_limits(uint codec, ref float low, ref float high, ref float granularity, ref int direction);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_audio_bitrate_limits", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_get_audio_bitrate_limits(uint codec, int samplerate, int mixdown, ref int low, ref int high);\r
+//float hb_audio_quality_get_best(uint32_t codec, float quality);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_audio_quality_limits", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern void hb_get_audio_quality_limits(uint codec, ref float low, ref float high, ref float granularity, ref int direction);\r
+ [DllImport("hb.dll", EntryPoint = "hb_audio_quality_get_default", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern float hb_audio_quality_get_default(uint codec);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_default_audio_quality", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern float hb_get_default_audio_quality(uint codec);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_audio_compression_limits", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern void hb_get_audio_compression_limits(uint codec, ref float low, ref float high, ref float granularity, ref int direction);\r
+ [DllImport("hb.dll", EntryPoint = "hb_audio_compression_get_limits", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern void hb_audio_compression_get_limits(uint codec, ref float low, ref float high, ref float granularity, ref int direction);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_default_audio_compression", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern float hb_get_default_audio_compression(uint codec);\r
+//float hb_audio_compression_get_best(uint32_t codec, float compression);\r
+\r
+ [DllImport("hb.dll", EntryPoint = "hb_audio_compression_get_default", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern float hb_audio_compression_get_default(uint codec);\r
+\r
+\r
+//int hb_audio_dither_get_default();\r
+//int hb_audio_dither_get_default_method(); // default method, if enabled && supported\r
+//int hb_audio_dither_is_supported(uint32_t codec);\r
+//int hb_audio_dither_get_from_name(const char *name);\r
+//const char* hb_audio_dither_get_description(int method);\r
+//const hb_dither_t* hb_audio_dither_get_next(const hb_dither_t *last);\r
+\r
+ [DllImport("hb.dll", EntryPoint = "hb_mixdown_is_supported", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern int hb_mixdown_is_supported(int mixdown, uint codec, ulong layout);\r
+\r
+ [DllImport("hb.dll", EntryPoint = "hb_mixdown_has_codec_support", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern int hb_mixdown_has_codec_support(int mixdown, uint codec);\r
+\r
+ [DllImport("hb.dll", EntryPoint = "hb_mixdown_has_remix_support", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern int hb_mixdown_has_remix_support(int mixdown, ulong layout);\r
\r
+//int hb_mixdown_get_discrete_channel_count(int mixdown);\r
+//int hb_mixdown_get_low_freq_channel_count(int mixdown);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_video_rates", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern IntPtr hb_get_video_rates();\r
+ [DllImport("hb.dll", EntryPoint = "hb_mixdown_get_best", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern int hb_mixdown_get_best(uint codec, ulong layout, int mixdown);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_video_rates_count", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_get_video_rates_count();\r
+ [DllImport("hb.dll", EntryPoint = "hb_mixdown_get_default", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern int hb_mixdown_get_default(uint codec, ulong layout);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_audio_rates", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern IntPtr hb_get_audio_rates();\r
+//int hb_mixdown_get_from_name(const char *name);\r
+//const char* hb_mixdown_get_name(int mixdown);\r
+//const char* hb_mixdown_get_short_name(int mixdown);\r
+//const char* hb_mixdown_sanitize_name(const char *name);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_audio_rates_count", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_get_audio_rates_count();\r
+ [DllImport("hb.dll", EntryPoint = "hb_mixdown_get_next", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern IntPtr hb_mixdown_get_next(IntPtr last);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_audio_rates_default", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_get_audio_rates_default();\r
+//int hb_video_encoder_get_default(int muxer);\r
+//int hb_video_encoder_get_from_name(const char *name);\r
+//const char* hb_video_encoder_get_name(int encoder);\r
+//const char* hb_video_encoder_get_short_name(int encoder);\r
+//const char* hb_video_encoder_sanitize_name(const char *name);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_audio_bitrates", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern IntPtr hb_get_audio_bitrates();\r
+ [DllImport("hb.dll", EntryPoint = "hb_video_encoder_get_next", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern IntPtr hb_video_encoder_get_next(IntPtr last);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_audio_bitrates_count", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_get_audio_bitrates_count();\r
+/*\r
+ * hb_audio_encoder_get_fallback_for_passthru() will sanitize a passthru codec\r
+ * to the matching audio encoder (if any is available).\r
+ *\r
+ * hb_audio_encoder_get_from_name(), hb_audio_encoder_sanitize_name() will\r
+ * sanitize legacy encoder names, but won't convert passthru to an encoder.\r
+ */\r
+//int hb_audio_encoder_get_fallback_for_passthru(int passthru);\r
+//int hb_audio_encoder_get_default(int muxer);\r
+//int hb_audio_encoder_get_from_name(const char *name);\r
+//const char* hb_audio_encoder_get_name(int encoder);\r
+//const char* hb_audio_encoder_get_short_name(int encoder);\r
+//const char* hb_audio_encoder_sanitize_name(const char *name);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_audio_mixdowns", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern IntPtr hb_get_audio_mixdowns();\r
+ [DllImport("hb.dll", EntryPoint = "hb_audio_encoder_get_next", CallingConvention = CallingConvention.Cdecl)]\r
+ public static extern IntPtr hb_audio_encoder_get_next(IntPtr last);\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_audio_mixdowns_count", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_get_audio_mixdowns_count();\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_video_encoders", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern IntPtr hb_get_video_encoders();\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_video_encoders_count", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_get_video_encoders_count();\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_audio_encoders", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern IntPtr hb_get_audio_encoders();\r
\r
- [DllImport("hb.dll", EntryPoint = "hb_get_audio_encoders_count", CallingConvention = CallingConvention.Cdecl)]\r
- public static extern int hb_get_audio_encoders_count();\r
\r
\r
/// void hb_autopassthru_apply_settings( hb_job_t * job )\r
{\r
/// char*\r
[MarshalAs(UnmanagedType.LPStr)]\r
- public string @string;\r
+ public string name;\r
\r
/// int\r
public int rate;\r
[StructLayout(LayoutKind.Sequential)]\r
public struct hb_mixdown_s\r
{\r
- /// char*\r
[MarshalAs(UnmanagedType.LPStr)]\r
- public string human_readable_name;\r
-\r
- /// char*\r
- [MarshalAs(UnmanagedType.LPStr)]\r
- public string internal_name;\r
+ public string name;\r
\r
/// char*\r
[MarshalAs(UnmanagedType.LPStr)]\r
public struct hb_encoder_s\r
{\r
[MarshalAs(UnmanagedType.LPStr)]\r
- public string human_readable_name;\r
+ public string name;\r
\r
[MarshalAs(UnmanagedType.LPStr)]\r
public string short_name;\r
\r
- public int encoder;\r
+ public int codec;\r
\r
public int muxers;\r
}\r
public const uint HB_ACODEC_AC3_PASS = (HB_ACODEC_AC3 | HB_ACODEC_PASS_FLAG);\r
public const uint HB_ACODEC_DCA_PASS = (HB_ACODEC_DCA | HB_ACODEC_PASS_FLAG);\r
public const uint HB_ACODEC_DCA_HD_PASS = (HB_ACODEC_DCA_HD | HB_ACODEC_PASS_FLAG);\r
- public const uint HB_ACODEC_ANY = (HB_ACODEC_MASK | HB_ACODEC_PASS_FLAG);
+ public const uint HB_ACODEC_ANY = (HB_ACODEC_MASK | HB_ACODEC_PASS_FLAG);\r
\r
// Subtitle Types\r
public const int HB_SUBSTREAM_BD_TRUEHD = 0x72;\r
// Muxers\r
public const int HB_MUX_MASK = 0xFF0000;\r
public const int HB_MUX_MP4 = 0x010000;\r
- public const int HB_MUX_MKV = 0x200000;\r
+ public const int HB_MUX_MKV = 0x100000;\r
\r
public const int HBTF_NO_IDR = 1 << 0;\r
\r
/// int\r
public int vbitrate;\r
\r
- public int pfr_vrate;\r
-\r
- public int pfr_vrate_base;\r
-\r
/// int\r
public int vrate;\r
\r
{\r
using System;\r
using System.Collections.Generic;\r
+ using System.Linq;\r
using System.Runtime.InteropServices;\r
\r
using HandBrake.Interop.HbLib;\r
+ using Model.Encoding;\r
\r
/// <summary>\r
/// Helper utilities for native interop.\r
}\r
\r
return result;\r
- } \r
+ }\r
\r
/// <summary>\r
/// Creats a new, empty native HandBrake list.\r
return returnList;\r
}\r
\r
+ /// <summary>\r
+ /// Reads in a list of objects given an interator and a conversion function.\r
+ /// </summary>\r
+ /// <typeparam name="T1">The type of the struct given by the iterator.</typeparam>\r
+ /// <typeparam name="T2">The object type to convert to.</typeparam>\r
+ /// <param name="iterator">The iterator to use to build the list.</param>\r
+ /// <param name="converter">The converter to convert from the struct to the object.</param>\r
+ /// <returns>The list of objects.</returns>\r
+ public static List<T2> GetListFromIterator<T1, T2>(Func<IntPtr, IntPtr> iterator, Func<T1, T2> converter)\r
+ {\r
+ return ReadStructureListFromIterator<T1>(iterator).Select(converter).ToList();\r
+ } \r
+\r
+ /// <summary>\r
+ /// Reads in a list of structs given an iterator.\r
+ /// </summary>\r
+ /// <typeparam name="T">The type of the struct.</typeparam>\r
+ /// <param name="iterator">The iterator to use to build the list.</param>\r
+ /// <returns>The list of structs.</returns>\r
+ public static List<T> ReadStructureListFromIterator<T>(Func<IntPtr, IntPtr> iterator)\r
+ {\r
+ var structureList = new List<T>();\r
+ IntPtr current = IntPtr.Zero;\r
+\r
+ current = iterator(current);\r
+ while (current != IntPtr.Zero)\r
+ {\r
+ T encoder = ReadStructure<T>(current);\r
+ structureList.Add(encoder);\r
+\r
+ current = iterator(current);\r
+ }\r
+\r
+ return structureList;\r
+ }\r
+\r
/// <summary>\r
/// Closes the given job.\r
/// </summary>\r
using HandBrake.Interop.Model.Encoding;\r
using HandBrake.Interop.SourceData;\r
\r
- /// <summary>\r
- /// The encoders.\r
- /// </summary>\r
- public static class Encoders\r
+ /// <summary>\r
+ /// The encoders.\r
+ /// </summary>\r
+ public static class Encoders\r
{\r
- /// <summary>\r
- /// The audio encoders.\r
- /// </summary>\r
- private static List<HBAudioEncoder> audioEncoders;\r
-\r
- /// <summary>\r
- /// The video encoders.\r
- /// </summary>\r
- private static List<HBVideoEncoder> videoEncoders;\r
-\r
- /// <summary>\r
- /// The mixdowns.\r
- /// </summary>\r
- private static List<HBMixdown> mixdowns;\r
-\r
- /// <summary>\r
- /// The audio bitrates.\r
- /// </summary>\r
- private static List<int> audioBitrates; \r
+ /// <summary>\r
+ /// The audio encoders.\r
+ /// </summary>\r
+ private static List<HBAudioEncoder> audioEncoders;\r
+\r
+ /// <summary>\r
+ /// The video encoders.\r
+ /// </summary>\r
+ private static List<HBVideoEncoder> videoEncoders;\r
+\r
+ /// <summary>\r
+ /// Video framerates in pts.\r
+ /// </summary>\r
+ private static List<HBRate> videoFramerates; \r
+\r
+ /// <summary>\r
+ /// The mixdowns.\r
+ /// </summary>\r
+ private static List<HBMixdown> mixdowns;\r
+\r
+ /// <summary>\r
+ /// The audio bitrates.\r
+ /// </summary>\r
+ private static List<int> audioBitrates;\r
+\r
+ /// <summary>\r
+ /// Audio sample rates in Hz.\r
+ /// </summary>\r
+ private static List<HBRate> audioSampleRates; \r
+\r
+ /// <summary>\r
+ /// Initializes static members of the Encoders class.\r
+ /// </summary>\r
+ static Encoders()\r
+ {\r
+ HandBrakeUtils.EnsureGlobalInit();\r
+ }\r
\r
/// <summary>\r
/// Gets a list of supported audio encoders.\r
{\r
if (audioEncoders == null)\r
{\r
- IntPtr encodersPtr = HBFunctions.hb_get_audio_encoders();\r
- int encoderCount = HBFunctions.hb_get_audio_encoders_count();\r
-\r
- audioEncoders = InteropUtilities.ConvertArray<hb_encoder_s>(encodersPtr, encoderCount)\r
- .Select(Converters.NativeToAudioEncoder)\r
- .ToList();\r
+ audioEncoders = InteropUtilities.GetListFromIterator<hb_encoder_s, HBAudioEncoder>(HBFunctions.hb_audio_encoder_get_next, Converters.NativeToAudioEncoder);\r
}\r
\r
return audioEncoders;\r
{\r
if (videoEncoders == null)\r
{\r
- IntPtr encodersPtr = HBFunctions.hb_get_video_encoders();\r
- int encoderCount = HBFunctions.hb_get_video_encoders_count();\r
-\r
- videoEncoders = InteropUtilities.ConvertArray<hb_encoder_s>(encodersPtr, encoderCount)\r
- .Select(Converters.NativeToVideoEncoder)\r
- .ToList();\r
+ videoEncoders = InteropUtilities.GetListFromIterator<hb_encoder_s, HBVideoEncoder>(HBFunctions.hb_video_encoder_get_next, Converters.NativeToVideoEncoder);\r
}\r
\r
return videoEncoders;\r
}\r
}\r
\r
+ /// <summary>\r
+ /// Gets a list of supported video framerates (in pts).\r
+ /// </summary>\r
+ public static List<HBRate> VideoFramerates\r
+ {\r
+ get\r
+ {\r
+ if (videoFramerates == null)\r
+ {\r
+ videoFramerates = InteropUtilities.GetListFromIterator<hb_rate_s, HBRate>(HBFunctions.hb_video_framerate_get_next, Converters.NativeToRate);\r
+ }\r
+\r
+ return videoFramerates;\r
+ }\r
+ } \r
+\r
/// <summary>\r
/// Gets a list of supported mixdowns.\r
/// </summary>\r
{\r
if (mixdowns == null)\r
{\r
- IntPtr mixdownsPtr = HBFunctions.hb_get_audio_mixdowns();\r
- int mixdownsCount = HBFunctions.hb_get_audio_mixdowns_count();\r
-\r
- mixdowns = InteropUtilities.ConvertArray<hb_mixdown_s>(mixdownsPtr, mixdownsCount)\r
- .Select(Converters.NativeToMixdown)\r
- .ToList();\r
+ mixdowns = InteropUtilities.GetListFromIterator<hb_mixdown_s, HBMixdown>(HBFunctions.hb_mixdown_get_next, Converters.NativeToMixdown);\r
}\r
\r
return mixdowns;\r
{\r
if (audioBitrates == null)\r
{\r
- IntPtr audioBitratesPtr = HBFunctions.hb_get_audio_bitrates();\r
- int audioBitratesCount = HBFunctions.hb_get_audio_bitrates_count();\r
-\r
- audioBitrates = InteropUtilities.ConvertArray<hb_rate_s>(audioBitratesPtr, audioBitratesCount)\r
- .Select(b => b.rate)\r
- .ToList();\r
+ audioBitrates = InteropUtilities.GetListFromIterator<hb_rate_s, int>(HBFunctions.hb_audio_bitrate_get_next, b => b.rate);\r
}\r
\r
return audioBitrates;\r
}\r
}\r
\r
+ /// <summary>\r
+ /// Gets a list of supported audio sample rates (in Hz).\r
+ /// </summary>\r
+ public static List<HBRate> AudioSampleRates\r
+ {\r
+ get\r
+ {\r
+ if (audioSampleRates == null)\r
+ {\r
+ audioSampleRates = InteropUtilities.GetListFromIterator<hb_rate_s, HBRate>(HBFunctions.hb_audio_samplerate_get_next, Converters.NativeToRate);\r
+ }\r
+\r
+ return audioSampleRates;\r
+ }\r
+ } \r
+\r
/// <summary>\r
/// Gets the audio encoder with the specified short name.\r
/// </summary>\r
/// <returns>A sanitized mixdown value.</returns>\r
public static HBMixdown SanitizeMixdown(HBMixdown mixdown, HBAudioEncoder encoder, ulong layout)\r
{\r
- int sanitizedMixdown = HBFunctions.hb_get_best_mixdown((uint)encoder.Id, layout, mixdown.Id);\r
+ int sanitizedMixdown = HBFunctions.hb_mixdown_get_best((uint)encoder.Id, layout, mixdown.Id);\r
return Mixdowns.Single(m => m.Id == sanitizedMixdown);\r
}\r
\r
/// <returns>The default mixdown for the given codec and channel layout.</returns>\r
public static HBMixdown GetDefaultMixdown(HBAudioEncoder encoder, ulong layout)\r
{\r
- int defaultMixdown = HBFunctions.hb_get_default_mixdown((uint)encoder.Id, layout);\r
+ int defaultMixdown = HBFunctions.hb_mixdown_get_default((uint)encoder.Id, layout);\r
return Mixdowns.Single(m => m.Id == defaultMixdown);\r
}\r
\r
int low = 0;\r
int high = 0;\r
\r
- HBFunctions.hb_get_audio_bitrate_limits((uint)encoder.Id, sampleRate, mixdown.Id, ref low, ref high);\r
+ HBFunctions.hb_audio_bitrate_get_limits((uint)encoder.Id, sampleRate, mixdown.Id, ref low, ref high);\r
\r
return new BitrateLimits { Low = low, High = high };\r
}\r
/// <returns>A sanitized audio bitrate.</returns>\r
public static int SanitizeAudioBitrate(int audioBitrate, HBAudioEncoder encoder, int sampleRate, HBMixdown mixdown)\r
{\r
- return HBFunctions.hb_get_best_audio_bitrate((uint)encoder.Id, audioBitrate, sampleRate, mixdown.Id);\r
+ return HBFunctions.hb_audio_bitrate_get_best((uint)encoder.Id, audioBitrate, sampleRate, mixdown.Id);\r
}\r
\r
/// <summary>\r
/// <returns>The default bitrate for these parameters.</returns>\r
public static int GetDefaultBitrate(HBAudioEncoder encoder, int sampleRate, HBMixdown mixdown)\r
{\r
- return HBFunctions.hb_get_default_audio_bitrate((uint) encoder.Id, sampleRate, mixdown.Id);\r
+ return HBFunctions.hb_audio_bitrate_get_default((uint) encoder.Id, sampleRate, mixdown.Id);\r
}\r
\r
/// <summary>\r
{\r
float low = 0, high = 0, granularity = 0;\r
int direction = 0;\r
- HBFunctions.hb_get_audio_quality_limits((uint)encoderId, ref low, ref high, ref granularity, ref direction);\r
+ HBFunctions.hb_audio_quality_get_limits((uint)encoderId, ref low, ref high, ref granularity, ref direction);\r
\r
return new RangeLimits\r
{\r
{\r
float low = 0, high = 0, granularity = 0;\r
int direction = 0;\r
- HBFunctions.hb_get_audio_compression_limits((uint)encoderId, ref low, ref high, ref granularity, ref direction);\r
+ HBFunctions.hb_audio_compression_get_limits((uint)encoderId, ref low, ref high, ref granularity, ref direction);\r
\r
return new RangeLimits\r
{\r
--- /dev/null
+// --------------------------------------------------------------------------------------------------------------------\r
+// <copyright file="HBRate.cs" company="HandBrake Project (http://handbrake.fr)">\r
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.\r
+// </copyright>\r
+// --------------------------------------------------------------------------------------------------------------------\r
+\r
+namespace HandBrake.Interop.Model.Encoding\r
+{\r
+ /// <summary>\r
+ /// Represents a rate in HandBrake: audio sample rate or video framerate.\r
+ /// </summary>\r
+ public class HBRate\r
+ {\r
+ /// <summary>\r
+ /// Gets or sets the name to use for this rate.\r
+ /// </summary>\r
+ public string Name { get; set; }\r
+\r
+ /// <summary>\r
+ /// Gets or sets the raw rate.\r
+ /// </summary>\r
+ public int Rate { get; set; }\r
+ }\r
+}\r
// You can specify all the values or you can default the Build and Revision Numbers \r
// by using the '*' as shown below:\r
// [assembly: AssemblyVersion("1.0.*")]\r
-[assembly: AssemblyVersion("1.40.0.0")]\r
-[assembly: AssemblyFileVersion("1.40.0.0")]\r
+[assembly: AssemblyVersion("1.43.0.0")]\r
+[assembly: AssemblyFileVersion("1.43.0.0")]\r