diff options
5 files changed, 335 insertions, 311 deletions
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeInstance.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeInstance.cs index 1e6fe8506..9962eca4d 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeInstance.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeInstance.cs @@ -14,12 +14,10 @@ namespace HandBrake.Interop using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
- using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
- using System.Text;
using System.Timers;
using System.Windows.Media.Imaging;
@@ -37,7 +35,7 @@ namespace HandBrake.Interop using Newtonsoft.Json;
- using Size = HandBrake.Interop.Model.Size;
+ using Geometry = HandBrake.Interop.Json.Anamorphic.Geometry;
/// <summary>
/// A wrapper for a HandBrake instance.
@@ -60,11 +58,6 @@ namespace HandBrake.Interop private IntPtr hbHandle;
/// <summary>
- /// The number of previews created during scan.
- /// </summary>
- private int previewCount;
-
- /// <summary>
/// The timer to poll for scan status.
/// </summary>
private Timer scanPollTimer;
@@ -90,11 +83,6 @@ namespace HandBrake.Interop private bool disposed;
/// <summary>
- /// The last scan.
- /// </summary>
- private JsonScanObject lastScan;
-
- /// <summary>
/// Finalizes an instance of the HandBrakeInstance class.
/// </summary>
~HandBrakeInstance()
@@ -134,17 +122,6 @@ namespace HandBrake.Interop }
/// <summary>
- /// Gets the number of previews created during scan.
- /// </summary>
- public int PreviewCount
- {
- get
- {
- return this.previewCount;
- }
- }
-
- /// <summary>
/// Gets the index of the default title.
/// </summary>
public int FeatureTitle
@@ -181,7 +158,9 @@ namespace HandBrake.Interop /// <summary>
/// Initializes this instance.
/// </summary>
- /// <param name="verbosity">The code for the logging verbosity to use.</param>
+ /// <param name="verbosity">
+ /// The code for the logging verbosity to use.
+ /// </param>
public void Initialize(int verbosity)
{
HandBrakeUtils.EnsureGlobalInit();
@@ -193,9 +172,15 @@ namespace HandBrake.Interop /// <summary>
/// Starts scanning the given path.
/// </summary>
- /// <param name="path">The path to the video to scan.</param>
- /// <param name="previewCount">The number of preview images to make.</param>
- /// <param name="minDuration">The minimum duration of a title to show up on the scan.</param>
+ /// <param name="path">
+ /// The path to the video to scan.
+ /// </param>
+ /// <param name="previewCount">
+ /// The number of preview images to make.
+ /// </param>
+ /// <param name="minDuration">
+ /// The minimum duration of a title to show up on the scan.
+ /// </param>
public void StartScan(string path, int previewCount, TimeSpan minDuration)
{
this.StartScan(path, previewCount, minDuration, 0);
@@ -204,8 +189,12 @@ namespace HandBrake.Interop /// <summary>
/// Starts a scan for the given input path.
/// </summary>
- /// <param name="path">The path of the video to scan.</param>
- /// <param name="previewCount">The number of preview images to generate for each title while scanning.</param>
+ /// <param name="path">
+ /// The path of the video to scan.
+ /// </param>
+ /// <param name="previewCount">
+ /// The number of preview images to generate for each title while scanning.
+ /// </param>
public void StartScan(string path, int previewCount)
{
this.StartScan(path, previewCount, TimeSpan.FromSeconds(10), 0);
@@ -214,9 +203,15 @@ namespace HandBrake.Interop /// <summary>
/// Starts a scan of the given path.
/// </summary>
- /// <param name="path">The path of the video to scan.</param>
- /// <param name="previewCount">The number of preview images to generate for each title while scanning.</param>
- /// <param name="titleIndex">The title index to scan (1-based, 0 for all titles).</param>
+ /// <param name="path">
+ /// The path of the video to scan.
+ /// </param>
+ /// <param name="previewCount">
+ /// The number of preview images to generate for each title while scanning.
+ /// </param>
+ /// <param name="titleIndex">
+ /// The title index to scan (1-based, 0 for all titles).
+ /// </param>
public void StartScan(string path, int previewCount, int titleIndex)
{
this.StartScan(path, previewCount, TimeSpan.Zero, titleIndex);
@@ -225,14 +220,20 @@ namespace HandBrake.Interop /// <summary>
/// Starts a scan of the given path.
/// </summary>
- /// <param name="path">The path of the video to scan.</param>
- /// <param name="previewCount">The number of previews to make on each title.</param>
- /// <param name="minDuration">The minimum duration of a title to show up on the scan.</param>
- /// <param name="titleIndex">The title index to scan (1-based, 0 for all titles).</param>
+ /// <param name="path">
+ /// The path of the video to scan.
+ /// </param>
+ /// <param name="previewCount">
+ /// The number of previews to make on each title.
+ /// </param>
+ /// <param name="minDuration">
+ /// The minimum duration of a title to show up on the scan.
+ /// </param>
+ /// <param name="titleIndex">
+ /// The title index to scan (1-based, 0 for all titles).
+ /// </param>
public void StartScan(string path, int previewCount, TimeSpan minDuration, int titleIndex)
{
- this.previewCount = previewCount;
-
IntPtr pathPtr = InteropUtilities.ToUtf8PtrFromString(path);
HBFunctions.hb_scan(this.hbHandle, pathPtr, titleIndex, previewCount, 1, (ulong)(minDuration.TotalSeconds * 90000));
Marshal.FreeHGlobal(pathPtr);
@@ -262,9 +263,15 @@ namespace HandBrake.Interop /// <remarks>
/// Only incorporates sizing and aspect ratio into preview image.
/// </remarks>
- /// <param name="job">The encode job to preview.</param>
- /// <param name="previewNumber">The index of the preview to get (0-based).</param>
- /// <returns>An image with the requested preview.</returns>
+ /// <param name="job">
+ /// The encode job to preview.
+ /// </param>
+ /// <param name="previewNumber">
+ /// The index of the preview to get (0-based).
+ /// </param>
+ /// <returns>
+ /// An image with the requested preview.
+ /// </returns>
[HandleProcessCorruptedStateExceptions]
public BitmapImage GetPreview(EncodeJob job, int previewNumber)
{
@@ -274,17 +281,17 @@ namespace HandBrake.Interop // Creat the Expected Output Geometry details for libhb.
hb_geometry_settings_s uiGeometry = new hb_geometry_settings_s
{
- crop = new[] { job.EncodingProfile.Cropping.Top, job.EncodingProfile.Cropping.Bottom, job.EncodingProfile.Cropping.Left, job.EncodingProfile.Cropping.Right },
- itu_par = 0,
+ crop = new[] { job.EncodingProfile.Cropping.Top, job.EncodingProfile.Cropping.Bottom, job.EncodingProfile.Cropping.Left, job.EncodingProfile.Cropping.Right },
+ itu_par = 0,
keep = (int)AnamorphicFactory.KeepSetting.HB_KEEP_WIDTH + (job.EncodingProfile.KeepDisplayAspect ? 0x04 : 0), // TODO Keep Width?
- maxWidth = job.EncodingProfile.MaxWidth,
- maxHeight = job.EncodingProfile.MaxHeight,
- mode = (int)(hb_anamorphic_mode_t)job.EncodingProfile.Anamorphic,
- modulus = job.EncodingProfile.Modulus,
+ maxWidth = job.EncodingProfile.MaxWidth,
+ maxHeight = job.EncodingProfile.MaxHeight,
+ mode = (int)(hb_anamorphic_mode_t)job.EncodingProfile.Anamorphic,
+ modulus = job.EncodingProfile.Modulus,
geometry = new hb_geometry_s
{
- height = job.EncodingProfile.Height,
- width = job.EncodingProfile.Width,
+ height = job.EncodingProfile.Height,
+ width = job.EncodingProfile.Width,
par = job.EncodingProfile.Anamorphic != Anamorphic.Custom
? new hb_rational_t { den = title.ParVal.Height, num = title.ParVal.Width }
: new hb_rational_t { den = job.EncodingProfile.PixelAspectY, num = job.EncodingProfile.PixelAspectX }
@@ -292,7 +299,7 @@ namespace HandBrake.Interop };
// Sanatise the input.
- Json.Anamorphic.Geometry resultGeometry = AnamorphicFactory.CreateGeometry(job, title, AnamorphicFactory.KeepSetting.HB_KEEP_WIDTH); // TODO this keep isn't right.
+ Geometry resultGeometry = AnamorphicFactory.CreateGeometry(job, title, AnamorphicFactory.KeepSetting.HB_KEEP_WIDTH); // TODO this keep isn't right.
int width = resultGeometry.Width * resultGeometry.PAR.Num / resultGeometry.PAR.Den;
int height = resultGeometry.Height;
uiGeometry.geometry.height = resultGeometry.Height; // Prased the height now.
@@ -353,91 +360,7 @@ namespace HandBrake.Interop }
}
- /// <summary>
- /// Calculates the video bitrate for the given job and target size.
- /// </summary>
- /// <param name="job">The encode job.</param>
- /// <param name="sizeMB">The target size in MB.</param>
- /// <param name="overallSelectedLengthSeconds">The currently selected encode length. Used in preview
- /// for calculating bitrate when the target size would be wrong.</param>
- /// <returns>The video bitrate in kbps.</returns>
- public int CalculateBitrate(EncodeJob job, int sizeMB, double overallSelectedLengthSeconds = 0)
- {
- long availableBytes = ((long)sizeMB) * 1024 * 1024;
-
- EncodingProfile profile = job.EncodingProfile;
- Title title = this.GetTitle(job.Title);
-
- double lengthSeconds = overallSelectedLengthSeconds > 0 ? overallSelectedLengthSeconds : HandBrakeUtils.GetJobLengthSeconds(job, title);
- lengthSeconds += 1.5;
-
- double outputFramerate;
- if (profile.Framerate == 0)
- {
- outputFramerate = title.Framerate;
- }
- else
- {
- // Not sure what to do for VFR here hb_calc_bitrate never handled it...
- // just use the peak for now.
- outputFramerate = profile.Framerate;
- }
-
- long frames = (long)(lengthSeconds * outputFramerate);
-
- availableBytes -= frames * HandBrakeUtils.ContainerOverheadPerFrame;
- List<Tuple<AudioEncoding, int>> outputTrackList = this.GetOutputTracks(job, title);
- availableBytes -= HandBrakeUtils.GetAudioSize(job, lengthSeconds, title, outputTrackList);
-
- if (availableBytes < 0)
- {
- return 0;
- }
-
- // Video bitrate is in kilobits per second, or where 1 kbps is 1000 bits per second.
- // So 1 kbps is 125 bytes per second.
- return (int)(availableBytes / (125 * lengthSeconds));
- }
-
- /// <summary>
- /// Gives estimated file size (in MB) of the given job and video bitrate.
- /// </summary>
- /// <param name="job">The encode job.</param>
- /// <param name="videoBitrate">The video bitrate to be used (kbps).</param>
- /// <returns>The estimated file size (in MB) of the given job and video bitrate.</returns>
- public double CalculateFileSize(EncodeJob job, int videoBitrate)
- {
- long totalBytes = 0;
-
- EncodingProfile profile = job.EncodingProfile;
- Title title = this.GetTitle(job.Title);
-
- double lengthSeconds = HandBrakeUtils.GetJobLengthSeconds(job, title);
- lengthSeconds += 1.5;
-
- double outputFramerate;
- if (profile.Framerate == 0)
- {
- outputFramerate = title.Framerate;
- }
- else
- {
- // Not sure what to do for VFR here hb_calc_bitrate never handled it...
- // just use the peak for now.
- outputFramerate = profile.Framerate;
- }
-
- long frames = (long)(lengthSeconds * outputFramerate);
-
- totalBytes += (long)(lengthSeconds * videoBitrate * 125);
- totalBytes += frames * HandBrakeUtils.ContainerOverheadPerFrame;
-
- List<Tuple<AudioEncoding, int>> outputTrackList = this.GetOutputTracks(job, title);
- totalBytes += HandBrakeUtils.GetAudioSize(job, lengthSeconds, title, outputTrackList);
-
- return (double)totalBytes / 1024 / 1024;
- }
/// <summary>
/// Starts an encode with the given job.
@@ -482,8 +405,6 @@ namespace HandBrake.Interop /// </param>
public void StartEncode(EncodeJob job, Title title, bool preview, int previewNumber, int previewSeconds, double overallSelectedLengthSeconds, int scanPreviewCount)
{
- this.previewCount = scanPreviewCount;
-
JsonEncodeObject encodeObject = EncodeFactory.Create(job, title);
JsonSerializerSettings settings = new JsonSerializerSettings
@@ -495,7 +416,7 @@ namespace HandBrake.Interop HBFunctions.hb_add_json(this.hbHandle, InteropUtilities.ToUtf8PtrFromString(encode));
HBFunctions.hb_start(this.hbHandle);
- this.encodePollTimer = new System.Timers.Timer();
+ this.encodePollTimer = new Timer();
this.encodePollTimer.Interval = EncodePollIntervalMs;
this.encodePollTimer.Elapsed += (o, e) =>
@@ -560,7 +481,9 @@ namespace HandBrake.Interop /// <summary>
/// Frees any resources associated with this object.
/// </summary>
- /// <param name="disposing">True if managed objects as well as unmanaged should be disposed.</param>
+ /// <param name="disposing">
+ /// True if managed objects as well as unmanaged should be disposed.
+ /// </param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
@@ -592,10 +515,10 @@ namespace HandBrake.Interop {
this.ScanProgress(this, new ScanProgressEventArgs
{
- Progress = state.Scanning.Progress,
- CurrentPreview = state.Scanning.Preview,
- Previews = state.Scanning.PreviewCount,
- CurrentTitle = state.Scanning.Title,
+ Progress = state.Scanning.Progress,
+ CurrentPreview = state.Scanning.Preview,
+ Previews = state.Scanning.PreviewCount,
+ CurrentTitle = state.Scanning.Title,
Titles = state.Scanning.TitleCount
});
}
@@ -609,7 +532,6 @@ namespace HandBrake.Interop string scanJson = InteropUtilities.ToStringFromUtf8Ptr(jsonMsg);
JsonScanObject scanObject = JsonConvert.DeserializeObject<JsonScanObject>(scanJson);
- lastScan = scanObject;
foreach (Title title in ScanFactory.CreateTitleSet(scanObject))
{
@@ -646,10 +568,10 @@ namespace HandBrake.Interop {
var progressEventArgs = new EncodeProgressEventArgs
{
- FractionComplete = state.Working.Progress,
- CurrentFrameRate = state.Working.Rate,
- AverageFrameRate = state.Working.RateAvg,
- EstimatedTimeLeft = new TimeSpan(state.Working.Hours, state.Working.Minutes, state.Working.Seconds),
+ FractionComplete = state.Working.Progress,
+ CurrentFrameRate = state.Working.Rate,
+ AverageFrameRate = state.Working.RateAvg,
+ EstimatedTimeLeft = new TimeSpan(state.Working.Hours, state.Working.Minutes, state.Working.Seconds),
Pass = 1, // TODO
};
@@ -670,56 +592,5 @@ namespace HandBrake.Interop }
}
- /// <summary>
- /// Gets a list of encodings and target track indices (1-based).
- /// </summary>
- /// <param name="job">The encode job</param>
- /// <param name="title">The title the job is meant to encode.</param>
- /// <returns>A list of encodings and target track indices (1-based).</returns>
- private List<Tuple<AudioEncoding, int>> GetOutputTracks(EncodeJob job, Title title)
- {
- var list = new List<Tuple<AudioEncoding, int>>();
-
- foreach (AudioEncoding encoding in job.EncodingProfile.AudioEncodings)
- {
- if (encoding.InputNumber == 0)
- {
- // Add this encoding for all chosen tracks
- foreach (int chosenTrack in job.ChosenAudioTracks)
- {
- // In normal cases we'll never have a chosen audio track that doesn't exist but when batch encoding
- // we just choose the first audio track without checking if it exists.
- if (chosenTrack <= title.AudioTracks.Count)
- {
- list.Add(new Tuple<AudioEncoding, int>(encoding, chosenTrack));
- }
- }
- }
- else if (encoding.InputNumber <= job.ChosenAudioTracks.Count)
- {
- // Add this encoding for the specified track, if it exists
- int trackNumber = job.ChosenAudioTracks[encoding.InputNumber - 1];
-
- // In normal cases we'll never have a chosen audio track that doesn't exist but when batch encoding
- // we just choose the first audio track without checking if it exists.
- if (trackNumber <= title.AudioTracks.Count)
- {
- list.Add(new Tuple<AudioEncoding, int>(encoding, trackNumber));
- }
- }
- }
-
- return list;
- }
-
- /// <summary>
- /// Gets the title, given the 1-based title number.
- /// </summary>
- /// <param name="titleNumber">The number of the title (1-based).</param>
- /// <returns>The requested Title.</returns>
- private Title GetTitle(int titleNumber)
- {
- return this.Titles.SingleOrDefault(title => title.TitleNumber == titleNumber);
- }
}
}
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs index fb92c3783..c1f5a5cad 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs @@ -11,19 +11,15 @@ namespace HandBrake.Interop {
using System;
using System.Collections.Generic;
- using System.Linq;
+ using System.Diagnostics;
using System.Runtime.InteropServices;
using HandBrake.Interop.EventArgs;
using HandBrake.Interop.HbLib;
- using HandBrake.Interop.Json.Anamorphic;
- using HandBrake.Interop.Json.Scan;
using HandBrake.Interop.Model;
using HandBrake.Interop.Model.Encoding;
using HandBrake.Interop.Model.Scan;
- using Newtonsoft.Json;
-
/// <summary>
/// HandBrake Interop Utilities
/// </summary>
@@ -109,7 +105,9 @@ namespace HandBrake.Interop /// <summary>
/// Enables or disables LibDVDNav. If disabled libdvdread will be used instead.
/// </summary>
- /// <param name="enableDvdNav">True to enable LibDVDNav.</param>
+ /// <param name="enableDvdNav">
+ /// True to enable LibDVDNav.
+ /// </param>
public static void SetDvdNav(bool enableDvdNav)
{
HBFunctions.hb_dvd_set_dvdnav(enableDvdNav ? 1 : 0);
@@ -142,7 +140,9 @@ namespace HandBrake.Interop /// <summary>
/// Handles log messages from HandBrake.
/// </summary>
- /// <param name="message">The log message (including newline).</param>
+ /// <param name="message">
+ /// The log message (including newline).
+ /// </param>
public static void LoggingHandler(string message)
{
if (!string.IsNullOrEmpty(message))
@@ -160,7 +160,9 @@ namespace HandBrake.Interop /// <summary>
/// Handles errors from HandBrake.
/// </summary>
- /// <param name="message">The error message.</param>
+ /// <param name="message">
+ /// The error message.
+ /// </param>
public static void ErrorHandler(string message)
{
if (!string.IsNullOrEmpty(message))
@@ -196,44 +198,76 @@ namespace HandBrake.Interop /// <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>
+ /// <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,
+ 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>
+ /// <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,
+ string preset,
+ IList<string> tunes,
+ string extraOptions,
+ string profile,
+ string level,
+ int width,
int height)
{
if (width <= 0)
@@ -247,12 +281,12 @@ namespace HandBrake.Interop }
IntPtr ptr = HBFunctions.hb_x264_param_unparse(
- preset,
- string.Join(",", tunes),
- extraOptions,
- profile,
- level,
- width,
+ preset,
+ string.Join(",", tunes),
+ extraOptions,
+ profile,
+ level,
+ width,
height);
string x264Settings = Marshal.PtrToStringAnsi(ptr);
@@ -263,9 +297,15 @@ namespace HandBrake.Interop /// <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>
+ /// <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)
@@ -292,9 +332,13 @@ namespace HandBrake.Interop /// <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>
+ /// <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)
@@ -322,11 +366,21 @@ namespace HandBrake.Interop /// <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>
+ /// <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;
@@ -336,7 +390,7 @@ namespace HandBrake.Interop AudioEncoding encoding = outputTrack.Item1;
AudioTrack track = title.AudioTracks[outputTrack.Item2 - 1];
- int samplesPerFrame = HandBrakeUtils.GetAudioSamplesPerFrame(encoding.Encoder);
+ int samplesPerFrame = GetAudioSamplesPerFrame(encoding.Encoder);
int audioBitrate;
HBAudioEncoder audioEncoder = Encoders.GetAudioEncoder(encoding.Encoder);
@@ -361,8 +415,8 @@ namespace HandBrake.Interop else
{
outputBitrate = Encoders.GetDefaultBitrate(
- audioEncoder,
- encoding.SampleRateRaw == 0 ? track.SampleRate : encoding.SampleRateRaw,
+ audioEncoder,
+ encoding.SampleRateRaw == 0 ? track.SampleRate : encoding.SampleRateRaw,
Encoders.SanitizeMixdown(Encoders.GetMixdown(encoding.Mixdown), audioEncoder, track.ChannelLayout));
}
@@ -380,9 +434,115 @@ namespace HandBrake.Interop }
/// <summary>
+ /// Calculates the video bitrate for the given job and target size.
+ /// </summary>
+ /// <param name="job">
+ /// The encode job.
+ /// </param>
+ /// <param name="title">
+ /// The title.
+ /// </param>
+ /// <param name="sizeMB">
+ /// The target size in MB.
+ /// </param>
+ /// <param name="overallSelectedLengthSeconds">
+ /// The currently selected encode length. Used in preview
+ /// for calculating bitrate when the target size would be wrong.
+ /// </param>
+ /// <returns>
+ /// The video bitrate in kbps.
+ /// </returns>
+ public static int CalculateBitrate(EncodeJob job, Title title, int sizeMB, double overallSelectedLengthSeconds = 0)
+ {
+ long availableBytes = ((long)sizeMB) * 1024 * 1024;
+
+ EncodingProfile profile = job.EncodingProfile;
+
+ double lengthSeconds = overallSelectedLengthSeconds > 0 ? overallSelectedLengthSeconds : GetJobLengthSeconds(job, title);
+ lengthSeconds += 1.5;
+
+ double outputFramerate;
+ if (profile.Framerate == 0)
+ {
+ outputFramerate = title.Framerate;
+ }
+ else
+ {
+ // Not sure what to do for VFR here hb_calc_bitrate never handled it...
+ // just use the peak for now.
+ outputFramerate = profile.Framerate;
+ }
+
+ long frames = (long)(lengthSeconds * outputFramerate);
+
+ availableBytes -= frames * ContainerOverheadPerFrame;
+
+ List<Tuple<AudioEncoding, int>> outputTrackList = GetOutputTracks(job, title);
+ availableBytes -= GetAudioSize(job, lengthSeconds, title, outputTrackList);
+
+ if (availableBytes < 0)
+ {
+ return 0;
+ }
+
+ // Video bitrate is in kilobits per second, or where 1 kbps is 1000 bits per second.
+ // So 1 kbps is 125 bytes per second.
+ return (int)(availableBytes / (125 * lengthSeconds));
+ }
+
+ /// <summary>
+ /// Gives estimated file size (in MB) of the given job and video bitrate.
+ /// </summary>
+ /// <param name="job">
+ /// The encode job.
+ /// </param>
+ /// <param name="title">
+ /// The title.
+ /// </param>
+ /// <param name="videoBitrate">
+ /// The video bitrate to be used (kbps).
+ /// </param>
+ /// <returns>
+ /// The estimated file size (in MB) of the given job and video bitrate.
+ /// </returns>
+ public static double CalculateFileSize(EncodeJob job, Title title, int videoBitrate)
+ {
+ long totalBytes = 0;
+
+ EncodingProfile profile = job.EncodingProfile;
+
+ double lengthSeconds = GetJobLengthSeconds(job, title);
+ lengthSeconds += 1.5;
+
+ double outputFramerate;
+ if (profile.Framerate == 0)
+ {
+ outputFramerate = title.Framerate;
+ }
+ else
+ {
+ // Not sure what to do for VFR here hb_calc_bitrate never handled it...
+ // just use the peak for now.
+ outputFramerate = profile.Framerate;
+ }
+
+ long frames = (long)(lengthSeconds * outputFramerate);
+
+ totalBytes += (long)(lengthSeconds * videoBitrate * 125);
+ totalBytes += frames * ContainerOverheadPerFrame;
+
+ List<Tuple<AudioEncoding, int>> outputTrackList = GetOutputTracks(job, title);
+ totalBytes += GetAudioSize(job, lengthSeconds, title, outputTrackList);
+
+ return (double)totalBytes / 1024 / 1024;
+ }
+
+ /// <summary>
/// Sends the message logged event to any registered listeners.
/// </summary>
- /// <param name="message">The message to send.</param>
+ /// <param name="message">
+ /// The message to send.
+ /// </param>
private static void SendMessageEvent(string message)
{
if (MessageLogged != null)
@@ -390,13 +550,15 @@ namespace HandBrake.Interop MessageLogged(null, new MessageLoggedEventArgs { Message = message });
}
- System.Diagnostics.Debug.WriteLine(message);
+ Debug.WriteLine(message);
}
/// <summary>
/// Sends the error logged event to any registered listeners.
/// </summary>
- /// <param name="message">The message to send</param>
+ /// <param name="message">
+ /// The message to send
+ /// </param>
private static void SendErrorEvent(string message)
{
if (ErrorLogged != null)
@@ -404,7 +566,49 @@ namespace HandBrake.Interop ErrorLogged(null, new MessageLoggedEventArgs { Message = message });
}
- System.Diagnostics.Debug.WriteLine("ERROR: " + message);
+ Debug.WriteLine("ERROR: " + message);
+ }
+
+ /// <summary>
+ /// Gets a list of encodings and target track indices (1-based).
+ /// </summary>
+ /// <param name="job">The encode job</param>
+ /// <param name="title">The title the job is meant to encode.</param>
+ /// <returns>A list of encodings and target track indices (1-based).</returns>
+ private static List<Tuple<AudioEncoding, int>> GetOutputTracks(EncodeJob job, Title title)
+ {
+ var list = new List<Tuple<AudioEncoding, int>>();
+
+ foreach (AudioEncoding encoding in job.EncodingProfile.AudioEncodings)
+ {
+ if (encoding.InputNumber == 0)
+ {
+ // Add this encoding for all chosen tracks
+ foreach (int chosenTrack in job.ChosenAudioTracks)
+ {
+ // In normal cases we'll never have a chosen audio track that doesn't exist but when batch encoding
+ // we just choose the first audio track without checking if it exists.
+ if (chosenTrack <= title.AudioTracks.Count)
+ {
+ list.Add(new Tuple<AudioEncoding, int>(encoding, chosenTrack));
+ }
+ }
+ }
+ else if (encoding.InputNumber <= job.ChosenAudioTracks.Count)
+ {
+ // Add this encoding for the specified track, if it exists
+ int trackNumber = job.ChosenAudioTracks[encoding.InputNumber - 1];
+
+ // In normal cases we'll never have a chosen audio track that doesn't exist but when batch encoding
+ // we just choose the first audio track without checking if it exists.
+ if (trackNumber <= title.AudioTracks.Count)
+ {
+ list.Add(new Tuple<AudioEncoding, int>(encoding, trackNumber));
+ }
+ }
+ }
+
+ return list;
}
}
}
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/Helpers/Utilities.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/Helpers/Utilities.cs index 77106f72d..ef450c62d 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/Helpers/Utilities.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/Helpers/Utilities.cs @@ -47,20 +47,5 @@ namespace HandBrake.Interop.Helpers return GreatestCommonFactor(a, b % a);
}
-
- /// <summary>
- /// Determines if the given audio encoder is a passthrough encoder choice.
- /// </summary>
- /// <param name="encoder">The audio encoder to examine.</param>
- /// <returns>True if the encoder is passthrough.</returns>
- public static bool IsPassthrough(AudioEncoder encoder)
- {
- return encoder == AudioEncoder.Ac3Passthrough ||
- encoder == AudioEncoder.DtsHDPassthrough ||
- encoder == AudioEncoder.DtsPassthrough ||
- encoder == AudioEncoder.Mp3Passthru ||
- encoder == AudioEncoder.AacPassthru ||
- encoder == AudioEncoder.Passthrough;
- }
}
}
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/Interfaces/IHandBrakeInstance.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/Interfaces/IHandBrakeInstance.cs index e6eeae943..40dd3de11 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/Interfaces/IHandBrakeInstance.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/Interfaces/IHandBrakeInstance.cs @@ -54,11 +54,6 @@ namespace HandBrake.Interop.Interfaces int FeatureTitle { get; }
/// <summary>
- /// Gets the number of previews created during scan.
- /// </summary>
- int PreviewCount { get; }
-
- /// <summary>
/// Gets the list of titles on this instance.
/// </summary>
List<Title> Titles { get; }
@@ -74,38 +69,6 @@ namespace HandBrake.Interop.Interfaces void Initialize(int verbosity);
/// <summary>
- /// Calculates the video bitrate for the given job and target size.
- /// </summary>
- /// <param name="job">
- /// The encode job.
- /// </param>
- /// <param name="sizeMB">
- /// The target size in MB.
- /// </param>
- /// <param name="overallSelectedLengthSeconds">
- /// The currently selected encode length. Used in preview
- /// for calculating bitrate when the target size would be wrong.
- /// </param>
- /// <returns>
- /// The video bitrate in kbps.
- /// </returns>
- int CalculateBitrate(EncodeJob job, int sizeMB, double overallSelectedLengthSeconds = 0);
-
- /// <summary>
- /// Gives estimated file size (in MB) of the given job and video bitrate.
- /// </summary>
- /// <param name="job">
- /// The encode job.
- /// </param>
- /// <param name="videoBitrate">
- /// The video bitrate to be used (kbps).
- /// </param>
- /// <returns>
- /// The estimated file size (in MB) of the given job and video bitrate.
- /// </returns>
- double CalculateFileSize(EncodeJob job, int videoBitrate);
-
- /// <summary>
/// Frees any resources associated with this object.
/// </summary>
void Dispose();
diff --git a/win/CS/HandBrake10.sln.DotSettings b/win/CS/HandBrake10.sln.DotSettings index 0f6feff62..7df7d44b1 100644 --- a/win/CS/HandBrake10.sln.DotSettings +++ b/win/CS/HandBrake10.sln.DotSettings @@ -7,6 +7,7 @@ <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CompareOfFloatsByEqualityOperator/@EntryIndexedValue">HINT</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue">HINT</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LocalizableElement/@EntryIndexedValue">DO_NOT_SHOW</s:String> + <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LoopCanBeConvertedToQuery/@EntryIndexedValue">HINT</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantNameQualifier/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantStringFormatCall/@EntryIndexedValue">HINT</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantThisQualifier/@EntryIndexedValue">DO_NOT_SHOW</s:String> |