The Audio Encoding Model
Example #1
0
        /// <summary>
        /// Applies an audio encoding to a native audio encoding base structure.
        /// </summary>
        /// <param name="encoding">The encoding to apply.</param>
        /// <param name="baseStruct">The base native structure.</param>
        /// <param name="outputTrack">The output track number (0-based).</param>
        /// <param name="allocatedMemory">The collection of allocated memory.</param>
        /// <returns>The resulting native audio structure.</returns>
        private hb_audio_s ConvertAudioBack(AudioEncoding encoding, hb_audio_s baseStruct, int outputTrack, List<IntPtr> allocatedMemory)
        {
            hb_audio_s nativeAudio = baseStruct;
            HBAudioEncoder encoder = Encoders.GetAudioEncoder(encoding.Encoder);

            nativeAudio.config.output.track = outputTrack;
            nativeAudio.config.output.codec = (uint)encoder.Id;

            if (!encoder.IsPassthrough)
            {
                if (encoding.SampleRateRaw == 0)
                {
                    nativeAudio.config.output.samplerate = nativeAudio.config.input.samplerate;
                }
                else
                {
                    nativeAudio.config.output.samplerate = encoding.SampleRateRaw;
                }

                HBMixdown mixdown = Encoders.GetMixdown(encoding.Mixdown);
                nativeAudio.config.output.mixdown = mixdown.Id;

                if (encoding.EncodeRateType == AudioEncodeRateType.Bitrate)
                {
                    // Disable quality targeting.
                    nativeAudio.config.output.quality = -1;

                    if (encoding.Bitrate == 0)
                    {
                        // Bitrate of 0 means auto: choose the default for this codec, sample rate and mixdown.
                        nativeAudio.config.output.bitrate = HBFunctions.hb_get_default_audio_bitrate(
                            nativeAudio.config.output.codec,
                            nativeAudio.config.output.samplerate,
                            nativeAudio.config.output.mixdown);
                    }
                    else
                    {
                        nativeAudio.config.output.bitrate = encoding.Bitrate;
                    }
                }
                else if (encoding.EncodeRateType == AudioEncodeRateType.Quality)
                {
                    // Bitrate of -1 signals quality targeting.
                    nativeAudio.config.output.bitrate = -1;
                    nativeAudio.config.output.quality = encoding.Quality;
                }

                // If this encoder supports compression level, pass it in.
                if (encoder.SupportsCompression)
                {
                    nativeAudio.config.output.compression_level = encoding.Compression;
                }

                nativeAudio.config.output.dynamic_range_compression = encoding.Drc;
                nativeAudio.config.output.gain = encoding.Gain;
            }

            if (!string.IsNullOrEmpty(encoding.Name))
            {
                IntPtr encodingNamePtr = Marshal.StringToHGlobalAnsi(encoding.Name);
                nativeAudio.config.output.name = encodingNamePtr;
                allocatedMemory.Add(encodingNamePtr);
            }

            nativeAudio.padding = new byte[MarshalingConstants.AudioPaddingBytes];

            return nativeAudio;
        }
        /*
         * TODO: This conversion class needs to be finished off before libencode will work.
         */
        /// <summary>
        /// Get an EncodeJob model for a LibHB Encode.
        /// </summary>
        /// <param name="task">
        /// The task.
        /// </param>
        /// <returns>
        /// An Interop.EncodeJob model.
        /// </returns>
        public static EncodeJob GetEncodeJob(QueueTask task)
        {
            // Sanity Checking
            if (task == null || task.Task == null)
            {
                return null;
            }

            // The current Job Configuration
            EncodeTask work = task.Task;

            // Which will be converted to this EncodeJob Model.
            EncodeJob job = new EncodeJob();

            EncodingProfile profile = new EncodingProfile();
            job.EncodingProfile = profile;

            profile.Anamorphic = work.Anamorphic;

            profile.AudioEncodings = new List<AudioEncoding>();
            job.ChosenAudioTracks = new List<int>();
            foreach (AudioTrack track in work.AudioTracks)
            {
                AudioEncoding newTrack = new AudioEncoding
                    {
                        Bitrate = track.Bitrate,
                        Drc = track.DRC,
                        Gain = track.Gain,
                        Encoder = Converters.GetCliAudioEncoder(track.Encoder),
                        InputNumber = track.Track.HasValue ? track.Track.Value : 0,
                        Mixdown = Converters.GetCliMixDown(track.MixDown),
                        SampleRateRaw = GetSampleRateRaw(track.SampleRate),
                    };

                profile.AudioEncodings.Add(newTrack);
                if (track.Track != null)
                {
                    job.ChosenAudioTracks.Add(track.Track.Value);
                }
            }
            profile.Cropping = new Cropping
                {
                    Top = work.Cropping.Top,
                    Bottom = work.Cropping.Bottom,
                    Left = work.Cropping.Left,
                    Right = work.Cropping.Right
                };

            profile.CroppingType = CroppingType.Custom; // TODO deal with this better
            profile.CustomDecomb = work.CustomDecomb;
            profile.CustomDeinterlace = work.CustomDeinterlace;
            profile.CustomDenoise = work.CustomDenoise;
            profile.CustomDetelecine = work.CustomDetelecine;
            profile.Deblock = work.Deblock;
            profile.Decomb = work.Decomb;
            profile.Deinterlace = work.Deinterlace;
            profile.Denoise = work.Denoise;
            profile.Detelecine = work.Detelecine;
            profile.DisplayWidth = work.DisplayWidth.HasValue
                                       ? int.Parse(Math.Round(work.DisplayWidth.Value, 0).ToString())
                                       : 0;
            profile.Framerate = work.Framerate.HasValue ? work.Framerate.Value : 0;
            profile.Grayscale = work.Grayscale;
            profile.Height = work.Height.HasValue ? work.Height.Value : 0;
            profile.IPod5GSupport = work.IPod5GSupport;
            profile.IncludeChapterMarkers = work.IncludeChapterMarkers;
            profile.KeepDisplayAspect = work.KeepDisplayAspect;
            profile.LargeFile = work.LargeFile;
            profile.MaxHeight = work.MaxHeight.HasValue ? work.MaxHeight.Value : 0;
            profile.MaxWidth = work.MaxWidth.HasValue ? work.MaxWidth.Value : 0;
            profile.Modulus = work.Modulus.HasValue ? work.Modulus.Value : 16;
            profile.Optimize = work.OptimizeMP4;
            switch (work.OutputFormat)
            {
                case OutputFormat.Mp4:
                case OutputFormat.M4V:
                    profile.OutputFormat = Container.Mp4;
                    break;
                case OutputFormat.Mkv:
                    profile.OutputFormat = Container.Mkv;
                    break;
            }
            profile.ConstantFramerate = work.FramerateMode == FramerateMode.CFR;
            profile.PixelAspectX = work.PixelAspectX;
            profile.PixelAspectY = work.PixelAspectY;

            switch (work.OutputFormat)
            {
                case OutputFormat.Mp4:
                    profile.PreferredExtension = OutputExtension.Mp4;
                    break;
                case OutputFormat.M4V:
                    profile.PreferredExtension = OutputExtension.M4v;
                    break;
            }
            profile.Quality = work.Quality.HasValue ? work.Quality.Value : 0;
            profile.UseDisplayWidth = true;
            profile.VideoBitrate = work.VideoBitrate.HasValue ? work.VideoBitrate.Value : 0;
            profile.VideoEncodeRateType = work.VideoEncodeRateType;
            profile.VideoEncoder = Converters.GetVideoEncoder(work.VideoEncoder);
            profile.Width = work.Width.HasValue ? work.Width.Value : 0;
            profile.X264Options = work.AdvancedEncoderOptions;

            if (work.PointToPointMode == PointToPointMode.Chapters)
            {
                job.ChapterStart = work.StartPoint;
                job.ChapterEnd = work.EndPoint;
            }

            job.Angle = work.Angle;
            job.EncodingProfile = profile;
            if (work.PointToPointMode == PointToPointMode.Frames)
            {
                job.FramesEnd = work.EndPoint;
                job.FramesStart = work.StartPoint;
            }

            job.CustomChapterNames = work.ChapterNames.Select(item => item.ChapterName).ToList();
            job.UseDefaultChapterNames = work.IncludeChapterMarkers;

            job.OutputPath = work.Destination;
            switch (work.PointToPointMode)
            {
                case PointToPointMode.Chapters:
                    job.RangeType = VideoRangeType.Chapters;
                    break;
                case PointToPointMode.Seconds:
                    job.RangeType = VideoRangeType.Seconds;
                    break;
                case PointToPointMode.Frames:
                    job.RangeType = VideoRangeType.Frames;
                    break;
            }

            if (work.PointToPointMode == PointToPointMode.Seconds)
            {
                job.SecondsEnd = work.EndPoint;
                job.SecondsStart = work.StartPoint;
            }

            job.SourcePath = work.Source;
            // job.SourceType = work.Type;
            job.Title = work.Title;

            // TODO Setup subtitles
            job.Subtitles = new Subtitles { SourceSubtitles = new List<SourceSubtitle>(), SrtSubtitles = new List<SrtSubtitle>() };
            //foreach (SubtitleTrack track in work.SubtitleTracks)
            //{
            //    // TODO
            //}

            return job;
        }
