Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BlockElement and SimpleBlockElement back #6

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions SpawnDev.EBML/EBMLParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public IEnumerable<Document> ParseDocuments(Stream stream)
{
stream.Position = startPos;
var doc = new Document(this, stream);
if (doc.Data.Count() == 0)
if (!doc.Data.Any())
{
yield break;
}
Expand All @@ -92,7 +92,7 @@ public IEnumerable<Document> ParseDocuments(Stream stream)
{
stream.Position = startPos;
var doc = new Document(this, stream);
if (doc.Data.Count() == 0)
if (!doc.Data.Any())
{
break;
}
Expand Down Expand Up @@ -133,6 +133,8 @@ public IEnumerable<Document> ParseDocuments(Stream stream)
case UTF8Element.TypeName: return typeof(UTF8Element);
case BinaryElement.TypeName: return typeof(BinaryElement);
case DateElement.TypeName: return typeof(DateElement);
case BlockElement.TypeName: return typeof(BlockElement);
case SimpleBlockElement.TypeName: return typeof(SimpleBlockElement);
default: return null;
}
}
Expand Down
5 changes: 2 additions & 3 deletions SpawnDev.EBML/Elements/BaseElement.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using SpawnDev.EBML.Extensions;
using SpawnDev.EBML.Segments;
using System.Collections;
using SpawnDev.EBML.Segments;
using SpawnDev.EBML.Extensions;

