diff options
Diffstat (limited to 'win/CS/HandBrake.Interop')
-rw-r--r-- | win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs | 732 |
1 files changed, 366 insertions, 366 deletions
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs index 62d2b09c4..2167734b6 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs @@ -9,370 +9,370 @@ namespace HandBrake.Interop
{
- using System;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
-
- using HandBrake.Interop.EventArgs;
- using HandBrake.Interop.HbLib;
- using HandBrake.Interop.Model;
- using HandBrake.Interop.Model.Encoding;
- using HandBrake.Interop.SourceData;
-
- /// <summary>
- /// HandBrake Interop Utilities
- /// </summary>
- public static class HandBrakeUtils
- {
- /// <summary>
- /// Estimated overhead in bytes for each frame in output container.
- /// </summary>
- internal const int ContainerOverheadPerFrame = 6;
-
- /// <summary>
- /// The callback for log messages from HandBrake.
- /// </summary>
- private static LoggingCallback loggingCallback;
-
- /// <summary>
- /// The callback for error messages from HandBrake.
- /// </summary>
- private static LoggingCallback errorCallback;
-
- /// <summary>
- /// True if the global initialize function has been called.
- /// </summary>
- private static bool globalInitialized;
-
- /// <summary>
- /// Fires when HandBrake has logged a message.
- /// </summary>
- public static event EventHandler<MessageLoggedEventArgs> MessageLogged;
-
- /// <summary>
- /// Fires when HandBrake has logged an error.
- /// </summary>
- public static event EventHandler<MessageLoggedEventArgs> ErrorLogged;
-
- /// <summary>
- /// Initializes static members of the HandBrakeUtils class.
- /// </summary>
- static HandBrakeUtils()
- {
- if (!globalInitialized)
- {
- if (HBFunctions.hb_global_init() == -1)
- {
- throw new InvalidOperationException("HB global init failed.");
- }
-
- globalInitialized = true;
- }
- }
-
- /// <summary>
- /// Ensures the HB global initialize method has been called.
- /// </summary>
- public static void EnsureGlobalInit()
- {
- // Does nothing, but invokes static ctor.
- }
-
- /// <summary>
- /// Enables or disables LibDVDNav. If disabled libdvdread will be used instead.
- /// </summary>
- /// <param name="enableDvdNav">True to enable LibDVDNav.</param>
- public static void SetDvdNav(bool enableDvdNav)
- {
- HBFunctions.hb_dvd_set_dvdnav(enableDvdNav ? 1 : 0);
- }
-
- /// <summary>
- /// Call before app shutdown. Performs global cleanup.
- /// </summary>
- public static void DisposeGlobal()
- {
- HBFunctions.hb_global_close();
- }
-
- /// <summary>
- /// Register the logger.
- /// </summary>
- public static void RegisterLogger()
- {
- // Register the logger if we have not already
- if (loggingCallback == null)
- {
- // Keep the callback as a member to prevent it from being garbage collected.
- loggingCallback = new LoggingCallback(LoggingHandler);
- errorCallback = new LoggingCallback(ErrorHandler);
- HBFunctions.hb_register_logger(loggingCallback);
- HBFunctions.hb_register_error_handler(errorCallback);
- }
- }
-
- /// <summary>
- /// Handles log messages from HandBrake.
- /// </summary>
- /// <param name="message">The log message (including newline).</param>
- public static void LoggingHandler(string message)
- {
- if (!string.IsNullOrEmpty(message))
- {
- string[] messageParts = message.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
-
- if (messageParts.Length > 0)
- {
- message = messageParts[0];
- SendMessageEvent(message);
- }
- }
- }
-
- /// <summary>
- /// Handles errors from HandBrake.
- /// </summary>
- /// <param name="message">The error message.</param>
- public static void ErrorHandler(string message)
- {
- if (!string.IsNullOrEmpty(message))
- {
- // These errors happen in normal operations. Log them as messages.
- if (message == "dvd: ifoOpen failed" || message.Contains("avformat_seek_file failed"))
- {
- SendMessageEvent(message);
- return;
- }
-
- SendErrorEvent(message);
- }
- }
-
- /// <summary>
- /// Gets the standard x264 option name given the starting point.
- /// </summary>
- /// <returns>The standard x264 option name.</returns>
- public static string SanitizeX264OptName(string name)
- {
- IntPtr namePtr = Marshal.StringToHGlobalAnsi(name);
- string sanitizedName = Marshal.PtrToStringAnsi(HBFunctions.hb_x264_encopt_name(namePtr));
- Marshal.FreeHGlobal(namePtr);
- return sanitizedName;
- }
-
- /// <summary>
- /// Checks to see if the given H.264 level is valid given the inputs.
- /// </summary>
- /// <param name="level">The level to check.</param>
- /// <param name="width">The output picture width.</param>
- /// <param name="height">The output picture height.</param>
- /// <param name="fpsNumerator">The rate numerator.</param>
- /// <param name="fpsDenominator">The rate denominator.</param>
- /// <param name="interlaced">True if x264 interlaced output is enabled.</param>
- /// <param name="fakeInterlaced">True if x264 fake interlacing is enabled.</param>
- /// <returns>True if the level is valid.</returns>
- public static bool IsH264LevelValid(string level, int width, int height, int fpsNumerator, int fpsDenominator, bool interlaced, bool fakeInterlaced)
- {
- return HBFunctions.hb_check_h264_level(
- level,
- width,
- height,
- fpsNumerator,
- fpsDenominator,
- interlaced ? 1 : 0,
- fakeInterlaced ? 1 : 0) == 0;
- }
-
- /// <summary>
- /// Creates an X264 options string from the given settings.
- /// </summary>
- /// <param name="preset">The x264 preset.</param>
- /// <param name="tunes">The x264 tunes being used.</param>
- /// <param name="extraOptions">The extra options string.</param>
- /// <param name="profile">The H.264 profile.</param>
- /// <param name="level">The H.264 level.</param>
- /// <param name="width">The width of the final picture.</param>
- /// <param name="height">The height of the final picture.</param>
- /// <returns>The full x264 options string from the given inputs.</returns>
- public static string CreateX264OptionsString(
- string preset,
- IList<string> tunes,
- string extraOptions,
- string profile,
- string level,
- int width,
- int height)
- {
- if (width <= 0)
- {
- throw new ArgumentException("width must be positive.");
- }
-
- if (height <= 0)
- {
- throw new ArgumentException("height must be positive.");
- }
-
- IntPtr ptr = HBFunctions.hb_x264_param_unparse(
- preset,
- string.Join(",", tunes),
- extraOptions,
- profile,
- level,
- width,
- height);
-
- string x264Settings = Marshal.PtrToStringAnsi(ptr);
-
-
- return x264Settings;
- }
-
- /// <summary>
- /// Gets the total number of seconds on the given encode job.
- /// </summary>
- /// <param name="job">The encode job to query.</param>
- /// <param name="title">The title being encoded.</param>
- /// <returns>The total number of seconds of video to encode.</returns>
- internal static double GetJobLengthSeconds(EncodeJob job, Title title)
- {
- switch (job.RangeType)
- {
- case VideoRangeType.All:
- return title.Duration.TotalSeconds;
- case VideoRangeType.Chapters:
- TimeSpan duration = TimeSpan.Zero;
- for (int i = job.ChapterStart; i <= job.ChapterEnd; i++)
- {
- duration += title.Chapters[i - 1].Duration;
- }
-
- return duration.TotalSeconds;
- case VideoRangeType.Seconds:
- return job.SecondsEnd - job.SecondsStart;
- case VideoRangeType.Frames:
- return (job.FramesEnd - job.FramesStart) / title.Framerate;
- }
-
- return 0;
- }
-
- /// <summary>
- /// Gets the number of audio samples used per frame for the given audio encoder.
- /// </summary>
- /// <param name="encoderName">The encoder to query.</param>
- /// <returns>The number of audio samples used per frame for the given
- /// audio encoder.</returns>
- internal static int GetAudioSamplesPerFrame(string encoderName)
- {
- switch (encoderName)
- {
- case "faac":
- case "ffaac":
- case "copy:aac":
- case "vorbis":
- return 1024;
- case "lame":
- case "copy:mp3":
- return 1152;
- case "ffac3":
- case "copy":
- case "copy:ac3":
- case "copy:dts":
- case "copy:dtshd":
- return 1536;
- }
-
- // Unknown encoder; make a guess.
- return 1536;
- }
-
- /// <summary>
- /// Gets the size in bytes for the audio with the given parameters.
- /// </summary>
- /// <param name="job">The encode job.</param>
- /// <param name="lengthSeconds">The length of the encode in seconds.</param>
- /// <param name="title">The title to encode.</param>
- /// <param name="outputTrackList">The list of tracks to encode.</param>
- /// <returns>The size in bytes for the audio with the given parameters.</returns>
- internal static long GetAudioSize(EncodeJob job, double lengthSeconds, Title title, List<Tuple<AudioEncoding, int>> outputTrackList)
- {
- long audioBytes = 0;
-
- foreach (Tuple<AudioEncoding, int> outputTrack in outputTrackList)
- {
- AudioEncoding encoding = outputTrack.Item1;
- AudioTrack track = title.AudioTracks[outputTrack.Item2 - 1];
-
- int samplesPerFrame = HandBrakeUtils.GetAudioSamplesPerFrame(encoding.Encoder);
- int audioBitrate;
-
- HBAudioEncoder audioEncoder = Encoders.GetAudioEncoder(encoding.Encoder);
-
- if (audioEncoder.IsPassthrough)
- {
- // Input bitrate is in bits/second.
- audioBitrate = track.Bitrate / 8;
- }
- else if (encoding.EncodeRateType == AudioEncodeRateType.Quality)
- {
- // Can't predict size of quality targeted audio encoding.
- audioBitrate = 0;
- }
- else
- {
- int outputBitrate;
- if (encoding.Bitrate > 0)
- {
- outputBitrate = encoding.Bitrate;
- }
- else
- {
- outputBitrate = Encoders.GetDefaultBitrate(
- audioEncoder,
- encoding.SampleRateRaw == 0 ? track.SampleRate : encoding.SampleRateRaw,
- Encoders.SanitizeMixdown(Encoders.GetMixdown(encoding.Mixdown), audioEncoder, track.ChannelLayout));
- }
-
- // Output bitrate is in kbps.
- audioBitrate = outputBitrate * 1000 / 8;
- }
-
- audioBytes += (long)(lengthSeconds * audioBitrate);
-
- // Audio overhead
- audioBytes += encoding.SampleRateRaw * ContainerOverheadPerFrame / samplesPerFrame;
- }
-
- return audioBytes;
- }
-
- /// <summary>
- /// Sends the message logged event to any registered listeners.
- /// </summary>
- /// <param name="message">The message to send.</param>
- private static void SendMessageEvent(string message)
- {
- if (MessageLogged != null)
- {
- MessageLogged(null, new MessageLoggedEventArgs { Message = message });
- }
-
- System.Diagnostics.Debug.WriteLine(message);
- }
-
- /// <summary>
- /// Sends the error logged event to any registered listeners.
- /// </summary>
- /// <param name="message">The message to send</param>
- private static void SendErrorEvent(string message)
- {
- if (ErrorLogged != null)
- {
- ErrorLogged(null, new MessageLoggedEventArgs { Message = message });
- }
-
- System.Diagnostics.Debug.WriteLine("ERROR: " + message);
- }
- }
+ using System;
+ using System.Collections.Generic;
+ using System.Runtime.InteropServices;
+
+ using HandBrake.Interop.EventArgs;
+ using HandBrake.Interop.HbLib;
+ using HandBrake.Interop.Model;
+ using HandBrake.Interop.Model.Encoding;
+ using HandBrake.Interop.SourceData;
+
+ /// <summary>
+ /// HandBrake Interop Utilities
+ /// </summary>
+ public static class HandBrakeUtils
+ {
+ /// <summary>
+ /// Estimated overhead in bytes for each frame in output container.
+ /// </summary>
+ internal const int ContainerOverheadPerFrame = 6;
+
+ /// <summary>
+ /// The callback for log messages from HandBrake.
+ /// </summary>
+ private static LoggingCallback loggingCallback;
+
+ /// <summary>
+ /// The callback for error messages from HandBrake.
+ /// </summary>
+ private static LoggingCallback errorCallback;
+
+ /// <summary>
+ /// True if the global initialize function has been called.
+ /// </summary>
+ private static bool globalInitialized;
+
+ /// <summary>
+ /// Fires when HandBrake has logged a message.
+ /// </summary>
+ public static event EventHandler<MessageLoggedEventArgs> MessageLogged;
+
+ /// <summary>
+ /// Fires when HandBrake has logged an error.
+ /// </summary>
+ public static event EventHandler<MessageLoggedEventArgs> ErrorLogged;
+
+ /// <summary>
+ /// Initializes static members of the HandBrakeUtils class.
+ /// </summary>
+ static HandBrakeUtils()
+ {
+ if (!globalInitialized)
+ {
+ if (HBFunctions.hb_global_init() == -1)
+ {
+ throw new InvalidOperationException("HB global init failed.");
+ }
+
+ globalInitialized = true;
+ }
+ }
+
+ /// <summary>
+ /// Ensures the HB global initialize method has been called.
+ /// </summary>
+ public static void EnsureGlobalInit()
+ {
+ // Does nothing, but invokes static ctor.
+ }
+
+ /// <summary>
+ /// Enables or disables LibDVDNav. If disabled libdvdread will be used instead.
+ /// </summary>
+ /// <param name="enableDvdNav">True to enable LibDVDNav.</param>
+ public static void SetDvdNav(bool enableDvdNav)
+ {
+ HBFunctions.hb_dvd_set_dvdnav(enableDvdNav ? 1 : 0);
+ }
+
+ /// <summary>
+ /// Call before app shutdown. Performs global cleanup.
+ /// </summary>
+ public static void DisposeGlobal()
+ {
+ HBFunctions.hb_global_close();
+ }
+
+ /// <summary>
+ /// Register the logger.
+ /// </summary>
+ public static void RegisterLogger()
+ {
+ // Register the logger if we have not already
+ if (loggingCallback == null)
+ {
+ // Keep the callback as a member to prevent it from being garbage collected.
+ loggingCallback = new LoggingCallback(LoggingHandler);
+ errorCallback = new LoggingCallback(ErrorHandler);
+ HBFunctions.hb_register_logger(loggingCallback);
+ HBFunctions.hb_register_error_handler(errorCallback);
+ }
+ }
+
+ /// <summary>
+ /// Handles log messages from HandBrake.
+ /// </summary>
+ /// <param name="message">The log message (including newline).</param>
+ public static void LoggingHandler(string message)
+ {
+ if (!string.IsNullOrEmpty(message))
+ {
+ string[] messageParts = message.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
+
+ if (messageParts.Length > 0)
+ {
+ message = messageParts[0];
+ SendMessageEvent(message);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Handles errors from HandBrake.
+ /// </summary>
+ /// <param name="message">The error message.</param>
+ public static void ErrorHandler(string message)
+ {
+ if (!string.IsNullOrEmpty(message))
+ {
+ // These errors happen in normal operations. Log them as messages.
+ if (message == "dvd: ifoOpen failed" || message.Contains("avformat_seek_file failed"))
+ {
+ SendMessageEvent(message);
+ return;
+ }
+
+ SendErrorEvent(message);
+ }
+ }
+
+ /// <summary>
+ /// Gets the standard x264 option name given the starting point.
+ /// </summary>
+ /// <returns>The standard x264 option name.</returns>
+ public static string SanitizeX264OptName(string name)
+ {
+ IntPtr namePtr = Marshal.StringToHGlobalAnsi(name);
+ string sanitizedName = Marshal.PtrToStringAnsi(HBFunctions.hb_x264_encopt_name(namePtr));
+ Marshal.FreeHGlobal(namePtr);
+ return sanitizedName;
+ }
+
+ /// <summary>
+ /// Checks to see if the given H.264 level is valid given the inputs.
+ /// </summary>
+ /// <param name="level">The level to check.</param>
+ /// <param name="width">The output picture width.</param>
+ /// <param name="height">The output picture height.</param>
+ /// <param name="fpsNumerator">The rate numerator.</param>
+ /// <param name="fpsDenominator">The rate denominator.</param>
+ /// <param name="interlaced">True if x264 interlaced output is enabled.</param>
+ /// <param name="fakeInterlaced">True if x264 fake interlacing is enabled.</param>
+ /// <returns>True if the level is valid.</returns>
+ public static bool IsH264LevelValid(string level, int width, int height, int fpsNumerator, int fpsDenominator, bool interlaced, bool fakeInterlaced)
+ {
+ return HBFunctions.hb_check_h264_level(
+ level,
+ width,
+ height,
+ fpsNumerator,
+ fpsDenominator,
+ interlaced ? 1 : 0,
+ fakeInterlaced ? 1 : 0) == 0;
+ }
+
+ /// <summary>
+ /// Creates an X264 options string from the given settings.
+ /// </summary>
+ /// <param name="preset">The x264 preset.</param>
+ /// <param name="tunes">The x264 tunes being used.</param>
+ /// <param name="extraOptions">The extra options string.</param>
+ /// <param name="profile">The H.264 profile.</param>
+ /// <param name="level">The H.264 level.</param>
+ /// <param name="width">The width of the final picture.</param>
+ /// <param name="height">The height of the final picture.</param>
+ /// <returns>The full x264 options string from the given inputs.</returns>
+ public static string CreateX264OptionsString(
+ string preset,
+ IList<string> tunes,
+ string extraOptions,
+ string profile,
+ string level,
+ int width,
+ int height)
+ {
+ if (width <= 0)
+ {
+ throw new ArgumentException("width must be positive.");
+ }
+
+ if (height <= 0)
+ {
+ throw new ArgumentException("height must be positive.");
+ }
+
+ IntPtr ptr = HBFunctions.hb_x264_param_unparse(
+ preset,
+ string.Join(",", tunes),
+ extraOptions,
+ profile,
+ level,
+ width,
+ height);
+
+ string x264Settings = Marshal.PtrToStringAnsi(ptr);
+
+
+ return x264Settings;
+ }
+
+ /// <summary>
+ /// Gets the total number of seconds on the given encode job.
+ /// </summary>
+ /// <param name="job">The encode job to query.</param>
+ /// <param name="title">The title being encoded.</param>
+ /// <returns>The total number of seconds of video to encode.</returns>
+ internal static double GetJobLengthSeconds(EncodeJob job, Title title)
+ {
+ switch (job.RangeType)
+ {
+ case VideoRangeType.All:
+ return title.Duration.TotalSeconds;
+ case VideoRangeType.Chapters:
+ TimeSpan duration = TimeSpan.Zero;
+ for (int i = job.ChapterStart; i <= job.ChapterEnd; i++)
+ {
+ duration += title.Chapters[i - 1].Duration;
+ }
+
+ return duration.TotalSeconds;
+ case VideoRangeType.Seconds:
+ return job.SecondsEnd - job.SecondsStart;
+ case VideoRangeType.Frames:
+ return (job.FramesEnd - job.FramesStart) / title.Framerate;
+ }
+
+ return 0;
+ }
+
+ /// <summary>
+ /// Gets the number of audio samples used per frame for the given audio encoder.
+ /// </summary>
+ /// <param name="encoderName">The encoder to query.</param>
+ /// <returns>The number of audio samples used per frame for the given
+ /// audio encoder.</returns>
+ internal static int GetAudioSamplesPerFrame(string encoderName)
+ {
+ switch (encoderName)
+ {
+ case "faac":
+ case "ffaac":
+ case "copy:aac":
+ case "vorbis":
+ return 1024;
+ case "lame":
+ case "copy:mp3":
+ return 1152;
+ case "ffac3":
+ case "copy":
+ case "copy:ac3":
+ case "copy:dts":
+ case "copy:dtshd":
+ return 1536;
+ }
+
+ // Unknown encoder; make a guess.
+ return 1536;
+ }
+
+ /// <summary>
+ /// Gets the size in bytes for the audio with the given parameters.
+ /// </summary>
+ /// <param name="job">The encode job.</param>
+ /// <param name="lengthSeconds">The length of the encode in seconds.</param>
+ /// <param name="title">The title to encode.</param>
+ /// <param name="outputTrackList">The list of tracks to encode.</param>
+ /// <returns>The size in bytes for the audio with the given parameters.</returns>
+ internal static long GetAudioSize(EncodeJob job, double lengthSeconds, Title title, List<Tuple<AudioEncoding, int>> outputTrackList)
+ {
+ long audioBytes = 0;
+
+ foreach (Tuple<AudioEncoding, int> outputTrack in outputTrackList)
+ {
+ AudioEncoding encoding = outputTrack.Item1;
+ AudioTrack track = title.AudioTracks[outputTrack.Item2 - 1];
+
+ int samplesPerFrame = HandBrakeUtils.GetAudioSamplesPerFrame(encoding.Encoder);
+ int audioBitrate;
+
+ HBAudioEncoder audioEncoder = Encoders.GetAudioEncoder(encoding.Encoder);
+
+ if (audioEncoder.IsPassthrough)
+ {
+ // Input bitrate is in bits/second.
+ audioBitrate = track.Bitrate / 8;
+ }
+ else if (encoding.EncodeRateType == AudioEncodeRateType.Quality)
+ {
+ // Can't predict size of quality targeted audio encoding.
+ audioBitrate = 0;
+ }
+ else
+ {
+ int outputBitrate;
+ if (encoding.Bitrate > 0)
+ {
+ outputBitrate = encoding.Bitrate;
+ }
+ else
+ {
+ outputBitrate = Encoders.GetDefaultBitrate(
+ audioEncoder,
+ encoding.SampleRateRaw == 0 ? track.SampleRate : encoding.SampleRateRaw,
+ Encoders.SanitizeMixdown(Encoders.GetMixdown(encoding.Mixdown), audioEncoder, track.ChannelLayout));
+ }
+
+ // Output bitrate is in kbps.
+ audioBitrate = outputBitrate * 1000 / 8;
+ }
+
+ audioBytes += (long)(lengthSeconds * audioBitrate);
+
+ // Audio overhead
+ audioBytes += encoding.SampleRateRaw * ContainerOverheadPerFrame / samplesPerFrame;
+ }
+
+ return audioBytes;
+ }
+
+ /// <summary>
+ /// Sends the message logged event to any registered listeners.
+ /// </summary>
+ /// <param name="message">The message to send.</param>
+ private static void SendMessageEvent(string message)
+ {
+ if (MessageLogged != null)
+ {
+ MessageLogged(null, new MessageLoggedEventArgs { Message = message });
+ }
+
+ System.Diagnostics.Debug.WriteLine(message);
+ }
+
+ /// <summary>
+ /// Sends the error logged event to any registered listeners.
+ /// </summary>
+ /// <param name="message">The message to send</param>
+ private static void SendErrorEvent(string message)
+ {
+ if (ErrorLogged != null)
+ {
+ ErrorLogged(null, new MessageLoggedEventArgs { Message = message });
+ }
+
+ System.Diagnostics.Debug.WriteLine("ERROR: " + message);
+ }
+ }
}
|