Initial commit

This commit is contained in:
Sven Weidauer 2013-05-05 16:20:40 +02:00
commit 3c881febc8
5 changed files with 831 additions and 0 deletions

26
OpenGL/Shader.h Normal file
View file

@ -0,0 +1,26 @@
//
// Shader.h
// gles2
//
// Created by Sven Weidauer on 08.07.12.
// Copyright (c) 2012 Sven Weidauer. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Shader : NSObject
@property (readonly, nonatomic) GLenum shaderType;
@property (readonly, nonatomic) GLuint shaderObject;
@property (readonly, nonatomic) NSString *infoLog;
+ (Shader *)vertexShaderNamed: (NSString *)name;
+ (Shader *)fragmentShaderNamed: (NSString *)name;
+ (Shader *)shaderNamed:(NSString *)name type: (GLenum) type;
- initWithType: (GLenum)type;
- (BOOL) compileSource: (NSString *)source;
- (BOOL) compileSourceData: (NSData *)data;
@end

92
OpenGL/Shader.m Normal file
View file

@ -0,0 +1,92 @@
//
// Shader.m
// gles2
//
// Created by Sven Weidauer on 08.07.12.
// Copyright (c) 2012 Sven Weidauer. All rights reserved.
//
#import "Shader.h"
@implementation Shader
- (id)initWithType:(GLenum)type;
{
self = [super init];
if (!self) return nil;
_shaderType = type;
_shaderObject = glCreateShader( type );
if (_shaderObject == 0) return nil;
return self;
}
- (void)dealloc;
{
if (_shaderObject != 0) {
glDeleteShader( _shaderObject );
}
}
- (BOOL)compileSource:(NSString *)source;
{
return [self compileSourceData: [source dataUsingEncoding: NSASCIIStringEncoding]];
}
- (BOOL)compileSourceData:(NSData *)data;
{
const GLchar *string = [data bytes];
GLint length = [data length];
glShaderSource( self.shaderObject, 1, &string, &length );
glCompileShader( self.shaderObject );
GLint compileStatus = 0;
glGetShaderiv( self.shaderObject, GL_COMPILE_STATUS, &compileStatus );
return compileStatus == GL_TRUE;
}
- (NSString *)infoLog;
{
GLint logLength = 0;
glGetShaderiv( self.shaderObject, GL_INFO_LOG_LENGTH, &logLength );
if (logLength == 0) return nil;
char buffer[logLength];
GLsizei actualLength = 0;
glGetShaderInfoLog( self.shaderObject, logLength, &actualLength, buffer );
return [[NSString alloc] initWithBytes: buffer length: actualLength encoding: NSUTF8StringEncoding];
}
+ (Shader *)shaderNamed:(NSString *)name type: (GLenum) type;
{
NSURL *url = [[NSBundle mainBundle] URLForResource: name withExtension: @"glsl"];
NSData *programData = [NSData dataWithContentsOfURL: url];
if (!programData) return nil;
Shader *result = [[self alloc] initWithType: type];
if (![result compileSourceData: programData]) {
NSLog( @"Error compiling shader: %@", result.infoLog );
return nil;
}
return result;
}
+ (Shader *)vertexShaderNamed:(NSString *)name;
{
return [self shaderNamed: name type: GL_VERTEX_SHADER];
}
+ (Shader *)fragmentShaderNamed:(NSString *)name;
{
return [self shaderNamed: name type: GL_FRAGMENT_SHADER];
}
@end

27
OpenGL/ShaderProgram.h Normal file
View file

@ -0,0 +1,27 @@
//
// ShaderProgram.h
// gles2
//
// Created by Sven Weidauer on 08.07.12.
// Copyright (c) 2012 Sven Weidauer. All rights reserved.
//
#import <Foundation/Foundation.h>
@class Shader;
@interface ShaderProgram : NSObject
@property (readonly, nonatomic) GLuint programObject;
@property (readonly, nonatomic) NSArray *shaders;
@property (readonly, nonatomic) NSString *infoLog;
- (void) attachShader: (Shader *)shader;
- (BOOL) link;
+ (ShaderProgram *)programWithShaders: (Shader *)shader, ... NS_REQUIRES_NIL_TERMINATION;
- (GLint)locationForAttribute: (NSString *)attribute;
- (void) use;
@end

106
OpenGL/ShaderProgram.m Normal file
View file