Example #3
0
		public AudioEncodingViewModel(AudioEncoding audioEncoding, Title selectedTitle, List<int> chosenAudioTracks, string containerName, AudioPanelViewModel audioPanelVM)
		{
			this.initializing = true;
			this.audioPanelVM = audioPanelVM;

			this.targetStreams = new ObservableCollection<TargetStreamViewModel>();
			this.targetStreamIndex = audioEncoding.InputNumber;

			this.SetChosenTracks(chosenAudioTracks, selectedTitle);

			this.audioEncoders = new List<AudioEncoderViewModel>();
			this.mixdownChoices = new List<MixdownViewModel>();

			this.containerName = containerName;
			this.RefreshEncoderChoices();

			HBAudioEncoder hbAudioEncoder = Encoders.GetAudioEncoder(audioEncoding.Encoder);
			if (hbAudioEncoder.IsPassthrough)
			{
				this.selectedAudioEncoder = this.audioEncoders[0];
				this.selectedPassthrough = audioEncoding.Encoder;
			}
			else
			{
				this.selectedAudioEncoder = this.audioEncoders.Skip(1).FirstOrDefault(e => e.Encoder.ShortName == audioEncoding.Encoder);
				this.selectedPassthrough = "copy";
			}

			if (this.selectedAudioEncoder == null)
			{
				this.selectedAudioEncoder = this.audioEncoders[1];
			}

			this.RefreshMixdownChoices();
			this.RefreshBitrateChoices();
			this.RefreshSampleRateChoices();

			this.SelectMixdown(Encoders.GetMixdown(audioEncoding.Mixdown));

			this.sampleRate = audioEncoding.SampleRateRaw;

			if (!this.HBAudioEncoder.SupportsQuality)
			{
				this.encodeRateType = AudioEncodeRateType.Bitrate;
			}
			else
			{
				this.encodeRateType = audioEncoding.EncodeRateType;
			}

			this.audioQuality = audioEncoding.Quality;

			if (audioEncoding.Compression >= 0)
			{
				this.audioCompression = audioEncoding.Compression;
			}
			else
			{
				this.audioCompression = this.HBAudioEncoder.DefaultCompression;
			}

			this.selectedBitrate = this.BitrateChoices.SingleOrDefault(b => b.Bitrate == audioEncoding.Bitrate);
			if (this.selectedBitrate == null)
			{
				this.selectedBitrate = this.BitrateChoices.First();
			}

			this.gain = audioEncoding.Gain;
			this.drc = audioEncoding.Drc;
			this.passthroughIfPossible = audioEncoding.PassthroughIfPossible;
			this.name = audioEncoding.Name;

			Messenger.Default.Register<SelectedTitleChangedMessage>(
				this,
				message =>
					{
						this.RefreshMixdownChoices();
						this.RefreshBitrateChoices();
						this.RefreshDrc();
					});

			Messenger.Default.Register<AudioInputChangedMessage>(
				this,
				message =>
					{
						this.RefreshMixdownChoices();
						this.RefreshBitrateChoices();
						this.RefreshDrc();
					});

			Messenger.Default.Register<OptionsChangedMessage>(
				this,
				message =>
					{
						this.RaisePropertyChanged(() => this.NameVisible);
					});

			Messenger.Default.Register<ContainerChangedMessage>(
				this,
				message =>
					{
						this.containerName = message.ContainerName;
						this.RefreshEncoderChoices();
					});

			this.initializing = false;
		}
        /// <summary>
        /// Get an EncodeJob model for a LibHB Encode.
        /// </summary>
        /// <param name="task">
        /// The task.
        /// </param>
        /// <returns>
        /// An Interop.EncodeJob model.
        /// </returns>
        public static EncodeJob GetEncodeJob(EncodeTask task)
        {
            // The current Job Configuration
            EncodeTask work = task;

            // Which will be converted to this EncodeJob Model.
            EncodeJob job = new EncodeJob();
            EncodingProfile profile = new EncodingProfile();
            job.EncodingProfile = profile;

            // Audio Settings
            profile.AudioEncodings = new List<AudioEncoding>();
            job.ChosenAudioTracks = new List<int>();
            foreach (AudioTrack track in work.AudioTracks)
            {
                AudioEncoding newTrack = new AudioEncoding
                    {
                        Bitrate = track.Bitrate,
                        Drc = track.DRC,
                        Gain = track.Gain,
                        Encoder = Converters.GetCliAudioEncoder(track.Encoder),
                        InputNumber = track.Track.HasValue ? track.Track.Value : 0,
                        Mixdown = Converters.GetCliMixDown(track.MixDown),
                        SampleRateRaw = GetSampleRateRaw(track.SampleRate),
                    };

                profile.AudioEncodings.Add(newTrack);
                if (track.Track != null)
                {
                    job.ChosenAudioTracks.Add(track.Track.Value);
                }
            }

            // Title Settings
            job.OutputPath = work.Destination;
            job.SourcePath = work.Source;
            job.Title = work.Title;
            // job.SourceType = work.Type;
            switch (work.PointToPointMode)
            {
                case PointToPointMode.Chapters:
                    job.RangeType = VideoRangeType.Chapters;
                    break;
                case PointToPointMode.Seconds:
                    job.RangeType = VideoRangeType.Seconds;
                    break;
                case PointToPointMode.Frames:
                    job.RangeType = VideoRangeType.Frames;
                    break;
            }

            if (work.PointToPointMode == PointToPointMode.Seconds)
            {
                job.SecondsEnd = work.EndPoint;
                job.SecondsStart = work.StartPoint;
            }
            if (work.PointToPointMode == PointToPointMode.Chapters)
            {
                job.ChapterStart = work.StartPoint;
                job.ChapterEnd = work.EndPoint;
            }
            if (work.PointToPointMode == PointToPointMode.Frames)
            {
                job.FramesEnd = work.EndPoint;
                job.FramesStart = work.StartPoint;
            }

            job.Angle = work.Angle;
            job.EncodingProfile = profile;

            // Output Settings
            profile.IPod5GSupport = work.IPod5GSupport;
            profile.Optimize = work.OptimizeMP4;
            switch (work.OutputFormat)
            {
                case OutputFormat.Mp4:
                case OutputFormat.M4V:
                    profile.OutputFormat = Container.Mp4;
                    break;
                case OutputFormat.Mkv:
                    profile.OutputFormat = Container.Mkv;
                    break;
            }

            // Picture Settings
            profile.Anamorphic = work.Anamorphic;
            profile.Cropping = new Cropping
                {
                    Top = work.Cropping.Top,
                    Bottom = work.Cropping.Bottom,
                    Left = work.Cropping.Left,
                    Right = work.Cropping.Right
                };
            profile.CroppingType = CroppingType.Custom; // TODO deal with this better
            profile.DisplayWidth = work.DisplayWidth.HasValue
                           ? int.Parse(Math.Round(work.DisplayWidth.Value, 0).ToString())
                           : 0;
            profile.PixelAspectX = work.PixelAspectX;
            profile.PixelAspectY = work.PixelAspectY;
            profile.Height = work.Height.HasValue ? work.Height.Value : 0;
            profile.KeepDisplayAspect = work.KeepDisplayAspect;
            profile.MaxHeight = work.MaxHeight.HasValue ? work.MaxHeight.Value : 0;
            profile.MaxWidth = work.MaxWidth.HasValue ? work.MaxWidth.Value : 0;
            profile.Modulus = work.Modulus.HasValue ? work.Modulus.Value : 16;
            profile.UseDisplayWidth = true;
            profile.Width = work.Width.HasValue ? work.Width.Value : 0;

            // Filter Settings
            profile.CustomDecomb = work.CustomDecomb;
            profile.CustomDeinterlace = work.CustomDeinterlace;
            profile.CustomDenoise = work.CustomDenoise;
            profile.CustomDetelecine = work.CustomDetelecine;
            if (work.Deblock > 4)
                profile.Deblock = work.Deblock;
            profile.Decomb = work.Decomb;
            profile.Deinterlace = work.Deinterlace;
            profile.Denoise = work.Denoise;
            profile.Detelecine = work.Detelecine;
            profile.Grayscale = work.Grayscale;

            // Video Settings
            profile.Framerate = work.Framerate.HasValue ? work.Framerate.Value : 0;
            profile.ConstantFramerate = work.FramerateMode == FramerateMode.CFR;
            profile.Quality = work.Quality.HasValue ? work.Quality.Value : 0;
            profile.VideoBitrate = work.VideoBitrate.HasValue ? work.VideoBitrate.Value : 0;
            profile.VideoEncodeRateType = work.VideoEncodeRateType;
            profile.VideoEncoder = Converters.GetVideoEncoder(work.VideoEncoder);

            profile.H264Level = work.H264Level;
            profile.X264Profile = work.H264Profile.ToString().ToLower().Replace(" ", string.Empty); // TODO change these away from strings.
            profile.X264Preset = work.X264Preset.ToString().ToLower().Replace(" ", string.Empty);
            profile.X264Tunes = new List<string>();

            if (work.X264Tune != x264Tune.None)
            {
                profile.X264Tunes.Add(work.X264Tune.ToString().ToLower().Replace(" ", string.Empty));
            }

            if (work.FastDecode)
            {
                profile.X264Tunes.Add("fastdecode");
            }

            // Chapter Markers
            profile.IncludeChapterMarkers = work.IncludeChapterMarkers;
            job.CustomChapterNames = work.ChapterNames.Select(item => item.ChapterName).ToList();
            job.UseDefaultChapterNames = work.IncludeChapterMarkers;

            // Advanced Settings
            profile.X264Options = work.AdvancedEncoderOptions;

            // Subtitles
            job.Subtitles = new Subtitles { SourceSubtitles = new List<SourceSubtitle>(), SrtSubtitles = new List<SrtSubtitle>() };
            foreach (SubtitleTrack track in work.SubtitleTracks)
            {
                if (track.IsSrtSubtitle)
                {
                    job.Subtitles.SrtSubtitles.Add(
                        new SrtSubtitle
                            {
                                CharacterCode = track.SrtCharCode,
                                Default = track.Default,
                                FileName = track.SrtFileName,
                                LanguageCode = track.SrtLang,
                                Offset = track.SrtOffset
                            });
                }
                else
                {
                    if (track.SourceTrack != null)
                    {
                        job.Subtitles.SourceSubtitles.Add(
                            new SourceSubtitle
                                {
                                    BurnedIn = track.Burned,
                                    Default = track.Default,
                                    Forced = track.Forced,
                                    TrackNumber = track.SourceTrack.TrackNumber
                                });
                    }
                }
            }

            return job;
        }
