/// <exception cref="DecoderException"></exception>
        public static DecodedVideoScaler Create(DecodedVideoFrameParameters decodedVideoFrameParms, TransformParameters transformParms)
        {
            if (decodedVideoFrameParms == null)
            {
                throw new ArgumentNullException(nameof(decodedVideoFrameParms));
            }
            if (transformParms == null)
            {
                throw new ArgumentNullException(nameof(transformParms));
            }

            int sourceLeft   = 0;
            int sourceTop    = 0;
            int sourceWidth  = decodedVideoFrameParms.Width;
            int sourceHeight = decodedVideoFrameParms.Height;
            int scaledWidth  = decodedVideoFrameParms.Width;
            int scaledHeight = decodedVideoFrameParms.Height;

            if (!transformParms.Region.IsEmpty)
            {
                sourceLeft   = transformParms.Region.Left;
                sourceTop    = transformParms.Region.Top;
                sourceWidth  = transformParms.Region.Width;
                sourceHeight = transformParms.Region.Height;
            }

            if (!transformParms.TargetSize.IsEmpty)
            {
                scaledWidth  = transformParms.TargetSize.Width;
                scaledHeight = transformParms.TargetSize.Height;

                ScalingPolicy scalingPolicy = transformParms.ScalePolicy;

                float srcAspectRatio  = (float)sourceWidth / sourceHeight;
                float destAspectRatio = (float)scaledWidth / scaledHeight;

                if (scalingPolicy == ScalingPolicy.Auto)
                {
                    float relativeChange = Math.Abs(srcAspectRatio - destAspectRatio) / srcAspectRatio;

                    scalingPolicy = relativeChange > MaxAspectRatioError
                        ? ScalingPolicy.RespectAspectRatio
                        : ScalingPolicy.Stretch;
                }

                if (scalingPolicy == ScalingPolicy.RespectAspectRatio)
                {
                    if (destAspectRatio < srcAspectRatio)
                    {
                        scaledHeight = sourceHeight * scaledWidth / sourceWidth;
                    }
                    else
                    {
                        scaledWidth = sourceWidth * scaledHeight / sourceHeight;
                    }
                }
            }

            FFmpegPixelFormat    pixelFormat  = ToFFmpegPixelFormat(transformParms.PixelFormat);
            FFmpegScalingQuality scaleQuality = ToFFmpegScaleQuality(transformParms.ScaleQuality);

            int resultCode = FFmpegVideoPInvoke.CreateVideoScaler
                             (
                sourceLeft, sourceTop, sourceWidth, sourceHeight,
                decodedVideoFrameParms.PixelFormat,
                scaledWidth, scaledHeight,
                pixelFormat, scaleQuality,
                out var handle
                             );

            if (resultCode != 0)
            {
                throw new DecoderException(@"An error occurred while creating scaler, code: {resultCode}");
            }

            return(new DecodedVideoScaler(handle, scaledWidth, scaledHeight, transformParms.PixelFormat));
        }