Спецификация AVI файлов

110
27 мая 2021, 23:20

Есть ли нормальная спецификация формата файлов AVI?

Желательно документированная, т.к. все что мне удалось найти, это некоторые огрызки на сайте майкрософт. А так же не совсем понятный файл, документации в котором явно указано, что это не официальная документация.

Все что мне удалось понять, это то что существует заголовок RIFF, который в себе содержит в хаотичном порядке заголовки LIST, CHUNK, AVIMAIN,и еще несколько.

Из-за отсутствия документации, я так и не смог понять, как можно унифицировать LIST заголовки, т.к. они могу в себя включать как вложенные LIST, CHUNK, и т.д.

Из-за нехватки информации, мне удается считать только RIFF и AVIMAIN

Определенный класс Riff, структура AviMain:

[StructLayout(LayoutKind.Sequential, Size = 4, Pack = 1)]
public struct FourCc
{
    public uint Value { get; private set; }
    public override string ToString()
    {
        return Value != 0 ? Encoding.ASCII.GetString(BitConverter.GetBytes(Value)) : string.Empty;
    }
    public static implicit operator FourCc(uint value)
    {
        return new FourCc
        {
            Value = value
        };
    }
}
[StructLayout(LayoutKind.Sequential, Size = 16)]
public struct Reserved
{
    public uint Reserved0 { get; set; }
    public uint Reserved1 { get; set; }
    public uint Reserved2 { get; set; }
    public uint Reserved3 { get; set; }
}
[StructLayout(LayoutKind.Sequential)]
public struct AviMain
{
    public FourCc Type { get; set; }
    public uint Size { get; set; }
    public uint MicroSecPerFrame { get; set; }
    public uint MaxBytesPerSec { get; set; }
    public uint PaddingGranularity { get; set; }
    public uint Flags { get; set; }
    public uint TotalFrames { get; set; }
    public uint InitialFrames { get; set; }
    public uint Streams { get; set; }
    public uint SuggestedBufferSize { get; set; }
    public uint Width { get; set; }
    public uint Height { get; set; }
    public Reserved Reserved { get; set; }
}
public class AviList
{
    public FourCc Type { get; set; }
    public uint Size { get; set; }
    public byte[] Data { get; set; }
    public T As<T>() where T : unmanaged
    {
        unsafe
        {
            byte[] bytes = Data;
            fixed (void* tPtr = bytes)
            {
                return *(T*) tPtr;
            }
        }
    }
}
public struct AviChunk
{
}
public class Riff
{
    public FourCc Fcc { get; set; }
    public uint FileSize { get; set; }
    public bool IsCorrectSize { get; set; }
    public FourCc FileType { get; set; }
    public IEnumerable<AviList> AviLists { get; set; }
}

Ну и небольшой, не доделанный Stream:

public sealed class AviFileStream : BinaryReader
{
    public AviFileStream(Stream input) : base(input, Encoding.ASCII)
    {
        FourCc fourCcValue = ReadUInt32();
        uint fileSize = ReadUInt32();
        FourCc fileType = ReadUInt32();
        FourCc listOrChunk = ReadUInt32();
        bool isList = string.Equals(listOrChunk.ToString(), "LIST", StringComparison.CurrentCultureIgnoreCase);
        List<AviList> aviLists = new List<AviList>();
        Riff riff = new Riff
        {
            Fcc = fourCcValue,
            FileSize = fileSize,
            IsCorrectSize = BaseStream.Length - fileSize == 8,
            FileType = fileType
        };
        if (isList)
        {
            uint listSize = ReadUInt32();
            unsafe
            {
                int readBytes = 0;
                byte[] bytes = new byte[listSize];
                Read(bytes, 0, bytes.Length);
                fixed (byte* bytesPtr = bytes)
                {
                    while (readBytes < listSize)
                    {
                        uint* dataPtr = (uint*) bytesPtr + readBytes;
                        AviList list = new AviList
                        {
                            Type = *dataPtr,
                            Size = *(dataPtr + 2)
                        };
                        ArraySegment<byte> dataSegment = new ArraySegment<byte>(bytes, 4, (int)list.Size);
                        byte[] dataBytes = dataSegment.ToArray();
                        list.Data = dataBytes;
                        readBytes += dataBytes.Length + 2;
                        aviLists.Add(list);
                    }
                }
            }
        }
        riff.AviLists = aviLists;
        Riff = riff;
        BaseStream.Seek(0, SeekOrigin.Begin);
    }
    public Riff Riff { get; }
}

Дело в том, что при получении размера списка uint listSize = ReadUInt32();, я получаю размер, около 8 КБ, далее читаю это кол-во байт, и пытаюсь вычитать список в цикле, однако, AviMain считывается, но далее, либо идет какой-то мусор, либо я чего-то не до понял.

Если посмотреть на эту страницу, то там вообще показано, что список идет список в списке, и какаим образом определить что идет список в списке, мне не понятно.

READ ALSO
Директивы компилятора для xaml, wpf

Директивы компилятора для xaml, wpf

Расскажите пожалуйста, можно ли добиться возможности использования директив компилятора в xaml, wpfЕсли можно, то как?

194
The chromedriver file does not exist in the current directory or in a directory on the PATH

The chromedriver file does not exist in the current directory or in a directory on the PATH

Формат драйвера, ниже прописал ошыбку ChromeOptions options = new ChromeOptions(); optionsAddUserProfilePreference("profile

247
Macroscop SDK С#, как вставить в меню свой пункт?

Macroscop SDK С#, как вставить в меню свой пункт?

Есть вопрос по Macroscop SDK С#: я пишу плагин-визуализатор, вообще по sdk информации очень мало, и пытаюсь вставить в меню свой пункт, непонятно как...

408
Как получить границы / рамки вокруг диапазона в Excel, используя EPPlus в C #

Как получить границы / рамки вокруг диапазона в Excel, используя EPPlus в C #

Код ниже генерирует границы для всех ячеек в пределах диапазона [2, 2, 5, 11], но я хочу, чтобы все было в рамках, как это сделать?

104