1
0
Fork 0
Aegisub/src/MatroskaParser.h

388 lines
10 KiB
C

/*
* Copyright (c) 2004-2009 Mike Matsnev. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Absolutely no warranty of function or purpose is made by the author
* Mike Matsnev.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdint.h>
#ifndef MATROSKA_PARSER_H
#define MATROSKA_PARSER_H
/* Random notes:
*
* The parser does not process frame data in any way and does not read it into
* the queue. The app should read it via mkv_ReadData if it is interested.
*
* The code here is 64-bit clean and was tested on FreeBSD/sparc 64-bit big endian
* system
*/
#ifdef MPDLLBUILD
#define X __declspec(dllexport)
#else
#ifdef MPDLL
#define X __declspec(dllimport)
#pragma comment(lib,"MatroskaParser")
#else
#define X
#endif
#endif
#define MATROSKA_COMPRESSION_SUPPORT
#define MATROSKA_INTEGER_ONLY
#ifdef __cplusplus
extern "C" {
#endif
/* MKFLOATing point */
#ifdef MATROSKA_INTEGER_ONLY
typedef struct {
int64_t v;
} MKFLOAT;
#else
typedef double MKFLOAT;
#endif
/* generic I/O */
struct InputStream {
/* read bytes from stream */
int (*read)(struct InputStream *cc,uint64_t pos,void *buffer,int count);
/* scan for a four byte signature, bytes must be nonzero */
int64_t (*scan)(struct InputStream *cc,uint64_t start,unsigned signature);
/* get cache size, this is used to cap readahead */
unsigned (*getcachesize)(struct InputStream *cc);
/* fetch last error message */
const char *(*geterror)(struct InputStream *cc);
/* memory allocation */
void *(*memalloc)(struct InputStream *cc,size_t size);
void *(*memrealloc)(struct InputStream *cc,void *mem,size_t newsize);
void (*memfree)(struct InputStream *cc,void *mem);
/* zero return causes parser to abort open */
int (*progress)(struct InputStream *cc,uint64_t cur,uint64_t max);
/* get file size, optional, can be NULL or return -1 if filesize is unknown */
int64_t (*getfilesize)(struct InputStream *cc);
};
typedef struct InputStream InputStream;
/* matroska file */
struct MatroskaFile; /* opaque */
typedef struct MatroskaFile MatroskaFile;
#define COMP_ZLIB 0
#define COMP_BZIP 1
#define COMP_LZO1X 2
#define COMP_PREPEND 3
#define TT_VIDEO 1
#define TT_AUDIO 2
#define TT_SUB 17
struct TrackInfo {
unsigned char Number;
unsigned char Type;
unsigned char TrackOverlay;
uint64_t UID;
uint64_t MinCache;
uint64_t MaxCache;
uint64_t DefaultDuration;
MKFLOAT TimecodeScale;
void *CodecPrivate;
unsigned CodecPrivateSize;
unsigned CompMethod;
void *CompMethodPrivate;
unsigned CompMethodPrivateSize;
unsigned MaxBlockAdditionID;
unsigned int Enabled:1;
unsigned int Default:1;
unsigned int Lacing:1;
unsigned int DecodeAll:1;
unsigned int CompEnabled:1;
union {
struct {
unsigned char StereoMode;
unsigned char DisplayUnit;
unsigned char AspectRatioType;
unsigned int PixelWidth;
unsigned int PixelHeight;
unsigned int DisplayWidth;
unsigned int DisplayHeight;
unsigned int CropL, CropT, CropR, CropB;
unsigned int ColourSpace;
MKFLOAT GammaValue;
unsigned int Interlaced:1;
} Video;
struct {
MKFLOAT SamplingFreq;
MKFLOAT OutputSamplingFreq;
unsigned char Channels;
unsigned char BitDepth;
} Audio;
} AV;
/* various strings */
char *Name;
char Language[4];
char *CodecID;
};
typedef struct TrackInfo TrackInfo;
struct SegmentInfo {
char UID[16];
char PrevUID[16];
char NextUID[16];
char *Filename;
char *PrevFilename;
char *NextFilename;
char *Title;
char *MuxingApp;
char *WritingApp;
uint64_t TimecodeScale;
uint64_t Duration;
int64_t DateUTC;
char DateUTCValid;
};
typedef struct SegmentInfo SegmentInfo;
struct Attachment {
uint64_t Position;
uint64_t Length;
uint64_t UID;
char *Name;
char *Description;
char *MimeType;
};
typedef struct Attachment Attachment;
struct ChapterDisplay {
char *String;
char Language[4];
char Country[4];
};
struct ChapterCommand {
unsigned Time;
unsigned CommandLength;
void *Command;
};
struct ChapterProcess {
unsigned CodecID;
unsigned CodecPrivateLength;
void *CodecPrivate;
unsigned nCommands,nCommandsSize;
struct ChapterCommand *Commands;
};
struct Chapter {
uint64_t UID;
uint64_t Start;
uint64_t End;
unsigned nTracks,nTracksSize;
uint64_t *Tracks;
unsigned nDisplay,nDisplaySize;
struct ChapterDisplay *Display;
unsigned nChildren,nChildrenSize;
struct Chapter *Children;
unsigned nProcess,nProcessSize;
struct ChapterProcess *Process;
char SegmentUID[16];
unsigned int Hidden:1;
unsigned int Enabled:1;
// Editions
unsigned int Default:1;
unsigned int Ordered:1;
};
typedef struct Chapter Chapter;
#define TARGET_TRACK 0
#define TARGET_CHAPTER 1
#define TARGET_ATTACHMENT 2
#define TARGET_EDITION 3
struct Target {
uint64_t UID;
unsigned Type;
};
struct SimpleTag {
char *Name;
char *Value;
char Language[4];
unsigned Default:1;
};
struct Tag {
unsigned nTargets,nTargetsSize;
struct Target *Targets;
unsigned nSimpleTags,nSimpleTagsSize;
struct SimpleTag *SimpleTags;
};
typedef struct Tag Tag;
/* Open a matroska file
* io pointer is recorded inside MatroskaFile
*/
X MatroskaFile *mkv_Open(/* in */ InputStream *io,
/* out */ char *err_msg,
/* in */ unsigned msgsize);
#define MKVF_AVOID_SEEKS 1 /* use sequential reading only */
X MatroskaFile *mkv_OpenEx(/* in */ InputStream *io,
/* in */ uint64_t base,
/* in */ unsigned flags,
/* out */ char *err_msg,
/* in */ unsigned msgsize);
/* Close and deallocate mf
* NULL pointer is ok and is simply ignored
*/
X void mkv_Close(/* in */ MatroskaFile *mf);
/* Fetch the error message of the last failed operation */
X const char *mkv_GetLastError(/* in */ MatroskaFile *mf);
/* Get file information */
X SegmentInfo *mkv_GetFileInfo(/* in */ MatroskaFile *mf);
/* Get track information */
X unsigned int mkv_GetNumTracks(/* in */ MatroskaFile *mf);
X TrackInfo *mkv_GetTrackInfo(/* in */ MatroskaFile *mf,/* in */ unsigned track);
/* chapters, tags and attachments */
X void mkv_GetAttachments(/* in */ MatroskaFile *mf,
/* out */ Attachment **at,
/* out */ unsigned *count);
X void mkv_GetChapters(/* in */ MatroskaFile *mf,
/* out */ Chapter **ch,
/* out */ unsigned *count);
X void mkv_GetTags(/* in */ MatroskaFile *mf,
/* out */ Tag **tag,
/* out */ unsigned *count);
X uint64_t mkv_GetSegmentTop(MatroskaFile *mf);
/* Seek to specified timecode,
* if timecode is past end of file,
* all tracks are set to return EOF
* on next read
*/
#define MKVF_SEEK_TO_PREV_KEYFRAME 1
#define MKVF_SEEK_TO_PREV_KEYFRAME_STRICT 2
X void mkv_Seek(/* in */ MatroskaFile *mf,
/* in */ uint64_t timecode /* in ns */,
/* in */ unsigned flags);
X void mkv_SkipToKeyframe(MatroskaFile *mf);
X uint64_t mkv_GetLowestQTimecode(MatroskaFile *mf);
X int mkv_TruncFloat(MKFLOAT f);
/*************************************************************************
* reading data, pull model
*/
/* frame flags */
#define FRAME_UNKNOWN_START 0x00000001
#define FRAME_UNKNOWN_END 0x00000002
#define FRAME_KF 0x00000004
#define FRAME_GAP 0x00800000
#define FRAME_STREAM_MASK 0xff000000
#define FRAME_STREAM_SHIFT 24
/* This sets the masking flags for the parser,
* masked tracks [with 1s in their bit positions]
* will be ignored when reading file data.
* This call discards all parsed and queued frames
*/
X void mkv_SetTrackMask(/* in */ MatroskaFile *mf,/* in */ unsigned int mask);
/* Read one frame from the queue.
* mask specifies what tracks to ignore.
* Returns -1 if there are no more frames in the specified
* set of tracks, 0 on success
*/
X int mkv_ReadFrame(/* in */ MatroskaFile *mf,
/* in */ unsigned int mask,
/* out */ unsigned int *track,
/* out */ uint64_t *StartTime /* in ns */,
/* out */ uint64_t *EndTime /* in ns */,
/* out */ uint64_t *FilePos /* in bytes from start of file */,
/* out */ unsigned int *FrameSize /* in bytes */,
/* out */ unsigned int *FrameFlags);
#ifdef MATROSKA_COMPRESSION_SUPPORT
/* Compressed streams support */
struct CompressedStream;
typedef struct CompressedStream CompressedStream;
X CompressedStream *cs_Create(/* in */ MatroskaFile *mf,
/* in */ unsigned tracknum,
/* out */ char *errormsg,
/* in */ unsigned msgsize);
X void cs_Destroy(/* in */ CompressedStream *cs);
/* advance to the next frame in matroska stream, you need to pass values returned
* by mkv_ReadFrame */
X void cs_NextFrame(/* in */ CompressedStream *cs,
/* in */ uint64_t pos,
/* in */ unsigned size);
/* read and decode more data from current frame, return number of bytes decoded,
* 0 on end of frame, or -1 on error */
X int cs_ReadData(CompressedStream *cs,char *buffer,unsigned bufsize);
/* return error message for the last error */
X const char *cs_GetLastError(CompressedStream *cs);
#endif
#ifdef __cplusplus
}
#endif
#undef X
#endif