Example #5
0
        /// <summary>
        /// Applies an audio encoding to a native audio encoding base structure.
        /// </summary>
        /// <param name="encoding">The encoding to apply.</param>
        /// <param name="baseStruct">The base native structure.</param>
        /// <param name="outputTrack">The output track number (0-based).</param>
        /// <param name="allocatedMemory">The collection of allocated memory.</param>
        /// <returns>The resulting native audio structure.</returns>
        private hb_audio_s ConvertAudioBack(AudioEncoding encoding, hb_audio_s baseStruct, int outputTrack, List<IntPtr> allocatedMemory)
        {
            hb_audio_s nativeAudio = baseStruct;

            nativeAudio.config.output.track = outputTrack;

            if (encoding.Encoder == AudioEncoder.Passthrough)
            {
                // If we've been given a general "Passthrough" codec, see if it's valid for this input track.
                uint audioCodec = baseStruct.config.input.codec & NativeConstants.HB_ACODEC_PASS_MASK;
                if (audioCodec > 0)
                {
                    // We can do passthrough for this input.
                    //nativeAudio.config.output.codec = NativeConstants.HB_ACODEC_PASS_MASK | NativeConstants.HB_ACODEC_PASS_FLAG;
                    nativeAudio.config.output.codec = audioCodec | NativeConstants.HB_ACODEC_PASS_FLAG;
                }
                else
                {
                    // We can't do passthrough for this input. Set it to a DTS passthrough, which will cause the track to be dropped.
                    nativeAudio.config.output.codec = NativeConstants.HB_ACODEC_DCA_PASS;
                }
            }
            else
            {
                nativeAudio.config.output.codec = Converters.AudioEncoderToNative(encoding.Encoder);
            }

            if (!Utilities.IsPassthrough(encoding.Encoder))
            {
                nativeAudio.config.output.bitrate = encoding.Bitrate;
                nativeAudio.config.output.dynamic_range_compression = encoding.Drc;
                nativeAudio.config.output.gain = encoding.Gain;

                if (encoding.Mixdown == Mixdown.Auto)
                {
                    nativeAudio.config.output.mixdown = HBFunctions.hb_get_default_mixdown(nativeAudio.config.output.codec, nativeAudio.config.input.channel_layout);
                }
                else
                {
                    nativeAudio.config.output.mixdown = Converters.MixdownToNative(encoding.Mixdown);
                }

                if (encoding.SampleRateRaw == 0)
                {
                    nativeAudio.config.output.samplerate = nativeAudio.config.input.samplerate;
                }
                else
                {
                    nativeAudio.config.output.samplerate = encoding.SampleRateRaw;
                }
            }

            if (!string.IsNullOrEmpty(encoding.Name))
            {
                IntPtr encodingNamePtr = Marshal.StringToHGlobalAnsi(encoding.Name);
                nativeAudio.config.output.name = encodingNamePtr;
                allocatedMemory.Add(encodingNamePtr);
            }

            nativeAudio.padding = new byte[MarshalingConstants.AudioPaddingBytes];

            return nativeAudio;
        }
        /// <summary>
        /// Applies an audio encoding to a native audio encoding base structure.
        /// </summary>
        /// <param name="encoding">The encoding to apply.</param>
        /// <param name="baseStruct">The base native structure.</param>
        /// <param name="outputTrack">The output track number (0-based).</param>
        /// <param name="allocatedMemory">The collection of allocated memory.</param>
        /// <returns>The resulting native audio structure.</returns>
        private hb_audio_s ConvertAudioBack(AudioEncoding encoding, hb_audio_s baseStruct, int outputTrack, List<IntPtr> allocatedMemory)
        {
            hb_audio_s nativeAudio = baseStruct;
            HBAudioEncoder encoder = Encoders.GetAudioEncoder(encoding.Encoder);

            if (encoder == null)
            {
                throw new InvalidOperationException("Could not find audio encoder " + encoding.Name);
            }

            bool isPassthrough = encoder.IsPassthrough;

            HBAudioEncoder inputCodec = Encoders.GetAudioEncoder((int)baseStruct.config.input.codec);

            uint outputCodec = (uint)encoder.Id;
            if (encoding.PassthroughIfPossible &&
                (encoder.Id == baseStruct.config.input.codec ||
                    inputCodec != null && (inputCodec.ShortName.ToLowerInvariant().Contains("aac") && encoder.ShortName.ToLowerInvariant().Contains("aac") ||
                    inputCodec.ShortName.ToLowerInvariant().Contains("mp3") && encoder.ShortName.ToLowerInvariant().Contains("mp3"))) &&
                (inputCodec.Id & NativeConstants.HB_ACODEC_PASS_MASK) > 0)
            {
                outputCodec = baseStruct.config.input.codec | NativeConstants.HB_ACODEC_PASS_FLAG;
                isPassthrough = true;
            }

            nativeAudio.config.output.track = outputTrack;
            nativeAudio.config.output.codec = outputCodec;
            nativeAudio.config.output.compression_level = -1;
            nativeAudio.config.output.samplerate = nativeAudio.config.input.samplerate;
            nativeAudio.config.output.dither_method = -1;

            if (!isPassthrough)
            {
                if (encoding.SampleRateRaw != 0)
                {
                    nativeAudio.config.output.samplerate = encoding.SampleRateRaw;
                }

                HBMixdown mixdown = Encoders.GetMixdown(encoding.Mixdown);
                nativeAudio.config.output.mixdown = mixdown.Id;

                if (encoding.EncodeRateType == AudioEncodeRateType.Bitrate)
                {
                    // Disable quality targeting.
                    nativeAudio.config.output.quality = -3;

                    if (encoding.Bitrate == 0)
                    {
                        // Bitrate of 0 means auto: choose the default for this codec, sample rate and mixdown.
                        nativeAudio.config.output.bitrate = HBFunctions.hb_audio_bitrate_get_default(
                            nativeAudio.config.output.codec,
                            nativeAudio.config.output.samplerate,
                            nativeAudio.config.output.mixdown);
                    }
                    else
                    {
                        nativeAudio.config.output.bitrate = encoding.Bitrate;
                    }
                }
                else if (encoding.EncodeRateType == AudioEncodeRateType.Quality)
                {
                    // Bitrate of -1 signals quality targeting.
                    nativeAudio.config.output.bitrate = -1;
                    nativeAudio.config.output.quality = encoding.Quality;
                }

                // If this encoder supports compression level, pass it in.
                if (encoder.SupportsCompression)
                {
                    nativeAudio.config.output.compression_level = encoding.Compression;
                }

                nativeAudio.config.output.dynamic_range_compression = encoding.Drc;
                nativeAudio.config.output.gain = encoding.Gain;
            }

            if (!string.IsNullOrEmpty(encoding.Name))
            {
                IntPtr encodingNamePtr = Marshal.StringToHGlobalAnsi(encoding.Name);
                nativeAudio.config.output.name = encodingNamePtr;
                allocatedMemory.Add(encodingNamePtr);
            }

            if (nativeAudio.padding == null)
            {
                nativeAudio.padding = new byte[MarshalingConstants.AudioPaddingBytes];
            }

            return nativeAudio;
        }
        /*
         * TODO: This conversion class needs to be finished off before libencode will work.
         */
        /// <summary>
        /// Get an EncodeJob model for a LibHB Encode.
        /// </summary>
        /// <param name="task">
        /// The task.
        /// </param>
        /// <returns>
        /// An Interop.EncodeJob model.
        /// </returns>
        public static EncodeJob GetEncodeJob(QueueTask task)
        {
            // Sanity Checking
            if (task == null || task.Task == null)
            {
                return null;
            }

            // The current Job Configuration
            EncodeTask work = task.Task;

            // Which will be converted to this EncodeJob Model.
            EncodeJob job = new EncodeJob();
            EncodingProfile profile = new EncodingProfile();
            job.EncodingProfile = profile;

            switch (work.Anamorphic)
            {
                case Model.Encoding.Anamorphic.Custom:
                    profile.Anamorphic = Interop.Model.Encoding.Anamorphic.Custom;
                    break;
                case Model.Encoding.Anamorphic.Strict:
                    profile.Anamorphic = Interop.Model.Encoding.Anamorphic.Strict;
                    break;
                case Model.Encoding.Anamorphic.Loose:
                    profile.Anamorphic = Interop.Model.Encoding.Anamorphic.Loose;
                    break;
                case Model.Encoding.Anamorphic.None:
                    profile.Anamorphic = Interop.Model.Encoding.Anamorphic.None;
                    break;
            }

            profile.AudioEncodings = new List<AudioEncoding>();
            foreach (AudioTrack track in work.AudioTracks)
            {
                AudioEncoding newTrack = new AudioEncoding
                    {
                        Bitrate = track.Bitrate,
                        Drc = track.DRC,
                        Gain = track.Gain,
                        //Encoder = track.Encoder,
                        // InputNumber = track.Track,
                        //Mixdown = track.MixDown,
                        //SampleRateRaw = track.SampleRate
                    };

                profile.AudioEncodings.Add(newTrack);
            }

            profile.Cropping = new HandBrake.Interop.Model.Cropping
                {
                    Top = work.Cropping.Top,
                    Bottom = work.Cropping.Bottom,
                    Left = work.Cropping.Left,
                    Right = work.Cropping.Right
                };

            profile.CustomCropping = true;
            profile.CustomDecomb = work.CustomDecomb;
            profile.CustomDeinterlace = work.CustomDeinterlace;
            profile.CustomDenoise = work.CustomDenoise;
            profile.CustomDetelecine = work.CustomDetelecine;
            profile.Deblock = work.Deblock;
            profile.Decomb = work.Decomb;
            profile.Deinterlace = work.Deinterlace;
            profile.Denoise = work.Denoise;
            profile.Detelecine = work.Detelecine;
            profile.DisplayWidth = work.DisplayWidth.HasValue
                                       ? int.Parse(Math.Round(work.DisplayWidth.Value, 0).ToString())
                                       : 0;
            profile.Framerate = work.Framerate.HasValue ? work.Framerate.Value : 0;
            profile.Grayscale = work.Grayscale;
            profile.Height = work.Height.HasValue ? work.Height.Value : 0;
            profile.IPod5GSupport = work.IPod5GSupport;
            profile.IncludeChapterMarkers = work.IncludeChapterMarkers;
            profile.KeepDisplayAspect = work.KeepDisplayAspect;
            profile.LargeFile = work.LargeFile;
            profile.MaxHeight = work.MaxHeight.HasValue ? work.MaxHeight.Value : 0;
            profile.MaxWidth = work.MaxWidth.HasValue ? work.MaxWidth.Value : 0;
            profile.Modulus = work.Modulus.HasValue ? work.Modulus.Value : 16;
            profile.Optimize = work.OptimizeMP4;
            switch (work.OutputFormat)
            {
                case OutputFormat.Mp4:
                case OutputFormat.M4V:
                    profile.OutputFormat = Interop.Model.Encoding.OutputFormat.Mp4;
                    break;
                case OutputFormat.Mkv:
                    profile.OutputFormat = Interop.Model.Encoding.OutputFormat.Mkv;
                    break;
            }
            profile.PeakFramerate = work.FramerateMode == FramerateMode.PFR;
            profile.PixelAspectX = work.PixelAspectX;
            profile.PixelAspectY = work.PixelAspectY;

            switch (work.OutputFormat)
            {
                case OutputFormat.Mp4:
                    profile.PreferredExtension = Interop.Model.Encoding.OutputExtension.Mp4;
                    break;
                case OutputFormat.M4V:
                    profile.PreferredExtension = Interop.Model.Encoding.OutputExtension.M4v;
                    break;
            }
            profile.Quality = work.Quality.HasValue ? work.Quality.Value : 0;
            profile.UseDisplayWidth = true;
            profile.VideoBitrate = work.VideoBitrate.HasValue ? work.VideoBitrate.Value : 0;
            profile.VideoEncodeRateType = work.VideoEncodeRateType;

            switch (work.VideoEncoder)
            {
                case VideoEncoder.X264:
                    profile.VideoEncoder = Interop.Model.Encoding.VideoEncoder.X264;
                    break;
                case VideoEncoder.FFMpeg:
                    profile.VideoEncoder = Interop.Model.Encoding.VideoEncoder.FFMpeg;
                    break;
                case VideoEncoder.FFMpeg2:
                    profile.VideoEncoder = Interop.Model.Encoding.VideoEncoder.FFMpeg; // TODO Fix This.
                    break;
                case VideoEncoder.Theora:
                    profile.VideoEncoder = Interop.Model.Encoding.VideoEncoder.Theora;
                    break;

            }

            profile.Width = work.Width.HasValue ? work.Width.Value : 0;
            profile.X264Options = work.AdvancedEncoderOptions;

            if (work.PointToPointMode == PointToPointMode.Chapters)
            {
                job.ChapterStart = work.StartPoint;
                job.ChapterEnd = work.EndPoint;
            }

            job.Angle = work.Angle;
            job.EncodingProfile = profile;
            if (work.PointToPointMode == PointToPointMode.Frames)
            {
                job.FramesEnd = work.EndPoint;
                job.FramesStart = work.StartPoint;
            }

            job.OutputPath = work.Destination;
            switch (work.PointToPointMode)
            {
                case PointToPointMode.Chapters:
                    job.RangeType = VideoRangeType.Chapters;
                    break;
                case PointToPointMode.Seconds:
                    job.RangeType = VideoRangeType.Seconds;
                    break;
                case PointToPointMode.Frames:
                    job.RangeType = VideoRangeType.Frames;
                    break;
            }

            if (work.PointToPointMode == PointToPointMode.Seconds)
            {
                job.SecondsEnd = work.EndPoint;
                job.SecondsStart = work.StartPoint;
            }

            job.SourcePath = work.Source;
            // job.SourceType = work.Type;
            job.Title = work.Title;
            job.Subtitles = new Subtitles { SourceSubtitles = new List<SourceSubtitle>(), SrtSubtitles = new List<SrtSubtitle>() };
            foreach (SubtitleTrack track in work.SubtitleTracks)
            {
                // TODO
            }

            return job;
        }
