diff --git a/FFmpeg.AutoGen.Abstractions/generated/Enums.g.cs b/FFmpeg.AutoGen.Abstractions/generated/Enums.g.cs index 4135fd8f..c273265d 100644 --- a/FFmpeg.AutoGen.Abstractions/generated/Enums.g.cs +++ b/FFmpeg.AutoGen.Abstractions/generated/Enums.g.cs @@ -1,3 +1,5 @@ +using System; + namespace FFmpeg.AutoGen.Abstractions; public enum AVActiveFormatDescription : int @@ -1051,10 +1053,11 @@ public enum AVFormatCommandID : int } /// Flags for frame cropping. +[Flags] public enum AvFrameCrop : int { /// Apply the maximum possible cropping, even if it requires setting the AVFrame.data[] entries to unaligned pointers. Passing unaligned data to FFmpeg API is generally not allowed, and causes undefined behavior (such as crashes). You can pass unaligned data only to FFmpeg APIs that are explicitly documented to accept it. Use this flag only if you absolutely know what you are doing. - @AV_FRAME_CROP_UNALIGNED = 1, + @AV_FRAME_CROP_UNALIGNED = 1 << 0, } /// @{ AVFrame is an abstraction for reference-counted raw multimedia data. @@ -1153,16 +1156,17 @@ public enum AVHWDeviceType : int } /// Flags to apply to frame mappings. +[Flags] public enum AvHwframeMap : int { /// The mapping must be readable. - @AV_HWFRAME_MAP_READ = 1, + @AV_HWFRAME_MAP_READ = 1 << 0, /// The mapping must be writeable. - @AV_HWFRAME_MAP_WRITE = 2, + @AV_HWFRAME_MAP_WRITE = 1 << 1, /// The mapped frame will be overwritten completely in subsequent operations, so the current frame data need not be loaded. Any values which are not overwritten are unspecified. - @AV_HWFRAME_MAP_OVERWRITE = 4, + @AV_HWFRAME_MAP_OVERWRITE = 1 << 2, /// The mapping must be direct. That is, there must not be any copying in the map or unmap steps. Note that performance of direct mappings may be much lower than normal memory. - @AV_HWFRAME_MAP_DIRECT = 8, + @AV_HWFRAME_MAP_DIRECT = 1 << 3, } public enum AVHWFrameTransferDirection : int @@ -2069,14 +2073,15 @@ public enum AVTimebaseSource : int @AVFMT_TBCF_R_FRAMERATE = 2, } +[Flags] public enum AVTimecodeFlag : int { /// timecode is drop frame - @AV_TIMECODE_FLAG_DROPFRAME = 1, + @AV_TIMECODE_FLAG_DROPFRAME = 1 << 0, /// timecode wraps after 24 hours - @AV_TIMECODE_FLAG_24HOURSMAX = 2, + @AV_TIMECODE_FLAG_24HOURSMAX = 1 << 1, /// negative time values are allowed - @AV_TIMECODE_FLAG_ALLOWNEGATIVE = 4, + @AV_TIMECODE_FLAG_ALLOWNEGATIVE = 1 << 2, } /// Dithering algorithms @@ -2143,48 +2148,49 @@ public enum SwsDither : int @SWS_DITHER_MAX_ENUM = 2147483647, } +[Flags] public enum SwsFlags : int { /// fast bilinear filtering - @SWS_FAST_BILINEAR = 1, + @SWS_FAST_BILINEAR = 1 << 0, /// bilinear filtering - @SWS_BILINEAR = 2, + @SWS_BILINEAR = 1 << 1, /// 2-tap cubic B-spline - @SWS_BICUBIC = 4, + @SWS_BICUBIC = 1 << 2, /// experimental - @SWS_X = 8, + @SWS_X = 1 << 3, /// nearest neighbor - @SWS_POINT = 16, + @SWS_POINT = 1 << 4, /// area averaging - @SWS_AREA = 32, + @SWS_AREA = 1 << 5, /// bicubic luma, bilinear chroma - @SWS_BICUBLIN = 64, + @SWS_BICUBLIN = 1 << 6, /// gaussian approximation - @SWS_GAUSS = 128, + @SWS_GAUSS = 1 << 7, /// unwindowed sinc - @SWS_SINC = 256, + @SWS_SINC = 1 << 8, /// 3-tap sinc/sinc - @SWS_LANCZOS = 512, + @SWS_LANCZOS = 1 << 9, /// cubic Keys spline - @SWS_SPLINE = 1024, + @SWS_SPLINE = 1 << 10, /// Return an error on underspecified conversions. Without this flag, unspecified fields are defaulted to sensible values. - @SWS_STRICT = 2048, + @SWS_STRICT = 1 << 11, /// Emit verbose log of scaling parameters. - @SWS_PRINT_INFO = 4096, + @SWS_PRINT_INFO = 1 << 12, /// Perform full chroma upsampling when upscaling to RGB. - @SWS_FULL_CHR_H_INT = 8192, + @SWS_FULL_CHR_H_INT = 1 << 13, /// Perform full chroma interpolation when downscaling RGB sources. - @SWS_FULL_CHR_H_INP = 16384, + @SWS_FULL_CHR_H_INP = 1 << 14, /// Force bit-exact output. This will prevent the use of platform-specific optimizations that may lead to slight difference in rounding, in favor of always maintaining exact bit output compatibility with the reference C code. - @SWS_ACCURATE_RND = 262144, + @SWS_ACCURATE_RND = 1 << 18, /// Force bit-exact output. This will prevent the use of platform-specific optimizations that may lead to slight difference in rounding, in favor of always maintaining exact bit output compatibility with the reference C code. - @SWS_BITEXACT = 524288, + @SWS_BITEXACT = 1 << 19, /// Allow using experimental new code paths. This may be faster, slower, or produce different output, with semantics subject to change at any point in time. For testing and debugging purposes only. - @SWS_UNSTABLE = 1048576, + @SWS_UNSTABLE = 1 << 20, /// This flag has no effect - @SWS_DIRECT_BGR = 32768, + @SWS_DIRECT_BGR = 1 << 15, /// Set `SwsContext.dither` instead - @SWS_ERROR_DIFFUSION = 8388608, + @SWS_ERROR_DIFFUSION = 1 << 23, } public enum SwsIntent : int diff --git a/FFmpeg.AutoGen.CppSharpUnsafeGenerator/Generation/EnumsGenerator.cs b/FFmpeg.AutoGen.CppSharpUnsafeGenerator/Generation/EnumsGenerator.cs index 08590874..d6f8722b 100644 --- a/FFmpeg.AutoGen.CppSharpUnsafeGenerator/Generation/EnumsGenerator.cs +++ b/FFmpeg.AutoGen.CppSharpUnsafeGenerator/Generation/EnumsGenerator.cs @@ -1,4 +1,6 @@ -using FFmpeg.AutoGen.CppSharpUnsafeGenerator.Definitions; +using System.Collections.Generic; +using System.Linq; +using FFmpeg.AutoGen.CppSharpUnsafeGenerator.Definitions; namespace FFmpeg.AutoGen.CppSharpUnsafeGenerator.Generation; @@ -8,6 +10,11 @@ public EnumsGenerator(string path, GenerationContext context) : base(path, conte { } + public override IEnumerable Usings() + { + yield return "System"; + } + public static void Generate(string path, GenerationContext context) { using var g = new EnumsGenerator(path, context); @@ -18,6 +25,12 @@ protected override void GenerateDefinition(EnumerationDefinition @enum) { this.WriteSummary(@enum); this.WriteObsoletion(@enum); + + // if every item in the enum is in the form 1 << n, then we will treat it + // as a flags enum + if (@enum.Items.All(test => test.Value.Contains("<<"))) + WriteLine("[Flags]"); + WriteLine($"public enum {@enum.Name} : {@enum.TypeName}"); using (BeginBlock()) diff --git a/FFmpeg.AutoGen.CppSharpUnsafeGenerator/Processing/EnumerationProcessor.cs b/FFmpeg.AutoGen.CppSharpUnsafeGenerator/Processing/EnumerationProcessor.cs index 315a70a6..c9754e46 100644 --- a/FFmpeg.AutoGen.CppSharpUnsafeGenerator/Processing/EnumerationProcessor.cs +++ b/FFmpeg.AutoGen.CppSharpUnsafeGenerator/Processing/EnumerationProcessor.cs @@ -1,12 +1,13 @@ using System; using System.Linq; +using System.Text.RegularExpressions; using CppSharp.AST; using CppSharp.AST.Extensions; using FFmpeg.AutoGen.CppSharpUnsafeGenerator.Definitions; namespace FFmpeg.AutoGen.CppSharpUnsafeGenerator.Processing; -internal class EnumerationProcessor +internal partial class EnumerationProcessor { private readonly ProcessingContext _context; @@ -81,7 +82,7 @@ public void MakeDefinition(Enumeration enumeration, string name) new EnumerationItem { Name = x.Name, - Value = ConvertValue(x.Value, enumeration.BuiltinType.Type).ToString(), + Value = ConvertValue(x.Expression, x.Value, enumeration.BuiltinType.Type).ToString(), Content = x.Comment?.BriefText }) .ToArray() @@ -90,9 +91,33 @@ public void MakeDefinition(Enumeration enumeration, string name) _context.AddDefinition(definition); } - private static object ConvertValue(ulong value, PrimitiveType primitiveType) + // A regular expression that looks if the expression ends in "= 1 << n" (with any + // number of spaces between the elements. + [GeneratedRegex(@"=\s*1\s*<<\s*(\d+)\s*$")] + private static partial Regex CheckForBitExpression(); + + private static string ConvertValue(string expression, ulong value, PrimitiveType primitiveType) { - return primitiveType switch + // Check if the expression is of the form 1 << n. If it is, preserve the original definition + // instead of collapsing the value. + if (CheckForBitExpression().Match(expression) is { Success: true } match) + { + // Keep it as a 1 << n in the output. We will always + // return it in the form "1 << n" with that exact spacing. + var suffix = primitiveType switch + { + PrimitiveType.Int => "", + PrimitiveType.UInt => "u", + PrimitiveType.Long => "l", + PrimitiveType.ULong => "ul", + _ => throw new NotSupportedException() + }; + + return $"1{suffix} << {match.Groups[1].Value}"; + } + + // Otherwise, fallback on using the compiler's value + object compilerValue = primitiveType switch { PrimitiveType.Int => value > int.MaxValue ? (int)value : value, PrimitiveType.UInt => value, @@ -100,5 +125,6 @@ private static object ConvertValue(ulong value, PrimitiveType primitiveType) PrimitiveType.ULong => value, _ => throw new NotSupportedException() }; + return compilerValue.ToString(); } } diff --git a/FFmpeg.AutoGen/generated/Enums.g.cs b/FFmpeg.AutoGen/generated/Enums.g.cs index 55259abd..962b59c6 100644 --- a/FFmpeg.AutoGen/generated/Enums.g.cs +++ b/FFmpeg.AutoGen/generated/Enums.g.cs @@ -1,3 +1,5 @@ +using System; + namespace FFmpeg.AutoGen; public enum AVActiveFormatDescription : int @@ -1051,10 +1053,11 @@ public enum AVFormatCommandID : int } /// Flags for frame cropping. +[Flags] public enum AvFrameCrop : int { /// Apply the maximum possible cropping, even if it requires setting the AVFrame.data[] entries to unaligned pointers. Passing unaligned data to FFmpeg API is generally not allowed, and causes undefined behavior (such as crashes). You can pass unaligned data only to FFmpeg APIs that are explicitly documented to accept it. Use this flag only if you absolutely know what you are doing. - @AV_FRAME_CROP_UNALIGNED = 1, + @AV_FRAME_CROP_UNALIGNED = 1 << 0, } /// @{ AVFrame is an abstraction for reference-counted raw multimedia data. @@ -1153,16 +1156,17 @@ public enum AVHWDeviceType : int } /// Flags to apply to frame mappings. +[Flags] public enum AvHwframeMap : int { /// The mapping must be readable. - @AV_HWFRAME_MAP_READ = 1, + @AV_HWFRAME_MAP_READ = 1 << 0, /// The mapping must be writeable. - @AV_HWFRAME_MAP_WRITE = 2, + @AV_HWFRAME_MAP_WRITE = 1 << 1, /// The mapped frame will be overwritten completely in subsequent operations, so the current frame data need not be loaded. Any values which are not overwritten are unspecified. - @AV_HWFRAME_MAP_OVERWRITE = 4, + @AV_HWFRAME_MAP_OVERWRITE = 1 << 2, /// The mapping must be direct. That is, there must not be any copying in the map or unmap steps. Note that performance of direct mappings may be much lower than normal memory. - @AV_HWFRAME_MAP_DIRECT = 8, + @AV_HWFRAME_MAP_DIRECT = 1 << 3, } public enum AVHWFrameTransferDirection : int @@ -2069,14 +2073,15 @@ public enum AVTimebaseSource : int @AVFMT_TBCF_R_FRAMERATE = 2, } +[Flags] public enum AVTimecodeFlag : int { /// timecode is drop frame - @AV_TIMECODE_FLAG_DROPFRAME = 1, + @AV_TIMECODE_FLAG_DROPFRAME = 1 << 0, /// timecode wraps after 24 hours - @AV_TIMECODE_FLAG_24HOURSMAX = 2, + @AV_TIMECODE_FLAG_24HOURSMAX = 1 << 1, /// negative time values are allowed - @AV_TIMECODE_FLAG_ALLOWNEGATIVE = 4, + @AV_TIMECODE_FLAG_ALLOWNEGATIVE = 1 << 2, } /// Dithering algorithms @@ -2143,48 +2148,49 @@ public enum SwsDither : int @SWS_DITHER_MAX_ENUM = 2147483647, } +[Flags] public enum SwsFlags : int { /// fast bilinear filtering - @SWS_FAST_BILINEAR = 1, + @SWS_FAST_BILINEAR = 1 << 0, /// bilinear filtering - @SWS_BILINEAR = 2, + @SWS_BILINEAR = 1 << 1, /// 2-tap cubic B-spline - @SWS_BICUBIC = 4, + @SWS_BICUBIC = 1 << 2, /// experimental - @SWS_X = 8, + @SWS_X = 1 << 3, /// nearest neighbor - @SWS_POINT = 16, + @SWS_POINT = 1 << 4, /// area averaging - @SWS_AREA = 32, + @SWS_AREA = 1 << 5, /// bicubic luma, bilinear chroma - @SWS_BICUBLIN = 64, + @SWS_BICUBLIN = 1 << 6, /// gaussian approximation - @SWS_GAUSS = 128, + @SWS_GAUSS = 1 << 7, /// unwindowed sinc - @SWS_SINC = 256, + @SWS_SINC = 1 << 8, /// 3-tap sinc/sinc - @SWS_LANCZOS = 512, + @SWS_LANCZOS = 1 << 9, /// cubic Keys spline - @SWS_SPLINE = 1024, + @SWS_SPLINE = 1 << 10, /// Return an error on underspecified conversions. Without this flag, unspecified fields are defaulted to sensible values. - @SWS_STRICT = 2048, + @SWS_STRICT = 1 << 11, /// Emit verbose log of scaling parameters. - @SWS_PRINT_INFO = 4096, + @SWS_PRINT_INFO = 1 << 12, /// Perform full chroma upsampling when upscaling to RGB. - @SWS_FULL_CHR_H_INT = 8192, + @SWS_FULL_CHR_H_INT = 1 << 13, /// Perform full chroma interpolation when downscaling RGB sources. - @SWS_FULL_CHR_H_INP = 16384, + @SWS_FULL_CHR_H_INP = 1 << 14, /// Force bit-exact output. This will prevent the use of platform-specific optimizations that may lead to slight difference in rounding, in favor of always maintaining exact bit output compatibility with the reference C code. - @SWS_ACCURATE_RND = 262144, + @SWS_ACCURATE_RND = 1 << 18, /// Force bit-exact output. This will prevent the use of platform-specific optimizations that may lead to slight difference in rounding, in favor of always maintaining exact bit output compatibility with the reference C code. - @SWS_BITEXACT = 524288, + @SWS_BITEXACT = 1 << 19, /// Allow using experimental new code paths. This may be faster, slower, or produce different output, with semantics subject to change at any point in time. For testing and debugging purposes only. - @SWS_UNSTABLE = 1048576, + @SWS_UNSTABLE = 1 << 20, /// This flag has no effect - @SWS_DIRECT_BGR = 32768, + @SWS_DIRECT_BGR = 1 << 15, /// Set `SwsContext.dither` instead - @SWS_ERROR_DIFFUSION = 8388608, + @SWS_ERROR_DIFFUSION = 1 << 23, } public enum SwsIntent : int