data Header {
byte signature[4]
int2 version
int2 headerLength
byte fourcc[4]
int2 width
int2 height
int4 numerator
int4 denominator
int4 frameCount
int4 unused
}
data FrameHeader {
int4 frameSize
int8 timestamp
}
data Int2 {
int2 value
}
data Int4 {
int4 value
}
const byte SIG[] = "DKIF"
component provides VideoFile:divf requires io.Output out, data.IntUtil iu {
bool VideoFile:validHeader(byte content[])
{
Header hdr = new Header()
dana.serial(hdr) =[] content
if (hdr.signature != SIG)
return false
if (hdr.version != 0)
return false
return true
}
byte[] endianSwap(byte bytes[])
{
byte result[] = new byte[bytes.arrayLength]
int rindex = result.arrayLength - 1
for (int i = 0; i < result.arrayLength; i++)
{
result[rindex - i] = bytes[i]
}
return result
}
int4 endianSwapI4(int4 v)
{
Int4 val = new Int4(v)
byte valStream[] = dana.serial(val)
valStream =[] endianSwap(valStream)
return val.value
}
int2 endianSwapI2(int2 v)
{
Int2 val = new Int2(v)
byte valStream[] = dana.serial(val)
valStream =[] endianSwap(valStream)
return val.value
}
VideoHeader VideoFile:readHeader(byte content[])
{
if (!validHeader(content))
{
throw new Exception("invalid IVF video format header")
}
Header hdr = new Header()
dana.serial(hdr) =[] content
VideoHeader vh = new VideoHeader()
vh.width = endianSwapI2(hdr.width)
vh.height = endianSwapI2(hdr.height)
vh.numerator = endianSwapI4(hdr.numerator)
vh.denominator = endianSwapI4(hdr.denominator)
vh.frames = endianSwapI4(hdr.frameCount)
vh.fourcc =[] hdr.fourcc
vh.headerLength = dana.serial(hdr).arrayLength
return vh
}
VideoFrame VideoFile:readFrame(byte content[], int offset)
{
FrameHeader hdr = new FrameHeader()
int hdrSize = dana.serial(hdr).arrayLength
if (offset + hdrSize >= content.arrayLength)
{
return null
}
dana.serial(hdr) =[] dana.sub(content, offset, content.arrayLength - offset)
hdr.frameSize = endianSwapI4(hdr.frameSize)
offset += hdrSize
if (offset + hdr.frameSize - 1 >= content.arrayLength)
{
throw new Exception("insufficient data for frame content")
}
//out.println("frame size at $(offset) is $(hdr.frameSize) bytes")
byte frameData[] = dana.sub(content, offset, offset + hdr.frameSize - 1)
return new VideoFrame(frameData, hdrSize, hdr.timestamp)
}
}To propose a new revision to this entity, use dana source put -uc your/new/version.dn -n media.video.VideoFile:divf -m "reason for update" -u yourUsername
Version 1 (this version) by barry
Notes for this version: Adds APIs for video decoding.