@ -0,0 +1,106 @@
//
// ShaderProgram.m
// gles2
//
// Created by Sven Weidauer on 08.07.12.
// Copyright (c) 2012 Sven Weidauer. All rights reserved.
//
#import "ShaderProgram.h"
#import "Shader.h"
@interface ShaderProgram ()
@property (strong, nonatomic) NSMutableArray *shaderArray;
@end
@implementation ShaderProgram
- (id)init;
{
self = [super init];
if (!self) return nil;
_programObject = glCreateProgram();
if (_programObject == 0) return nil;
_shaderArray = [NSMutableArray array];
return self;
}
- (NSArray *)shaders;
{
return [self.shaderArray copy];
}
- (void)dealloc;
{
if (_programObject != 0) {
glDeleteProgram( _programObject );
}
}
- (void)attachShader:(Shader *)shader;
{
[self.shaderArray addObject: shader];
glAttachShader( self.programObject, shader.shaderObject );
}
- (BOOL)link;
{
glLinkProgram( self.programObject );
GLint linkStatus = 0;
glGetProgramiv( self.programObject, GL_LINK_STATUS, &linkStatus );
return linkStatus == GL_TRUE;
}
- (NSString *)infoLog;
{
GLint logLength = 0;
glGetProgramiv( self.programObject, GL_INFO_LOG_LENGTH, &logLength );
if (logLength == 0) return nil;
char buffer[logLength];
GLsizei length = 0;
glGetProgramInfoLog( self.programObject, logLength, &length, buffer );
return [[NSString alloc] initWithBytes: buffer length: length encoding: NSUTF8StringEncoding];
}
+ (ShaderProgram *)programWithShaders:(Shader *)shader, ...;
{
ShaderProgram *result = [[self alloc] init];
va_list args;
va_start( args, shader );
while (shader) {
[result attachShader: shader];
shader = va_arg( args, Shader * );
}
va_end( args );
if (![ result link]) {
NSLog( @"Error linking shader program: %@", result.infoLog );
return nil;
}
return result;
}
- (GLint)locationForAttribute:(NSString *)attribute;
{
return glGetAttribLocation( self.programObject, [attribute cStringUsingEncoding: NSASCIIStringEncoding] );
}
- (void)use;
{
glUseProgram( self.programObject );
}
@end

580
asf.c Normal file
View file

