diff options
author | randomengy <[email protected]> | 2013-03-31 20:55:00 +0000 |
---|---|---|
committer | randomengy <[email protected]> | 2013-03-31 20:55:00 +0000 |
commit | b37e7f1b4078fa478424a80fbaf1f56639e50eaa (patch) | |
tree | e0f9e61f67ebc56bd0258f000243c40ec12eb8fe | |
parent | 09e3a53c02d90e793885983a384a9283b8243590 (diff) |
Exposing DurationPts on titles and chapters from scans, along with some conversion functions.
Adding values to ScanProgressEventArgs to expose more fine-tuned progress.
Updating structs to catch up to most recent HB SVN.
Added a new VideoRangeType: All. This allows you to specify an entire title to convert without counting chapters.
We now create the filter list sorted and pass in the RENDERSUB filter with correct cropping values. This fixes burned-in subtitles getting cut off by cropping.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5369 b64f7644-9d1e-0410-96f1-a4d463321fa5
12 files changed, 199 insertions, 80 deletions
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/Converters.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/Converters.cs index 1dc2a1e74..e7f172e32 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/Converters.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/Converters.cs @@ -17,10 +17,10 @@ namespace HandBrake.Interop using HandBrake.Interop.SourceData;
using HandBrake.Interop.Model;
- /// <summary>
- /// The converters.
- /// </summary>
- public static class Converters
+ /// <summary>
+ /// Converters for various encoding values.
+ /// </summary>
+ public static class Converters
{
/// <summary>
/// Video Frame Rates
@@ -35,7 +35,7 @@ namespace HandBrake.Interop {24, 1125000},
{25, 1080000},
{29.97, 900900},
- {30, 900000},
+ {30, 900000},
{50, 540000},
{59.94, 450450},
{60, 450000}
@@ -94,8 +94,8 @@ namespace HandBrake.Interop return NativeConstants.HB_ACODEC_DCA_HD_PASS;
case AudioEncoder.Vorbis:
return NativeConstants.HB_ACODEC_VORBIS;
- case AudioEncoder.ffflac:
- return NativeConstants.HB_ACODEC_FFFLAC;
+ case AudioEncoder.ffflac:
+ return NativeConstants.HB_ACODEC_FFFLAC;
}
return 0;
@@ -128,8 +128,8 @@ namespace HandBrake.Interop case NativeConstants.HB_ACODEC_CA_AAC:
case NativeConstants.HB_ACODEC_CA_HAAC:
return AudioCodec.Aac;
- case NativeConstants.HB_ACODEC_FFFLAC:
- return AudioCodec.Flac;
+ case NativeConstants.HB_ACODEC_FFFLAC:
+ return AudioCodec.Flac;
default:
return AudioCodec.Other;
}
@@ -204,11 +204,31 @@ namespace HandBrake.Interop public static HBMixdown NativeToMixdown(hb_mixdown_s mixdown)
{
return new HBMixdown
- {
+ {
Id = mixdown.amixdown,
ShortName = mixdown.short_name,
DisplayName = mixdown.human_readable_name
- };
+ };
+ }
+
+ /// <summary>
+ /// Converts the PTS amount to a TimeSpan. There may be some accuracy loss here.
+ /// </summary>
+ /// <param name="pts">The PTS to convert.</param>
+ /// <returns>The timespan for it.</returns>
+ public static TimeSpan PtsToTimeSpan(ulong pts)
+ {
+ return TimeSpan.FromTicks((long)((pts * 10000000) / 90000));
+ }
+
+ /// <summary>
+ /// Converts the PTS amount to seconds.
+ /// </summary>
+ /// <param name="pts">The PTS to convert.</param>
+ /// <returns>The corresponding number of seconds.</returns>
+ public static double PtsToSeconds(ulong pts)
+ {
+ return (double)pts / 90000;
}
}
}
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/EventArgs/ScanProgressEventArgs.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/EventArgs/ScanProgressEventArgs.cs index b342c8f12..56c3c116a 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/EventArgs/ScanProgressEventArgs.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/EventArgs/ScanProgressEventArgs.cs @@ -9,21 +9,36 @@ namespace HandBrake.Interop.EventArgs
{
- using System;
+ using System;
- /// <summary>
- /// The Scan Progress Event Args
- /// </summary>
- public class ScanProgressEventArgs : EventArgs
+ /// <summary>
+ /// The Scan Progress Event Args
+ /// </summary>
+ public class ScanProgressEventArgs : EventArgs
{
- /// <summary>
- /// Gets or sets CurrentTitle.
- /// </summary>
- public int CurrentTitle { get; set; }
+ /// <summary>
+ /// Gets or sets the total progress fraction for the scan.
+ /// </summary>
+ public float Progress { get; set; }
- /// <summary>
- /// Gets or sets Titles.
- /// </summary>
- public int Titles { get; set; }
+ /// <summary>
+ /// Gets or sets the current preview being processed on the scan.
+ /// </summary>
+ public int CurrentPreview { get; set; }
+
+ /// <summary>
+ /// Gets or sets the total number of previews to process.
+ /// </summary>
+ public int Previews { get; set; }
+
+ /// <summary>
+ /// Gets or sets the current title being processed on the scan.
+ /// </summary>
+ public int CurrentTitle { get; set; }
+
+ /// <summary>
+ /// Gets or sets the total number of titles to process.
+ /// </summary>
+ public int Titles { get; set; }
}
}
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeInstance.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeInstance.cs index 0a1c8a32c..a65ca3e10 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeInstance.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeInstance.cs @@ -110,6 +110,11 @@ namespace HandBrake.Interop private List<IntPtr> encodeAllocatedMemory;
/// <summary>
+ /// A value indicating whether this object has been disposed or not.
+ /// </summary>
+ private bool disposed;
+
+ /// <summary>
/// Finalizes an instance of the HandBrakeInstance class.
/// </summary>
~HandBrakeInstance()
@@ -427,8 +432,8 @@ namespace HandBrake.Interop if (!string.IsNullOrEmpty(profile.X264Profile))
{
- nativeJob.x264_profile = Marshal.StringToHGlobalAnsi(profile.X264Profile);
- this.encodeAllocatedMemory.Add(nativeJob.x264_profile);
+ nativeJob.h264_profile = Marshal.StringToHGlobalAnsi(profile.X264Profile);
+ this.encodeAllocatedMemory.Add(nativeJob.h264_profile);
}
if (!string.IsNullOrEmpty(profile.X264Preset))
@@ -600,6 +605,11 @@ namespace HandBrake.Interop /// </summary>
public void Dispose()
{
+ if (this.disposed)
+ {
+ return;
+ }
+
this.Dispose(true);
GC.SuppressFinalize(this);
}
@@ -620,6 +630,8 @@ namespace HandBrake.Interop Marshal.WriteIntPtr(handlePtr, this.hbHandle);
HBFunctions.hb_close(handlePtr);
Marshal.FreeHGlobal(handlePtr);
+
+ this.disposed = true;
}
/// <summary>
@@ -754,9 +766,16 @@ namespace HandBrake.Interop {
if (this.ScanProgress != null)
{
- int currentTitle = state.param.scanning.title_cur;
- int totalTitles = state.param.scanning.title_count;
- this.ScanProgress(this, new ScanProgressEventArgs { CurrentTitle = currentTitle, Titles = totalTitles });
+ hb_state_scanning_anon scanningState = state.param.scanning;
+
+ this.ScanProgress(this, new ScanProgressEventArgs
+ {
+ Progress = scanningState.progress,
+ CurrentPreview = scanningState.preview_cur,
+ Previews = scanningState.preview_count,
+ CurrentTitle = scanningState.title_cur,
+ Titles = scanningState.title_count
+ });
}
}
else if (state.state == NativeConstants.HB_STATE_SCANDONE)
@@ -930,8 +949,9 @@ namespace HandBrake.Interop {
switch (job.RangeType)
{
+ case VideoRangeType.All:
+ break;
case VideoRangeType.Chapters:
-
if (job.ChapterStart > 0 && job.ChapterEnd > 0)
{
nativeJob.chapter_start = job.ChapterStart;
@@ -950,9 +970,13 @@ namespace HandBrake.Interop throw new ArgumentException("Seconds range " + job.SecondsStart + "-" + job.SecondsEnd + " is invalid.", "job");
}
- // For some reason "pts_to_stop" actually means the number of pts to stop AFTER the start point.
- nativeJob.pts_to_start = (int)(job.SecondsStart * 90000);
- nativeJob.pts_to_stop = (int)((job.SecondsEnd - job.SecondsStart) * 90000);
+ // If they've selected the "full" title duration, leave off the arguments to make it clean
+ if (job.SecondsStart > 0 || job.SecondsEnd < title.Duration.TotalSeconds)
+ {
+ // For some reason "pts_to_stop" actually means the number of pts to stop AFTER the start point.
+ nativeJob.pts_to_start = (int) (job.SecondsStart * 90000);
+ nativeJob.pts_to_stop = (int) ((job.SecondsEnd - job.SecondsStart) * 90000);
+ }
break;
case VideoRangeType.Frames:
if (job.FramesStart < 0 || job.FramesEnd < 0 || job.FramesStart >= job.FramesEnd)
@@ -1005,7 +1029,7 @@ namespace HandBrake.Interop nativeJob.crop[2] = crop.Left;
nativeJob.crop[3] = crop.Right;
- var filterList = new List<IntPtr>();
+ var filterList = new List<hb_filter_object_s>();
// FILTERS: These must be added in the correct order since we cannot depend on the automatic ordering in hb_add_filter . Ordering is determined
// by the order they show up in the filters enum.
@@ -1115,7 +1139,7 @@ namespace HandBrake.Interop }
string vfrSettings = string.Format(CultureInfo.InvariantCulture, "{0}:{1}:{2}", nativeJob.cfr, nativeJob.vrate, nativeJob.vrate_base);
- this.AddFilter(filterList, (int) hb_filter_ids.HB_FILTER_VFR, vfrSettings, allocatedMemory);
+ this.AddFilter(filterList, (int)hb_filter_ids.HB_FILTER_VFR, vfrSettings, allocatedMemory);
// Deblock
if (profile.Deblock > 0)
@@ -1296,12 +1320,9 @@ namespace HandBrake.Interop nativeJob.crop[1],
nativeJob.crop[2],
nativeJob.crop[3]);
- this.AddFilter(filterList, (int) hb_filter_ids.HB_FILTER_CROP_SCALE, cropScaleSettings, allocatedMemory);
+ this.AddFilter(filterList, (int)hb_filter_ids.HB_FILTER_CROP_SCALE, cropScaleSettings, allocatedMemory);
+
- // Construct final filter list
- NativeList filterListNative = InteropUtilities.CreateIntPtrList(filterList);
- nativeJob.list_filter = filterListNative.ListPtr;
- allocatedMemory.AddRange(filterListNative.AllocatedMemory);
@@ -1432,8 +1453,17 @@ namespace HandBrake.Interop }
}
}
+
+ bool hasBurnedSubtitle = job.Subtitles.SourceSubtitles.Any(s => s.BurnedIn);
+ if (hasBurnedSubtitle)
+ {
+ 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);
+ }
}
+ // Construct final filter list
+ nativeJob.list_filter = this.ConvertFilterListToNative(filterList, allocatedMemory).ListPtr;
+
if (profile.OutputFormat == Container.Mp4)
{
nativeJob.mux = NativeConstants.HB_MUX_MP4;
@@ -1526,18 +1556,42 @@ namespace HandBrake.Interop /// <param name="filterType">The type of filter.</param>
/// <param name="settings">Settings for the filter.</param>
/// <param name="allocatedMemory">The list of allocated memory.</param>
- private void AddFilter(List<IntPtr> filterList, int filterType, string settings, List<IntPtr> allocatedMemory)
+ private void AddFilter(List<hb_filter_object_s> filterList, int filterType, string settings, List<IntPtr> allocatedMemory)
{
IntPtr settingsNativeString = Marshal.StringToHGlobalAnsi(settings);
hb_filter_object_s filter = InteropUtilities.ReadStructure<hb_filter_object_s>(HBFunctions.hb_filter_init(filterType));
filter.settings = settingsNativeString;
- IntPtr filterPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(hb_filter_object_s)));
- Marshal.StructureToPtr(filter, filterPtr, false);
-
- filterList.Add(filterPtr);
allocatedMemory.Add(settingsNativeString);
- allocatedMemory.Add(filterPtr);
+ filterList.Add(filter);
+ }
+
+ /// <summary>
+ /// Converts the given filter list to a native list.
+ /// </summary>
+ /// <remarks>Sorts the list by filter ID before converting to a native list, as HB expects it that way.
+ /// The list memory itself will be added to the allocatedMemory list.</remarks>
+ /// <param name="filterList">The filter list to convert.</param>
+ /// <param name="allocatedMemory">The list of allocated memory to add to.</param>
+ /// <returns>The converted list.</returns>
+ private NativeList ConvertFilterListToNative(List<hb_filter_object_s> filterList, List<IntPtr> allocatedMemory)
+ {
+ var filterPtrList = new List<IntPtr>();
+
+ var sortedList = filterList.OrderBy(f => f.id);
+ foreach (var filter in sortedList)
+ {
+ IntPtr filterPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(hb_filter_object_s)));
+ Marshal.StructureToPtr(filter, filterPtr, false);
+
+ allocatedMemory.Add(filterPtr);
+ filterPtrList.Add(filterPtr);
+ }
+
+ NativeList filterListNative = InteropUtilities.CreateIntPtrList(filterPtrList);
+ allocatedMemory.AddRange(filterListNative.AllocatedMemory);
+
+ return filterListNative;
}
/// <summary>
@@ -1682,7 +1736,8 @@ namespace HandBrake.Interop Playlist = title.playlist,
Resolution = new Size(title.width, title.height),
ParVal = new Size(title.pixel_aspect_width, title.pixel_aspect_height),
- Duration = TimeSpan.FromSeconds(title.duration / 90000),
+ Duration = Converters.PtsToTimeSpan(title.duration),
+ DurationPts = title.duration,
AutoCropDimensions = new Cropping
{
Top = title.crop[0],
@@ -1794,7 +1849,8 @@ namespace HandBrake.Interop var newChapter = new Chapter
{
ChapterNumber = chapter.index,
- Duration = TimeSpan.FromSeconds(((double)chapter.duration) / 90000)
+ Duration = Converters.PtsToTimeSpan(chapter.duration),
+ DurationPts = chapter.duration
};
newTitle.Chapters.Add(newChapter);
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs index 568e41a31..eb9353aa7 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeUtils.cs @@ -217,6 +217,8 @@ namespace HandBrake.Interop {
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++)
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/Misc.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/Misc.cs index fd464b7c8..c34f5daf5 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/Misc.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/Misc.cs @@ -145,6 +145,12 @@ namespace HandBrake.Interop.HbLib [StructLayout(LayoutKind.Sequential)]
public struct hb_state_scanning_anon
{
+ public float progress;
+
+ public int preview_cur;
+
+ public int preview_count;
+
/// int
public int title_cur;
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/NativeConstants.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/NativeConstants.cs index e7a841251..23181e7fe 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/NativeConstants.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/NativeConstants.cs @@ -12,7 +12,7 @@ namespace HandBrake.Interop.HbLib {
public partial class NativeConstants
{
- public const uint HB_ACODEC_MASK = 0x001FFF00;
+ public const uint HB_ACODEC_MASK = 0x00FFFF00;
public const uint HB_ACODEC_FAAC = 0x00000100;
public const uint HB_ACODEC_LAME = 0x00000200;
public const uint HB_ACODEC_VORBIS = 0x00000400;
@@ -26,7 +26,9 @@ namespace HandBrake.Interop.HbLib public const uint HB_ACODEC_DCA_HD = 0x00040000;
public const uint HB_ACODEC_MP3 = 0x00080000;
public const uint HB_ACODEC_FFFLAC = 0x00100000;
- public const uint HB_ACODEC_FF_MASK = 0x001f2000;
+ public const uint HB_ACODEC_FDK_AAC = 0x00400000;
+ public const uint HB_ACODEC_FDK_HAAC = 0x00800000;
+ public const uint HB_ACODEC_FF_MASK = 0x00FF2000;
public const uint HB_ACODEC_PASS_FLAG = 0x40000000;
public const uint HB_ACODEC_PASS_MASK = (HB_ACODEC_MP3 | HB_ACODEC_FFAAC | HB_ACODEC_DCA_HD | HB_ACODEC_AC3 | HB_ACODEC_DCA);
public const uint HB_ACODEC_AUTO_PASS = (HB_ACODEC_PASS_MASK | HB_ACODEC_PASS_FLAG);
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_audio.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_audio.cs index 26b836094..a219c3db9 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_audio.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_audio.cs @@ -69,6 +69,8 @@ namespace HandBrake.Interop.HbLib public int normalize_mix_level;
+ public int dither_method;
+
public IntPtr name;
}
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_job_s.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_job_s.cs index d4c95d904..e9f08fe47 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_job_s.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_job_s.cs @@ -92,14 +92,14 @@ namespace HandBrake.Interop.HbLib public int fastfirstpass;
- public IntPtr advanced_opts;
-
- public IntPtr x264_profile;
-
public IntPtr x264_preset;
public IntPtr x264_tune;
+ public IntPtr advanced_opts;
+
+ public IntPtr h264_profile;
+
public IntPtr h264_level;
/// int
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/Model/VideoRangeType.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/Model/VideoRangeType.cs index a99005e77..afde441e5 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/Model/VideoRangeType.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/Model/VideoRangeType.cs @@ -9,29 +9,35 @@ namespace HandBrake.Interop.Model
{
- using System.ComponentModel.DataAnnotations;
+ using System.ComponentModel.DataAnnotations;
- /// <summary>
- /// The video range type.
- /// </summary>
- public enum VideoRangeType
- {
- /// <summary>
- /// The chapters.
- /// </summary>
- [Display(Name = "Chapters")]
- Chapters,
+ /// <summary>
+ /// The video range type.
+ /// </summary>
+ public enum VideoRangeType
+ {
+ /// <summary>
+ /// The entire title.
+ /// </summary>
+ [Display(Name = "All")]
+ All,
- /// <summary>
- /// The seconds.
- /// </summary>
- [Display(Name = "Seconds")]
- Seconds,
+ /// <summary>
+ /// A chapter range.
+ /// </summary>
+ [Display(Name = "Chapters")]
+ Chapters,
- /// <summary>
- /// The frames.
- /// </summary>
- [Display(Name = "Frames")]
- Frames
- }
+ /// <summary>
+ /// A timespan range in seconds.
+ /// </summary>
+ [Display(Name = "Seconds")]
+ Seconds,
+
+ /// <summary>
+ /// A frame range.
+ /// </summary>
+ [Display(Name = "Frames")]
+ Frames
+ }
}
\ No newline at end of file diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/Properties/AssemblyInfo.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/Properties/AssemblyInfo.cs index 7536fd261..936eb0fa9 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/Properties/AssemblyInfo.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.35.0.0")]
-[assembly: AssemblyFileVersion("1.35.0.0")]
+[assembly: AssemblyVersion("1.40.0.0")]
+[assembly: AssemblyFileVersion("1.40.0.0")]
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Chapter.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Chapter.cs index efec79d75..411a8d851 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Chapter.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Chapter.cs @@ -23,11 +23,16 @@ namespace HandBrake.Interop.SourceData public int ChapterNumber { get; set; }
/// <summary>
- /// Gets or sets the length in time this Chapter spans
+ /// Gets or sets the duration of this chapter.
/// </summary>
public TimeSpan Duration { get; set; }
/// <summary>
+ /// Gets or sets the duration of this chapter in PTS.
+ /// </summary>
+ public ulong DurationPts { get; set; }
+
+ /// <summary>
/// Override of the ToString method to make this object easier to use in the UI
/// </summary>
/// <returns>A string formatted as: {chapter #}</returns>
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Title.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Title.cs index 57201e847..8c7d65412 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Title.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Title.cs @@ -84,11 +84,16 @@ namespace HandBrake.Interop.SourceData public int Playlist { get; set; }
/// <summary>
- /// Gets or sets the length in time of this Title
+ /// Gets or sets the duration of this title.
/// </summary>
public TimeSpan Duration { get; set; }
/// <summary>
+ /// Gets or sets the duration of the title in PTS.
+ /// </summary>
+ public ulong DurationPts { get; set; }
+
+ /// <summary>
/// Gets or sets the resolution (width/height) of this Title
/// </summary>
public Size Resolution { get; set; }
|