public IntPtr hb_job(IntPtr hbHandle, int jobIndex) { return(HBFunctions.hb_job(hbHandle, jobIndex)); }
/// <summary> /// Sanitizes an audio bitrate given the output codec, sample rate and mixdown. /// </summary> /// <param name="audioBitrate"> /// The desired audio bitrate. /// </param> /// <param name="encoder"> /// The output encoder to be used. /// </param> /// <param name="sampleRate"> /// The output sample rate to be used. /// </param> /// <param name="mixdown"> /// The mixdown to be used. /// </param> /// <returns> /// A sanitized audio bitrate. /// </returns> public static int SanitizeAudioBitrate(int audioBitrate, HBAudioEncoder encoder, int sampleRate, HBMixdown mixdown) { return(HBFunctions.hb_audio_bitrate_get_best((uint)encoder.Id, audioBitrate, sampleRate, mixdown.Id)); }
/// <summary> /// The get default quality. /// </summary> /// <param name="encoder"> /// The encoder. /// </param> /// <returns> /// The <see cref="double"/>. /// </returns> public static double GetDefaultQuality(HBAudioEncoder encoder) { return(HBFunctions.hb_audio_quality_get_default((uint)encoder.Id)); }
/// <summary> /// Determines if a mixdown is available for a given track and encoder. /// </summary> /// <param name="mixdown"> /// The mixdown to evaluate. /// </param> /// <param name="encoder"> /// The encoder to evaluate. /// </param> /// <param name="channelLayout">channel layout of the source track</param> /// <returns>True if available.</returns> public static bool MixdownIsSupported(HBMixdown mixdown, HBAudioEncoder encoder, long channelLayout) { return(HBFunctions.hb_mixdown_is_supported(mixdown.Id, (uint)encoder.Id, (uint)channelLayout) > 0); }
/// <summary> /// Gets the default mixdown for the given audio encoder and channel layout. /// </summary> /// <param name="encoder"> /// The output codec to be used. /// </param> /// <param name="layout"> /// The input channel layout. /// </param> /// <returns> /// The default mixdown for the given codec and channel layout. /// </returns> public static HBMixdown GetDefaultMixdown(HBAudioEncoder encoder, ulong layout) { int defaultMixdown = HBFunctions.hb_mixdown_get_default((uint)encoder.Id, layout); return(Mixdowns.Single(m => m.Id == defaultMixdown)); }
/// <summary> /// Returns true if the subtitle source type can be burned in. /// </summary> /// <param name="source"> /// The subtitle source type (SSA, VobSub, etc) /// </param> /// <returns> /// True if the subtitle source type can be burned in. /// </returns> public static bool SubtitleCanBurn(int source) { return(HBFunctions.hb_subtitle_can_burn(source) > 0); }
/// <summary> /// Determines if the given mixdown supports the given channel layout. /// </summary> /// <param name="mixdown"> /// The mixdown to evaluate. /// </param> /// <param name="layout"> /// The channel layout to evaluate. /// </param> /// <returns> /// True if the mixdown supports the given channel layout. /// </returns> public static bool MixdownHasRemixSupport(HBMixdown mixdown, ulong layout) { return(HBFunctions.hb_mixdown_has_remix_support(mixdown.Id, layout) > 0); }
/// <summary> /// Gets the language object for the given code. /// </summary> /// <param name="code">The ISO-639-2 code for the language.</param> /// <returns>Object that describes the language.</returns> public static Language Get(string code) { iso639_lang_t language = InteropUtilities.ToStructureFromPtr <iso639_lang_t>(HBFunctions.lang_for_code2(code)); return(HandBrakeUnitConversionHelpers.NativeToLanguage(language)); }
/// <summary> /// Returns true if the subtitle can be passed through using the given muxer. /// </summary> /// <param name="muxer">The muxer ID.</param> /// <returns>True if the subtitle can be passed through.</returns> public bool CanPass(int muxer) { return(HBFunctions.hb_subtitle_can_pass(this.SubtitleSourceInt, muxer) > 0); }
public static HBAudioEncoder GetAutoPassthruEncoder(int inputCodec, int copyMask, int fallback, int muxer) { int encoder = HBFunctions.hb_autopassthru_get_encoder(inputCodec, copyMask, fallback, muxer); return(GetAudioEncoder(encoder)); }
/// <summary> /// The create filter. /// </summary> /// <param name="job"> /// The job. /// </param> /// <returns> /// The <see cref="Filters"/>. /// </returns> private static Filters CreateFilters(EncodeTask job) { Filters filter = new Filters { FilterList = new List <Filter>(), }; // Note, order is important. // Detelecine if (job.Detelecine != Detelecine.Off) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_DETELECINE, null, null, job.CustomDetelecine); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DETELECINE, Settings = settings }; filter.FilterList.Add(filterItem); } } // Deinterlace if (job.DeinterlaceFilter == DeinterlaceFilter.Yadif) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_DEINTERLACE, EnumHelper <Deinterlace> .GetShortName(job.Deinterlace), null, job.CustomDeinterlace); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken root = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DEINTERLACE, Settings = root }; filter.FilterList.Add(filterItem); } } // Decomb if (job.DeinterlaceFilter == DeinterlaceFilter.Decomb) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_DECOMB, EnumHelper <Decomb> .GetShortName(job.Decomb), null, job.CustomDecomb); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DECOMB, Settings = settings }; filter.FilterList.Add(filterItem); } } if (job.DeinterlaceFilter == DeinterlaceFilter.Decomb || job.DeinterlaceFilter == DeinterlaceFilter.Yadif) { if (job.CombDetect != CombDetect.Off) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_COMB_DETECT, EnumHelper <CombDetect> .GetShortName(job.CombDetect), null, job.CustomCombDetect); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_COMB_DETECT, Settings = settings }; filter.FilterList.Add(filterItem); } } } // Denoise if (job.Denoise != Denoise.Off) { hb_filter_ids id = job.Denoise == Denoise.hqdn3d ? hb_filter_ids.HB_FILTER_HQDN3D : hb_filter_ids.HB_FILTER_NLMEANS; IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)id, job.DenoisePreset.ToString().ToLower().Replace(" ", string.Empty), job.DenoiseTune.ToString().ToLower().Replace(" ", string.Empty), job.CustomDenoise); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)id, Settings = settings }; filter.FilterList.Add(filterItem); } } // Deblock if (job.Deblock >= 5) { IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_DEBLOCK, null, null, string.Format("qp={0}", job.Deblock)); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DEBLOCK, Settings = settings }; filter.FilterList.Add(filterItem); } } // CropScale Filter string cropSettings = string.Format("width={0}:height={1}:crop-top={2}:crop-bottom={3}:crop-left={4}:crop-right={5}", job.Width, job.Height, job.Cropping.Top, job.Cropping.Bottom, job.Cropping.Left, job.Cropping.Right); IntPtr cropSettingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_CROP_SCALE, null, null, cropSettings); string unparsedCropSettingsJson = Marshal.PtrToStringAnsi(cropSettingsPtr); if (!string.IsNullOrEmpty(unparsedCropSettingsJson)) { JToken cropSettingsJson = JObject.Parse(unparsedCropSettingsJson); Filter cropScale = new Filter { ID = (int)hb_filter_ids.HB_FILTER_CROP_SCALE, Settings = cropSettingsJson }; filter.FilterList.Add(cropScale); } // Grayscale if (job.Grayscale) { Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_GRAYSCALE, Settings = null }; filter.FilterList.Add(filterItem); } // Rotate if (job.Rotation != 0 || job.FlipVideo) { string rotateSettings = string.Format("angle={0}:hflip={1}", job.Rotation, job.FlipVideo ? "1" : "0"); IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_ROTATE, null, null, rotateSettings); string unparsedJson = Marshal.PtrToStringAnsi(settingsPtr); if (!string.IsNullOrEmpty(unparsedJson)) { JToken settings = JObject.Parse(unparsedJson); Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_ROTATE, Settings = settings }; filter.FilterList.Add(filterItem); } } // Framerate shaping filter int fm = job.FramerateMode == FramerateMode.CFR ? 1 : job.FramerateMode == FramerateMode.PFR ? 2 : 0; int?num = null, den = null; if (job.Framerate != null) { IntPtr frameratePrt = Marshal.StringToHGlobalAnsi(job.Framerate.Value.ToString(CultureInfo.InvariantCulture)); int vrate = HBFunctions.hb_video_framerate_get_from_name(frameratePrt); if (vrate > 0) { num = 27000000; den = vrate; } } string framerateString = num.HasValue ? string.Format("mode={0}:rate={1}/{2}", fm, num, den) : string.Format("mode={0}", fm); // filter_cfr, filter_vrate.num, filter_vrate.den IntPtr framerateSettingsPtr = HBFunctions.hb_generate_filter_settings_json((int)hb_filter_ids.HB_FILTER_VFR, null, null, framerateString); string unparsedFramerateJson = Marshal.PtrToStringAnsi(framerateSettingsPtr); if (!string.IsNullOrEmpty(unparsedFramerateJson)) { JToken framerateSettings = JObject.Parse(unparsedFramerateJson); Filter framerateShaper = new Filter { ID = (int)hb_filter_ids.HB_FILTER_VFR, Settings = framerateSettings }; filter.FilterList.Add(framerateShaper); } return(filter); }
/// <summary> /// Gets a list of keys for custom settings for the filter. /// </summary> /// <param name="filter">The filter to look up.</param> /// <returns>The list of keys for custom settings for the filter.</returns> public static List <string> GetFilterKeys(int filter) { IntPtr ptr = HBFunctions.hb_filter_get_keys(filter); return(InteropUtilities.ToStringListFromArrayPtr(ptr)); }
/// <summary> /// Sanitizes a mixdown given the output codec and input channel layout. /// </summary> /// <param name="mixdown">The desired mixdown.</param> /// <param name="encoder">The output encoder to be used.</param> /// <param name="layout">The input channel layout.</param> /// <returns>A sanitized mixdown value.</returns> public static HBMixdown SanitizeMixdown(HBMixdown mixdown, HBAudioEncoder encoder, ulong layout) { int sanitizedMixdown = HBFunctions.hb_get_best_mixdown((uint)encoder.Id, layout, mixdown.Id); return(Mixdowns.Single(m => m.Id == sanitizedMixdown)); }
public void hb_rem(IntPtr hbHandle, IntPtr job) { HBFunctions.hb_rem(hbHandle, job); }
/// <summary> /// Call before app shutdown. Performs global cleanup. /// </summary> public static void DisposeGlobal() { HBFunctions.hb_global_close(); }
/// <summary> /// Convert Interop Title objects to App Services Title object /// </summary> /// <param name="titles"> /// The titles. /// </param> /// <returns> /// The convert titles. /// </returns> internal static List <Title> ConvertTitles(JsonScanObject titles) { List <Title> titleList = new List <Title>(); foreach (SourceTitle title in titles.TitleList) { Title converted = new Title { TitleNumber = title.Index, Duration = new TimeSpan(0, title.Duration.Hours, title.Duration.Minutes, title.Duration.Seconds), Resolution = new Size(title.Geometry.Width, title.Geometry.Height), AngleCount = title.AngleCount, ParVal = new Size(title.Geometry.PAR.Num, title.Geometry.PAR.Den), AutoCropDimensions = new Cropping { Top = title.Crop[0], Bottom = title.Crop[1], Left = title.Crop[2], Right = title.Crop[3] }, Fps = ((double)title.FrameRate.Num) / title.FrameRate.Den, SourceName = title.Path, MainTitle = titles.MainFeature == title.Index, Playlist = title.Type == 1 ? string.Format(" {0:d5}.MPLS", title.Playlist).Trim() : null, FramerateNumerator = title.FrameRate.Num, FramerateDenominator = title.FrameRate.Den }; int currentTrack = 1; foreach (SourceChapter chapter in title.ChapterList) { string chapterName = !string.IsNullOrEmpty(chapter.Name) ? chapter.Name : string.Empty; converted.Chapters.Add(new Chapter(currentTrack, chapterName, new TimeSpan(chapter.Duration.Hours, chapter.Duration.Minutes, chapter.Duration.Seconds))); currentTrack++; } int currentAudioTrack = 1; foreach (SourceAudioTrack track in title.AudioList) { converted.AudioTracks.Add(new Audio(currentAudioTrack, track.Language, track.LanguageCode, track.Description, track.Codec, track.SampleRate, track.BitRate, track.ChannelLayout)); currentAudioTrack++; } int currentSubtitleTrack = 1; foreach (SourceSubtitleTrack track in title.SubtitleList) { SubtitleType convertedType = new SubtitleType(); switch (track.Source) { case 0: convertedType = SubtitleType.VobSub; break; case 4: convertedType = SubtitleType.UTF8Sub; break; case 5: convertedType = SubtitleType.TX3G; break; case 6: convertedType = SubtitleType.SSA; break; case 1: convertedType = SubtitleType.SRT; break; case 2: convertedType = SubtitleType.CC; break; case 3: convertedType = SubtitleType.CC; break; case 7: convertedType = SubtitleType.PGS; break; } bool canBurn = HBFunctions.hb_subtitle_can_burn(track.Source) > 0; bool canSetForcedOnly = HBFunctions.hb_subtitle_can_force(track.Source) > 0; converted.Subtitles.Add(new Subtitle(track.Source, currentSubtitleTrack, track.Language, track.LanguageCode, convertedType, canBurn, canSetForcedOnly)); currentSubtitleTrack++; } titleList.Add(converted); } return(titleList); }
/// <summary> /// Returns true if the subtitle source type can be set to forced only. /// </summary> /// <param name="source"> /// The subtitle source type (SSA, VobSub, etc) /// </param> /// <returns> /// True if the subtitle source type can be set to forced only. /// </returns> public static bool SubtitleCanSetForcedOnly(int source) { return(HBFunctions.hb_subtitle_can_force(source) > 0); }
public void StopScan() { HBFunctions.hb_scan_stop(this.hbHandle); }
/// <summary> /// Returns true if the subtitle type can be passed through using the given muxer. /// </summary> /// <param name="subtitleSourceType"> /// The subtitle source type (SSA, VobSub, etc) /// </param> /// <param name="muxer"> /// The ID of the muxer. /// </param> /// <returns> /// True if the subtitle type can be passed through with the given muxer. /// </returns> public static bool SubtitleCanPassthrough(int subtitleSourceType, int muxer) { return(HBFunctions.hb_subtitle_can_pass(subtitleSourceType, muxer) > 0); }
public BitmapImage GetPreview(PreviewSettings settings, int previewNumber) { SourceTitle title = this.Titles.TitleList.FirstOrDefault(t => t.Index == settings.TitleNumber); // Create the Expected Output Geometry details for libhb. hb_geometry_settings_s uiGeometry = new hb_geometry_settings_s { crop = new[] { settings.Cropping.Top, settings.Cropping.Bottom, settings.Cropping.Left, settings.Cropping.Right }, itu_par = 0, keep = (int)AnamorphicFactory.KeepSetting.HB_KEEP_WIDTH + (settings.KeepDisplayAspect ? 0x04 : 0), // TODO Keep Width? maxWidth = settings.MaxWidth, maxHeight = settings.MaxHeight, mode = (int)(hb_anamorphic_mode_t)settings.Anamorphic, modulus = settings.Modulus ?? 16, geometry = new hb_geometry_s { height = settings.Height, width = settings.Width, par = settings.Anamorphic != Anamorphic.Custom ? new hb_rational_t { den = title.Geometry.PAR.Den, num = title.Geometry.PAR.Num } : new hb_rational_t { den = settings.PixelAspectY, num = settings.PixelAspectX } } }; // Sanitize the input. Geometry resultGeometry = AnamorphicFactory.CreateGeometry(settings, new SourceVideoInfo(new Size(title.Geometry.Width, title.Geometry.Height), new Size(title.Geometry.PAR.Num, title.Geometry.PAR.Den))); int width = resultGeometry.Width * resultGeometry.PAR.Num / resultGeometry.PAR.Den; int height = resultGeometry.Height; uiGeometry.geometry.width = width; uiGeometry.geometry.height = height; uiGeometry.geometry.par.num = settings.PixelAspectX; uiGeometry.geometry.par.den = settings.PixelAspectY; // Fetch the image data from LibHb IntPtr resultingImageStuct = HBFunctions.hb_get_preview2(this.hbHandle, settings.TitleNumber, previewNumber, ref uiGeometry, 0); hb_image_s image = InteropUtilities.ToStructureFromPtr <hb_image_s>(resultingImageStuct); // Copy the filled image buffer to a managed array. int stride_width = image.plane[0].stride; int stride_height = image.plane[0].height_stride; int imageBufferSize = stride_width * stride_height; // int imageBufferSize = outputWidth * outputHeight * 4; byte[] managedBuffer = new byte[imageBufferSize]; Marshal.Copy(image.plane[0].data, managedBuffer, 0, imageBufferSize); var bitmap = new Bitmap(width, height); BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb); IntPtr ptr = bitmapData.Scan0; // Pointer to the first pixel. for (int i = 0; i < image.height; i++) { try { Marshal.Copy(managedBuffer, i * stride_width, ptr, stride_width); ptr = IntPtr.Add(ptr, width * 4); } catch (Exception exc) { Debug.WriteLine(exc); // In theory, this will allow a partial image display if this happens. TODO add better logging of this. } } bitmap.UnlockBits(bitmapData); // Close the image so we don't leak memory. IntPtr nativeJobPtrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); Marshal.WriteIntPtr(nativeJobPtrPtr, resultingImageStuct); HBFunctions.hb_image_close(nativeJobPtrPtr); Marshal.FreeHGlobal(nativeJobPtrPtr); // Create a Bitmap Image for display. using (var memoryStream = new MemoryStream()) { try { bitmap.Save(memoryStream, ImageFormat.Bmp); } finally { bitmap.Dispose(); } var wpfBitmap = new BitmapImage(); wpfBitmap.BeginInit(); wpfBitmap.CacheOption = BitmapCacheOption.OnLoad; wpfBitmap.StreamSource = memoryStream; wpfBitmap.EndInit(); wpfBitmap.Freeze(); return(wpfBitmap); } }
/// <summary> /// Determines if the given encoder supports the given mixdown. /// </summary> /// <param name="mixdown"> /// The mixdown to evaluate. /// </param> /// <param name="encoder"> /// The encoder to evaluate. /// </param> /// <returns> /// True if the encoder supports the mixdown. /// </returns> public static bool MixdownHasCodecSupport(HBMixdown mixdown, HBAudioEncoder encoder) { return(HBFunctions.hb_mixdown_has_codec_support(mixdown.Id, (uint)encoder.Id) > 0); }
/// <summary> /// Determines if DRC can be applied to the given track with the given encoder. /// </summary> /// <param name="trackNumber">The track Number.</param> /// <param name="encoder">The encoder to use for DRC.</param> /// <param name="title">The title.</param> /// <returns>True if DRC can be applied to the track with the given encoder.</returns> public bool CanApplyDrc(int trackNumber, HBAudioEncoder encoder, int title) { return(HBFunctions.hb_audio_can_apply_drc2(this.hbHandle, title, trackNumber, encoder.Id) > 0); }
/// <summary> /// Determines if DRC can be applied to the given track with the given encoder. /// </summary> /// <param name="trackNumber"> /// The track Number. /// </param> /// <param name="encoder"> /// The encoder to use for DRC. /// </param> /// <param name="title"> /// The title. /// </param> /// <returns> /// True if DRC can be applied to the track with the given encoder. /// </returns> public static bool CanApplyDrc(int trackNumber, HBAudioEncoder encoder, int title) { return(HBFunctions.hb_audio_can_apply_drc2(HandBrakeInstanceManager.LastScanHandle, title, trackNumber, encoder.Id) > 0); }
public void PauseEncode() { HBFunctions.hb_pause(this.hbHandle); }
/// <summary> /// Sanitizes the given sample rate for the given encoder. /// </summary> /// <param name="encoder">The encoder.</param> /// <param name="sampleRate">The sample rate to sanitize.</param> /// <returns>The sanitized sample rate.</returns> public static int SanitizeSampleRate(HBAudioEncoder encoder, int sampleRate) { return(HBFunctions.hb_audio_samplerate_find_closest(sampleRate, (uint)encoder.Id)); }
public void ResumeEncode() { HBFunctions.hb_resume(this.hbHandle); }
/// <summary> /// Gets the default audio bitrate for the given parameters. /// </summary> /// <param name="encoder"> /// The encoder to use. /// </param> /// <param name="sampleRate"> /// The sample rate to use. /// </param> /// <param name="mixdown"> /// The mixdown to use. /// </param> /// <returns> /// The default bitrate for these parameters. /// </returns> public static int GetDefaultBitrate(HBAudioEncoder encoder, int sampleRate, HBMixdown mixdown) { return(HBFunctions.hb_audio_bitrate_get_default((uint)encoder.Id, sampleRate, mixdown.Id)); }
/// <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> /// The get default audio compression. /// </summary> /// <param name="encoder"> /// The encoder. /// </param> /// <returns> /// The <see cref="double"/>. /// </returns> public static double GetDefaultAudioCompression(HBAudioEncoder encoder) { return(HBFunctions.hb_audio_compression_get_default((uint)encoder.Id)); }
public int hb_count(IntPtr hbHandle) { return(HBFunctions.hb_count(hbHandle)); }