@ -0,0 +1,580 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <assert.h>
uint8_t *buffer;
uint8_t *cursor;
#define BIT( n ) (1 << n)
typedef enum {
GUIDUnknown,
GUIDHeader,
GUIDData,
GUIDFileProperties,
GUIDStreamProperties,
GUIDHeaderExtension,
GUIDMediaTypeAudio,
GUIDMediaTypeVideo,
GUIDErrorCorrectionNone,
GUIDErrorCorrectionAudioSpread,
} GUIDType;
typedef struct GUIDEntry {
GUIDType type;
uint8_t data[16];
} GUIDEntry;
GUIDEntry guids[] = {
GUIDHeader, { 0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C },
GUIDData, { 0x36, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C },
GUIDFileProperties, { 0xA1, 0xDC, 0xAB, 0x8C, 0x47, 0xA9, 0xCF, 0x11, 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 },
GUIDStreamProperties, { 0x91, 0x07, 0xDC, 0xB7, 0xB7, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 },
GUIDHeaderExtension, { 0xB5, 0x03, 0xBF, 0x5F, 0x2E, 0xA9, 0xCF, 0x11, 0x8E, 0xE3, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 },
GUIDMediaTypeAudio, { 0x40, 0x9E, 0x69, 0xF8, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B },
GUIDMediaTypeVideo, { 0xC0, 0xEF, 0x19, 0xBC, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B },
GUIDErrorCorrectionNone, { 0x00, 0x57, 0xFB, 0x20, 0x55, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B },
GUIDErrorCorrectionAudioSpread, { 0x50, 0xCD, 0xC3, 0xBF, 0x8F, 0x61, 0xCF, 0x11, 0x8B, 0xB2, 0x00, 0xAA, 0x00, 0xB4, 0xE2, 0x20 },
};
GUIDType ReadGUID()
{
uint8_t *start = cursor;
cursor += 16;
for (size_t i = 0; i < sizeof guids / sizeof guids[0]; i++) {
if (memcmp( start, guids[i].data, 16) == 0) {
return guids[i].type;
}
}
return GUIDUnknown;
}
uint8_t ReadByte()
{
uint8_t result = *cursor;
cursor++;
return result;
}
uint16_t ReadWord()
{
return ReadByte() | (uint16_t)ReadByte() << 8;
}
uint32_t ReadDWord()
{
return ReadWord() | (uint32_t)ReadWord() << 16;
}
uint64_t ReadQWord()
{
return ReadDWord() | (uint64_t)ReadDWord() << 32;
}
uint32_t packetSize = 0;
void PrintGUID()
{
printf( "%04X-%02X-%02X-", ReadDWord(), ReadWord(), ReadWord() );
printf( "%02X%02X-", ReadByte(), ReadByte() );
printf( "%02X%02X%02X%02X%02X%02X\n", ReadByte(), ReadByte(), ReadByte(), ReadByte(), ReadByte(), ReadByte() );
}
void ParseFileProperties()
{
printf( "\t\tFile ID: " ); PrintGUID();
printf( "\t\tFile size: %llu\n", ReadQWord() );
printf( "\t\tCreation date: %llu\n", ReadQWord() );
printf( "\t\tPacket count: %llu\n", ReadQWord() );
printf( "\t\tPlay duration: %llu\n", ReadQWord() );
printf( "\t\tSend duration: %llu\n", ReadQWord() );
printf( "\t\tPreroll: %llu\n", ReadQWord() );
printf( "\t\tFlags: %u\n", ReadDWord() );
packetSize = ReadDWord() ;
printf( "\t\tMin Pack. size %u\n", packetSize );
uint32_t maxPacketSize = ReadDWord();
printf( "\t\tMax Pack. size %u\n", maxPacketSize );
printf( "\t\tMax bitrate %u\n", ReadDWord() );
printf( "\tend file properties\n" );
}
typedef enum StreamType {
StreamTypeError,
StreamTypeVideo,
StreamTypeAudio,
} StreamType;
typedef enum ErrorCorrectionType {
ErrorCorrectionTypeNone,
ErrorCorrectionTypeAudioSpread,
} ErrorCorrectionType;
typedef struct AudioMediaInfo {
uint16_t codecId;
uint16_t channelCount;
uint32_t samplesPerSecond;
uint32_t bytesPerSecond;
uint16_t blockAlignment;
uint16_t bitsPerSample;
uint16_t specificDataSize;
uint8_t specificData[0];
} __attribute__((packed)) AudioMediaInfo;
typedef struct BitmapInfo {
uint32_t formatDataSize;
int32_t width;
int32_t height;
uint16_t reserved;
uint16_t bitsPerPixel;
union {
uint8_t compression[4];
uint32_t compressionId;
};
uint32_t imageSize;
int32_t horizontalPixelsPerMeter;
int32_t verticalPixelsPerMeter;
uint32_t colorsUsedCount;
uint32_t importantColorsCount;
uint8_t codecSpecificData[0];
} __attribute__((packed)) BitmapInfo;
typedef struct VideoMediaInfo {
uint32_t imageWidth;
uint32_t imageHeight;
uint8_t flags;
uint16_t formatDataSize;
union {
uint8_t formatData[0];
BitmapInfo bitmapInfo;
};
} __attribute__((packed)) VideoMediaInfo;
typedef struct Stream {
StreamType type;
ErrorCorrectionType ecType;
size_t specificDataLength;
size_t ecDataLength;
uint64_t timeOffset;
union {
uint8_t *specificData;
AudioMediaInfo *audioInfo;
VideoMediaInfo *videoInfo;
};
uint8_t *ecData;
bool encrypted;
} Stream;
Stream *streams = NULL;
size_t streamCount = 0;
StreamType ReadStreamType()
{
GUIDType guid = ReadGUID();
switch (guid) {
case GUIDMediaTypeAudio:
return StreamTypeAudio;
case GUIDMediaTypeVideo:
return StreamTypeVideo;
default:
printf( "Found invalid stream type\n" );
return StreamTypeError;
}
}
ErrorCorrectionType ReadErrorCorrectionType()
{
GUIDType guid = ReadGUID();
switch (guid) {
case GUIDErrorCorrectionNone:
return ErrorCorrectionTypeNone;
case GUIDErrorCorrectionAudioSpread:
return ErrorCorrectionTypeAudioSpread;
default:
printf( "Found invalid error correction type\n" );
return ErrorCorrectionTypeNone;
}
}
void DumpAudioInfo( const AudioMediaInfo *info )
{
printf( "\t\tAudio info:\n" );
printf( "\t\t\tCodec ID: 0x%04X\n", info->codecId );
printf( "\t\t\tNumber of channels: %d\n", info->channelCount );
printf( "\t\t\tSamples per second: %d\n", info->samplesPerSecond );
printf( "\t\t\tAvg. bytes per second: %d\n", info->bytesPerSecond );
printf( "\t\t\tBlock alignment: %d\n", info->blockAlignment );
printf( "\t\t\tBits per sample: %d\n", info->bitsPerSample );
printf( "\t\t\tSpecific data size: %d\n", info->specificDataSize );
}
void DumpVideoInfo( const VideoMediaInfo *info )
{
printf( "\t\tVideo info:\n" );
printf( "\t\t\tFrame size: %dx%d\n", info->imageWidth, info->imageHeight );
printf( "\t\t\tFlags: %d\n", info->flags );
printf( "\t\t\tFormat data size: %d\n", info->formatDataSize );
printf( "\t\t\tSize: %dx%d\n", info->bitmapInfo.width, info->bitmapInfo.height );
printf( "\t\t\tBits per pixel: %d\n", info->bitmapInfo.bitsPerPixel );
printf( "\t\t\tCodec: %c%c%c%c\n", info->bitmapInfo.compression[0], info->bitmapInfo.compression[1], info->bitmapInfo.compression[2], info->bitmapInfo.compression[3] );
printf( "\t\t\tImage size: %d\n", info->bitmapInfo.imageSize );
printf( "\t\t\tH Pixels per meter: %d\n", info->bitmapInfo.horizontalPixelsPerMeter );
printf( "\t\t\tV Pixels per meter: %d\n", info->bitmapInfo.verticalPixelsPerMeter );
printf( "\t\t\tColors used count: %d\n", info->bitmapInfo.colorsUsedCount );
printf( "\t\t\tImportant colors count: %d\n", info->bitmapInfo.importantColorsCount );
}
void ParseStreamProperties()
{
StreamType type = ReadStreamType();
printf( "\t\tStream type: " );
switch (type) {
case StreamTypeAudio: printf( "Audio\n" ); break;
case StreamTypeVideo: printf( "Video\n" ); break;
default: printf( "Error, invalid\n" ); break;
}
ErrorCorrectionType ecType = ReadErrorCorrectionType();
printf( "\t\tEC type: " );
switch (ecType) {
case ErrorCorrectionTypeNone: printf( "None\n" ); break;
case ErrorCorrectionTypeAudioSpread: printf( "Audio spread\n" ); break;
}
uint64_t timeOffset = ReadQWord();
printf( "\t\tTime offset: %llu\n", timeOffset );
size_t specificLength = ReadDWord();
printf( "\t\tSpecific data length: %zu\n", specificLength );
size_t ecDataLength = ReadDWord();
printf( "\t\tEC data length: %zu\n", ecDataLength );
uint16_t flags = ReadWord();
cursor += 4; // Skip reserved
uint8_t streamNumber = flags & (BIT( 0 ) | BIT( 1 ) | BIT( 2 ) | BIT( 3 ) | BIT( 4 ) | BIT( 5 ) | BIT( 6 ) | BIT( 7 ));
printf( "\t\tStream number: %u\n", streamNumber );
bool encrypted = (flags & BIT( 15 )) != 0;
printf( "\t\tEncrypted: %s\n", encrypted ? "yes" : "no" );
if (streamNumber > streamCount) {
printf( "\t\tGrowing stream count from %zu to %d\n", streamCount, streamNumber );
streamCount = streamNumber;
streams = realloc( streams, streamCount * sizeof (Stream) );
}
streams[streamNumber - 1].type = type;
streams[streamNumber - 1].ecType = ecType;
streams[streamNumber - 1].specificDataLength = specificLength;
streams[streamNumber - 1].ecDataLength = ecDataLength;
streams[streamNumber - 1].specificData = cursor;
streams[streamNumber - 1].ecData = cursor + specificLength;
streams[streamNumber - 1].timeOffset = timeOffset;
streams[streamNumber - 1].encrypted = encrypted;
switch (type) {
case StreamTypeAudio:
DumpAudioInfo( streams[streamNumber - 1].audioInfo );
break;
case StreamTypeVideo:
DumpVideoInfo( streams[streamNumber - 1].videoInfo );
break;
default:
break;
}
}
void ParseHeaderExtension()
{
cursor += 16; // Skip reserved field 1
cursor += 2; // Skip reserved field 2
uint16_t dataSize = ReadDWord();
printf( "\tHeader extension data size: %d\n", dataSize );
uint8_t *end = cursor + dataSize;
while (cursor < end) {
uint8_t *objectStart = cursor;
GUIDType type = ReadGUID();
uint64_t size = ReadQWord();
uint8_t *next = objectStart + size;
switch (type) {
case GUIDUnknown:
default:
printf( "Unknown extended header object\n" );
break;
}
cursor = next;
}
}
void ParseHeaders()
{
printf( "Begin parsing headers\n" );
uint32_t headerCount = ReadDWord();
cursor += 2;
printf( "\t%d headers\n\n", headerCount );
for (uint32_t i = 0; i < headerCount; i++) {
uint8_t *objectStart = cursor;
GUIDType type = ReadGUID();
uint64_t size = ReadQWord();
uint8_t *next = objectStart + size;
printf( "\tOffset %ld, Object size: %llu\n", objectStart - buffer, size );
switch (type) {
case GUIDFileProperties:
printf( "\tFile properties found...\n" );
ParseFileProperties();
break;
case GUIDStreamProperties:
printf( "\tStream properties found...\n" );
ParseStreamProperties();
break;
case GUIDHeaderExtension:
printf( "\tHeader extension found...\n" );
ParseHeaderExtension();
break;
case GUIDUnknown:
default:
printf( "\tUnknown GUID\n" );
break;
}
cursor = next;
printf( "\n" );
}
printf( "end parsing headers\n" );
}
void ParseFile()
{
for (;;) {
uint8_t *objectStart = cursor;
GUIDType type = ReadGUID();
uint64_t size = ReadQWord();
uint8_t *next = objectStart + size;
printf( "Object size: %llu\n", size );
switch (type) {
case GUIDHeader:
printf( "Header GUID\n" );
ParseHeaders();
break;
case GUIDData:
printf( "Found Data object\n" );
return;
case GUIDUnknown:
default:
printf( "Unknown GUID\n" );
break;
}
cursor = next;
}
}
uint32_t ReadNumber( int type )
{
switch (type) {
case 1: return ReadByte();
case 2: return ReadWord();
case 3: return ReadDWord();
default:
case 0: return 0;
}
}
typedef struct ParseInfo {
int repDataLengthType;
int offsetLengthType;
int objectNumberLengthType;
} ParseInfo;
typedef struct MediaObject {
size_t size;
uint8_t *data;
uint32_t presentationTime;
uint32_t sequenceNumber;
size_t nextOffset;
size_t object;
} MediaObject;
MediaObject *currentObjects = NULL;
uint8_t *packetStart = NULL;
void AddDataToObject( MediaObject *o, size_t offset, size_t len, const uint8_t *data )
{
printf( "Offset: %zu\n", offset );
printf( "Next offset: %zu\n", o->nextOffset );
printf( "Len: %zu\n", len );
if (o->nextOffset + len >= o->size) {
printf( "Error: Packet too big\n" );
return;
}
memcpy( o->data + o->nextOffset, data, len );
o->nextOffset += len;
}
void ParseECData( uint8_t flags )
{
printf( "\tParsing EC data...\n" );
int ecDataLength = flags & (BIT(0)|BIT(1)|BIT(2)|BIT(3));
printf( "\tEC data length: %d\n", ecDataLength );
bool opaque = flags & BIT(4);
printf( "\tOpaque data present: %s\n", opaque ? "yes" : "no" );
int ecLengthType = (flags & (BIT( 5 ) | BIT( 6 ))) >> 5;
printf( "\tEC length type: %d\n", ecLengthType );
printf( "\tSkipping EC data...\n");
cursor += ecDataLength;
}
void ParsePayload( const ParseInfo *info )
{
printf( "\tParse payload...\n" );
uint8_t tmp = ReadByte();
uint8_t streamNumber = tmp & (BIT( 0 ) | BIT( 1 ) | BIT( 2 ) | BIT( 3 ) | BIT( 4 ) | BIT( 5 ) | BIT( 6 ));
bool isKeyFrame = (tmp & BIT( 7 )) != 0;
uint32_t mediaObjectNumber = ReadNumber( info->objectNumberLengthType );
uint32_t offset = ReadNumber( info->offsetLengthType );
uint32_t repLength = ReadNumber( info->repDataLengthType );
printf( "\t\tStream number: %d\n", streamNumber );
printf( "\t\tKey frame: %s\n", isKeyFrame ? "yes" : "no" );
printf( "\t\tMedia object number: %d\n", mediaObjectNumber );
printf( "\t\tOffset into object: %d\n", offset );
printf( "\t\tReplicated data length: %d\n", repLength );
if (repLength >= 8) {
printf( "\t\tReplicated data:\n" );
printf( "\t\t\tMedia object size: %d\n", ReadDWord() );
printf( "\t\t\tPresentation time: %d\n", ReadDWord() );
printf( "\t\tSkipping rest of replicated data...\n" );
cursor += repLength - 8;
} else {
cursor += repLength;
}
size_t headerSize = cursor - packetStart;
size_t dataSize = packetSize - headerSize - 0;
printf( "\t\tData offset: %ld\n", cursor - buffer );
AddDataToObject( &currentObjects[streamNumber], offset, dataSize, cursor );
}
void ParseMultiplePayloads( const ParseInfo *info )
{
printf( "\tParse multiple payloads...\n" );
}
void ParsePayloadHeader( uint8_t flags )
{
printf( "\tParsing payload parsing information...\n" );
bool multiplePayloads = (flags & BIT( 0 )) != 0;
int sequenceType = (flags & (BIT( 1 ) | BIT( 2 ))) >> 1;
int paddingLengthType = (flags & (BIT( 3 ) | BIT( 4 ))) >> 3;
int packetLengthType = (flags & (BIT( 5 ) | BIT( 6 ))) >> 5;
bool ecPresent = (flags & BIT( 7 )) != 0;
printf( "\tMultiple Payloads %s\n", multiplePayloads ? "yes" : "no" );
printf( "\tSequence type: %d\n", sequenceType );
printf( "\tPadding length type: %d\n", paddingLengthType );
printf( "\tPacket length type: %d\n", packetLengthType );
printf( "\tEC present: %s\n", ecPresent ? "yes" : "no" );
uint8_t propertyFlags = ReadByte();
ParseInfo info;
info.repDataLengthType = propertyFlags & (BIT( 0 ) | BIT( 1 ));
info.offsetLengthType = (propertyFlags & (BIT( 2 ) | BIT( 3 ))) >> 2;
info.objectNumberLengthType = (propertyFlags & (BIT( 4 ) | BIT( 5 ))) >> 4;
int streamNumberLengthType = (propertyFlags & (BIT( 6 ) | BIT( 7 ))) >> 6;
printf( "\tRepl. data length type %d\n", info.repDataLengthType );
printf( "\tOffset into media object length type %d\n", info.offsetLengthType );
printf( "\tMedia object number lengtht type %d\n", info.objectNumberLengthType );
printf( "\tStream Number Length Type %d\n", streamNumberLengthType );
uint32_t packetLength = ReadNumber( packetLengthType );
printf( "\tPacket length: %d\n", packetLength );
uint32_t sequence = ReadNumber( sequenceType );
printf( "\tSequence number: %d\n", sequence );
uint32_t paddingLength = ReadNumber( paddingLengthType );
printf( "\tPadding length: %d\n", paddingLength );
uint32_t sendTime = ReadDWord();
printf( "\tSend time: %d\n", sendTime );
uint16_t duration = ReadWord();
printf( "\tDuration: %d\n", duration );
if (multiplePayloads) ParseMultiplePayloads( &info );
else ParsePayload( &info );
}
void ParsePacket()
{
packetStart = cursor;
printf( "Parsing packet...\n" );
uint8_t flags = ReadByte();
if (flags & BIT( 7 )) {
ParseECData( flags );
flags = ReadByte();
ParsePayloadHeader( flags );
} else {
ParsePayloadHeader( flags );
}
}
uint8_t *end = 0;
void ParseData()
{
currentObjects = calloc( sizeof (MediaObject), streamCount );
printf( "Data begins...\n" );
printf( "File ID: " ); PrintGUID();
printf( "Total packets: %llu\n", ReadQWord() );
cursor += 2; // Skip reserved field
while (cursor < end) {
uint8_t *tmp = cursor;
ParsePacket();
cursor = tmp + packetSize;
}
}
int main( int argc, char **argv )
{
int handle = open( argv[1], O_RDONLY );
struct stat buf;
fstat( handle, &buf );
cursor = buffer = mmap( NULL, buf.st_size, PROT_READ, MAP_FILE|MAP_PRIVATE, handle, 0 );
end = buffer + buf.st_size;
ParseFile();
ParseData();
}