namespace SpawnDev.EBML.Elements
{
Expand Down
68 changes: 68 additions & 0 deletions SpawnDev.EBML/Elements/BlockElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using SpawnDev.EBML.Extensions;
using SpawnDev.EBML.Segments;

namespace SpawnDev.EBML.Elements
{
public enum BlockLacing : byte
{
None = 0,
Xiph,
Fixed,
EBML,
}

public class BlockElement : BaseElement<byte[]>
{
public const string TypeName = "mkvBlock";

protected override bool EqualCheck(byte[] obj1, byte[] obj2) => obj1 == obj2 || obj1.SequenceEqual(obj2);

public BlockElement(SchemaElement schemaElement, SegmentSource source, ElementHeader? header = null) : base(schemaElement, source, header) { }
public BlockElement(SchemaElement schemaElement, byte[] value) : base(schemaElement, value) { }
public BlockElement(SchemaElement schemaElement) : base(schemaElement, Array.Empty<byte>()) { }


// Binary audio/video data
private SegmentSource? BlockData = null;

private ulong _TrackId { get; set; }
public ulong TrackId
{
get => _TrackId;
set => _TrackId = value;
}
private short _Timecode { get; set; }
public short Timecode
{
get => _Timecode;
set => _Timecode = value;
}
private byte _Flags { get; set; }
public byte Flags
{
get => _Flags;
set => _Flags = value;
}

public bool Invisible => (Flags & 8) != 0;
public BlockLacing Lacing => (BlockLacing)((Flags >> 1) & 3);

protected override void DataFromSegmentSource(ref byte[] data)
{
SegmentSource.Position = 0;
_TrackId = SegmentSource.ReadEBMLVINT();
_Timecode = BigEndian.ToInt16(SegmentSource.ReadBytes(2));
_Flags = SegmentSource.ReadByteOrThrow();
BlockData = SegmentSource.Slice(SegmentSource.Length - SegmentSource.Position);
}

protected override void DataToSegmentSource(ref SegmentSource source)
{
BlockData!.Position = 0;
source.Write(EBMLConverter.ToVINTBytes(TrackId));
source.Write(BigEndian.GetBytes(Timecode));
source.WriteByte(Flags);
BlockData!.CopyTo(source, 100 * 1024);
}
}
}
22 changes: 22 additions & 0 deletions SpawnDev.EBML/Elements/MasterElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,22 @@ public IEnumerable<MasterElement> AddMissingContainers()
AddElement(element);
return element;
}
public BlockElement? AddBlock(string name, byte[] data)
{
var schemaElement = SchemaSet.GetElement(name, DocType);
if (schemaElement == null || schemaElement.Type != BlockElement.TypeName) throw new Exception("Invalid element type");
var element = new BlockElement(schemaElement, data);
AddElement(element);
return element;
}
public BlockElement? AddSimpleBlock(string name, byte[] data)
{
var schemaElement = SchemaSet.GetElement(name, DocType);
if (schemaElement == null || schemaElement.Type != SimpleBlockElement.TypeName) throw new Exception("Invalid element type");
var element = new SimpleBlockElement(schemaElement, data);
AddElement(element);
return element;
}
public TElement AddElement<TElement>(SchemaElement elementSchema) where TElement : BaseElement
{
var element = Create<TElement>(elementSchema);
Expand Down Expand Up @@ -470,6 +486,8 @@ protected override void DataFromSegmentSource(ref IEnumerable<BaseElement> _data
UTF8Element.TypeName => new UTF8Element(schemaElement, source, header),
BinaryElement.TypeName => new BinaryElement(schemaElement, source, header),
DateElement.TypeName => new DateElement(schemaElement, source, header),
BlockElement.TypeName => new BlockElement(schemaElement, source, header),
SimpleBlockElement.TypeName => new SimpleBlockElement(schemaElement, source, header),
_ => null
};
return ret;
Expand All @@ -490,6 +508,8 @@ protected override void DataFromSegmentSource(ref IEnumerable<BaseElement> _data
UTF8Element.TypeName => new UTF8Element(schemaElement),
BinaryElement.TypeName => new BinaryElement(schemaElement),
DateElement.TypeName => new DateElement(schemaElement),
BlockElement.TypeName => new BlockElement(schemaElement),
SimpleBlockElement.TypeName => new SimpleBlockElement(schemaElement),
_ => null
};
return (TElement?)ret;
Expand All @@ -509,6 +529,8 @@ protected override void DataFromSegmentSource(ref IEnumerable<BaseElement> _data
UTF8Element.TypeName => new UTF8Element(schemaElement),
BinaryElement.TypeName => new BinaryElement(schemaElement),
DateElement.TypeName => new DateElement(schemaElement),
BlockElement.TypeName => new BlockElement(schemaElement),
SimpleBlockElement.TypeName => new SimpleBlockElement(schemaElement),
_ => null
};
return ret;
Expand Down
16 changes: 16 additions & 0 deletions SpawnDev.EBML/Elements/SimpleBlockElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using SpawnDev.EBML.Segments;

namespace SpawnDev.EBML.Elements
{
public class SimpleBlockElement : BlockElement
{
public const string TypeName = "mkvSimpleBlock";

public SimpleBlockElement(SchemaElement schemaElement, SegmentSource source, ElementHeader? header = null) : base(schemaElement, source, header) { }
public SimpleBlockElement(SchemaElement schemaElement, byte[] value) : base(schemaElement, value) { }
public SimpleBlockElement(SchemaElement schemaElement) : base(schemaElement, Array.Empty<byte>()) { }

public bool Keyframe => (Flags & 128) != 0;
public bool Discardable => (Flags & 1) != 0;
}
}
4 changes: 2 additions & 2 deletions SpawnDev.EBML/Schemas/ebml_matroska.xml
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ It might help to resynchronize the offset on damaged streams.</documentation>
<extension type="libmatroska" cppname="ClusterPrevSize"/>
<extension type="webmproject.org" webm="1"/>
</element>
<element name="SimpleBlock" path="\Segment\Cluster\SimpleBlock" id="0xA3" type="binary" minver="2">
<element name="SimpleBlock" path="\Segment\Cluster\SimpleBlock" id="0xA3" type="mkvSimpleBlock" minver="2">
<documentation lang="en" purpose="definition">Similar to `Block` (see (#block-structure)) but without all the extra information.
Mostly used to reduce overhead when no extra feature is needed; see (#simpleblock-structure) on `SimpleBlock` Structure.</documentation>
<extension type="webmproject.org" webm="1"/>
Expand All @@ -159,7 +159,7 @@ Mostly used to reduce overhead when no extra feature is needed; see (#simplebloc
<documentation lang="en" purpose="definition">Basic container of information containing a single `Block` and information specific to that `Block`.</documentation>
<extension type="webmproject.org" webm="1"/>
</element>
<element name="Block" path="\Segment\Cluster\BlockGroup\Block" id="0xA1" type="binary" minOccurs="1" maxOccurs="1">
<element name="Block" path="\Segment\Cluster\BlockGroup\Block" id="0xA1" type="mkvBlock" minOccurs="1" maxOccurs="1">
<documentation lang="en" purpose="definition">`Block` containing the actual data to be rendered and a timestamp relative to the `Cluster` Timestamp;
see (#block-structure) on `Block` Structure.</documentation>
<extension type="webmproject.org" webm="1"/>
Expand Down
4 changes: 2 additions & 2 deletions SpawnDev.EBML/Schemas/ebml_webm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ It might help to resynchronize the offset on damaged streams.</documentation>
<extension type="libmatroska" cppname="ClusterPrevSize"/>
<extension type="webmproject.org" webm="1"/>
</element>
<element name="SimpleBlock" path="\Segment\Cluster\SimpleBlock" id="0xA3" type="binary" minver="2">
<element name="SimpleBlock" path="\Segment\Cluster\SimpleBlock" id="0xA3" type="mkvSimpleBlock" minver="2">
<documentation lang="en" purpose="definition">Similar to `Block` (see (#block-structure)) but without all the extra information.
Mostly used to reduce overhead when no extra feature is needed; see (#simpleblock-structure) on `SimpleBlock` Structure.</documentation>
<extension type="webmproject.org" webm="1"/>
Expand All @@ -159,7 +159,7 @@ Mostly used to reduce overhead when no extra feature is needed; see (#simplebloc
<documentation lang="en" purpose="definition">Basic container of information containing a single `Block` and information specific to that `Block`.</documentation>
<extension type="webmproject.org" webm="1"/>
</element>
<element name="Block" path="\Segment\Cluster\BlockGroup\Block" id="0xA1" type="binary" minOccurs="1" maxOccurs="1">
<element name="Block" path="\Segment\Cluster\BlockGroup\Block" id="0xA1" type="mkvBlock" minOccurs="1" maxOccurs="1">
<documentation lang="en" purpose="definition">`Block` containing the actual data to be rendered and a timestamp relative to the `Cluster` Timestamp;
see (#block-structure) on `Block` Structure.</documentation>
<extension type="webmproject.org" webm="1"/>
Expand Down