Example #8
0
        /// <summary>
        /// Applies an audio encoding to a native audio encoding base structure.
        /// </summary>
        /// <param name="encoding">The encoding to apply.</param>
        /// <param name="baseStruct">The base native structure.</param>
        /// <param name="outputTrack">The output track number (0-based).</param>
        /// <param name="allocatedMemory">The collection of allocated memory.</param>
        /// <returns>The resulting native audio structure.</returns>
        private hb_audio_s ConvertAudioBack(AudioEncoding encoding, hb_audio_s baseStruct, int outputTrack, List<IntPtr> allocatedMemory)
        {
            hb_audio_s nativeAudio = baseStruct;

            nativeAudio.config.output.track = outputTrack;
            nativeAudio.config.output.codec = Converters.AudioEncoderToNative(encoding.Encoder);

            if (!Utilities.IsPassthrough(encoding.Encoder))
            {
                nativeAudio.config.output.bitrate = encoding.Bitrate;
                nativeAudio.config.output.dynamic_range_compression = encoding.Drc;
                nativeAudio.config.output.gain = encoding.Gain;

                if (encoding.Mixdown == Mixdown.Auto)
                {
                    nativeAudio.config.output.mixdown = HBFunctions.hb_get_default_mixdown(nativeAudio.config.output.codec, nativeAudio.config.input.channel_layout);
                }
                else
                {
                    nativeAudio.config.output.mixdown = Converters.MixdownToNative(encoding.Mixdown);
                }

                if (encoding.SampleRateRaw == 0)
                {
                    nativeAudio.config.output.samplerate = nativeAudio.config.input.samplerate;
                }
                else
                {
                    nativeAudio.config.output.samplerate = encoding.SampleRateRaw;
                }
            }

            if (!string.IsNullOrEmpty(encoding.Name))
            {
                IntPtr encodingNamePtr = Marshal.StringToHGlobalAnsi(encoding.Name);
                nativeAudio.config.output.name = encodingNamePtr;
                allocatedMemory.Add(encodingNamePtr);
            }

            nativeAudio.padding = new byte[MarshalingConstants.AudioPaddingBytes];

            return nativeAudio;
        }