/// <summary> /// Converts a native language structure to a Language object. /// </summary> /// <param name="language"> /// The structure to convert. /// </param> /// <returns> /// The converted structure. /// </returns> public static Language NativeToLanguage(iso639_lang_t language) { string englishName = InteropUtilities.ToStringFromUtf8Ptr(language.eng_name); string nativeName = InteropUtilities.ToStringFromUtf8Ptr(language.native_name); return(new Language { Code = language.iso639_2, EnglishName = englishName, NativeName = nativeName }); }
/// <summary> /// Checks the status of the ongoing scan. /// </summary> private void PollScanProgress() { IntPtr json = HBFunctions.hb_get_state_json(this.hbHandle); string statusJson = Marshal.PtrToStringAnsi(json); JsonState state = JsonConvert.DeserializeObject <JsonState>(statusJson); if (state.State == NativeConstants.HB_STATE_SCANNING) { if (this.ScanProgress != null) { this.ScanProgress(this, new ScanProgressEventArgs { Progress = state.Scanning.Progress, CurrentPreview = state.Scanning.Preview, Previews = state.Scanning.PreviewCount, CurrentTitle = state.Scanning.Title, Titles = state.Scanning.TitleCount }); } } else if (state.State == NativeConstants.HB_STATE_SCANDONE) { this.titles = new List <Title>(); var jsonMsg = HBFunctions.hb_get_title_set_json(this.hbHandle); string scanJson = InteropUtilities.ToStringFromUtf8Ptr(jsonMsg); JsonScanObject scanObject = JsonConvert.DeserializeObject <JsonScanObject>(scanJson); foreach (Title title in ScanFactory.CreateTitleSet(scanObject)) { // Set the Main Title. this.featureTitle = title.IsMainFeature ? title.TitleNumber : 0; this.titles.Add(title); } this.scanPollTimer.Stop(); if (this.ScanCompleted != null) { this.ScanCompleted(this, new System.EventArgs()); } } }
/// <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> public void StartScan(string path, int previewCount, TimeSpan minDuration, int titleIndex) { IntPtr pathPtr = InteropUtilities.ToUtf8PtrFromString(path); HBFunctions.hb_scan(this.hbHandle, pathPtr, titleIndex, previewCount, 1, (ulong)(minDuration.TotalSeconds * 90000)); Marshal.FreeHGlobal(pathPtr); this.scanPollTimer = new Timer(); this.scanPollTimer.Interval = ScanPollIntervalMs; // Lambda notation used to make sure we can view any JIT exceptions the method throws this.scanPollTimer.Elapsed += (o, e) => { this.PollScanProgress(); }; this.scanPollTimer.Start(); }
public void StartEncode(EncodeJob job, Title title) { JsonEncodeObject encodeObject = EncodeFactory.Create(job, title); JsonSerializerSettings settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, }; string encode = JsonConvert.SerializeObject(encodeObject, Formatting.Indented, settings); HBFunctions.hb_add_json(this.hbHandle, InteropUtilities.ToUtf8PtrFromString(encode)); HBFunctions.hb_start(this.hbHandle); this.encodePollTimer = new Timer(); this.encodePollTimer.Interval = EncodePollIntervalMs; this.encodePollTimer.Elapsed += (o, e) => { this.PollEncodeProgress(); }; this.encodePollTimer.Start(); }
public BitmapImage GetPreview(EncodeJob job, int previewNumber) { Title title = this.Titles.FirstOrDefault(t => t.TitleNumber == job.Title); Validate.NotNull(title, "GetPreview: Title should not have been null. This is probably a bug."); // Creat the Expected Output Geometry details for libhb. hb_geometry_settings_s uiGeometry = new hb_geometry_settings_s { crop = new[] { job.Cropping.Top, job.Cropping.Bottom, job.Cropping.Left, job.Cropping.Right }, itu_par = 0, keep = (int)AnamorphicFactory.KeepSetting.HB_KEEP_WIDTH + (job.KeepDisplayAspect ? 0x04 : 0), // TODO Keep Width? maxWidth = job.MaxWidth, maxHeight = job.MaxHeight, mode = (int)(hb_anamorphic_mode_t)job.Anamorphic, modulus = job.Modulus, geometry = new hb_geometry_s { height = job.Height, width = job.Width, par = job.Anamorphic != Anamorphic.Custom ? new hb_rational_t { den = title.ParVal.Height, num = title.ParVal.Width } : new hb_rational_t { den = job.PixelAspectY, num = job.PixelAspectX } } }; // Sanatise the input. 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. int outputWidth = width; int outputHeight = height; // Fetch the image data from LibHb IntPtr resultingImageStuct = HBFunctions.hb_get_preview2(this.hbHandle, job.Title, 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(outputWidth, outputHeight); BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, outputWidth, outputHeight), 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, outputWidth * 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> /// 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.ReadStructure <iso639_lang_t>(HBFunctions.lang_for_code2(code)); return(Converters.NativeToLanguage(language)); }
/// <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)); }