diff --git a/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.c b/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.c index c32ba5cfb1..b89aabd763 100644 --- a/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.c +++ b/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Mike Matsnev. All Rights Reserved. + * Copyright (c) 2004-2005 Mike Matsnev. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: MatroskaParser.c,v 1.8 2004/09/17 12:23:51 mike Exp $ + * $Id: MatroskaParser.c,v 1.31 2005/03/07 11:22:16 mike Exp $ * */ @@ -37,21 +37,22 @@ #ifdef _WIN32 // MS names some functions differently -#define vsnprintf _vsnprintf #define alloca _alloca #define inline __inline #include #endif -#include - #ifndef EVCBUG #define EVCBUG #endif #include "MatroskaParser.h" +#ifdef MATROSKA_COMPRESSION_SUPPORT +#include +#endif + #define EBML_VERSION 1 #define EBML_MAX_ID_LENGTH 4 #define EBML_MAX_SIZE_LENGTH 8 @@ -61,7 +62,7 @@ #define MAX_STRING_LEN 1023 #define QSEGSIZE 512 #define MAX_TRACKS 32 -#define MAX_READAHEAD (384*1024) +#define MAX_READAHEAD (512*1024) #define DEFAULT_PAGE_SIZE 65536 #define MIN_PAGE_SIZE 4096 @@ -69,11 +70,19 @@ #define MAXCLUSTER (64*1048576) #define MAXFRAME (4*1048576) -#define MAXU64 0xffffffffffffffff +#ifdef WIN32 +#define LL(x) x##i64 +#define ULL(x) x##ui64 +#else +#define LL(x) x##ll +#define ULL(x) x##ull +#endif + +#define MAXU64 ULL(0xffffffffffffffff) +#define ONE ULL(1) // compatibility -#ifdef _WIN32_WCE -static char *strdup(const char *src) { +static char *mystrdup(struct InputStream *is,const char *src) { size_t len; char *dst; @@ -81,7 +90,7 @@ static char *strdup(const char *src) { return NULL; len = strlen(src); - dst = malloc(len+1); + dst = (char *)is->memalloc(is,len+1); if (dst==NULL) return NULL; @@ -89,9 +98,8 @@ static char *strdup(const char *src) { return dst; } -#endif -#if defined(_WIN32) || defined(__BEOS___) +#ifdef _WIN32 static void strlcpy(char *dst,const char *src,unsigned size) { unsigned i; @@ -135,7 +143,7 @@ struct MatroskaFile { unsigned flags; // input - FileCache *cache; + InputStream *cache; // internal buffering char inbuf[IBSZ]; @@ -208,11 +216,194 @@ struct MatroskaFile { /////////////////////////////////////////////////////////////////////////// // error reporting +static void myvsnprintf_string(char **pdest,char *de,const char *str) { + char *dest = *pdest; + + while (dest < de && *str) + *dest++ = *str++; + + *pdest = dest; +} + +static void myvsnprintf_uint_impl(char **pdest,char *de,int width,int zero, + int neg,unsigned base,int letter, + int ms,ulonglong val) +{ + char *dest = *pdest; + char tmp[21]; /* enough for 64 bit ints */ + char *np = tmp + sizeof(tmp); + int rw,pad,trail; + char pc = zero ? '0' : ' '; + + *--np = '\0'; + while (val != 0) { + int rem = (int)(val % base); + val = val / base; + + *--np = rem < 10 ? rem + '0' : rem - 10 + letter; + } + + rw = (int)(tmp - np + sizeof(tmp) - 1); + if (ms) + ++rw; + + pad = trail = 0; + + if (rw < width) + pad = width - rw; + + if (neg) + trail = pad, pad = 0; + + if (dest < de && ms) + *dest++ = '-'; + + while (dest < de && pad--) + *dest++ = pc; + + while (dest < de && *np) + *dest++ = *np++; + + while (dest < de && trail--) + *dest++ = ' '; + + *pdest = dest; +} + +static void myvsnprintf_uint(char **pdest,char *de,int width,int zero, + int neg,unsigned base,int letter, + ulonglong val) +{ + myvsnprintf_uint_impl(pdest,de,width,zero,neg,base,letter,0,val); +} + +static void myvsnprintf_int(char **pdest,char *de,int width,int zero, + int neg,unsigned base,int letter, + longlong val) +{ + if (val < 0) + myvsnprintf_uint_impl(pdest,de,width,zero,neg,base,letter,1,-val); + else + myvsnprintf_uint_impl(pdest,de,width,zero,neg,base,letter,0,val); +} + +static void myvsnprintf(char *dest,unsigned dsize,const char *fmt,va_list ap) { + // s,d,x,u,ll + char *de = dest + dsize - 1; + int state = 0, width, zero, neg, ll; + + if (dsize <= 1) { + if (dsize > 0) + *dest = '\0'; + return; + } + + while (*fmt && dest < de) + switch (state) { + case 0: + if (*fmt == '%') { + ++fmt; + state = 1; + width = zero = neg = ll = 0; + } else + *dest++ = *fmt++; + break; + case 1: + if (*fmt == '-') { + neg = 1; + ++fmt; + state = 2; + break; + } + state = 2; + case 2: + if (*fmt >= '0' && *fmt <= '9') { + width = width * 10 + *fmt++ - '0'; + break; + } + state = 3; + case 3: + if (*fmt == 'l') { + ++ll; + ++fmt; + break; + } + state = 4; + case 4: + switch (*fmt) { + case 's': + myvsnprintf_string(&dest,de,va_arg(ap,const char *)); + break; + case 'd': + switch (ll) { + case 0: + myvsnprintf_int(&dest,de,width,zero,neg,10,'a',va_arg(ap,int)); + break; + case 1: + myvsnprintf_int(&dest,de,width,zero,neg,10,'a',va_arg(ap,long)); + break; + case 2: + myvsnprintf_int(&dest,de,width,zero,neg,10,'a',va_arg(ap,longlong)); + break; + } + break; + case 'u': + switch (ll) { + case 0: + myvsnprintf_uint(&dest,de,width,zero,neg,10,'a',va_arg(ap,unsigned int)); + break; + case 1: + myvsnprintf_uint(&dest,de,width,zero,neg,10,'a',va_arg(ap,unsigned long)); + break; + case 2: + myvsnprintf_uint(&dest,de,width,zero,neg,10,'a',va_arg(ap,ulonglong)); + break; + } + break; + case 'x': + switch (ll) { + case 0: + myvsnprintf_uint(&dest,de,width,zero,neg,16,'a',va_arg(ap,unsigned int)); + break; + case 1: + myvsnprintf_uint(&dest,de,width,zero,neg,16,'a',va_arg(ap,unsigned long)); + break; + case 2: + myvsnprintf_uint(&dest,de,width,zero,neg,16,'a',va_arg(ap,ulonglong)); + break; + } + break; + case 'X': + switch (ll) { + case 0: + myvsnprintf_uint(&dest,de,width,zero,neg,16,'A',va_arg(ap,unsigned int)); + break; + case 1: + myvsnprintf_uint(&dest,de,width,zero,neg,16,'A',va_arg(ap,unsigned long)); + break; + case 2: + myvsnprintf_uint(&dest,de,width,zero,neg,16,'A',va_arg(ap,ulonglong)); + break; + } + break; + default: + break; + } + ++fmt; + state = 0; + break; + default: + state = 0; + break; + } + *dest = '\0'; +} + static void errorjmp(MatroskaFile *mf,const char *fmt, ...) { va_list ap; va_start(ap, fmt); - vsnprintf(mf->errmsg,sizeof(mf->errmsg),fmt,ap); + myvsnprintf(mf->errmsg,sizeof(mf->errmsg),fmt,ap); va_end(ap); mf->flags |= MPF_ERROR; @@ -231,7 +422,7 @@ static void *ArrayAlloc(MatroskaFile *mf,void **base, if (newsize==0) newsize = 1; - np = realloc(*base,newsize*elem_size); + np = mf->cache->memrealloc(mf->cache,*base,newsize*elem_size); if (np==NULL) errorjmp(mf,"Out of memory in ArrayAlloc"); @@ -242,11 +433,11 @@ static void *ArrayAlloc(MatroskaFile *mf,void **base, return (char*)*base + elem_size * (*cur)++; } -static void ArrayReleaseMemory(void **base, +static void ArrayReleaseMemory(MatroskaFile *mf,void **base, unsigned cur,unsigned *max,unsigned elem_size) { if (cur<*max) { - void *np = realloc(*base,cur*elem_size); + void *np = mf->cache->memrealloc(mf->cache,*base,cur*elem_size); *base = np; *max = cur; } @@ -255,7 +446,7 @@ static void ArrayReleaseMemory(void **base, #define ASGET(f,s,name) ArrayAlloc((f),(void**)&(s)->name,&(s)->n##name,&(s)->n##name##Size,sizeof(*((s)->name))) #define AGET(f,name) ArrayAlloc((f),(void**)&(f)->name,&(f)->n##name,&(f)->n##name##Size,sizeof(*((f)->name))) -#define ARELEASE(f,name) ArrayReleaseMemory((void**)&(f)->name,(f)->n##name,&(f)->n##name##Size,sizeof(*((f)->name))) +#define ARELEASE(f,s,name) ArrayReleaseMemory((f),(void**)&(s)->name,(s)->n##name,&(s)->n##name##Size,sizeof(*((s)->name))) /////////////////////////////////////////////////////////////////////////// // queues @@ -287,7 +478,7 @@ static struct QueueEntry *QAlloc(MatroskaFile *mf) { qep = AGET(mf,QBlocks); - *qep = malloc(QSEGSIZE * sizeof(*qe)); + *qep = mf->cache->memalloc(mf->cache,QSEGSIZE * sizeof(*qe)); if (*qep == NULL) errorjmp(mf,"Ouf of memory"); @@ -346,7 +537,7 @@ static inline ulonglong filepos(MatroskaFile *mf) { } static void readbytes(MatroskaFile *mf,void *buffer,int len) { - char *cp = buffer; + char *cp = (char *)buffer; int nb = mf->buflen - mf->bufpos; if (nb > len) @@ -423,7 +614,6 @@ static inline longlong mul3(MKFLOAT scale,longlong tc) { // .. r1 r0 .. // // r = ((x0*y0) >> 32) + (x1*y0) + (x0*y1) + ((x1*y1) << 32) - // TODO calc tc*scale unsigned x0,x1,y0,y1; ulonglong p; char sign = 0; @@ -445,7 +635,7 @@ static inline longlong mul3(MKFLOAT scale,longlong tc) { return p; #else - return (ulonglong)(scale * tc); + return (longlong)(scale * tc); #endif } @@ -524,15 +714,15 @@ static ulonglong readSize(MatroskaFile *mf) { ulonglong v = readVLUIntImp(mf,&m); // see if it's unspecified - if (v == (0xffffffffffffffff >> (57-m*7))) + if (v == (MAXU64 >> (57-m*7))) errorjmp(mf,"Unspecified element size is not supported here."); return v; } static inline longlong readVLSInt(MatroskaFile *mf) { - static longlong bias[8] = { (1<<6)-1, (1<<13)-1, (1<<20)-1, (1<<27)-1, - (1LL<<34)-1, (1LL<<41)-1, (1LL<<48)-1, (1LL<<55)-1 }; + static longlong bias[8] = { (ONE<<6)-1, (ONE<<13)-1, (ONE<<20)-1, (ONE<<27)-1, + (ONE<<34)-1, (ONE<<41)-1, (ONE<<48)-1, (ONE<<55)-1 }; int m; longlong v = readVLUIntImp(mf,&m); @@ -553,7 +743,7 @@ static ulonglong readUInt(MatroskaFile *mf,unsigned int len) { do { c = readch(mf); if (c == EOF) - errorjmp(mf,"Got EOF while read EBML unsigned integer"); + errorjmp(mf,"Got EOF while reading EBML unsigned integer"); v = (v<<8) | c; } while (--m); @@ -595,9 +785,9 @@ zero: else if (shift == 255) inf: if (ui & 0x80000000) - f.v = 0x8000000000000000; + f.v = LL(0x8000000000000000); else - f.v = 0x7fffffffffffffff; + f.v = LL(0x7fffffffffffffff); else { shift += -127 + 9; if (shift > 39) @@ -608,11 +798,9 @@ shift: else if (shift > 0) f.v = f.v << shift; } - } - - if (len == 8) { - ulonglong ui = (unsigned)readUInt(mf,(unsigned)len); - f.v = (ui & 0xfffffffffffff) | 0x10000000000000; + } else if (len == 8) { + ulonglong ui = readUInt(mf,(unsigned)len); + f.v = (ui & LL(0xfffffffffffff)) | LL(0x10000000000000); if (ui & 0x80000000) f.v = -f.v; shift = (int)((ui >> 52) & 0x7ff); @@ -695,19 +883,20 @@ static void readString(MatroskaFile *mf,ulonglong len,char *buffer,int buflen) { #define ENDFOR(f) ENDFOR1(f) ENDFOR2() +#define myalloca(f,c) alloca(c) #define STRGETF(f,v,len,func) \ { \ char *TmpVal; \ unsigned TmpLen = (len)>MAX_STRING_LEN ? MAX_STRING_LEN : (unsigned)(len); \ - TmpVal = func(TmpLen+1); \ + TmpVal = (char *)func(f->cache,TmpLen+1); \ if (TmpVal == NULL) \ errorjmp(mf,"Out of memory"); \ readString(f,len,TmpVal,TmpLen+1); \ (v) = TmpVal; \ } -#define STRGETA(f,v,len) STRGETF(f,v,len,alloca) -#define STRGETM(f,v,len) STRGETF(f,v,len,malloc) +#define STRGETA(f,v,len) STRGETF(f,v,len,myalloca) +#define STRGETM(f,v,len) STRGETF(f,v,len,f->cache->memalloc) static int IsWritingApp(MatroskaFile *mf,const char *str) { const char *cp = mf->Seg.WritingApp; @@ -819,8 +1008,10 @@ static void parseSeekHead(MatroskaFile *mf,ulonglong toplen) { static void parseSegmentInfo(MatroskaFile *mf,ulonglong toplen) { MKFLOAT duration; - if (mf->seen.SegmentInfo) + if (mf->seen.SegmentInfo) { + skipbytes(mf,toplen); return; + } mf->seen.SegmentInfo = 1; mf->Seg.TimecodeScale = 1000000; // Default value @@ -852,6 +1043,8 @@ static void parseSegmentInfo(MatroskaFile *mf,ulonglong toplen) { break; case 0x2ad7b1: // TimecodeScale mf->Seg.TimecodeScale = readUInt(mf,(unsigned)len); + if (mf->Seg.TimecodeScale == 0) + errorjmp(mf,"Segment timecode scale is zero"); break; case 0x4489: // Duration duration = readFloat(mf,(unsigned)len); @@ -1089,7 +1282,7 @@ static void parseTrackEntry(MatroskaFile *mf,ulonglong toplen) { if (len>262144) // 256KB errorjmp(mf,"CodecPrivate is too large: %d",(int)len); cplen = (unsigned)len; - cp = alloca(cplen); + cp = (char *)alloca(cplen); readbytes(mf,cp,(int)cplen); break; case 0x258688: // CodecName @@ -1161,7 +1354,7 @@ static void parseTrackEntry(MatroskaFile *mf,ulonglong toplen) { errorjmp(mf,"Track has no Codec ID"); // allocate new track - tpp = AGET(mf,Tracks); + tpp = (TrackInfo **)AGET(mf,Tracks); // copy strings if (t.Name) @@ -1171,7 +1364,7 @@ static void parseTrackEntry(MatroskaFile *mf,ulonglong toplen) { if (t.CodecID) cpadd += strlen(t.CodecID)+1; - tp = malloc(sizeof(*tp) + cplen + cpadd); + tp = (TrackInfo *)mf->cache->memalloc(mf->cache,sizeof(*tp) + cplen + cpadd); if (tp == NULL) errorjmp(mf,"Out of memory"); @@ -1211,14 +1404,36 @@ static void addCue(MatroskaFile *mf,ulonglong pos,ulonglong timecode) { cc->Block = 0; } +static void fixupCues(MatroskaFile *mf) { + // adjust cues, shift cues if file does not start at 0 + unsigned i; + longlong adjust = mf->firstTimecode * mf->Seg.TimecodeScale; + + for (i=0;inCues;++i) { + mf->Cues[i].Time *= mf->Seg.TimecodeScale; + mf->Cues[i].Time -= adjust; + } +} + static void parseCues(MatroskaFile *mf,ulonglong toplen) { + jmp_buf jb; ulonglong v; struct Cue cc; unsigned i,j,k; mf->seen.Cues = 1; + mf->nCues = 0; cc.Block = 0; + memcpy(&jb,&mf->jb,sizeof(jb)); + + if (setjmp(mf->jb)) { + memcpy(&mf->jb,&jb,sizeof(jb)); + mf->nCues = 0; + mf->seen.Cues = 0; + return; + } + FOREACH(mf,toplen) case 0xbb: // CuePoint FOREACH(mf,len) @@ -1262,24 +1477,29 @@ static void parseCues(MatroskaFile *mf,ulonglong toplen) { break; ENDFOR(mf); - if (mf->nCues == 0) - addCue(mf,mf->pCluster,mf->firstTimecode); + if (mf->nCues == 0 && mf->pCluster - mf->pSegment != cc.Position) + addCue(mf,mf->pCluster - mf->pSegment,mf->firstTimecode); memcpy(AGET(mf,Cues),&cc,sizeof(cc)); break; ENDFOR(mf); - ARELEASE(mf,Cues); + memcpy(&mf->jb,&jb,sizeof(jb)); + + ARELEASE(mf,mf,Cues); // bubble sort the cues and fuck the losers that write unordered cues - for (i = mf->nCues - 1, k = 1; i > 0 && k > 0; --i) - for (j = k = 0; j < i; ++j) - if (mf->Cues[j].Time > mf->Cues[j+1].Time) { - struct Cue tmp = mf->Cues[j+1]; - mf->Cues[j+1] = mf->Cues[j]; - mf->Cues[j] = tmp; - ++k; - } + if (mf->nCues > 0) + for (i = mf->nCues - 1, k = 1; i > 0 && k > 0; --i) + for (j = k = 0; j < i; ++j) + if (mf->Cues[j].Time > mf->Cues[j+1].Time) { + struct Cue tmp = mf->Cues[j+1]; + mf->Cues[j+1] = mf->Cues[j]; + mf->Cues[j] = tmp; + ++k; + } + + fixupCues(mf); } static void parseAttachment(MatroskaFile *mf,ulonglong toplen) { @@ -1313,11 +1533,11 @@ static void parseAttachment(MatroskaFile *mf,ulonglong toplen) { memcpy(pa,&a,sizeof(a)); if (a.Description) - pa->Description = strdup(a.Description); + pa->Description = mystrdup(mf->cache,a.Description); if (a.Name) - pa->Name = strdup(a.Name); + pa->Name = mystrdup(mf->cache,a.Name); if (a.MimeType) - pa->MimeType = strdup(a.MimeType); + pa->MimeType = mystrdup(mf->cache,a.MimeType); } static void parseAttachments(MatroskaFile *mf,ulonglong toplen) { @@ -1332,8 +1552,9 @@ static void parseAttachments(MatroskaFile *mf,ulonglong toplen) { static void parseChapter(MatroskaFile *mf,ulonglong toplen,struct Chapter *parent) { struct ChapterDisplay *disp; + struct ChapterProcess *proc; struct ChapterCommand *cmd; - struct Chapter *ch = ASGET(mf,parent,Children); + struct Chapter *ch = (Chapter *)ASGET(mf,parent,Children); memset(ch,0,sizeof(*ch)); @@ -1399,45 +1620,80 @@ static void parseChapter(MatroskaFile *mf,ulonglong toplen,struct Chapter *paren ENDFOR(mf); if (disp && !disp->String) { - free(disp->Language); - free(disp->Country); + mf->cache->memfree(mf->cache,disp->Language); + mf->cache->memfree(mf->cache,disp->Country); --ch->nDisplay; } break; - case 0x6944: // ChapterCommand - cmd = NULL; + case 0x6944: // ChapProcess + proc = NULL; FOREACH(mf,len) - case 0x6922: // ChapterCommandTime - if (cmd == NULL) { - cmd = ASGET(mf,ch,Commands); - memset(cmd, 0, sizeof(*cmd)); + case 0x6955: // ChapProcessCodecID + if (proc == NULL) { + proc = ASGET(mf, ch, Process); + memset(proc, 0, sizeof(*proc)); } - cmd->Time = readUInt(mf,(unsigned)len); + proc->CodecID = (unsigned)readUInt(mf,(unsigned)len); break; - case 0x6937: // ChapterCommandString - if (cmd == NULL) { - cmd = ASGET(mf,ch,Commands); - memset(cmd, 0, sizeof(*cmd)); + case 0x450d: // ChapProcessPrivate + if (proc == NULL) { + proc = ASGET(mf, ch, Process); + memset(proc, 0, sizeof(*proc)); } - if (cmd->String) - skipbytes(mf,len); - else - STRGETM(mf,cmd->String,len); + if (proc->CodecPrivate) + skipbytes(mf, len); + else { + proc->CodecPrivateLength = (unsigned)len; + STRGETM(mf,proc->CodecPrivate,len); + } + break; + case 0x6911: // ChapProcessCommand + if (proc == NULL) { + proc = ASGET(mf, ch, Process); + memset(proc, 0, sizeof(*proc)); + } + + cmd = NULL; + + FOREACH(mf,len) + case 0x6922: // ChapterCommandTime + if (cmd == NULL) { + cmd = ASGET(mf,proc,Commands); + memset(cmd, 0, sizeof(*cmd)); + } + cmd->Time = (unsigned)readUInt(mf,(unsigned)len); + break; + case 0x6933: // ChapterCommandString + if (cmd == NULL) { + cmd = ASGET(mf,proc,Commands); + memset(cmd, 0, sizeof(*cmd)); + } + if (cmd->Command) + skipbytes(mf,len); + else { + cmd->CommandLength = (unsigned)len; + STRGETM(mf,cmd->Command,len); + } + break; + ENDFOR(mf); + + if (cmd && !cmd->Command) + --proc->nCommands; break; ENDFOR(mf); - if (cmd && !cmd->String) - --ch->nCommands; + if (proc && !proc->nCommands) + --ch->nProcess; break; case 0xb6: // Nested ChapterAtom parseChapter(mf,len,ch); break; ENDFOR(mf); - ARELEASE(ch,Tracks); - ARELEASE(ch,Display); - ARELEASE(ch,Children); + ARELEASE(mf,ch,Tracks); + ARELEASE(mf,ch,Display); + ARELEASE(mf,ch,Children); } static void parseChapters(MatroskaFile *mf,ulonglong toplen) { @@ -1447,7 +1703,7 @@ static void parseChapters(MatroskaFile *mf,ulonglong toplen) { FOREACH(mf,toplen) case 0x45b9: // EditionEntry - ch = AGET(mf,Chapters); + ch = (Chapter *)AGET(mf,Chapters); memset(ch, 0, sizeof(*ch)); FOREACH(mf,len) case 0x45bc: // EditionUID @@ -1459,8 +1715,8 @@ static void parseChapters(MatroskaFile *mf,ulonglong toplen) { case 0x45db: // EditionFlagDefault ch->Default = readUInt(mf,(unsigned)len)!=0; break; - case 0x45dd: // EditionManaged - ch->Managed = readUInt(mf,(unsigned)len)!=0; + case 0x45dd: // EditionFlagOrdered + ch->Ordered = readUInt(mf,(unsigned)len)!=0; break; case 0xb6: // ChapterAtom parseChapter(mf,len,ch); @@ -1479,7 +1735,7 @@ static void parseTags(MatroskaFile *mf,ulonglong toplen) { FOREACH(mf,toplen) case 0x7373: // Tag - tag = AGET(mf,Tags); + tag = (Tag *)AGET(mf,Tags); memset(tag,0,sizeof(*tag)); FOREACH(mf,len) @@ -1536,8 +1792,8 @@ static void parseTags(MatroskaFile *mf,ulonglong toplen) { ENDFOR(mf); if (!st->Name || !st->Value) { - free(st->Name); - free(st->Value); + mf->cache->memfree(mf->cache,st->Name); + mf->cache->memfree(mf->cache,st->Value); --tag->nSimpleTags; } break; @@ -1591,8 +1847,12 @@ static void parsePointers(MatroskaFile *mf) { parseContainerPos(mf,mf->pCluster); if (mf->pTracks && !mf->seen.Tracks) parseContainerPos(mf,mf->pTracks); - if (mf->pCues && !mf->seen.Cues) + if (mf->pCues && !mf->seen.Cues) { parseContainerPos(mf,mf->pCues); + + // ignore errors + mf->flags &= ~MPF_ERROR; + } if (mf->pAttachments && !mf->seen.Attachments) parseContainerPos(mf,mf->pAttachments); if (mf->pChapters && !mf->seen.Chapters) @@ -1747,7 +2007,7 @@ found: nframes = c+1; } else nframes = 1; - sizes = alloca(nframes*sizeof(*sizes)); + sizes = (unsigned *)alloca(nframes*sizeof(*sizes)); switch (lacing) { case 0: // No lacing @@ -1904,7 +2164,7 @@ static int readMoreBlocks(MatroskaFile *mf) { if (++retries > 3) // don't try too hard goto ex; - for (;;cp) { // <-- XXX TODO FIX THIS! + for (;;) { if (filepos(mf) >= mf->pSegmentTop) { mf->readPosition = filepos(mf); goto ex; @@ -1941,7 +2201,7 @@ static int readMoreBlocks(MatroskaFile *mf) { seek(mf,mf->readPosition); - for (;;) { + while (filepos(mf) < mf->pSegmentTop) { cid = readID(mf); if (cid == EOF) { ret = EOF; @@ -1972,7 +2232,7 @@ static int readMoreBlocks(MatroskaFile *mf) { out:; } else { if (toplen > MAXFRAME) - errorjmp(mf,"Element in a cluster is too large %X [%u]",cid,(unsigned)toplen); + errorjmp(mf,"Element in a cluster is too large around %llu, %X [%u]",filepos(mf),cid,(unsigned)toplen); if (cid == 0xa0) // BlockGroup parseBlockGroup(mf,toplen,mf->tcCluster); else @@ -2019,8 +2279,173 @@ static int fillQueues(MatroskaFile *mf,unsigned int mask) { } } +static void reindex(MatroskaFile *mf) { + jmp_buf jb; + ulonglong pos = mf->pCluster; + ulonglong step = 10*1024*1024; + ulonglong size, tc, isize; + longlong next_cluster; + int id, have_tc, bad; + struct Cue *cue; + + if (pos >= mf->pSegmentTop) + return; + + if (pos + step * 10 > mf->pSegmentTop) + step = (mf->pSegmentTop - pos) / 10; + if (step == 0) + step = 1; + + memcpy(&jb,&mf->jb,sizeof(jb)); + + // remove all cues + mf->nCues = 0; + + bad = 0; + + while (pos < mf->pSegmentTop) { + if (!mf->cache->progress(mf->cache,pos,mf->pSegmentTop)) + break; + + if (++bad > 50) { + pos += step; + bad = 0; + continue; + } + + // find next cluster header + next_cluster = mf->cache->scan(mf->cache,pos,0x1f43b675); // cluster + if (next_cluster < 0 || (ulonglong)next_cluster >= mf->pSegmentTop) + break; + + pos = next_cluster + 4; // prevent endless loops + + if (setjmp(mf->jb)) // something evil happened while reindexing + continue; + + seek(mf,next_cluster); + + id = readID(mf); + if (id == EOF) + break; + if (id != 0x1f43b675) // shouldn't happen + continue; + + size = readVLUInt(mf); + if (size >= MAXCLUSTER || size < 1024) + continue; + + have_tc = 0; + size += filepos(mf); + + while (filepos(mf) < (ulonglong)next_cluster + 1024) { + id = readID(mf); + if (id == EOF) + break; + + isize = readVLUInt(mf); + + if (id == 0xe7) { // cluster timecode + tc = readUInt(mf,(unsigned)isize); + have_tc = 1; + break; + } + + skipbytes(mf,isize); + } + + if (!have_tc) + continue; + + seek(mf,size); + id = readID(mf); + + if (id == EOF) + break; + + if (id != 0x1f43b675) // cluster + continue; + + // good cluster, remember it + cue = AGET(mf,Cues); + cue->Time = tc; + cue->Position = next_cluster - mf->pSegment; + cue->Block = 0; + cue->Track = 0; + + // advance to the next point + pos = next_cluster + step; + if (pos < size) + pos = size; + + bad = 0; + } + + fixupCues(mf); + + if (mf->nCues == 0) { + cue = AGET(mf,Cues); + cue->Time = mf->firstTimecode; + cue->Position = mf->pCluster - mf->pSegment; + cue->Block = 0; + cue->Track = 0; + } + + mf->cache->progress(mf->cache,0,0); + + memcpy(&mf->jb,&jb,sizeof(jb)); +} + +static void fixupChapter(ulonglong adj, struct Chapter *ch) { + unsigned i; + + if (ch->Start != 0) + ch->Start -= adj; + if (ch->End != 0) + ch->End -= adj; + + for (i=0;inChildren;++i) + fixupChapter(adj,&ch->Children[i]); +} + +static longlong findLastTimecode(MatroskaFile *mf) { + ulonglong nd = 0; + unsigned n,vtrack; + + if (mf->nCues == 0 || mf->nTracks == 0) + return -1; + + for (n=vtrack=0;nnTracks;++n) + if (mf->Tracks[n]->Type == TT_VIDEO) { + vtrack = n; + goto ok; + } + + return -1; +ok: + + mf->trackMask = ~(1 << vtrack); + mf->readPosition = mf->Cues[mf->nCues - 1].Position + mf->pSegment; + mf->tcCluster = mf->Cues[mf->nCues - 1].Time / mf->Seg.TimecodeScale; + + do + while (mf->Queues[vtrack].head) + { + ulonglong tc = mf->Queues[vtrack].head->flags & FRAME_UNKNOWN_END ? + mf->Queues[vtrack].head->Start : mf->Queues[vtrack].head->End; + if (nd < tc) + nd = tc; + QFree(mf,QGet(&mf->Queues[vtrack])); + } + while (readMoreBlocks(mf) != EOF); + + mf->trackMask = 0; + + return nd; +} + static void parseFile(MatroskaFile *mf) { - ulonglong len; + ulonglong len = filepos(mf), adjust; unsigned i; int id = readID(mf); int m; @@ -2028,6 +2453,11 @@ static void parseFile(MatroskaFile *mf) { if (id==EOF) errorjmp(mf,"Unexpected EOF at start of file"); + // files with multiple concatenated segments can have only + // one EBML prolog + if (len > 0 && id == 0x18538067) + goto segment; + if (id!=0x1a45dfa3) errorjmp(mf,"First element in file is not EBML"); @@ -2038,6 +2468,7 @@ static void parseFile(MatroskaFile *mf) { id = readID(mf); if (id==EOF) errorjmp(mf,"No segments found in the file"); +segment: len = readVLUIntImp(mf,&m); // see if it's unspecified if (len == (MAXU64 >> (57-m*7))) @@ -2060,50 +2491,65 @@ static void parseFile(MatroskaFile *mf) { if (!mf->seen.Cluster) errorjmp(mf,"Couldn't find any Clusters"); - // ensure we have cues - if (mf->nCues == 0) - addCue(mf,mf->pCluster,mf->firstTimecode); + adjust = mf->firstTimecode * mf->Seg.TimecodeScale; + + for (i=0;inChapters;++i) + fixupChapter(adjust, &mf->Chapters[i]); // release extra memory - ARELEASE(mf,Tracks); - - // adjust cues - for (i=0;inCues;++i) - mf->Cues[i].Time *= mf->Seg.TimecodeScale; + ARELEASE(mf,mf,Tracks); // initialize reader - mf->readPosition = mf->pCluster; - mf->Queues = malloc(mf->nTracks * sizeof(*mf->Queues)); + mf->Queues = mf->cache->memalloc(mf->cache,mf->nTracks * sizeof(*mf->Queues)); if (mf->Queues == NULL) errorjmp(mf, "Ouf of memory"); memset(mf->Queues, 0, mf->nTracks * sizeof(*mf->Queues)); + + // try to detect real duration + if (!(mf->flags & MKVF_AVOID_SEEKS)) { + longlong nd = findLastTimecode(mf); + if (nd > 0) + mf->Seg.Duration = nd; + } + + // move to first frame + mf->readPosition = mf->pCluster; + mf->tcCluster = mf->firstTimecode; } -static void DeleteChapter(struct Chapter *ch) { - unsigned i; +static void DeleteChapter(MatroskaFile *mf,struct Chapter *ch) { + unsigned i,j; for (i=0;inDisplay;++i) { - free(ch->Display[i].String); - free(ch->Display[i].Language); - free(ch->Display[i].Country); + mf->cache->memfree(mf->cache,ch->Display[i].String); + mf->cache->memfree(mf->cache,ch->Display[i].Language); + mf->cache->memfree(mf->cache,ch->Display[i].Country); } - free(ch->Display); - free(ch->Tracks); + mf->cache->memfree(mf->cache,ch->Display); + mf->cache->memfree(mf->cache,ch->Tracks); + + for (i=0;inProcess;++i) { + for (j=0;jProcess[i].nCommands;++j) + mf->cache->memfree(mf->cache,ch->Process[i].Commands[j].Command); + mf->cache->memfree(mf->cache,ch->Process[i].Commands); + mf->cache->memfree(mf->cache,ch->Process[i].CodecPrivate); + } + mf->cache->memfree(mf->cache,ch->Process); for (i=0;inChildren;++i) - DeleteChapter(&ch->Children[i]); - free(ch->Children); + DeleteChapter(mf,&ch->Children[i]); + mf->cache->memfree(mf->cache,ch->Children); } /////////////////////////////////////////////////////////////////////////// // public interface -MatroskaFile *mkv_OpenEx(FileCache *io, +MatroskaFile *mkv_OpenEx(InputStream *io, + ulonglong base, unsigned flags, char *err_msg,unsigned msgsize) { - MatroskaFile *mf = malloc(sizeof(*mf)); + MatroskaFile *mf = (MatroskaFile *)io->memalloc(io,sizeof(*mf)); if (mf == NULL) { - io->close(io); strlcpy(err_msg,"Out of memory",msgsize); return NULL; } @@ -2112,10 +2558,12 @@ MatroskaFile *mkv_OpenEx(FileCache *io, mf->cache = io; mf->flags = flags; + io->progress(io,0,0); - if (setjmp(mf->jb)==0) + if (setjmp(mf->jb)==0) { + seek(mf,base); parseFile(mf); - else { // parser error + } else { // parser error strlcpy(err_msg,mf->errmsg,msgsize); mkv_Close(mf); return NULL; @@ -2124,95 +2572,59 @@ MatroskaFile *mkv_OpenEx(FileCache *io, return mf; } -MatroskaFile *mkv_Open(FileCache *io, +MatroskaFile *mkv_Open(InputStream *io, char *err_msg,unsigned msgsize) { - return mkv_OpenEx(io,0,err_msg,msgsize); + return mkv_OpenEx(io,0,0,err_msg,msgsize); } -#if 0 -MatroskaFile *mkv_OpenFile(const char *filename, - unsigned cache_size, - unsigned flags, - char *err_msg, - unsigned msgsize) -{ - InputFile *ii; - FileCache *cc; - unsigned pages,psize; - - if (cache_size > 0) { - psize = DEFAULT_PAGE_SIZE; - pages = cache_size / DEFAULT_PAGE_SIZE; - if (pages < MIN_PAGES) - pages = MIN_PAGES; - } else { - psize = MIN_PAGE_SIZE; - pages = MIN_PAGES; - } - - if ((ii = fileio_open(filename,err_msg,msgsize)) == NULL) - return NULL; - - if ((cc = CacheAlloc(ii,pages,psize)) == NULL) { - ii->close(ii); - strlcpy(err_msg,"Can't allocate file cache",msgsize); - return NULL; - } - - return mkv_OpenEx(cc,flags,err_msg,msgsize); -} -#endif - void mkv_Close(MatroskaFile *mf) { unsigned i,j; if (mf==NULL) return; - mf->cache->close(mf->cache); - for (i=0;inTracks;++i) - free(mf->Tracks[i]); - free(mf->Tracks); + mf->cache->memfree(mf->cache,mf->Tracks[i]); + mf->cache->memfree(mf->cache,mf->Tracks); for (i=0;inQBlocks;++i) - free(mf->QBlocks[i]); - free(mf->QBlocks); + mf->cache->memfree(mf->cache,mf->QBlocks[i]); + mf->cache->memfree(mf->cache,mf->QBlocks); - free(mf->Queues); + mf->cache->memfree(mf->cache,mf->Queues); - free(mf->Seg.Title); - free(mf->Seg.MuxingApp); - free(mf->Seg.WritingApp); - free(mf->Seg.Filename); - free(mf->Seg.NextFilename); - free(mf->Seg.PrevFilename); + mf->cache->memfree(mf->cache,mf->Seg.Title); + mf->cache->memfree(mf->cache,mf->Seg.MuxingApp); + mf->cache->memfree(mf->cache,mf->Seg.WritingApp); + mf->cache->memfree(mf->cache,mf->Seg.Filename); + mf->cache->memfree(mf->cache,mf->Seg.NextFilename); + mf->cache->memfree(mf->cache,mf->Seg.PrevFilename); - free(mf->Cues); + mf->cache->memfree(mf->cache,mf->Cues); for (i=0;inAttachments;++i) { - free(mf->Attachments[i].Description); - free(mf->Attachments[i].Name); - free(mf->Attachments[i].MimeType); + mf->cache->memfree(mf->cache,mf->Attachments[i].Description); + mf->cache->memfree(mf->cache,mf->Attachments[i].Name); + mf->cache->memfree(mf->cache,mf->Attachments[i].MimeType); } - free(mf->Attachments); + mf->cache->memfree(mf->cache,mf->Attachments); for (i=0;inChapters;++i) - DeleteChapter(&mf->Chapters[i]); - free(mf->Chapters); + DeleteChapter(mf,&mf->Chapters[i]); + mf->cache->memfree(mf->cache,mf->Chapters); for (i=0;inTags;++i) { for (j=0;jTags[i].nSimpleTags;++j) { - free(mf->Tags[i].SimpleTags[j].Name); - free(mf->Tags[i].SimpleTags[j].Value); + mf->cache->memfree(mf->cache,mf->Tags[i].SimpleTags[j].Name); + mf->cache->memfree(mf->cache,mf->Tags[i].SimpleTags[j].Value); } - free(mf->Tags[i].Targets); - free(mf->Tags[i].SimpleTags); + mf->cache->memfree(mf->cache,mf->Tags[i].Targets); + mf->cache->memfree(mf->cache,mf->Tags[i].SimpleTags); } - free(mf->Tags); + mf->cache->memfree(mf->cache,mf->Tags); - free(mf); + mf->cache->memfree(mf->cache,mf); } const char *mkv_GetLastError(MatroskaFile *mf) { @@ -2249,6 +2661,10 @@ void mkv_GetTags(MatroskaFile *mf,Tag **tag,unsigned *count) { *count = mf->nTags; } +ulonglong mkv_GetSegmentTop(MatroskaFile *mf) { + return mf->pSegmentTop; +} + #define IS_DELTA(f) (!((f)->flags & FRAME_KF) || ((f)->flags & FRAME_UNKNOWN_START)) void mkv_Seek(MatroskaFile *mf,ulonglong timecode,unsigned flags) { @@ -2257,7 +2673,22 @@ void mkv_Seek(MatroskaFile *mf,ulonglong timecode,unsigned flags) { ulonglong m_kftime[MAX_TRACKS]; unsigned char m_seendf[MAX_TRACKS]; - if ((mf->flags & MKVF_AVOID_SEEKS) || mf->nCues==0) + if (mf->flags & MKVF_AVOID_SEEKS) + return; + + if (timecode == 0) { + EmptyQueues(mf); + mf->readPosition = mf->pCluster; + mf->tcCluster = mf->firstTimecode; + mf->flags &= ~MPF_ERROR; + + return; + } + + if (mf->nCues==0) + reindex(mf); + + if (mf->nCues==0) return; mf->flags &= ~MPF_ERROR; @@ -2289,6 +2720,7 @@ void mkv_Seek(MatroskaFile *mf,ulonglong timecode,unsigned flags) { EmptyQueues(mf); mf->readPosition = mf->Cues[j].Position + mf->pSegment; + mf->tcCluster = mf->Cues[j].Time / mf->Seg.TimecodeScale; for (;;) { if ((ret = fillQueues(mf,0)) < 0 || ret == RBRESYNC) @@ -2343,6 +2775,7 @@ again:; EmptyQueues(mf); mf->readPosition = mf->Cues[j].Position + mf->pSegment; + mf->tcCluster = mf->Cues[j].Time / mf->Seg.TimecodeScale; for (mask=0;;) { if ((ret = fillQueues(mf,mask)) < 0 || ret == RBRESYNC) @@ -2429,7 +2862,7 @@ ulonglong mkv_GetLowestQTimecode(MatroskaFile *mf) { if (mf->Queues[n].head && (!seen || t > mf->Queues[n].head->Start)) t = mf->Queues[n].head->Start, seen=1; - return seen ? t : -1; + return seen ? t : (ulonglong)LL(-1); } int mkv_TruncFloat(MKFLOAT f) { @@ -2464,9 +2897,6 @@ int mkv_ReadFrame(MatroskaFile *mf, unsigned int i,j; struct QueueEntry *qe; - if (mf->flags & MPF_ERROR) - return -1; - if (setjmp(mf->jb)!=0) return -1; @@ -2498,28 +2928,15 @@ int mkv_ReadFrame(MatroskaFile *mf, return 0; } + + if (mf->flags & MPF_ERROR) + return -1; + } while (fillQueues(mf,mask)>=0); return EOF; } -int mkv_ReadData(MatroskaFile *mf,ulonglong FilePos, - void *Buffer,unsigned int Count) -{ - int rd; - - if (mf->flags & MPF_ERROR) - return -1; - - rd = mf->cache->read(mf->cache,FilePos,Buffer,Count); - if (rd<0) { - const char *ce = mf->cache->geterror(mf->cache); - snprintf(mf->errmsg,sizeof(mf->errmsg),"I/O Error: %s",ce); - return -1; - } - return rd; -} - #ifdef MATROSKA_COMPRESSION_SUPPORT /************************************************************************* * Compressed streams support @@ -2567,7 +2984,7 @@ CompressedStream *cs_Create(/* in */ MatroskaFile *mf, return NULL; } - cs = malloc(sizeof(*cs)); + cs = mf->cache->memalloc(mf->cache,sizeof(*cs)); if (cs == NULL) { strlcpy(errormsg, "Ouf of memory.", msgsize); return NULL; @@ -2577,7 +2994,7 @@ CompressedStream *cs_Create(/* in */ MatroskaFile *mf, code = inflateInit(&cs->zs); if (code != Z_OK) { strlcpy(errormsg, "ZLib error.", msgsize); - free(cs); + mf->cache->memfree(mf->cache,cs); return NULL; } @@ -2593,7 +3010,7 @@ void cs_Destroy(/* in */ CompressedStream *cs) { return; inflateEnd(&cs->zs); - free(cs); + cs->mf->cache->memfree(cs->mf->cache,cs); } /* advance to the next frame in matroska stream, you need to pass values returned @@ -2609,6 +3026,11 @@ void cs_NextFrame(/* in */ CompressedStream *cs, cs->decoded_ptr = cs->decoded_size = 0; } +int mkv_ReadData(MatroskaFile *mf,ulonglong FilePos, void *Buffer,unsigned int Count) +{ + return (mf->cache->read(mf->cache, FilePos, Buffer, Count) != Count); +} + /* read and decode more data from current frame, return number of bytes decoded, * 0 on end of frame, or -1 on error */ int cs_ReadData(CompressedStream *cs,char *buffer,unsigned bufsize) @@ -2641,8 +3063,8 @@ int cs_ReadData(CompressedStream *cs,char *buffer,unsigned bufsize) if (todo > sizeof(cs->frame_buffer)) todo = sizeof(cs->frame_buffer); - if (mkv_ReadData(cs->mf, cs->frame_pos, cs->frame_buffer, todo)<0) { - strlcpy(cs->errmsg, mkv_GetLastError(cs->mf), sizeof(cs->errmsg)); + if (cs->mf->cache->read(cs->mf->cache, cs->frame_pos, cs->frame_buffer, todo) != (int)todo) { + strlcpy(cs->errmsg, "File read failed", sizeof(cs->errmsg)); return -1; } diff --git a/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.h b/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.h index 4d87e3830d..dfbe36f43f 100644 --- a/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.h +++ b/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Mike Matsnev. All Rights Reserved. + * Copyright (c) 2004-2005 Mike Matsnev. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: MatroskaParser.h,v 1.3 2004/09/17 12:59:07 mike Exp $ + * $Id: MatroskaParser.h,v 1.10 2005/01/10 04:52:34 mike Exp $ * */ @@ -53,7 +53,7 @@ #endif #define MATROSKA_COMPRESSION_SUPPORT -#undef MATROSKA_INTEGER_ONLY +//#define MATROSKA_INTEGER_ONLY #ifdef __cplusplus extern "C" { @@ -78,39 +78,24 @@ typedef double MKFLOAT; #endif /* generic I/O */ -struct InputFile { - /* reading files - * Matroska parser does internal buffering and will can these - * functions with suitably aligned buffers and offsets */ - int (*read)(struct InputFile *inf,void *buffer,int count); - longlong (*seek)(struct InputFile *inf,longlong where,int how); - void (*close)(struct InputFile *inf); - - /* allocate a suitably aligned buffer */ - void *(*memalloc)(struct InputFile *inf, unsigned size); - void (*memfree)(struct InputFile *inf, void *mem, unsigned size); - - /* error message for last operation */ - const char *last_error; +struct InputStream { + /* read bytes from stream */ + int (*read)(struct InputStream *cc,ulonglong pos,void *buffer,int count); + /* scan for a four byte signature, bytes must be nonzero */ + longlong (*scan)(struct InputStream *cc,ulonglong start,unsigned signature); + /* get cache size, this is used to cap readahead */ + unsigned (*getsize)(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,ulonglong cur,ulonglong max); }; -typedef struct InputFile InputFile; - -X InputFile *fileio_open(/* in */ const char *filename, - /* out */ char *errormsg, - /* in */ int msglen); - -struct FileCache { - int (*read)(struct FileCache *cc,ulonglong pos,void *buffer,int count); - longlong (*scan)(struct FileCache *cc,ulonglong start,unsigned signature); - void (*close)(struct FileCache *cc); - unsigned (*getsize)(struct FileCache *cc); - const char *(*geterror)(struct FileCache *cc); -}; - -typedef struct FileCache FileCache; - -FileCache *CacheAlloc(InputFile *io, unsigned pages, unsigned pagesize); +typedef struct InputStream InputStream; /* matroska file */ struct MatroskaFile; /* opaque */ @@ -119,6 +104,10 @@ typedef struct MatroskaFile MatroskaFile; #define COMP_ZLIB 0 +#define TT_VIDEO 1 +#define TT_AUDIO 2 +#define TT_SUB 17 + struct TrackInfo { unsigned char Number; unsigned char Type; @@ -131,12 +120,15 @@ struct TrackInfo { void *CodecPrivate; unsigned CodecPrivateSize; unsigned CompMethod; + struct { 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; @@ -147,7 +139,9 @@ struct TrackInfo { unsigned int DisplayHeight; unsigned int ColourSpace; MKFLOAT GammaValue; + struct { unsigned int Interlaced:1; + }; } Video; struct { MKFLOAT SamplingFreq; @@ -155,6 +149,7 @@ struct TrackInfo { unsigned char Channels; unsigned char BitDepth; } Audio; + }; /* various strings */ char *Name; @@ -199,8 +194,17 @@ struct ChapterDisplay { }; struct ChapterCommand { - ulonglong Time; - char *String; + unsigned Time; + unsigned CommandLength; + char *Command; +}; + +struct ChapterProcess { + unsigned CodecID; + unsigned CodecPrivateLength; + char *CodecPrivate; + unsigned nCommands,nCommandsSize; + struct ChapterCommand *Commands; }; struct Chapter { @@ -214,15 +218,17 @@ struct Chapter { struct ChapterDisplay *Display; unsigned nChildren,nChildrenSize; struct Chapter *Children; - unsigned nCommands,nCommandsSize; - struct ChapterCommand *Commands; + unsigned nProcess,nProcessSize; + struct ChapterProcess *Process; + struct { unsigned int Hidden:1; unsigned int Enabled:1; // Editions - unsigned int Managed:1; unsigned int Default:1; + unsigned int Ordered:1; + }; }; typedef struct Chapter Chapter; @@ -253,30 +259,25 @@ struct Tag { typedef struct Tag Tag; -/* Open a matroska file, ownership of io is passed to MatroskaFile - * if Open fails, io is still closed and destroyed +/* Open a matroska file + * io pointer is recorded inside MatroskaFile */ -X MatroskaFile *mkv_Open(/* in */ FileCache *io, +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 */ FileCache *io, +X MatroskaFile *mkv_OpenEx(/* in */ InputStream *io, + /* in */ ulonglong base, /* in */ unsigned flags, /* out */ char *err_msg, /* in */ unsigned msgsize); -X MatroskaFile *mkv_OpenFile(/* in */ const char *filename, - /* in */ unsigned cache_size, - /* in */ unsigned flags, - /* out */ char *err_msg, - /* in */ unsigned msgsize); - -/* Close and deallocate mf, this close the underlying InputFile +/* Close and deallocate mf * NULL pointer is ok and is simply ignored */ -X void mkv_Close(/* in */ MatroskaFile *mf); +X void mkv_Close(/* in */ MatroskaFile *mf); /* Fetch the error message of the last failed operation */ X const char *mkv_GetLastError(/* in */ MatroskaFile *mf); @@ -299,6 +300,8 @@ X void mkv_GetTags(/* in */ MatroskaFile *mf, /* out */ Tag **tag, /* out */ unsigned *count); +X ulonglong mkv_GetSegmentTop(MatroskaFile *mf); + /* Seek to specified timecode, * if timecode is past end of file, * all tracks are set to return EOF diff --git a/src/add-ons/media/plugins/matroska/libMatroskaParser/StreamIO.cpp b/src/add-ons/media/plugins/matroska/libMatroskaParser/StreamIO.cpp index feb5175f56..b2bfdcb283 100644 --- a/src/add-ons/media/plugins/matroska/libMatroskaParser/StreamIO.cpp +++ b/src/add-ons/media/plugins/matroska/libMatroskaParser/StreamIO.cpp @@ -28,45 +28,70 @@ #include "StreamIO.h" struct StreamIO { - FileCache filecache; + InputStream filecache; BPositionIO *source; }; static int -stream_read(struct FileCache *cc, ulonglong pos, void *buffer, int count) +stream_read(struct InputStream *cc, ulonglong pos, void *buffer, int count) { return reinterpret_cast(cc)->source->ReadAt(pos, buffer, count); } - +// Only needed if resync required. static longlong -stream_scan(struct FileCache *cc, ulonglong start, unsigned signature) +stream_scan(struct InputStream *cc, ulonglong start, unsigned signature) { return -1; } +//static void +//stream_close(struct InputStream *cc) +//{ +//} -static void -stream_close(struct FileCache *cc) -{ -} - - +// Size of a buffer +// we might want to test against bytes remaining in file. static unsigned -stream_getsize(struct FileCache *cc) +stream_getsize(struct InputStream *cc) { return 524288; } - static const char * -stream_geterror(struct FileCache *cc) +stream_geterror(struct InputStream *cc) { return ""; } +/* memory allocation */ +static void * +stream_memalloc(struct InputStream *cc, size_t size) +{ + return malloc(size); +} -FileCache * +static void * +stream_memrealloc(struct InputStream *cc,void *mem,size_t newsize) +{ + return realloc(mem,newsize); +} + +static void +stream_memfree(struct InputStream *cc, void *mem) +{ + free(mem); +} + +// zero return causes parser to abort open +static int +stream_progress(struct InputStream *cc, ulonglong cur, ulonglong max) +{ +// no idea what this function is supposed to do. + return max-cur; +} + +InputStream * CreateFileCache(BDataIO *dataio) { BPositionIO *posio; @@ -81,11 +106,15 @@ CreateFileCache(BDataIO *dataio) io->filecache.read = &stream_read; io->filecache.scan = &stream_scan; - io->filecache.close = &stream_close; +// io->filecache.close = &stream_close; io->filecache.getsize = &stream_getsize; io->filecache.geterror = &stream_geterror; + io->filecache.memalloc = &stream_memalloc; + io->filecache.memrealloc = &stream_memrealloc; + io->filecache.memfree = &stream_memfree; + io->filecache.progress = &stream_progress; io->source = posio; - return reinterpret_cast(io); + return reinterpret_cast(io); } diff --git a/src/add-ons/media/plugins/matroska/libMatroskaParser/StreamIO.h b/src/add-ons/media/plugins/matroska/libMatroskaParser/StreamIO.h index 8301e36b9a..c9e77e1d76 100644 --- a/src/add-ons/media/plugins/matroska/libMatroskaParser/StreamIO.h +++ b/src/add-ons/media/plugins/matroska/libMatroskaParser/StreamIO.h @@ -28,6 +28,6 @@ #include #include "MatroskaParser.h" -FileCache *CreateFileCache(BDataIO *dataio); +InputStream *CreateFileCache(BDataIO *dataio); #endif diff --git a/src/add-ons/media/plugins/matroska/libebml/Debug.cpp b/src/add-ons/media/plugins/matroska/libebml/Debug.cpp index 5f1b8ee1d5..b9bd654bc0 100644 --- a/src/add-ons/media/plugins/matroska/libebml/Debug.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/Debug.cpp @@ -30,7 +30,7 @@ /*! \file - \version \$Id: Debug.cpp 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: Debug.cpp 1268 2007-01-19 10:15:08Z robux4 $ \author Steve Lhomme \author Moritz Bunkus */ @@ -84,7 +84,7 @@ inline int ADbg::_OutPut(const char * format,va_list params) const SYSTEMTIME time; GetSystemTime(&time); if (prefix[0] == '\0') - wsprintf(myformat,"%04d/%02d/%02d %02d:%02d:%02d.%03d UTC : %s\r\n", + wsprintfA(myformat,"%04d/%02d/%02d %02d:%02d:%02d.%03d UTC : %s\r\n", time.wYear, time.wMonth, time.wDay, @@ -94,7 +94,7 @@ inline int ADbg::_OutPut(const char * format,va_list params) const time.wMilliseconds, format); else - wsprintf(myformat,"%04d/%02d/%02d %02d:%02d:%02d.%03d UTC : %s - %s\r\n", + wsprintfA(myformat,"%04d/%02d/%02d %02d:%02d:%02d.%03d UTC : %s - %s\r\n", time.wYear, time.wMonth, time.wDay, @@ -106,19 +106,19 @@ inline int ADbg::_OutPut(const char * format,va_list params) const format); } else { if (prefix[0] == '\0') - wsprintf( myformat, "%s\r\n", format); + wsprintfA( myformat, "%s\r\n", format); else - wsprintf( myformat, "%s - %s\r\n", prefix, format); + wsprintfA( myformat, "%s - %s\r\n", prefix, format); } result = vsprintf(tst,myformat,params); if (my_debug_output) - OutputDebugString(tst); + OutputDebugStringA(tst); if (my_use_file && (hFile != NULL)) { SetFilePointer( hFile, 0, 0, FILE_END ); DWORD written; - WriteFile( hFile, tst, lstrlen(tst), &written, NULL ); + WriteFile( hFile, tst, lstrlenA(tst), &written, NULL ); } #else if (my_time_included) { @@ -133,12 +133,12 @@ inline int ADbg::_OutPut(const char * format,va_list params) const sprintf(myformat,"%04d/%02d/%02d %02d:%02d:%02ld.%03ld UTC : %s\r\n", now->tm_year, now->tm_mon, now->tm_mday, now->tm_hour, now->tm_min, tv.tv_sec, - tv.tv_usec / 1000, format); + (long)tv.tv_usec / 1000, format); else sprintf(myformat,"%04d/%02d/%02d %02d:%02d:%02ld.%03ld UTC : %s - %s\r\n", now->tm_year, now->tm_mon, now->tm_mday, now->tm_hour, now->tm_min, tv.tv_sec, - tv.tv_usec / 1000, prefix, format); + (long)tv.tv_usec / 1000, prefix, format); } else { if (prefix[0] == '\0') @@ -192,7 +192,7 @@ bool ADbg::setDebugFile(const char * NewFilename) { result = false; #ifdef WIN32 - hFile = CreateFile(NewFilename, GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + hFile = CreateFileA(NewFilename, GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if (hFile != INVALID_HANDLE_VALUE) { SetFilePointer( hFile, 0, 0, FILE_END ); diff --git a/src/add-ons/media/plugins/matroska/libebml/EbmlBinary.cpp b/src/add-ons/media/plugins/matroska/libebml/EbmlBinary.cpp index 440e0d9950..d23a88d4fb 100644 --- a/src/add-ons/media/plugins/matroska/libebml/EbmlBinary.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/EbmlBinary.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlBinary.cpp 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlBinary.cpp 1112 2005-03-28 09:55:50Z mosu $ \author Steve Lhomme \author Julien Coloos */ @@ -44,26 +44,24 @@ EbmlBinary::EbmlBinary() :EbmlElement(0, false), Data(NULL) {} -/*! - \todo shouldn't we copy the Data if they exist ??? -*/ EbmlBinary::EbmlBinary(const EbmlBinary & ElementToClone) :EbmlElement(ElementToClone) { if (ElementToClone.Data == NULL) Data = NULL; else { - Data = new binary[Size]; + Data = (binary *)malloc(Size * sizeof(binary)); + assert(Data != NULL); memcpy(Data, ElementToClone.Data, Size); } } EbmlBinary::~EbmlBinary(void) { if(Data) - delete[] Data; + free(Data); } -uint32 EbmlBinary::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault) +uint32 EbmlBinary::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact) { output.writeFully(Data,Size); @@ -73,7 +71,7 @@ uint32 EbmlBinary::RenderData(IOCallback & output, bool bForceRender, bool bSave /*! \note no Default binary value handled */ -uint64 EbmlBinary::UpdateSize(bool bSaveDefault, bool bForceRender) +uint64 EbmlBinary::UpdateSize(bool bKeepIntact, bool bForceRender) { return Size; } @@ -81,7 +79,7 @@ uint64 EbmlBinary::UpdateSize(bool bSaveDefault, bool bForceRender) uint64 EbmlBinary::ReadData(IOCallback & input, ScopeMode ReadFully) { if (Data != NULL) - delete Data; + free(Data); if (ReadFully == SCOPE_NO_DATA) { @@ -89,9 +87,15 @@ uint64 EbmlBinary::ReadData(IOCallback & input, ScopeMode ReadFully) return Size; } - Data = new binary[Size]; + Data = (binary *)malloc(Size * sizeof(binary)); + assert(Data != NULL); bValueIsSet = true; return input.read(Data, Size); } +bool EbmlBinary::operator==(const EbmlBinary & ElementToCompare) const +{ + return ((Size == ElementToCompare.Size) && !memcmp(Data, ElementToCompare.Data, Size)); +} + END_LIBEBML_NAMESPACE diff --git a/src/add-ons/media/plugins/matroska/libebml/EbmlCrc32.cpp b/src/add-ons/media/plugins/matroska/libebml/EbmlCrc32.cpp index e4520a0007..bb66c5a5a9 100644 --- a/src/add-ons/media/plugins/matroska/libebml/EbmlCrc32.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/EbmlCrc32.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlCrc32.cpp 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlCrc32.cpp 1155 2005-05-06 11:43:38Z robux4 $ \author Steve Lhomme \author Jory Stone */ @@ -41,10 +41,10 @@ START_LIBEBML_NAMESPACE EbmlId EbmlCrc32_TheId(0xBF, 1); -const EbmlCallbacks EbmlCrc32::ClassInfos(EbmlCrc32::Create, EbmlCrc32_TheId, "EBMLCrc32", EbmlVoid_Context); +const EbmlCallbacks EbmlCrc32::ClassInfos(EbmlCrc32::Create, EbmlCrc32_TheId, "EBMLCrc32\0ratamadabapa", EbmlVoid_Context); const uint32 EbmlCrc32::m_tab[] = { -#if WORDS_BIGENDIAN +#ifdef WORDS_BIGENDIAN 0x00000000L, 0x96300777L, 0x2c610eeeL, 0xba510999L, 0x19c46d07L, 0x8ff46a70L, 0x35a563e9L, 0xa395649eL, 0x3288db0eL, 0xa4b8dc79L, 0x1ee9d5e0L, 0x88d9d297L, 0x2b4cb609L, 0xbd7cb17eL, 0x072db8e7L, @@ -193,7 +193,7 @@ bool EbmlCrc32::CheckElementCRC32(EbmlElement &ElementToCRC) return CheckCRC(m_crc_final, memoryBuffer.GetDataBuffer(), memoryBuffer.GetDataBufferSize()); }; -uint32 EbmlCrc32::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault) +uint32 EbmlCrc32::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact) { uint32 Result = DIGESTSIZE; diff --git a/src/add-ons/media/plugins/matroska/libebml/EbmlDate.cpp b/src/add-ons/media/plugins/matroska/libebml/EbmlDate.cpp index ce5c6f23d1..32d49abac0 100644 --- a/src/add-ons/media/plugins/matroska/libebml/EbmlDate.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/EbmlDate.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ /*! \file - \version \$Id: EbmlDate.cpp 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlDate.cpp 1079 2005-03-03 13:18:14Z robux4 $ \author Steve Lhomme */ #include @@ -65,7 +65,7 @@ uint64 EbmlDate::ReadData(IOCallback & input, ScopeMode ReadFully) return Size; } -uint32 EbmlDate::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault) +uint32 EbmlDate::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact) { if (Size != 0) { assert(Size == 8); diff --git a/src/add-ons/media/plugins/matroska/libebml/EbmlElement.cpp b/src/add-ons/media/plugins/matroska/libebml/EbmlElement.cpp index 73c57dcc50..50f3b16ff2 100644 --- a/src/add-ons/media/plugins/matroska/libebml/EbmlElement.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/EbmlElement.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ /*! \file - \version \$Id: EbmlElement.cpp 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlElement.cpp 1232 2005-10-15 15:56:52Z robux4 $ \author Steve Lhomme */ @@ -46,20 +46,32 @@ START_LIBEBML_NAMESPACE /*! \todo handle more than CodedSize of 5 */ -int CodedSizeLength(uint64 Length, unsigned int SizeLength) +int CodedSizeLength(uint64 Length, unsigned int SizeLength, bool bSizeFinite) { - unsigned int CodedSize; - // prepare the head of the size (000...01xxxxxx) - // optimal size - if (Length < 127) // 2^7 - 1 - CodedSize = 1; - else if (Length < 16383) // 2^14 - 1 - CodedSize = 2; - else if (Length < 2097151L) // 2^21 - 1 - CodedSize = 3; - else if (Length < 268435455L) // 2^28 - 1 - CodedSize = 4; - else CodedSize = 5; + int CodedSize; + if (bSizeFinite) { + // prepare the head of the size (000...01xxxxxx) + // optimal size + if (Length < 127) // 2^7 - 1 + CodedSize = 1; + else if (Length < 16383) // 2^14 - 1 + CodedSize = 2; + else if (Length < 2097151L) // 2^21 - 1 + CodedSize = 3; + else if (Length < 268435455L) // 2^28 - 1 + CodedSize = 4; + else CodedSize = 5; + } else { + if (Length <= 127) // 2^7 - 1 + CodedSize = 1; + else if (Length <= 16383) // 2^14 - 1 + CodedSize = 2; + else if (Length <= 2097151L) // 2^21 - 1 + CodedSize = 3; + else if (Length <= 268435455L) // 2^28 - 1 + CodedSize = 4; + else CodedSize = 5; + } if (SizeLength > 0 && CodedSize < SizeLength) { // defined size @@ -328,7 +340,7 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe bool bFound; int UpperLevel_original = UpperLevel; - while (1) { + do { // read a potential ID do { assert(ReadIndex < 16); @@ -359,7 +371,7 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe } ReadSize++; - } while (!bFound); + } while (!bFound && MaxDataSize > ReadSize); SizeIdx = ReadIndex; ReadIndex -= PossibleID_Length; @@ -382,6 +394,7 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe ReadSize += DataStream.read(&PossibleIdNSize[SizeIdx++], 1); PossibleSizeLength++; } + if (bFound) { // find the element in the context and use the correct creator EbmlId PossibleID(PossibleIdNSize, PossibleID_Length); @@ -392,7 +405,12 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe Result->SetSizeLength(_SizeLength); Result->Size = SizeFound; - if (Result->ValidateSize() && (UpperLevel > 0 || MaxDataSize >= SizeFound || MaxDataSize == 0)) { + // UpperLevel values + // -1 : global element + // 0 : child + // 1 : same level + // + : further parent + if (Result->ValidateSize() && (UpperLevel > 0 || MaxDataSize == 0 || MaxDataSize >= (PossibleID_Length + PossibleSizeLength + SizeFound))) { if (SizeFound == SizeUnknown) { Result->SetSizeInfinite(); } @@ -412,7 +430,7 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe ReadIndex = SizeIdx - 1; memmove(&PossibleIdNSize[0], &PossibleIdNSize[1], ReadIndex); UpperLevel = UpperLevel_original; - } + } while ( MaxDataSize > DataStream.getFilePointer() - SizeIdx + PossibleID_Length ); return NULL; } @@ -426,7 +444,7 @@ EbmlElement * EbmlElement::SkipData(EbmlStream & DataStream, const EbmlSemanticC if (bSizeIsFinite) { assert(TestReadElt == NULL); assert(ElementPosition < SizePosition); - DataStream.I_O().setFilePointer(SizePosition + CodedSizeLength(Size, SizeLength) + Size, seek_beginning); + DataStream.I_O().setFilePointer(SizePosition + CodedSizeLength(Size, SizeLength, bSizeIsFinite) + Size, seek_beginning); // DataStream.I_O().setFilePointer(Size, seek_current); } else { ///////////////////////////////////////////////// @@ -529,19 +547,19 @@ EbmlElement *EbmlElement::CreateElementUsingContext(const EbmlId & aID, const Eb /*! \todo verify that the size written is the same as the data written */ -uint32 EbmlElement::Render(IOCallback & output, bool bSaveDefault, bool bKeepPosition, bool bForceRender) +uint32 EbmlElement::Render(IOCallback & output, bool bKeepIntact, bool bKeepPosition, bool bForceRender) { - assert(bValueIsSet); // an element is been rendered without a value set !!! + assert(bValueIsSet || (bKeepIntact && DefaultISset())); // an element is been rendered without a value set !!! // it may be a mandatory element without a default value try { - if (!bSaveDefault && IsDefaultValue()) { + if (!bKeepIntact && IsDefaultValue()) { return 0; } #if defined(_DEBUG) || defined(DEBUG) - uint64 SupposedSize = UpdateSize(bSaveDefault, bForceRender); + uint64 SupposedSize = UpdateSize(bKeepIntact, bForceRender); #endif // _DEBUG - uint32 result = RenderHead(output, bForceRender, bSaveDefault, bKeepPosition); - uint64 WrittenSize = RenderData(output, bForceRender, bSaveDefault); + uint32 result = RenderHead(output, bForceRender, bKeepIntact, bKeepPosition); + uint64 WrittenSize = RenderData(output, bForceRender, bKeepIntact); #if defined(_DEBUG) || defined(DEBUG) if (SupposedSize != (0-1)) assert(WrittenSize == SupposedSize); #endif // DEBUG @@ -559,12 +577,12 @@ uint32 EbmlElement::Render(IOCallback & output, bool bSaveDefault, bool bKeepPos \todo handle exceptions on errors \todo handle CodeSize bigger than 5 bytes */ -uint32 EbmlElement::RenderHead(IOCallback & output, bool bForceRender, bool bSaveDefault, bool bKeepPosition) +uint32 EbmlElement::RenderHead(IOCallback & output, bool bForceRender, bool bKeepIntact, bool bKeepPosition) { if (EbmlId(*this).Length <= 0 || EbmlId(*this).Length > 4) return 0; - UpdateSize(bSaveDefault, bForceRender); + UpdateSize(bKeepIntact, bForceRender); return MakeRenderHead(output, bKeepPosition); } @@ -577,7 +595,7 @@ uint32 EbmlElement::MakeRenderHead(IOCallback & output, bool bKeepPosition) FinalHeadSize = EbmlId(*this).Length; EbmlId(*this).Fill(FinalHead); - int CodedSize = CodedSizeLength(Size, SizeLength); + int CodedSize = CodedSizeLength(Size, SizeLength, bSizeIsFinite); CodedValueLength(Size, CodedSize, &FinalHead[FinalHeadSize]); FinalHeadSize += CodedSize; @@ -590,11 +608,11 @@ uint32 EbmlElement::MakeRenderHead(IOCallback & output, bool bKeepPosition) return FinalHeadSize; } -uint64 EbmlElement::ElementSize(bool bSaveDefault) const +uint64 EbmlElement::ElementSize(bool bKeepIntact) const { - if (!bSaveDefault && IsDefaultValue()) + if (!bKeepIntact && IsDefaultValue()) return 0; // won't be saved - return Size + EbmlId(*this).Length + CodedSizeLength(Size, SizeLength); + return Size + EbmlId(*this).Length + CodedSizeLength(Size, SizeLength, bSizeIsFinite); } bool EbmlElement::CompareElements(const EbmlElement *A, const EbmlElement *B) @@ -616,12 +634,12 @@ bool EbmlElement::ForceSize(uint64 NewSize) return false; } - int OldSizeLen = CodedSizeLength(Size, SizeLength); + int OldSizeLen = CodedSizeLength(Size, SizeLength, bSizeIsFinite); uint64 OldSize = Size; Size = NewSize; - if (CodedSizeLength(Size, SizeLength) == OldSizeLen) { + if (CodedSizeLength(Size, SizeLength, bSizeIsFinite) == OldSizeLen) { bSizeIsFinite = true; return true; } @@ -643,14 +661,14 @@ uint32 EbmlElement::OverwriteHead(IOCallback & output, bool bKeepPosition) return Result; } -uint32 EbmlElement::VoidMe(IOCallback & output, bool bSaveDefault) +uint32 EbmlElement::VoidMe(IOCallback & output, bool bKeepIntact) { if (ElementPosition == 0) { return 0; // the element has not been written } EbmlVoid Dummy; - return Dummy.Overwrite(*this, output, bSaveDefault); + return Dummy.Overwrite(*this, output, bKeepIntact); } END_LIBEBML_NAMESPACE diff --git a/src/add-ons/media/plugins/matroska/libebml/EbmlFloat.cpp b/src/add-ons/media/plugins/matroska/libebml/EbmlFloat.cpp index ea94717a5d..c03f4c6e3a 100644 --- a/src/add-ons/media/plugins/matroska/libebml/EbmlFloat.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/EbmlFloat.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlFloat.cpp 710 2004-08-10 12:27:34Z robux4 $ + \version \$Id: EbmlFloat.cpp 1243 2006-03-30 19:33:22Z mosu $ \author Steve Lhomme */ @@ -64,26 +64,30 @@ EbmlFloat::EbmlFloat(const EbmlFloat & ElementToClone) \todo handle exception on errors \todo handle 10 bits precision */ -uint32 EbmlFloat::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault) +uint32 EbmlFloat::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact) { assert(Size == 4 || Size == 8); if (Size == 4) { float val = Value; - big_int32 TmpToWrite(*((int32 *) &val)); + int Tmp; + memcpy(&Tmp, &val, 4); + big_int32 TmpToWrite(Tmp); output.writeFully(&TmpToWrite.endian(), Size); } else if (Size == 8) { double val = Value; - big_int64 TmpToWrite(*((int64 *) &val)); + int64 Tmp; + memcpy(&Tmp, &val, 8); + big_int64 TmpToWrite(Tmp); output.writeFully(&TmpToWrite.endian(), Size); } return Size; } -uint64 EbmlFloat::UpdateSize(bool bSaveDefault, bool bForceRender) +uint64 EbmlFloat::UpdateSize(bool bKeepIntact, bool bForceRender) { - if (!bSaveDefault && IsDefaultValue()) + if (!bKeepIntact && IsDefaultValue()) return 0; return Size; } @@ -102,14 +106,18 @@ uint64 EbmlFloat::ReadData(IOCallback & input, ScopeMode ReadFully) if (Size == 4) { big_int32 TmpRead; TmpRead.Eval(Buffer); - float val = *((float *)&(int32(TmpRead))); + int32 tmpp = int32(TmpRead); + float val; + memcpy(&val, &tmpp, 4); Value = val; bValueIsSet = true; } else if (Size == 8) { big_int64 TmpRead; TmpRead.Eval(Buffer); int64 tmpp = int64(TmpRead); - Value = *((double *) &tmpp); + double val; + memcpy(&val, &tmpp, 8); + Value = val; bValueIsSet = true; } } diff --git a/src/add-ons/media/plugins/matroska/libebml/EbmlHead.cpp b/src/add-ons/media/plugins/matroska/libebml/EbmlHead.cpp index de52db9dd1..5e36dbab58 100644 --- a/src/add-ons/media/plugins/matroska/libebml/EbmlHead.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/EbmlHead.cpp @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlHead.cpp 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlHead.cpp 1096 2005-03-17 09:14:52Z robux4 $ \author Steve Lhomme */ #include "ebml/EbmlHead.h" @@ -53,7 +53,7 @@ const EbmlSemantic EbmlHead_ContextList[] = const EbmlSemanticContext EbmlHead_Context = EbmlSemanticContext(countof(EbmlHead_ContextList), EbmlHead_ContextList, NULL, *GetEbmlGlobal_Context, &EbmlHead::ClassInfos); EbmlId EbmlHead_TheId(0x1A45DFA3, 4); -const EbmlCallbacks EbmlHead::ClassInfos(EbmlHead::Create, EbmlHead_TheId, "EBMLHead", EbmlHead_Context); +const EbmlCallbacks EbmlHead::ClassInfos(EbmlHead::Create, EbmlHead_TheId, "EBMLHead\0ratamapaga", EbmlHead_Context); EbmlHead::EbmlHead() :EbmlMaster(EbmlHead_Context) diff --git a/src/add-ons/media/plugins/matroska/libebml/EbmlMaster.cpp b/src/add-ons/media/plugins/matroska/libebml/EbmlMaster.cpp index b3c44d0205..3efe21aa5b 100644 --- a/src/add-ons/media/plugins/matroska/libebml/EbmlMaster.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/EbmlMaster.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlMaster.cpp 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlMaster.cpp 1178 2005-05-19 15:47:11Z robux4 $ \author Steve Lhomme */ @@ -87,26 +87,27 @@ EbmlMaster::~EbmlMaster() \todo handle exception on errors \todo write all the Mandatory elements in the Context, otherwise assert */ -uint32 EbmlMaster::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault) +uint32 EbmlMaster::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact) { uint32 Result = 0; size_t Index; - if (!bForceRender) + if (!bForceRender) { assert(CheckMandatory()); + } if (!bChecksumUsed) { // old school for (Index = 0; Index < ElementList.size(); Index++) { - if (!bSaveDefault && (ElementList[Index])->IsDefaultValue()) + if (!bKeepIntact && (ElementList[Index])->IsDefaultValue()) continue; - Result += (ElementList[Index])->Render(output, bSaveDefault, false ,bForceRender); + Result += (ElementList[Index])->Render(output, bKeepIntact, false ,bForceRender); } } else { // new school MemIOCallback TmpBuf(Size - 6); for (Index = 0; Index < ElementList.size(); Index++) { - if (!bSaveDefault && (ElementList[Index])->IsDefaultValue()) + if (!bKeepIntact && (ElementList[Index])->IsDefaultValue()) continue; - (ElementList[Index])->Render(TmpBuf, bSaveDefault, false ,bForceRender); + (ElementList[Index])->Render(TmpBuf, bKeepIntact, false ,bForceRender); } Checksum.FillCRC32(TmpBuf.GetDataBuffer(), TmpBuf.GetDataBufferSize()); Result += Checksum.Render(output, true, false ,bForceRender); @@ -126,23 +127,24 @@ bool EbmlMaster::PushElement(EbmlElement & element) return true; } -uint64 EbmlMaster::UpdateSize(bool bSaveDefault, bool bForceRender) +uint64 EbmlMaster::UpdateSize(bool bKeepIntact, bool bForceRender) { Size = 0; if (!bSizeIsFinite) return (0-1); - if (!bForceRender) + if (!bForceRender) { assert(CheckMandatory()); + } size_t Index; for (Index = 0; Index < ElementList.size(); Index++) { - if (!bSaveDefault && (ElementList[Index])->IsDefaultValue()) + if (!bKeepIntact && (ElementList[Index])->IsDefaultValue()) continue; - (ElementList[Index])->UpdateSize(bSaveDefault, bForceRender); - uint64 SizeToAdd = (ElementList[Index])->ElementSize(bSaveDefault); + (ElementList[Index])->UpdateSize(bKeepIntact, bForceRender); + uint64 SizeToAdd = (ElementList[Index])->ElementSize(bKeepIntact); #if defined(_DEBUG) || defined(DEBUG) if (SizeToAdd == (0-1)) return (0-1); @@ -156,10 +158,10 @@ uint64 EbmlMaster::UpdateSize(bool bSaveDefault, bool bForceRender) return Size; } -uint32 EbmlMaster::WriteHead(IOCallback & output, int nSizeLength, bool bSaveDefault) +uint32 EbmlMaster::WriteHead(IOCallback & output, int nSizeLength, bool bKeepIntact) { SetSizeLength(nSizeLength); - return RenderHead(output, false, bSaveDefault); + return RenderHead(output, false, bKeepIntact); } /*! @@ -414,7 +416,7 @@ void EbmlMaster::Read(EbmlStream & inDataStream, const EbmlSemanticContext & sCo inDataStream.I_O().setFilePointer(SizePosition + SizeLength, seek_beginning); ElementLevelA = inDataStream.FindNextElement(sContext, UpperEltFound, MaxSizeToRead, AllowDummyElt); while (ElementLevelA != NULL && MaxSizeToRead > 0 && UpperEltFound <= 0) { - MaxSizeToRead -= ElementLevelA->ElementSize(true); // even if it's the default value + MaxSizeToRead = GetEndPosition() - ElementLevelA->GetEndPosition(); // even if it's the default value if (!AllowDummyElt && ElementLevelA->IsDummy()) { ElementLevelA->SkipData(inDataStream, sContext); delete ElementLevelA; // forget this unknown element diff --git a/src/add-ons/media/plugins/matroska/libebml/EbmlSInteger.cpp b/src/add-ons/media/plugins/matroska/libebml/EbmlSInteger.cpp index dd05d27ccf..b53c1eb136 100644 --- a/src/add-ons/media/plugins/matroska/libebml/EbmlSInteger.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/EbmlSInteger.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ /*! \file - \version \$Id: EbmlSInteger.cpp 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlSInteger.cpp 1079 2005-03-03 13:18:14Z robux4 $ \author Steve Lhomme \author Moritz Bunkus */ @@ -58,7 +58,7 @@ EbmlSInteger::EbmlSInteger(const EbmlSInteger & ElementToClone) /*! \todo handle exception on errors */ -uint32 EbmlSInteger::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault) +uint32 EbmlSInteger::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact) { binary FinalData[8]; // we don't handle more than 64 bits integers unsigned int i; @@ -77,9 +77,9 @@ uint32 EbmlSInteger::RenderData(IOCallback & output, bool bForceRender, bool bSa return Size; } -uint64 EbmlSInteger::UpdateSize(bool bSaveDefault, bool bForceRender) +uint64 EbmlSInteger::UpdateSize(bool bKeepIntact, bool bForceRender) { - if (!bSaveDefault && IsDefaultValue()) + if (!bKeepIntact && IsDefaultValue()) return 0; if (Value <= 0x7F && Value >= (-0x80)) { diff --git a/src/add-ons/media/plugins/matroska/libebml/EbmlString.cpp b/src/add-ons/media/plugins/matroska/libebml/EbmlString.cpp index 1ae9d0ec68..9a659dc338 100644 --- a/src/add-ons/media/plugins/matroska/libebml/EbmlString.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/EbmlString.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlString.cpp 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlString.cpp 1079 2005-03-03 13:18:14Z robux4 $ \author Steve Lhomme */ #include @@ -73,7 +73,7 @@ EbmlString::EbmlString(const EbmlString & ElementToClone) /*! \todo handle exception on errors */ -uint32 EbmlString::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault) +uint32 EbmlString::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact) { uint32 Result; output.writeFully(Value.c_str(), Value.length()); @@ -106,9 +106,9 @@ EbmlString & EbmlString::operator=(const std::string NewString) return *this; } -uint64 EbmlString::UpdateSize(bool bSaveDefault, bool bForceRender) +uint64 EbmlString::UpdateSize(bool bKeepIntact, bool bForceRender) { - if (!bSaveDefault && IsDefaultValue()) + if (!bKeepIntact && IsDefaultValue()) return 0; if (Value.length() < DefaultSize) { diff --git a/src/add-ons/media/plugins/matroska/libebml/EbmlUInteger.cpp b/src/add-ons/media/plugins/matroska/libebml/EbmlUInteger.cpp index ec853997ab..f153c5ba36 100644 --- a/src/add-ons/media/plugins/matroska/libebml/EbmlUInteger.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/EbmlUInteger.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlUInteger.cpp 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlUInteger.cpp 1079 2005-03-03 13:18:14Z robux4 $ \author Steve Lhomme \author Moritz Bunkus */ @@ -60,7 +60,7 @@ EbmlUInteger::EbmlUInteger(const EbmlUInteger & ElementToClone) /*! \todo handle exception on errors */ -uint32 EbmlUInteger::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault) +uint32 EbmlUInteger::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact) { binary FinalData[8]; // we don't handle more than 64 bits integers @@ -78,9 +78,9 @@ uint32 EbmlUInteger::RenderData(IOCallback & output, bool bForceRender, bool bSa return Size; } -uint64 EbmlUInteger::UpdateSize(bool bSaveDefault, bool bForceRender) +uint64 EbmlUInteger::UpdateSize(bool bKeepIntact, bool bForceRender) { - if (!bSaveDefault && IsDefaultValue()) + if (!bKeepIntact && IsDefaultValue()) return 0; if (Value <= 0xFF) { diff --git a/src/add-ons/media/plugins/matroska/libebml/EbmlUnicodeString.cpp b/src/add-ons/media/plugins/matroska/libebml/EbmlUnicodeString.cpp index af84f52c0a..972799749f 100644 --- a/src/add-ons/media/plugins/matroska/libebml/EbmlUnicodeString.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/EbmlUnicodeString.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,14 +30,14 @@ /*! \file - \version \$Id: EbmlUnicodeString.cpp 653 2004-07-21 18:12:51Z mosu $ + \version \$Id: EbmlUnicodeString.cpp 1079 2005-03-03 13:18:14Z robux4 $ \author Steve Lhomme \author Jory Stone */ #include -#if __GNUC__ == 2 +#if __GNUC__ == 2 && ! defined ( __OpenBSD__ ) #include #endif @@ -228,7 +228,7 @@ EbmlUnicodeString::EbmlUnicodeString(const EbmlUnicodeString & ElementToClone) \note limited to UCS-2 \todo handle exception on errors */ -uint32 EbmlUnicodeString::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault) +uint32 EbmlUnicodeString::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact) { uint32 Result = Value.GetUTF8().length(); @@ -261,9 +261,9 @@ EbmlUnicodeString & EbmlUnicodeString::operator=(const UTFstring & NewString) /*! \note limited to UCS-2 */ -uint64 EbmlUnicodeString::UpdateSize(bool bSaveDefault, bool bForceRender) +uint64 EbmlUnicodeString::UpdateSize(bool bKeepIntact, bool bForceRender) { - if (!bSaveDefault && IsDefaultValue()) + if (!bKeepIntact && IsDefaultValue()) return 0; Size = Value.GetUTF8().length(); diff --git a/src/add-ons/media/plugins/matroska/libebml/EbmlVoid.cpp b/src/add-ons/media/plugins/matroska/libebml/EbmlVoid.cpp index 59c05afcd5..1454b66c59 100644 --- a/src/add-ons/media/plugins/matroska/libebml/EbmlVoid.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/EbmlVoid.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlVoid.cpp 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlVoid.cpp 1232 2005-10-15 15:56:52Z robux4 $ \author Steve Lhomme */ #include "ebml/EbmlVoid.h" @@ -46,7 +46,7 @@ EbmlVoid::EbmlVoid() bValueIsSet = true; } -uint32 EbmlVoid::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault) +uint32 EbmlVoid::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact) { // write dummy data by 4KB chunks static binary DummyBuf[4*1024]; @@ -61,9 +61,9 @@ uint32 EbmlVoid::RenderData(IOCallback & output, bool bForceRender, bool bSaveDe return Size; } -uint64 EbmlVoid::ReplaceWith(EbmlElement & EltToReplaceWith, IOCallback & output, bool ComeBackAfterward, bool bSaveDefault) +uint64 EbmlVoid::ReplaceWith(EbmlElement & EltToReplaceWith, IOCallback & output, bool ComeBackAfterward, bool bKeepIntact) { - EltToReplaceWith.UpdateSize(bSaveDefault); + EltToReplaceWith.UpdateSize(bKeepIntact); if (HeadSize() + Size < EltToReplaceWith.GetSize() + EltToReplaceWith.HeadSize()) { // the element can't be written here ! return 0; @@ -76,19 +76,19 @@ uint64 EbmlVoid::ReplaceWith(EbmlElement & EltToReplaceWith, IOCallback & output uint64 CurrentPosition = output.getFilePointer(); output.setFilePointer(GetElementPosition()); - EltToReplaceWith.Render(output, bSaveDefault); + EltToReplaceWith.Render(output, bKeepIntact); if (HeadSize() + Size - EltToReplaceWith.GetSize() - EltToReplaceWith.HeadSize() > 1) { // fill the rest with another void element EbmlVoid aTmp; aTmp.SetSize(HeadSize() + Size - EltToReplaceWith.GetSize() - EltToReplaceWith.HeadSize() - 1); // 1 is the length of the Void ID int HeadBefore = aTmp.HeadSize(); - aTmp.SetSize(aTmp.GetSize() - CodedSizeLength(aTmp.Size, aTmp.SizeLength)); + aTmp.SetSize(aTmp.GetSize() - CodedSizeLength(aTmp.Size, aTmp.SizeLength, aTmp.bSizeIsFinite)); int HeadAfter = aTmp.HeadSize(); if (HeadBefore != HeadAfter) { - aTmp.SetSizeLength(CodedSizeLength(aTmp.Size, aTmp.SizeLength) - (HeadAfter - HeadBefore)); + aTmp.SetSizeLength(CodedSizeLength(aTmp.Size, aTmp.SizeLength, aTmp.bSizeIsFinite) - (HeadAfter - HeadBefore)); } - aTmp.RenderHead(output, false, bSaveDefault); // the rest of the data is not rewritten + aTmp.RenderHead(output, false, bKeepIntact); // the rest of the data is not rewritten } if (ComeBackAfterward) { @@ -98,9 +98,9 @@ uint64 EbmlVoid::ReplaceWith(EbmlElement & EltToReplaceWith, IOCallback & output return Size + HeadSize(); } -uint64 EbmlVoid::Overwrite(const EbmlElement & EltToVoid, IOCallback & output, bool ComeBackAfterward, bool bSaveDefault) +uint64 EbmlVoid::Overwrite(const EbmlElement & EltToVoid, IOCallback & output, bool ComeBackAfterward, bool bKeepIntact) { -// EltToVoid.UpdateSize(bSaveDefault); +// EltToVoid.UpdateSize(bKeepIntact); if (EltToVoid.GetElementPosition() == 0) { // this element has never been written return 0; @@ -116,17 +116,17 @@ uint64 EbmlVoid::Overwrite(const EbmlElement & EltToVoid, IOCallback & output, b // compute the size of the voided data based on the original one Size = EltToVoid.GetSize() + EltToVoid.HeadSize() - 1; // 1 for the ID - Size -= CodedSizeLength(Size, SizeLength); + Size -= CodedSizeLength(Size, SizeLength, bSizeIsFinite); // make sure we handle even the strange cases //uint32 A1 = Size + HeadSize(); //uint32 A2 = EltToVoid.GetSize() + EltToVoid.HeadSize(); if (Size + HeadSize() != EltToVoid.GetSize() + EltToVoid.HeadSize()) { Size--; - SetSizeLength(CodedSizeLength(Size, SizeLength) + 1); + SetSizeLength(CodedSizeLength(Size, SizeLength, bSizeIsFinite) + 1); } if (Size != 0) { - RenderHead(output, false, bSaveDefault); // the rest of the data is not rewritten + RenderHead(output, false, bKeepIntact); // the rest of the data is not rewritten } if (ComeBackAfterward) { diff --git a/src/add-ons/media/plugins/matroska/libebml/StdIOCallback.cpp b/src/add-ons/media/plugins/matroska/libebml/StdIOCallback.cpp index 1e4728672b..6bb43b17dd 100644 --- a/src/add-ons/media/plugins/matroska/libebml/StdIOCallback.cpp +++ b/src/add-ons/media/plugins/matroska/libebml/StdIOCallback.cpp @@ -28,7 +28,7 @@ /*! \file - \version \$Id: StdIOCallback.cpp 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: StdIOCallback.cpp 1298 2008-02-21 22:14:18Z mosu $ \author Steve Lhomme \author Moritz Bunkus */ @@ -64,7 +64,7 @@ StdIOCallback::StdIOCallback(const char*Path, const open_mode aMode) { assert(Path!=0); - char *Mode; + const char *Mode; switch (aMode) { case MODE_READ: @@ -92,6 +92,7 @@ StdIOCallback::StdIOCallback(const char*Path, const open_mode aMode) throw CRTError(Msg.str()); #endif // GCC2 } + mCurrentPosition = 0; } @@ -107,6 +108,7 @@ uint32 StdIOCallback::read(void*Buffer,size_t Size) assert(File!=0); size_t result = fread(Buffer, 1, Size, File); + mCurrentPosition += result; return result; } @@ -133,20 +135,38 @@ void StdIOCallback::setFilePointer(int64 Offset,seek_mode Mode) Msg<<"Failed to seek file "< ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlBinary.h 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlBinary.h 1298 2008-02-21 22:14:18Z mosu $ \author Steve Lhomme \author Julien Coloos */ @@ -38,6 +38,7 @@ #define LIBEBML_BINARY_H #include +#include #include "EbmlTypes.h" #include "EbmlElement.h" @@ -62,9 +63,9 @@ class EBML_DLL_API EbmlBinary : public EbmlElement { EbmlBinary(const EbmlBinary & ElementToClone); virtual ~EbmlBinary(void); - uint32 RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false); + uint32 RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact = false); uint64 ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA); - uint64 UpdateSize(bool bSaveDefault = false, bool bForceRender = false); + uint64 UpdateSize(bool bKeepIntact = false, bool bForceRender = false); void SetBuffer(const binary *Buffer, const uint32 BufferSize) { Data = (binary *) Buffer; @@ -76,8 +77,8 @@ class EBML_DLL_API EbmlBinary : public EbmlElement { void CopyBuffer(const binary *Buffer, const uint32 BufferSize) { if (Data != NULL) - delete Data; - Data = new binary[BufferSize]; + free(Data); + Data = (binary *)malloc(BufferSize * sizeof(binary)); memcpy(Data, Buffer, BufferSize); Size = BufferSize; bValueIsSet = true; @@ -90,6 +91,8 @@ class EBML_DLL_API EbmlBinary : public EbmlElement { return false; } + bool operator==(const EbmlBinary & ElementToCompare) const; + protected: binary *Data; // the binary data inside the element }; diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlConfig.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlConfig.h index 76abe224a6..d042a6e68a 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlConfig.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlConfig.h @@ -28,7 +28,7 @@ /*! \file - \version \$Id: EbmlConfig.h 710 2004-08-10 12:27:34Z robux4 $ + \version \$Id: EbmlConfig.h 1241 2006-01-25 00:59:45Z robux4 $ \author Steve Lhomme \author Moritz Bunkus */ @@ -38,13 +38,13 @@ // automatic endianess detection working on GCC #if !defined(WORDS_BIGENDIAN) -#if (defined (__arm__) && ! defined (__ARMEB__)) || defined (__i386__) || defined (__i860__) || defined (__ns32000__) || defined (__vax__) || defined (__amd64__) -#define WORDS_BIGENDIAN 0 +#if (defined (__arm__) && ! defined (__ARMEB__)) || defined (__i386__) || defined (__i860__) || defined (__ns32000__) || defined (__vax__) || defined (__amd64__) || defined (__x86_64__) +#undef WORDS_BIGENDIAN #elif defined (__sparc__) || defined (__alpha__) || defined (__PPC__) || defined (__mips__) || defined (__ppc__) || defined (__BIG_ENDIAN__) #define WORDS_BIGENDIAN 1 #else // not automatically detected, put it yourself -#define WORDS_BIGENDIAN 0 // for my testing platform (x86) +#undef WORDS_BIGENDIAN // for my testing platform (x86) #endif #endif // not autoconf @@ -102,4 +102,9 @@ #define EBML_PRETTYLONGINT(c) (c) #endif // __GNUC__ +#if __BORLANDC__ >= 0x0581 //Borland C++ Builder 2006 preview + #include //malloc(), free() + #include //memcpy() +#endif //__BORLANDC__ + #endif // LIBEBML_CONFIG_H diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlCrc32.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlCrc32.h index 20032334a1..902aa59483 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlCrc32.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlCrc32.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlCrc32.h 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlCrc32.h 1155 2005-05-06 11:43:38Z robux4 $ \author Steve Lhomme \author Jory Stone */ @@ -44,7 +44,7 @@ START_LIBEBML_NAMESPACE const uint32 CRC32_NEGL = 0xffffffffL; -#if WORDS_BIGENDIAN +#ifdef WORDS_BIGENDIAN # define CRC32_INDEX(c) (c >> 24) # define CRC32_SHIFTED(c) (c << 8) #else @@ -59,9 +59,9 @@ class EBML_DLL_API EbmlCrc32 : public EbmlBinary { static EbmlElement & Create() {return *(new EbmlCrc32);} const EbmlCallbacks & Generic() const {return ClassInfos;} bool ValidateSize() const {return (Size == 4);} - uint32 RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false); + uint32 RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact = false); uint64 ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA); -// uint64 UpdateSize(bool bSaveDefault = false); +// uint64 UpdateSize(bool bKeepIntact = false); static const EbmlCallbacks ClassInfos; bool IsDefaultValue() const { @@ -143,7 +143,7 @@ inline T2 ModPowerOf2(T1 a, T2 b) inline bool IsAlignedOn(const void *p, unsigned int alignment) { - return IsPowerOf2(alignment) ? ModPowerOf2((unsigned int)p, alignment) == 0 : (unsigned int)p % alignment == 0; + return IsPowerOf2(alignment) ? ModPowerOf2((unsigned long)p, alignment) == 0 : (unsigned long)p % alignment == 0; } template diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlDate.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlDate.h index ba2016a180..7adefdd6d5 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlDate.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlDate.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ /*! \file - \version \$Id: EbmlDate.h 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlDate.h 1079 2005-03-03 13:18:14Z robux4 $ \author Steve Lhomme */ #ifndef LIBEBML_DATE_H @@ -65,7 +65,7 @@ class EBML_DLL_API EbmlDate : public EbmlElement { /*! \note no Default date handled */ - uint64 UpdateSize(bool bSaveDefault = false, bool bForceRender = false) { + uint64 UpdateSize(bool bKeepIntact = false, bool bForceRender = false) { if(!bValueIsSet) Size = 0; else @@ -82,7 +82,7 @@ class EBML_DLL_API EbmlDate : public EbmlElement { } protected: - uint32 RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false); + uint32 RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact = false); int64 myDate; ///< internal format of the date diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlElement.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlElement.h index e3d61c0f30..ebe7e6e132 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlElement.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlElement.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ /*! \file - \version \$Id: EbmlElement.h 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlElement.h 1232 2005-10-15 15:56:52Z robux4 $ \author Steve Lhomme */ #ifndef LIBEBML_ELEMENT_H @@ -45,7 +45,7 @@ START_LIBEBML_NAMESPACE /*! \brief The size of the EBML-coded length */ -int EBML_DLL_API CodedSizeLength(uint64 Length, unsigned int SizeLength); +int EBML_DLL_API CodedSizeLength(uint64 Length, unsigned int SizeLength, bool bSizeIsFinite = true); /*! \brief The coded value of the EBML-coded length @@ -180,14 +180,16 @@ class EBML_DLL_API EbmlElement { virtual bool ValidateSize() const = 0; - uint64 GetElementPosition() const {return ElementPosition;} + uint64 GetElementPosition() const { + return ElementPosition; + } - uint64 ElementSize(bool bSaveDefault = false) const; /// return the size of the header+data + uint64 ElementSize(bool bKeepIntact = false) const; /// return the size of the header+data, before writing - uint32 Render(IOCallback & output, bool bSaveDefault = false, bool bKeepPosition = false, bool bForceRender = false); + uint32 Render(IOCallback & output, bool bKeepIntact = false, bool bKeepPosition = false, bool bForceRender = false); - virtual uint64 UpdateSize(bool bSaveDefault = false, bool bForceRender = false) = 0; /// update the Size of the Data stored - virtual uint64 GetSize() const {return Size;} + virtual uint64 UpdateSize(bool bKeepIntact = false, bool bForceRender = false) = 0; /// update the Size of the Data stored + virtual uint64 GetSize() const {return Size;} /// return the size of the data stored in the element, on reading virtual uint64 ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA) = 0; virtual void Read(EbmlStream & inDataStream, const EbmlSemanticContext & Context, int & UpperEltFound, EbmlElement * & FoundElt, bool AllowDummyElt = false, ScopeMode ReadFully = SCOPE_ALL_DATA); @@ -210,7 +212,9 @@ class EBML_DLL_API EbmlElement { virtual bool IsDummy() const {return false;} virtual bool IsMaster() const {return false;} - uint8 HeadSize() const {return EbmlId(*this).Length + CodedSizeLength(Size, SizeLength);} + uint8 HeadSize() const { + return EbmlId(*this).Length + CodedSizeLength(Size, SizeLength, bSizeIsFinite); + } /// return the size of the head, on reading/writing /*! \brief Force the size of an element @@ -223,7 +227,7 @@ class EBML_DLL_API EbmlElement { /*! \brief void the content of the element (replace by EbmlVoid) */ - uint32 VoidMe(IOCallback & output, bool bSaveDefault = false); + uint32 VoidMe(IOCallback & output, bool bKeepIntact = false); bool DefaultISset() const {return DefaultIsSet;} virtual bool IsDefaultValue() const = 0; @@ -235,6 +239,10 @@ class EBML_DLL_API EbmlElement { virtual void SetDefaultSize(const uint64 aDefaultSize) {DefaultSize = aDefaultSize;} bool ValueIsSet() const {return bValueIsSet;} + + inline uint64 GetEndPosition() const { + return SizePosition + CodedSizeLength(Size, SizeLength, bSizeIsFinite) + Size; + } protected: uint64 Size; ///< the size of the data to write @@ -253,13 +261,13 @@ class EBML_DLL_API EbmlElement { */ static EbmlElement *CreateElementUsingContext(const EbmlId & aID, const EbmlSemanticContext & Context, int & LowLevel, bool IsGlobalContext, bool bAllowDummy = false, unsigned int MaxLowerLevel = 1); - uint32 RenderHead(IOCallback & output, bool bForceRender, bool bSaveDefault = false, bool bKeepPosition = false); + uint32 RenderHead(IOCallback & output, bool bForceRender, bool bKeepIntact = false, bool bKeepPosition = false); uint32 MakeRenderHead(IOCallback & output, bool bKeepPosition); /*! \brief prepare the data before writing them (in case it's not already done by default) */ - virtual uint32 RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false) = 0; + virtual uint32 RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact = false) = 0; /*! \brief special constructor for cloning diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlEndian.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlEndian.h index 18f8effaaa..c034fd7ee2 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlEndian.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlEndian.h @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlEndian.h 736 2004-08-28 14:05:09Z robux4 $ + \version \$Id: EbmlEndian.h 1298 2008-02-21 22:14:18Z mosu $ \author Ingo Ralf Blum \author Lasse Kärkkäinen \author Steve Lhomme @@ -39,6 +39,7 @@ #define LIBEBML_ENDIAN_H #include +#include #include "EbmlConfig.h" // contains _ENDIANESS_ @@ -92,7 +93,7 @@ template class Endian inline void process_endian() { endian_value = platform_value; -#if WORDS_BIGENDIAN +#ifdef WORDS_BIGENDIAN if (ENDIAN == little_endian) std::reverse(reinterpret_cast(&endian_value),reinterpret_cast(&endian_value+1)); #else // _ENDIANESS_ @@ -104,7 +105,7 @@ template class Endian inline void process_platform() { platform_value = endian_value; -#if WORDS_BIGENDIAN +#ifdef WORDS_BIGENDIAN if (ENDIAN == little_endian) std::reverse(reinterpret_cast(&platform_value),reinterpret_cast(&platform_value+1)); #else // _ENDIANESS_ diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlFloat.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlFloat.h index 4360d24c67..9bfc94877f 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlFloat.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlFloat.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlFloat.h 737 2004-08-28 14:18:17Z robux4 $ + \version \$Id: EbmlFloat.h 1079 2005-03-03 13:18:14Z robux4 $ \author Steve Lhomme */ #ifndef LIBEBML_FLOAT_H @@ -61,9 +61,9 @@ class EBML_DLL_API EbmlFloat : public EbmlElement { return (Size == 4 || Size == 8); } - uint32 RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false); + uint32 RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact = false); uint64 ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA); - uint64 UpdateSize(bool bSaveDefault = false, bool bForceRender = false); + uint64 UpdateSize(bool bKeepIntact = false, bool bForceRender = false); void SetPrecision(const EbmlFloat::Precision prec = FLOAT_32) { diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlId.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlId.h index 5ccbc5a6e7..1ad297c14c 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlId.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlId.h @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlId.h 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlId.h 936 2004-11-10 20:46:28Z mosu $ \author Steve Lhomme */ #ifndef LIBEBML_ID_H @@ -66,6 +66,10 @@ class EBML_DLL_API EbmlId { { return ((TestId.Length == Length) && (TestId.Value == Value)); } + inline bool operator!=(const EbmlId & TestId) const + { + return !(*this == TestId); + } inline void Fill(binary * Buffer) const { unsigned int i; diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlMaster.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlMaster.h index b6b3162918..c0b6d6cfb4 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlMaster.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlMaster.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlMaster.h 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlMaster.h 1232 2005-10-15 15:56:52Z robux4 $ \author Steve Lhomme */ #ifndef LIBEBML_MASTER_H @@ -61,9 +61,9 @@ class EBML_DLL_API EbmlMaster : public EbmlElement { */ virtual ~EbmlMaster(); - uint32 RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false); + uint32 RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact = false); uint64 ReadData(IOCallback & input, ScopeMode ReadFully); - uint64 UpdateSize(bool bSaveDefault = false, bool bForceRender = false); + uint64 UpdateSize(bool bKeepIntact = false, bool bForceRender = false); /*! \brief Set wether the size is finite (size is known in advance when writing, or infinite size is not known on writing) @@ -77,6 +77,10 @@ class EBML_DLL_API EbmlMaster : public EbmlElement { else return (0-1); } + + uint64 GetDataStart() const { + return ElementPosition + EbmlId(*this).Length + CodedSizeLength(Size, SizeLength, bSizeIsFinite); + } /*! \brief find the element corresponding to the ID of the element, NULL if not found @@ -111,13 +115,13 @@ class EBML_DLL_API EbmlMaster : public EbmlElement { */ void Sort(); - unsigned int ListSize() const {return ElementList.size();} + size_t ListSize() const {return ElementList.size();} EbmlElement * operator[](unsigned int position) {return ElementList[position];} const EbmlElement * operator[](unsigned int position) const {return ElementList[position];} bool IsDefaultValue() const { - return false; + return (ElementList.size() == 0); } virtual bool IsMaster() const {return true;} @@ -132,11 +136,16 @@ class EBML_DLL_API EbmlMaster : public EbmlElement { */ void Remove(size_t Index); + /*! + \brief remove all elements, even the mandatory ones + */ + void RemoveAll() {ElementList.clear();} + /*! \brief facility for Master elements to write only the head and force the size later \warning */ - uint32 WriteHead(IOCallback & output, int SizeLength, bool bSaveDefault = false); + uint32 WriteHead(IOCallback & output, int SizeLength, bool bKeepIntact = false); void EnableChecksum(bool bIsEnabled = true) { bChecksumUsed = bIsEnabled; } bool HasChecksum() const {return bChecksumUsed;} @@ -147,11 +156,6 @@ class EBML_DLL_API EbmlMaster : public EbmlElement { bChecksumUsed = true; } - /*! - \brief remove all elements, even the mandatory ones - */ -// void ClearElement() {ElementList.clear();} - /*! \brief drill down all sub-elements, finding any missing elements */ diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlSInteger.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlSInteger.h index f83566c224..f627aa69db 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlSInteger.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlSInteger.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlSInteger.h 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlSInteger.h 1079 2005-03-03 13:18:14Z robux4 $ \author Steve Lhomme \author Julien Coloos \author Moritz Bunkus @@ -63,9 +63,9 @@ class EBML_DLL_API EbmlSInteger : public EbmlElement { void SetDefaultSize(const int nDefaultSize = DEFAULT_INT_SIZE) {Size = nDefaultSize;} bool ValidateSize() const {return (Size <= 8);} - uint32 RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false); + uint32 RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact = false); uint64 ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA); - uint64 UpdateSize(bool bSaveDefault = false, bool bForceRender = false); + uint64 UpdateSize(bool bKeepIntact = false, bool bForceRender = false); bool operator<(const EbmlSInteger & EltCmp) const {return Value < EltCmp.Value;} diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlString.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlString.h index b74065ed12..19d950740b 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlString.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlString.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlString.h 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlString.h 1079 2005-03-03 13:18:14Z robux4 $ \author Steve Lhomme */ #ifndef LIBEBML_STRING_H @@ -56,9 +56,9 @@ class EBML_DLL_API EbmlString : public EbmlElement { virtual ~EbmlString() {} bool ValidateSize() const {return true;} // any size is possible - uint32 RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false); + uint32 RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact = false); uint64 ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA); - uint64 UpdateSize(bool bSaveDefault = false, bool bForceRender = false); + uint64 UpdateSize(bool bKeepIntact = false, bool bForceRender = false); EbmlString & operator=(const std::string); operator const std::string &() const {return Value;} diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlUInteger.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlUInteger.h index b9a7d1a400..2008a926e9 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlUInteger.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlUInteger.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlUInteger.h 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlUInteger.h 1079 2005-03-03 13:18:14Z robux4 $ \author Steve Lhomme \author Julien Coloos \author Moritz Bunkus @@ -63,9 +63,9 @@ class EBML_DLL_API EbmlUInteger : public EbmlElement { void SetDefaultSize(const int nDefaultSize = DEFAULT_UINT_SIZE) {Size = nDefaultSize;} bool ValidateSize() const {return (Size <= 8);} - uint32 RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false); + uint32 RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact = false); uint64 ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA); - uint64 UpdateSize(bool bSaveDefault = false, bool bForceRender = false); + uint64 UpdateSize(bool bKeepIntact = false, bool bForceRender = false); bool operator<(const EbmlUInteger & EltCmp) const {return Value < EltCmp.Value;} diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlUnicodeString.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlUnicodeString.h index 4b5c8a5b0c..ee8279fe1c 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlUnicodeString.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlUnicodeString.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlUnicodeString.h 652 2004-07-21 18:09:38Z mosu $ + \version \$Id: EbmlUnicodeString.h 1079 2005-03-03 13:18:14Z robux4 $ \author Steve Lhomme \author Moritz Bunkus \author Jory Stone @@ -59,7 +59,11 @@ public: UTFstring(const UTFstring &); virtual ~UTFstring(); - bool operator==(const UTFstring&) const; + bool operator==(const UTFstring&) const; + inline bool operator!=(const UTFstring &cmp) const + { + return !(*this == cmp); + } UTFstring & operator=(const UTFstring &); UTFstring & operator=(const wchar_t *); UTFstring & operator=(wchar_t); @@ -97,9 +101,9 @@ class EBML_DLL_API EbmlUnicodeString : public EbmlElement { virtual ~EbmlUnicodeString() {} bool ValidateSize() const {return true;} // any size is possible - uint32 RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false); + uint32 RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact = false); uint64 ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA); - uint64 UpdateSize(bool bSaveDefault = false, bool bForceRender = false); + uint64 UpdateSize(bool bKeepIntact = false, bool bForceRender = false); EbmlUnicodeString & operator=(const UTFstring &); ///< platform dependant code operator const UTFstring &() const {return Value;} diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlVersion.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlVersion.h index c9adb9e167..33ec86958d 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlVersion.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlVersion.h @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlVersion.h 839 2004-09-26 10:03:40Z mosu $ + \version \$Id: EbmlVersion.h 1299 2008-03-05 11:06:00Z mosu $ \author Steve Lhomme */ #ifndef LIBEBML_VERSION_H @@ -42,9 +42,9 @@ START_LIBEBML_NAMESPACE -#define LIBEBML_VERSION 000702 +#define LIBEBML_VERSION 0x000708 -static const std::string EbmlCodeVersion = "0.7.2"; +static const std::string EbmlCodeVersion = "0.7.8"; static const std::string EbmlCodeDate = __TIMESTAMP__; /*! diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlVoid.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlVoid.h index f3ee14d3fe..125c65aea3 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlVoid.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlVoid.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libebml. ** @@ -30,7 +30,7 @@ /*! \file - \version \$Id: EbmlVoid.h 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: EbmlVoid.h 1079 2005-03-03 13:18:14Z robux4 $ \author Steve Lhomme */ #ifndef LIBEBML_VOID_H @@ -61,17 +61,17 @@ class EBML_DLL_API EbmlVoid : public EbmlBinary { /*! \note overwrite to write fake data */ - uint32 RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false); + uint32 RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact = false); /*! \brief Replace the void element content (written) with this one */ - uint64 ReplaceWith(EbmlElement & EltToReplaceWith, IOCallback & output, bool ComeBackAfterward = true, bool bSaveDefault = false); + uint64 ReplaceWith(EbmlElement & EltToReplaceWith, IOCallback & output, bool ComeBackAfterward = true, bool bKeepIntact = false); /*! \brief Void the content of an element */ - uint64 Overwrite(const EbmlElement & EltToVoid, IOCallback & output, bool ComeBackAfterward = true, bool bSaveDefault = false); + uint64 Overwrite(const EbmlElement & EltToVoid, IOCallback & output, bool ComeBackAfterward = true, bool bKeepIntact = false); EbmlElement * Clone() const {return new EbmlVoid(*this);} }; diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/MemIOCallback.h b/src/add-ons/media/plugins/matroska/libebml/ebml/MemIOCallback.h index 3530ea0069..48fed9b03a 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/MemIOCallback.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/MemIOCallback.h @@ -28,7 +28,7 @@ /*! \file - \version \$Id: MemIOCallback.h 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: MemIOCallback.h 1298 2008-02-21 22:14:18Z mosu $ \author Jory Stone */ #ifndef LIBEBML_MEMIOCALLBACK_H @@ -36,10 +36,6 @@ #include "IOCallback.h" #include -// Several gcc versions have some header problem, others don't - -// but those that do will have problems with min being defined as a -// macro upon inclusion of some stream header. -#undef min #ifndef __BEOS__ #include #else diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/StdIOCallback.h b/src/add-ons/media/plugins/matroska/libebml/ebml/StdIOCallback.h index 468492deaa..90089e5fed 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/StdIOCallback.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/StdIOCallback.h @@ -28,7 +28,7 @@ /*! \file - \version \$Id: StdIOCallback.h 639 2004-07-09 20:59:14Z mosu $ + \version \$Id: StdIOCallback.h 1090 2005-03-16 12:47:59Z robux4 $ */ #ifndef LIBEBML_STDIOCALLBACK_H #define LIBEBML_STDIOCALLBACK_H @@ -66,6 +66,7 @@ class EBML_DLL_API StdIOCallback:public IOCallback { private: FILE*File; + uint64 mCurrentPosition; public: // StdIOCallback(const char*Path,const char*Mode); diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/c/libebml_t.h b/src/add-ons/media/plugins/matroska/libebml/ebml/c/libebml_t.h index 612185e525..218ef2ff03 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/c/libebml_t.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/c/libebml_t.h @@ -30,7 +30,7 @@ /*! \file libebml_t.h - \version \$Id: libebml_t.h 837 2004-09-23 22:54:24Z mosu $ + \version \$Id: libebml_t.h 1298 2008-02-21 22:14:18Z mosu $ \author Steve Lhomme \author Ingo Ralf Blum \author Moritz Bunkus @@ -72,6 +72,8 @@ extern "C" { typedef uint16_t uint16; typedef uint8_t uint8; # endif // __GNUC__ +#elif defined(__BEOS__) +#include #elif defined(DJGPP) /* SL : DJGPP doesn't support POSIX types ???? */ typedef signed long long int64; typedef signed long int32; @@ -121,9 +123,7 @@ typedef enum open_mode { MODE_SAFE } open_mode; -#if !defined(min) -#define min(x,y) ((x)<(y) ? (x) : (y)) -#endif +#define EBML_MIN(x,y) ((x)<(y) ? (x) : (y)) #ifdef __cplusplus } diff --git a/src/add-ons/media/plugins/matroska/libmatroska/KaxAttached.cpp b/src/add-ons/media/plugins/matroska/libmatroska/KaxAttached.cpp index 73469656f9..d725e39f4b 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/KaxAttached.cpp +++ b/src/add-ons/media/plugins/matroska/libmatroska/KaxAttached.cpp @@ -29,7 +29,7 @@ /*! \file - \version \$Id: KaxAttached.cpp 640 2004-07-09 21:05:36Z mosu $ + \version \$Id: KaxAttached.cpp 1202 2005-08-30 14:39:01Z robux4 $ \author Steve Lhomme */ #include "matroska/KaxAttached.h" @@ -41,13 +41,20 @@ using namespace LIBEBML_NAMESPACE; START_LIBMATROSKA_NAMESPACE +#if MATROSKA_VERSION == 1 EbmlSemantic KaxAttached_ContextList[5] = +#else // MATROSKA_VERSION +EbmlSemantic KaxAttached_ContextList[6] = +#endif // MATROSKA_VERSION { EbmlSemantic(true, true, KaxFileName::ClassInfos), EbmlSemantic(true, true, KaxMimeType::ClassInfos), EbmlSemantic(true, true, KaxFileData::ClassInfos), EbmlSemantic(false, true, KaxFileDescription::ClassInfos), EbmlSemantic(true, true, KaxFileUID::ClassInfos), +#if MATROSKA_VERSION >= 2 + EbmlSemantic(false, true, KaxFileReferral::ClassInfos), +#endif // MATROSKA_VERSION }; EbmlId KaxAttached_TheId (0x61A7, 2); @@ -56,6 +63,9 @@ EbmlId KaxFileName_TheId (0x466E, 2); EbmlId KaxMimeType_TheId (0x4660, 2); EbmlId KaxFileData_TheId (0x465C, 2); EbmlId KaxFileUID_TheId (0x46AE, 2); +#if MATROSKA_VERSION >= 2 +EbmlId KaxFileReferral_TheId (0x4675, 2); +#endif // MATROSKA_VERSION const EbmlSemanticContext KaxAttached_Context = EbmlSemanticContext(countof(KaxAttached_ContextList), KaxAttached_ContextList, &KaxAttachments_Context, *GetKaxGlobal_Context, &KaxAttached::ClassInfos); const EbmlSemanticContext KaxFileDescription_Context = EbmlSemanticContext(0, NULL, &KaxAttachments_Context, *GetKaxGlobal_Context, &KaxFileDescription::ClassInfos); @@ -63,6 +73,9 @@ const EbmlSemanticContext KaxFileName_Context = EbmlSemanticContext(0, NU const EbmlSemanticContext KaxMimeType_Context = EbmlSemanticContext(0, NULL, &KaxAttachments_Context, *GetKaxGlobal_Context, &KaxMimeType::ClassInfos); const EbmlSemanticContext KaxFileData_Context = EbmlSemanticContext(0, NULL, &KaxAttachments_Context, *GetKaxGlobal_Context, &KaxFileData::ClassInfos); const EbmlSemanticContext KaxFileUID_Context = EbmlSemanticContext(0, NULL, &KaxAttachments_Context, *GetKaxGlobal_Context, &KaxFileUID::ClassInfos); +#if MATROSKA_VERSION >= 2 +const EbmlSemanticContext KaxFileReferral_Context = EbmlSemanticContext(0, NULL, &KaxAttachments_Context, *GetKaxGlobal_Context, &KaxFileReferral::ClassInfos); +#endif // MATROSKA_VERSION const EbmlCallbacks KaxAttached::ClassInfos(KaxAttached::Create, KaxAttached_TheId, "AttachedFile", KaxAttached_Context); const EbmlCallbacks KaxFileDescription::ClassInfos(KaxFileDescription::Create, KaxFileDescription_TheId, "FileDescription", KaxFileDescription_Context); @@ -70,6 +83,9 @@ const EbmlCallbacks KaxFileName::ClassInfos(KaxFileName::Create, KaxFileName_The const EbmlCallbacks KaxMimeType::ClassInfos(KaxMimeType::Create, KaxMimeType_TheId, "FileMimeType", KaxMimeType_Context); const EbmlCallbacks KaxFileData::ClassInfos(KaxFileData::Create, KaxFileData_TheId, "FileData", KaxFileData_Context); const EbmlCallbacks KaxFileUID::ClassInfos(KaxFileUID::Create, KaxFileUID_TheId, "FileUID", KaxFileUID_Context); +#if MATROSKA_VERSION >= 2 +const EbmlCallbacks KaxFileReferral::ClassInfos(KaxFileReferral::Create, KaxFileReferral_TheId, "FileReferral", KaxFileReferral_Context); +#endif // MATROSKA_VERSION KaxAttached::KaxAttached() :EbmlMaster(KaxAttached_Context) diff --git a/src/add-ons/media/plugins/matroska/libmatroska/KaxBlock.cpp b/src/add-ons/media/plugins/matroska/libmatroska/KaxBlock.cpp index f3b06e0fd3..9b121ab40e 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/KaxBlock.cpp +++ b/src/add-ons/media/plugins/matroska/libmatroska/KaxBlock.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ /*! \file - \version \$Id: KaxBlock.cpp 640 2004-07-09 21:05:36Z mosu $ + \version \$Id: KaxBlock.cpp 1265 2007-01-14 17:20:35Z mosu $ \author Steve Lhomme \author Julien Coloos */ @@ -43,9 +43,9 @@ START_LIBMATROSKA_NAMESPACE #if MATROSKA_VERSION == 1 -const EbmlSemantic KaxBlockGroup_ContextList[5] = +const EbmlSemantic KaxBlockGroup_ContextList[6] = #else // MATROSKA_VERSION -const EbmlSemantic KaxBlockGroup_ContextList[8] = +const EbmlSemantic KaxBlockGroup_ContextList[9] = #endif // MATROSKA_VERSION { EbmlSemantic(true, true, KaxBlock::ClassInfos), @@ -58,11 +58,11 @@ const EbmlSemantic KaxBlockGroup_ContextList[8] = EbmlSemantic(false, false, KaxReferenceBlock::ClassInfos), #if MATROSKA_VERSION >= 2 EbmlSemantic(false, true, KaxReferenceVirtual::ClassInfos), - EbmlSemantic(false, true, KaxBlockAdditions::ClassInfos), + EbmlSemantic(false, true, KaxCodecState::ClassInfos), #endif // MATROSKA_VERSION + EbmlSemantic(false, true, KaxBlockAdditions::ClassInfos), }; -#if MATROSKA_VERSION >= 2 const EbmlSemantic KaxBlockAdditions_ContextList[1] = { EbmlSemantic(true, false, KaxBlockMore::ClassInfos) @@ -73,44 +73,50 @@ const EbmlSemantic KaxBlockMore_ContextList[2] = EbmlSemantic(true, true, KaxBlockAddID::ClassInfos), EbmlSemantic(true, true, KaxBlockAdditional::ClassInfos) }; -#endif // MATROSKA_VERSION EbmlId KaxBlockGroup_TheId (0xA0, 1); EbmlId KaxBlock_TheId (0xA1, 1); +EbmlId KaxSimpleBlock_TheId (0xA3, 1); EbmlId KaxBlockDuration_TheId (0x9B, 1); #if MATROSKA_VERSION >= 2 EbmlId KaxBlockVirtual_TheId (0xA2, 1); +EbmlId KaxCodecState_TheId (0xA4, 1); +#endif // MATROSKA_VERSION EbmlId KaxBlockAdditions_TheId (0x75A1, 2); EbmlId KaxBlockMore_TheId (0xA6, 1); EbmlId KaxBlockAddID_TheId (0xEE, 1); EbmlId KaxBlockAdditional_TheId(0xA5, 1); -#endif // MATROSKA_VERSION const EbmlSemanticContext KaxBlockGroup_Context = EbmlSemanticContext(countof(KaxBlockGroup_ContextList), KaxBlockGroup_ContextList, &KaxCluster_Context, *GetKaxGlobal_Context, &KaxBlockGroup::ClassInfos); const EbmlSemanticContext KaxBlock_Context = EbmlSemanticContext(0, NULL, &KaxBlockGroup_Context, *GetKaxGlobal_Context, &KaxBlock::ClassInfos); const EbmlSemanticContext KaxBlockDuration_Context = EbmlSemanticContext(0, NULL, &KaxBlockGroup_Context, *GetKaxGlobal_Context, &KaxBlockDuration::ClassInfos); #if MATROSKA_VERSION >= 2 +const EbmlSemanticContext KaxSimpleBlock_Context = EbmlSemanticContext(0, NULL, &KaxCluster_Context, *GetKaxGlobal_Context, &KaxSimpleBlock::ClassInfos); const EbmlSemanticContext KaxBlockVirtual_Context = EbmlSemanticContext(0, NULL, &KaxBlockGroup_Context, *GetKaxGlobal_Context, &KaxBlockVirtual::ClassInfos); +const EbmlSemanticContext KaxCodecState_Context = EbmlSemanticContext(0, NULL, &KaxBlockGroup_Context, *GetKaxGlobal_Context, &KaxCodecState::ClassInfos); +#endif // MATROSKA_VERSION const EbmlSemanticContext KaxBlockAdditions_Context = EbmlSemanticContext(countof(KaxBlockAdditions_ContextList), KaxBlockAdditions_ContextList, &KaxBlockGroup_Context, *GetKaxGlobal_Context, &KaxBlockAdditions::ClassInfos); const EbmlSemanticContext KaxBlockMore_Context = EbmlSemanticContext(countof(KaxBlockMore_ContextList), KaxBlockMore_ContextList, &KaxBlockAdditions_Context, *GetKaxGlobal_Context, &KaxBlockMore::ClassInfos); const EbmlSemanticContext KaxBlockAddID_Context = EbmlSemanticContext(0, NULL, &KaxBlockMore_Context, *GetKaxGlobal_Context, &KaxBlockAddID::ClassInfos); const EbmlSemanticContext KaxBlockAdditional_Context = EbmlSemanticContext(0, NULL, &KaxBlockMore_Context, *GetKaxGlobal_Context, &KaxBlockAdditional::ClassInfos); -#endif // MATROSKA_VERSION const EbmlCallbacks KaxBlockGroup::ClassInfos(KaxBlockGroup::Create, KaxBlockGroup_TheId, "BlockGroup", KaxBlockGroup_Context); const EbmlCallbacks KaxBlock::ClassInfos(KaxBlock::Create, KaxBlock_TheId, "Block", KaxBlock_Context); const EbmlCallbacks KaxBlockDuration::ClassInfos(KaxBlockDuration::Create, KaxBlockDuration_TheId, "BlockDuration", KaxBlockDuration_Context); #if MATROSKA_VERSION >= 2 +const EbmlCallbacks KaxSimpleBlock::ClassInfos(KaxSimpleBlock::Create, KaxSimpleBlock_TheId, "SimpleBlock", KaxSimpleBlock_Context); const EbmlCallbacks KaxBlockVirtual::ClassInfos(KaxBlockVirtual::Create, KaxBlockVirtual_TheId, "BlockVirtual", KaxBlockVirtual_Context); +const EbmlCallbacks KaxCodecState::ClassInfos(KaxCodecState::Create, KaxCodecState_TheId, "CodecState", KaxCodecState_Context); +#endif // MATROSKA_VERSION const EbmlCallbacks KaxBlockAdditions::ClassInfos(KaxBlockAdditions::Create, KaxBlockAdditions_TheId, "BlockAdditions", KaxBlockAdditions_Context); const EbmlCallbacks KaxBlockMore::ClassInfos(KaxBlockMore::Create, KaxBlockMore_TheId, "BlockMore", KaxBlockMore_Context); const EbmlCallbacks KaxBlockAddID::ClassInfos(KaxBlockAddID::Create, KaxBlockAddID_TheId, "BlockAddID", KaxBlockAddID_Context); const EbmlCallbacks KaxBlockAdditional::ClassInfos(KaxBlockAdditional::Create, KaxBlockAdditional_TheId, "BlockAdditional", KaxBlockAdditional_Context); -#endif // MATROSKA_VERSION DataBuffer * DataBuffer::Clone() { - binary *ClonedData = new binary[mySize]; + binary *ClonedData = (binary *)malloc(mySize * sizeof(binary)); + assert(ClonedData != NULL); memcpy(ClonedData, myBuffer ,mySize ); SimpleDataBuffer * result = new SimpleDataBuffer(ClonedData, mySize, 0); @@ -119,30 +125,30 @@ DataBuffer * DataBuffer::Clone() } SimpleDataBuffer::SimpleDataBuffer(const SimpleDataBuffer & ToClone) - :DataBuffer(new binary[ToClone.mySize], ToClone.mySize, myFreeBuffer) + :DataBuffer((binary *)malloc(ToClone.mySize * sizeof(binary)), ToClone.mySize, myFreeBuffer) { + assert(myBuffer != NULL); memcpy(myBuffer, ToClone.myBuffer ,mySize ); bValidValue = ToClone.bValidValue; } -bool KaxBlock::ValidateSize() const +bool KaxInternalBlock::ValidateSize() const { return (Size >= 4); /// for the moment } -KaxBlock::~KaxBlock() +KaxInternalBlock::~KaxInternalBlock() { ReleaseFrames(); } -KaxBlock::KaxBlock(const KaxBlock & ElementToClone) +KaxInternalBlock::KaxInternalBlock(const KaxInternalBlock & ElementToClone) :EbmlBinary(ElementToClone) ,myBuffers(ElementToClone.myBuffers.size()) ,Timecode(ElementToClone.Timecode) ,LocalTimecode(ElementToClone.LocalTimecode) ,bLocalTimecodeUsed(ElementToClone.bLocalTimecodeUsed) ,TrackNumber(ElementToClone.TrackNumber) - ,bGap(ElementToClone.bGap) ,ParentCluster(ElementToClone.ParentCluster) ///< \todo not exactly { // add a clone of the list @@ -167,7 +173,6 @@ KaxBlockGroup::KaxBlockGroup() ,ParentTrack(NULL) {} -#if MATROSKA_VERSION >= 2 KaxBlockAdditions::KaxBlockAdditions() :EbmlMaster(KaxBlockAdditions_Context) {} @@ -175,38 +180,41 @@ KaxBlockAdditions::KaxBlockAdditions() KaxBlockMore::KaxBlockMore() :EbmlMaster(KaxBlockMore_Context) {} -#endif // MATROSKA_VERSION /*! \todo handle flags \todo hardcoded limit of the number of frames in a lace should be a parameter \return true if more frames can be added to this Block */ -bool KaxBlock::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing) +bool KaxInternalBlock::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing, bool invisible) { bValueIsSet = true; if (myBuffers.size() == 0) { // first frame Timecode = timecode; TrackNumber = track.TrackNumber(); + mInvisible = invisible; mLacing = lacing; } myBuffers.push_back(&buffer); // we don't allow more than 8 frames in a Block because the overhead improvement is minimal - if (myBuffers.size() >= 8) + if (myBuffers.size() >= 8 || lacing == LACING_NONE) return false; - // decide wether a new frame can be added or not - // a frame in a lace is not efficient when the place necessary to code it in a lace is bigger - // than the size of a simple Block. That means more than 6 bytes (4 in struct + 2 for EBML) to code the size - return (buffer.Size() < 6*0xFF); + if (lacing == LACING_XIPH) + // decide wether a new frame can be added or not + // a frame in a lace is not efficient when the place necessary to code it in a lace is bigger + // than the size of a simple Block. That means more than 6 bytes (4 in struct + 2 for EBML) to code the size + return (buffer.Size() < 6*0xFF); + else + return true; } /*! \return Returns the lacing type that produces the smallest footprint. */ -LacingType KaxBlock::GetBestLacingType() const { +LacingType KaxInternalBlock::GetBestLacingType() const { int XiphLacingSize, EbmlLacingSize, i; bool SameSize = true; @@ -220,7 +228,7 @@ LacingType KaxBlock::GetBestLacingType() const { SameSize = false; XiphLacingSize += myBuffers[i]->Size() / 255 + 1; } - EbmlLacingSize += CodedSizeLength(myBuffers[0]->Size(), 0); + EbmlLacingSize += CodedSizeLength(myBuffers[0]->Size(), 0, bSizeIsFinite); for (i = 1; i < (int)myBuffers.size() - 1; i++) EbmlLacingSize += CodedSizeLengthSigned(int64(myBuffers[i]->Size()) - int64(myBuffers[i - 1]->Size()), 0); if (SameSize) @@ -231,13 +239,10 @@ LacingType KaxBlock::GetBestLacingType() const { return LACING_EBML; } -/*! - \todo handle gap flag -*/ -uint64 KaxBlock::UpdateSize(bool bSaveDefault, bool bForceRender) +uint64 KaxInternalBlock::UpdateSize(bool bSaveDefault, bool bForceRender) { LacingType LacingHere; - assert(Data == NULL); // Data is not used for KaxBlock + assert(Data == NULL); // Data is not used for KaxInternalBlock assert(TrackNumber < 0x4000); // no more allowed for the moment unsigned int i; @@ -263,7 +268,7 @@ uint64 KaxBlock::UpdateSize(bool bSaveDefault, bool bForceRender) } break; case LACING_EBML: - Size += myBuffers[0]->Size() + CodedSizeLength(myBuffers[0]->Size(), 0); + Size += myBuffers[0]->Size() + CodedSizeLength(myBuffers[0]->Size(), 0, bSizeIsFinite); for (i=1; iSize() + CodedSizeLengthSigned(int64(myBuffers[i]->Size()) - int64(myBuffers[i-1]->Size()), 0);; @@ -298,9 +303,6 @@ KaxBlockVirtual::KaxBlockVirtual(const KaxBlockVirtual & ElementToClone) Data = DataBlock; } -/*! - \todo handle the gap flag -*/ uint64 KaxBlockVirtual::UpdateSize(bool bSaveDefault, bool bForceRender) { assert(TrackNumber < 0x4000); @@ -319,7 +321,7 @@ uint64 KaxBlockVirtual::UpdateSize(bool bSaveDefault, bool bForceRender) b16.Fill(cursor); cursor += 2; - *cursor++ = (0 << 0); // no gap + *cursor++ = 0; // flags return Size; } @@ -329,7 +331,7 @@ uint64 KaxBlockVirtual::UpdateSize(bool bSaveDefault, bool bForceRender) \todo more optimisation is possible (render the Block head and don't copy the buffer in memory, care should be taken with the allocation of Data) \todo the actual timecode to write should be retrieved from the Cluster from here */ -uint32 KaxBlock::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault) +uint32 KaxInternalBlock::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault) { if (myBuffers.size() == 0) { return 0; @@ -363,22 +365,34 @@ uint32 KaxBlock::RenderData(IOCallback & output, bool bForceRender, bool bSaveDe b16.Fill(cursor); cursor += 2; - *cursor = (0 << 0); // no gap + *cursor = 0; // flags if (mLacing == LACING_AUTO) { mLacing = GetBestLacingType(); } + // invisible flag + if (mInvisible) + *cursor = 0x08; + + if (bIsSimple) { + if (bIsKeyframe) + *cursor |= 0x80; + if (bIsDiscardable) + *cursor |= 0x01; + } + + // lacing flag switch (mLacing) { case LACING_XIPH: - *cursor++ |= 0x2; + *cursor++ |= 0x02; break; case LACING_EBML: - *cursor++ |= 0x6; + *cursor++ |= 0x06; break; case LACING_FIXED: - *cursor++ |= 0x4; + *cursor++ |= 0x04; break; case LACING_NONE: break; @@ -422,7 +436,7 @@ uint32 KaxBlock::RenderData(IOCallback & output, bool bForceRender, bool bSaveDe _Size = myBuffers[0]->Size(); - _CodedSize = CodedSizeLength(_Size, 0); + _CodedSize = CodedSizeLength(_Size, 0, bSizeIsFinite); // first size in the lace is not a signed CodedValueLength(_Size, _CodedSize, _FinalHead); @@ -460,7 +474,7 @@ uint32 KaxBlock::RenderData(IOCallback & output, bool bForceRender, bool bSaveDe return Size; } -uint64 KaxBlock::ReadInternalHead(IOCallback & input) +uint64 KaxInternalBlock::ReadInternalHead(IOCallback & input) { binary Buffer[5], *cursor = Buffer; uint64 Result = input.read(cursor, 4); @@ -490,14 +504,13 @@ uint64 KaxBlock::ReadInternalHead(IOCallback & input) bLocalTimecodeUsed = false; cursor += 2; - bGap = (*cursor && 0x01); return Result; } /*! \todo better zero copy handling */ -uint64 KaxBlock::ReadData(IOCallback & input, ScopeMode ReadFully) +uint64 KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully) { uint64 Result; @@ -530,7 +543,11 @@ uint64 KaxBlock::ReadData(IOCallback & input, ScopeMode ReadFully) bLocalTimecodeUsed = true; cursor += 2; - bGap = (*cursor && 0x01); + if (EbmlId(*this) == KaxSimpleBlock::ClassInfos.GlobalId) { + bIsKeyframe = (*cursor & 0x80) != 0; + bIsDiscardable = (*cursor & 0x01) != 0; + } + mInvisible = (*cursor & 0x08) >> 3; mLacing = LacingType((*cursor++ & 0x06) >> 1); // put all Frames in the list @@ -633,7 +650,11 @@ uint64 KaxBlock::ReadData(IOCallback & input, ScopeMode ReadFully) bLocalTimecodeUsed = true; cursor += 2; - bGap = (*cursor && 0x01); + if (EbmlId(*this) == KaxSimpleBlock::ClassInfos.GlobalId) { + bIsKeyframe = (*cursor & 0x80) != 0; + bIsDiscardable = (*cursor & 0x01) != 0; + } + mInvisible = (*cursor & 0x08) >> 3; mLacing = LacingType((*cursor++ & 0x06) >> 1); if (cursor == &_TempHead[4]) { @@ -772,20 +793,45 @@ bool KaxBlockGroup::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataB return bRes; } +bool KaxBlockGroup::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, const KaxBlockBlob * PastBlock, const KaxBlockBlob * ForwBlock, LacingType lacing) +{ + KaxBlock & theBlock = GetChild(*this); + assert(ParentCluster != NULL); + theBlock.SetParent(*ParentCluster); + ParentTrack = &track; + bool bRes = theBlock.AddFrame(track, timecode, buffer, lacing); + + if (PastBlock != NULL) + { + KaxReferenceBlock & thePastRef = GetChild(*this); + thePastRef.SetReferencedBlock(PastBlock); + thePastRef.SetParentBlock(*this); + } + + if (ForwBlock != NULL) + { + KaxReferenceBlock & theFutureRef = AddNewChild(*this); + theFutureRef.SetReferencedBlock(ForwBlock); + theFutureRef.SetParentBlock(*this); + } + + return bRes; +} + /*! \todo we may cache the reference to the timecode block */ uint64 KaxBlockGroup::GlobalTimecode() const { assert(ParentCluster != NULL); // impossible otherwise - KaxBlock & MyBlock = *static_cast(this->FindElt(KaxBlock::ClassInfos)); + KaxInternalBlock & MyBlock = *static_cast(this->FindElt(KaxBlock::ClassInfos)); return MyBlock.GlobalTimecode(); } uint16 KaxBlockGroup::TrackNumber() const { - KaxBlock & MyBlock = *static_cast(this->FindElt(KaxBlock::ClassInfos)); + KaxInternalBlock & MyBlock = *static_cast(this->FindElt(KaxBlock::ClassInfos)); return MyBlock.TrackNum(); } @@ -795,6 +841,12 @@ uint64 KaxBlockGroup::ClusterPosition() const return ParentCluster->GetPosition(); } +uint64 KaxInternalBlock::ClusterPosition() const +{ + assert(ParentCluster != NULL); // impossible otherwise + return ParentCluster->GetPosition(); +} + unsigned int KaxBlockGroup::ReferenceCount() const { unsigned int Result = 0; @@ -824,11 +876,11 @@ const KaxReferenceBlock & KaxBlockGroup::Reference(unsigned int Index) const void KaxBlockGroup::ReleaseFrames() { - KaxBlock & MyBlock = *static_cast(this->FindElt(KaxBlock::ClassInfos)); + KaxInternalBlock & MyBlock = *static_cast(this->FindElt(KaxBlock::ClassInfos)); MyBlock.ReleaseFrames(); } -void KaxBlock::ReleaseFrames() +void KaxInternalBlock::ReleaseFrames() { // free the allocated Frames int i; @@ -861,7 +913,18 @@ bool KaxBlockGroup::GetBlockDuration(uint64 &TheTimecode) const return true; } -void KaxBlock::SetParent(KaxCluster & aParentCluster) +KaxBlockGroup::operator KaxInternalBlock &() { + KaxBlock & theBlock = GetChild(*this); + return theBlock; +} + +void KaxBlockGroup::SetParent(KaxCluster & aParentCluster) { + ParentCluster = &aParentCluster; + KaxBlock & theBlock = GetChild(*this); + theBlock.SetParent( aParentCluster ); +} + +void KaxInternalBlock::SetParent(KaxCluster & aParentCluster) { ParentCluster = &aParentCluster; if (bLocalTimecodeUsed) { @@ -870,7 +933,7 @@ void KaxBlock::SetParent(KaxCluster & aParentCluster) } } -int64 KaxBlock::GetDataPosition(size_t FrameNumber) +int64 KaxInternalBlock::GetDataPosition(size_t FrameNumber) { int64 _Result = -1; @@ -888,7 +951,7 @@ int64 KaxBlock::GetDataPosition(size_t FrameNumber) return _Result; } -int64 KaxBlock::GetFrameSize(size_t FrameNumber) +int64 KaxInternalBlock::GetFrameSize(size_t FrameNumber) { int64 _Result = -1; @@ -900,4 +963,134 @@ int64 KaxBlock::GetFrameSize(size_t FrameNumber) return _Result; } +KaxBlockBlob::operator KaxBlockGroup &() +{ + assert(!bUseSimpleBlock); + assert(Block.group); + return *Block.group; +} + +KaxBlockBlob::operator const KaxBlockGroup &() const +{ + assert(!bUseSimpleBlock); + assert(Block.group); + return *Block.group; +} + +KaxBlockBlob::operator KaxInternalBlock &() +{ + assert(Block.group); +#if MATROSKA_VERSION >= 2 + if (bUseSimpleBlock) + return *Block.simpleblock; + else +#endif + return *Block.group; +} + +KaxBlockBlob::operator const KaxInternalBlock &() const +{ + assert(Block.group); +#if MATROSKA_VERSION >= 2 + if (bUseSimpleBlock) + return *Block.simpleblock; + else +#endif + return *Block.group; +} + +#if MATROSKA_VERSION >= 2 +KaxBlockBlob::operator KaxSimpleBlock &() +{ + assert(bUseSimpleBlock); + assert(Block.simpleblock); + return *Block.simpleblock; +} +#endif + +bool KaxBlockBlob::AddFrameAuto(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing, const KaxBlockBlob * PastBlock, const KaxBlockBlob * ForwBlock) +{ + bool bResult = false; +#if MATROSKA_VERSION >= 2 + if ((SimpleBlockMode == BLOCK_BLOB_ALWAYS_SIMPLE) || (SimpleBlockMode == BLOCK_BLOB_SIMPLE_AUTO && PastBlock == NULL && ForwBlock == NULL)) { + assert(bUseSimpleBlock == true); + if (Block.simpleblock == NULL) { + Block.simpleblock = new KaxSimpleBlock(); + Block.simpleblock->SetParent(*ParentCluster); + } + + bResult = Block.simpleblock->AddFrame(track, timecode, buffer, lacing); + if (PastBlock == NULL && ForwBlock == NULL) { + Block.simpleblock->SetKeyframe(true); + Block.simpleblock->SetDiscardable(false); + } else { + Block.simpleblock->SetKeyframe(false); + if ((ForwBlock == NULL || ((const KaxInternalBlock &)*ForwBlock).GlobalTimecode() <= timecode) && + (PastBlock == NULL || ((const KaxInternalBlock &)*PastBlock).GlobalTimecode() <= timecode)) + Block.simpleblock->SetDiscardable(false); + else + Block.simpleblock->SetDiscardable(true); + } + } + else +#endif + { + if (ReplaceSimpleByGroup()) { + bResult = Block.group->AddFrame(track, timecode, buffer, PastBlock, ForwBlock, lacing); + } + } + + return bResult; +} + +void KaxBlockBlob::SetParent(KaxCluster & parent_clust) +{ + ParentCluster = &parent_clust; +} + +void KaxBlockBlob::SetBlockDuration(uint64 TimeLength) +{ + if (ReplaceSimpleByGroup()) + Block.group->SetBlockDuration(TimeLength); +} + +bool KaxBlockBlob::ReplaceSimpleByGroup() +{ + if (SimpleBlockMode== BLOCK_BLOB_ALWAYS_SIMPLE) + return false; + + if (!bUseSimpleBlock) { + if (Block.group == NULL) { + Block.group = new KaxBlockGroup(); + } + } +#if MATROSKA_VERSION >= 2 + else + { + + if (Block.simpleblock != NULL) { + KaxSimpleBlock *old_simpleblock = Block.simpleblock; + Block.group = new KaxBlockGroup(); + // _TODO_ : move all the data to the blockgroup + assert(false); + // -> while(frame) AddFrame(myBuffer) + delete old_simpleblock; + } else { + Block.group = new KaxBlockGroup(); + } + } +#endif + if (ParentCluster != NULL) + Block.group->SetParent(*ParentCluster); + + bUseSimpleBlock = false; + return true; +} + +void KaxBlockBlob::SetBlockGroup( KaxBlockGroup &BlockRef ) +{ + assert(!bUseSimpleBlock); + Block.group = &BlockRef; +} + END_LIBMATROSKA_NAMESPACE diff --git a/src/add-ons/media/plugins/matroska/libmatroska/KaxBlockData.cpp b/src/add-ons/media/plugins/matroska/libmatroska/KaxBlockData.cpp index db329e7a11..b204f27dba 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/KaxBlockData.cpp +++ b/src/add-ons/media/plugins/matroska/libmatroska/KaxBlockData.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ /*! \file - \version \$Id: KaxBlockData.cpp 640 2004-07-09 21:05:36Z mosu $ + \version \$Id: KaxBlockData.cpp 1226 2005-10-13 21:16:43Z robux4 $ \author Steve Lhomme */ #include @@ -101,7 +101,7 @@ KaxTimeSlice::KaxTimeSlice() :EbmlMaster(KaxTimeSlice_Context) {} -const KaxBlockGroup & KaxReferenceBlock::RefBlock() const +const KaxBlockBlob & KaxReferenceBlock::RefBlock() const { assert(RefdBlock != NULL); return *RefdBlock; @@ -113,9 +113,26 @@ uint64 KaxReferenceBlock::UpdateSize(bool bSaveDefault, bool bForceRender) assert(RefdBlock != NULL); assert(ParentBlock != NULL); - Value = (int64(RefdBlock->GlobalTimecode()) - int64(ParentBlock->GlobalTimecode())) / int64(ParentBlock->GlobalTimecodeScale()); + const KaxInternalBlock &block = *RefdBlock; + Value = (int64(block.GlobalTimecode()) - int64(ParentBlock->GlobalTimecode())) / int64(ParentBlock->GlobalTimecodeScale()); } return EbmlSInteger::UpdateSize(bSaveDefault, bForceRender); } +void KaxReferenceBlock::SetReferencedBlock(const KaxBlockBlob * aRefdBlock) +{ + assert(RefdBlock == NULL); + assert(aRefdBlock != NULL); + RefdBlock = aRefdBlock; + bValueIsSet = true; +} + +void KaxReferenceBlock::SetReferencedBlock(const KaxBlockGroup & aRefdBlock) +{ + KaxBlockBlob *block_blob = new KaxBlockBlob(BLOCK_BLOB_NO_SIMPLE); + block_blob->SetBlockGroup(*const_cast(&aRefdBlock)); + RefdBlock = block_blob; + bValueIsSet = true; +} + END_LIBMATROSKA_NAMESPACE diff --git a/src/add-ons/media/plugins/matroska/libmatroska/KaxChapters.cpp b/src/add-ons/media/plugins/matroska/libmatroska/KaxChapters.cpp index 31707d1371..cbb163c570 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/KaxChapters.cpp +++ b/src/add-ons/media/plugins/matroska/libmatroska/KaxChapters.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libmatroska. ** @@ -29,7 +29,7 @@ /*! \file - \version \$Id: KaxChapters.cpp 745 2004-09-04 16:29:03Z robux4 $ + \version \$Id: KaxChapters.cpp 1201 2005-08-30 14:28:27Z robux4 $ \author Steve Lhomme */ #include "matroska/KaxChapters.h" @@ -48,11 +48,11 @@ EbmlSemantic KaxEditionEntry_ContextList[5] = EbmlSemantic(false, true , KaxEditionUID::ClassInfos), EbmlSemantic(true , true , KaxEditionFlagHidden::ClassInfos), EbmlSemantic(true , true , KaxEditionFlagDefault::ClassInfos), - EbmlSemantic(true , true , KaxEditionProcessed::ClassInfos), + EbmlSemantic(false, true , KaxEditionFlagOrdered::ClassInfos), EbmlSemantic(true , false, KaxChapterAtom::ClassInfos), }; -EbmlSemantic KaxChapterAtom_ContextList[11] = +EbmlSemantic KaxChapterAtom_ContextList[12] = { EbmlSemantic(false, false, KaxChapterAtom::ClassInfos), EbmlSemantic(true, true, KaxChapterUID::ClassInfos), @@ -60,11 +60,12 @@ EbmlSemantic KaxChapterAtom_ContextList[11] = EbmlSemantic(false, true, KaxChapterTimeEnd::ClassInfos), EbmlSemantic(true , true, KaxChapterFlagHidden::ClassInfos), EbmlSemantic(true , true, KaxChapterFlagEnabled::ClassInfos), + EbmlSemantic(false, true, KaxChapterSegmentUID::ClassInfos), + EbmlSemantic(false, true, KaxChapterSegmentEditionUID::ClassInfos), EbmlSemantic(false, true, KaxChapterPhysicalEquiv::ClassInfos), EbmlSemantic(false, true, KaxChapterTrack::ClassInfos), EbmlSemantic(false, false, KaxChapterDisplay::ClassInfos), EbmlSemantic(false, false, KaxChapterProcess::ClassInfos), - EbmlSemantic(false, true, KaxChapterProcessedPrivate::ClassInfos), }; EbmlSemantic KaxChapterTrack_ContextList[1] = @@ -79,10 +80,17 @@ EbmlSemantic KaxChapterDisplay_ContextList[3] = EbmlSemantic(false, false, KaxChapterCountry::ClassInfos), }; -EbmlSemantic KaxChapterProcess_ContextList[2] = +EbmlSemantic KaxChapterProcess_ContextList[3] = +{ + EbmlSemantic(true, true, KaxChapterProcessCodecID::ClassInfos), + EbmlSemantic(false, true, KaxChapterProcessPrivate::ClassInfos), + EbmlSemantic(false, false, KaxChapterProcessCommand::ClassInfos), +}; + +EbmlSemantic KaxChapterProcessCommand_ContextList[2] = { EbmlSemantic(true, true, KaxChapterProcessTime::ClassInfos), - EbmlSemantic(true, true, KaxChapterProcessCommand::ClassInfos), + EbmlSemantic(true, true, KaxChapterProcessData::ClassInfos), }; const EbmlSemanticContext KaxChapters_Context = EbmlSemanticContext(countof(KaxChapters_ContextList), KaxChapters_ContextList, &KaxSegment_Context, *GetKaxGlobal_Context, &KaxChapters::ClassInfos); @@ -90,8 +98,7 @@ const EbmlSemanticContext KaxEditionEntry_Context = EbmlSemanticContext(countof( const EbmlSemanticContext KaxEditionUID_Context = EbmlSemanticContext(0, NULL, &KaxEditionEntry_Context, *GetKaxGlobal_Context, &KaxEditionUID::ClassInfos); const EbmlSemanticContext KaxEditionFlagHidden_Context = EbmlSemanticContext(0, NULL, &KaxEditionEntry_Context, *GetKaxGlobal_Context, &KaxEditionFlagHidden::ClassInfos); const EbmlSemanticContext KaxEditionFlagDefault_Context = EbmlSemanticContext(0, NULL, &KaxEditionEntry_Context, *GetKaxGlobal_Context, &KaxEditionFlagDefault::ClassInfos); -const EbmlSemanticContext KaxEditionProcessed_Context = EbmlSemanticContext(0, NULL, &KaxEditionEntry_Context, *GetKaxGlobal_Context, &KaxEditionProcessed::ClassInfos); -const EbmlSemanticContext KaxChapterProcessedPrivate_Context = EbmlSemanticContext(0, NULL, &KaxEditionEntry_Context, *GetKaxGlobal_Context, &KaxChapterProcessedPrivate::ClassInfos); +const EbmlSemanticContext KaxEditionFlagOrdered_Context = EbmlSemanticContext(0, NULL, &KaxEditionEntry_Context, *GetKaxGlobal_Context, &KaxEditionFlagOrdered::ClassInfos); const EbmlSemanticContext KaxChapterAtom_Context = EbmlSemanticContext(countof(KaxChapterAtom_ContextList), KaxChapterAtom_ContextList, &KaxEditionEntry_Context, *GetKaxGlobal_Context, &KaxChapterAtom::ClassInfos); const EbmlSemanticContext KaxChapterTrack_Context = EbmlSemanticContext(countof(KaxChapterTrack_ContextList), KaxChapterTrack_ContextList, &KaxChapterAtom_Context, *GetKaxGlobal_Context, &KaxChapterTrack::ClassInfos); const EbmlSemanticContext KaxChapterDisplay_Context = EbmlSemanticContext(countof(KaxChapterDisplay_ContextList), KaxChapterDisplay_ContextList, &KaxChapterAtom_Context, *GetKaxGlobal_Context, &KaxChapterDisplay::ClassInfos); @@ -100,28 +107,34 @@ const EbmlSemanticContext KaxChapterTimeStart_Context = EbmlSemanticContext(0, N const EbmlSemanticContext KaxChapterTimeEnd_Context = EbmlSemanticContext(0, NULL, &KaxChapterAtom_Context, *GetKaxGlobal_Context, &KaxChapterTimeEnd::ClassInfos); const EbmlSemanticContext KaxChapterFlagHidden_Context = EbmlSemanticContext(0, NULL, &KaxChapterAtom_Context, *GetKaxGlobal_Context, &KaxChapterFlagHidden::ClassInfos); const EbmlSemanticContext KaxChapterFlagEnabled_Context = EbmlSemanticContext(0, NULL, &KaxChapterAtom_Context, *GetKaxGlobal_Context, &KaxChapterFlagEnabled::ClassInfos); +const EbmlSemanticContext KaxChapterSegmentUID_Context = EbmlSemanticContext(0, NULL, &KaxChapterAtom_Context, *GetKaxGlobal_Context, &KaxChapterSegmentUID::ClassInfos); +const EbmlSemanticContext KaxChapterSegmentEditionUID_Context = EbmlSemanticContext(0, NULL, &KaxChapterAtom_Context, *GetKaxGlobal_Context, &KaxChapterSegmentEditionUID::ClassInfos); const EbmlSemanticContext KaxChapterPhysicalEquiv_Context = EbmlSemanticContext(0, NULL, &KaxChapterAtom_Context, *GetKaxGlobal_Context, &KaxChapterPhysicalEquiv::ClassInfos); const EbmlSemanticContext KaxChapterTrackNumber_Context = EbmlSemanticContext(0, NULL, &KaxChapterTrack_Context, *GetKaxGlobal_Context, &KaxChapterTrackNumber::ClassInfos); const EbmlSemanticContext KaxChapterString_Context = EbmlSemanticContext(0, NULL, &KaxChapterDisplay_Context, *GetKaxGlobal_Context, &KaxChapterString::ClassInfos); const EbmlSemanticContext KaxChapterLanguage_Context = EbmlSemanticContext(0, NULL, &KaxChapterLanguage_Context, *GetKaxGlobal_Context, &KaxChapterLanguage::ClassInfos); const EbmlSemanticContext KaxChapterCountry_Context = EbmlSemanticContext(0, NULL, &KaxChapterCountry_Context, *GetKaxGlobal_Context, &KaxChapterCountry::ClassInfos); const EbmlSemanticContext KaxChapterProcess_Context = EbmlSemanticContext(countof(KaxChapterProcess_ContextList), KaxChapterProcess_ContextList, &KaxChapterAtom_Context, *GetKaxGlobal_Context, &KaxChapterProcess::ClassInfos); -const EbmlSemanticContext KaxChapterProcessTime_Context = EbmlSemanticContext(0, NULL, &KaxChapterProcess_Context, *GetKaxGlobal_Context, &KaxChapterProcessTime::ClassInfos); -const EbmlSemanticContext KaxChapterProcessCommand_Context = EbmlSemanticContext(0, NULL, &KaxChapterProcess_Context, *GetKaxGlobal_Context, &KaxChapterProcessCommand::ClassInfos); +const EbmlSemanticContext KaxChapterProcessCodecID_Context = EbmlSemanticContext(0, NULL, &KaxChapterProcess_Context, *GetKaxGlobal_Context, &KaxChapterProcessCodecID::ClassInfos); +const EbmlSemanticContext KaxChapterProcessPrivate_Context = EbmlSemanticContext(0, NULL, &KaxChapterProcess_Context, *GetKaxGlobal_Context, &KaxChapterProcessPrivate::ClassInfos); +const EbmlSemanticContext KaxChapterProcessCommand_Context = EbmlSemanticContext(countof(KaxChapterProcessCommand_ContextList), KaxChapterProcessCommand_ContextList, &KaxChapterProcess_Context, *GetKaxGlobal_Context, &KaxChapterProcessCommand::ClassInfos); +const EbmlSemanticContext KaxChapterProcessTime_Context = EbmlSemanticContext(0, NULL, &KaxChapterProcessCommand_Context, *GetKaxGlobal_Context, &KaxChapterProcessTime::ClassInfos); +const EbmlSemanticContext KaxChapterProcessData_Context = EbmlSemanticContext(0, NULL, &KaxChapterProcessCommand_Context, *GetKaxGlobal_Context, &KaxChapterProcessData::ClassInfos); EbmlId KaxChapters_TheId (0x1043A770, 4); EbmlId KaxEditionEntry_TheId (0x45B9, 2); EbmlId KaxEditionUID_TheId (0x45BC, 2); EbmlId KaxEditionFlagHidden_TheId (0x45BD, 2); EbmlId KaxEditionFlagDefault_TheId (0x45DB, 2); -EbmlId KaxEditionProcessed_TheId (0x45DD, 2); -EbmlId KaxChapterProcessedPrivate_TheId(0x450D, 2); +EbmlId KaxEditionFlagOrdered_TheId (0x45DD, 2); EbmlId KaxChapterAtom_TheId (0xB6, 1); EbmlId KaxChapterUID_TheId (0x73C4, 2); EbmlId KaxChapterTimeStart_TheId (0x91, 1); EbmlId KaxChapterTimeEnd_TheId (0x92, 1); EbmlId KaxChapterFlagHidden_TheId (0x98, 1); EbmlId KaxChapterFlagEnabled_TheId (0x4598, 2); +EbmlId KaxChapterSegmentUID_TheId (0x6E67, 2); +EbmlId KaxChapterSegmentEditionUID_TheId(0x6EBC, 2); EbmlId KaxChapterPhysicalEquiv_TheId (0x63C3, 2); EbmlId KaxChapterTrack_TheId (0x8F, 1); EbmlId KaxChapterTrackNumber_TheId (0x89, 1); @@ -130,22 +143,26 @@ EbmlId KaxChapterString_TheId (0x85, 1); EbmlId KaxChapterLanguage_TheId (0x437C, 2); EbmlId KaxChapterCountry_TheId (0x437E, 2); EbmlId KaxChapterProcess_TheId (0x6944, 2); +EbmlId KaxChapterProcessCodecID_TheId (0x6955, 2); +EbmlId KaxChapterProcessPrivate_TheId (0x450D, 2); +EbmlId KaxChapterProcessCommand_TheId (0x6911, 2); EbmlId KaxChapterProcessTime_TheId (0x6922, 2); -EbmlId KaxChapterProcessCommand_TheId (0x6933, 2); +EbmlId KaxChapterProcessData_TheId (0x6933, 2); const EbmlCallbacks KaxChapters::ClassInfos(KaxChapters::Create, KaxChapters_TheId, "Chapters", KaxChapters_Context); const EbmlCallbacks KaxEditionEntry::ClassInfos(KaxEditionEntry::Create, KaxEditionEntry_TheId, "EditionEntry", KaxEditionEntry_Context); const EbmlCallbacks KaxEditionUID::ClassInfos(KaxEditionUID::Create, KaxEditionUID_TheId, "EditionUID", KaxEditionUID_Context); const EbmlCallbacks KaxEditionFlagHidden::ClassInfos(KaxEditionFlagHidden::Create, KaxEditionFlagHidden_TheId, "EditionFlagHidden", KaxEditionFlagHidden_Context); const EbmlCallbacks KaxEditionFlagDefault::ClassInfos(KaxEditionFlagDefault::Create, KaxEditionFlagDefault_TheId, "EditionFlagDefault", KaxEditionFlagDefault_Context); -const EbmlCallbacks KaxEditionProcessed::ClassInfos(KaxEditionProcessed::Create, KaxEditionProcessed_TheId, "EditionProcessed", KaxEditionProcessed_Context); -const EbmlCallbacks KaxChapterProcessedPrivate::ClassInfos(KaxChapterProcessedPrivate::Create, KaxChapterProcessedPrivate_TheId, "ChapterProcessedPrivate", KaxChapterProcessedPrivate_Context); +const EbmlCallbacks KaxEditionFlagOrdered::ClassInfos(KaxEditionFlagOrdered::Create, KaxEditionFlagOrdered_TheId, "EditionFlagOrdered", KaxEditionFlagOrdered_Context); const EbmlCallbacks KaxChapterAtom::ClassInfos(KaxChapterAtom::Create, KaxChapterAtom_TheId, "ChapterAtom", KaxChapterAtom_Context); const EbmlCallbacks KaxChapterUID::ClassInfos(KaxChapterUID::Create, KaxChapterUID_TheId, "ChapterUID", KaxChapterUID_Context); const EbmlCallbacks KaxChapterTimeStart::ClassInfos(KaxChapterTimeStart::Create, KaxChapterTimeStart_TheId, "ChapterTimeStart", KaxChapterTimeStart_Context); const EbmlCallbacks KaxChapterTimeEnd::ClassInfos(KaxChapterTimeEnd::Create, KaxChapterTimeEnd_TheId, "ChapterTimeEnd", KaxChapterTimeEnd_Context); const EbmlCallbacks KaxChapterFlagHidden::ClassInfos(KaxChapterFlagHidden::Create, KaxChapterFlagHidden_TheId, "ChapterFlagHidden", KaxChapterFlagHidden_Context); const EbmlCallbacks KaxChapterFlagEnabled::ClassInfos(KaxChapterFlagEnabled::Create, KaxChapterFlagEnabled_TheId, "ChapterFlagEnabled", KaxChapterFlagEnabled_Context); +const EbmlCallbacks KaxChapterSegmentUID::ClassInfos(KaxChapterSegmentUID::Create, KaxChapterSegmentUID_TheId, "ChapterSegmentUID", KaxChapterSegmentUID_Context); +const EbmlCallbacks KaxChapterSegmentEditionUID::ClassInfos(KaxChapterSegmentEditionUID::Create, KaxChapterSegmentEditionUID_TheId, "ChapterSegmentEditionUID", KaxChapterSegmentEditionUID_Context); const EbmlCallbacks KaxChapterPhysicalEquiv::ClassInfos(KaxChapterPhysicalEquiv::Create, KaxChapterPhysicalEquiv_TheId, "ChapterPhysicalEquiv", KaxChapterPhysicalEquiv_Context); const EbmlCallbacks KaxChapterTrack::ClassInfos(KaxChapterTrack::Create, KaxChapterTrack_TheId, "ChapterTrack", KaxChapterTrack_Context); const EbmlCallbacks KaxChapterTrackNumber::ClassInfos(KaxChapterTrackNumber::Create, KaxChapterTrackNumber_TheId, "ChapterTrackNumber", KaxChapterTrackNumber_Context); @@ -154,8 +171,11 @@ const EbmlCallbacks KaxChapterString::ClassInfos(KaxChapterString::Create, KaxCh const EbmlCallbacks KaxChapterLanguage::ClassInfos(KaxChapterLanguage::Create, KaxChapterLanguage_TheId, "ChapterLanguage", KaxChapterLanguage_Context); const EbmlCallbacks KaxChapterCountry::ClassInfos(KaxChapterCountry::Create, KaxChapterCountry_TheId, "ChapterCountry", KaxChapterCountry_Context); const EbmlCallbacks KaxChapterProcess::ClassInfos(KaxChapterProcess::Create, KaxChapterProcess_TheId, "ChapterProcess", KaxChapterProcess_Context); -const EbmlCallbacks KaxChapterProcessTime::ClassInfos(KaxChapterProcessTime::Create, KaxChapterProcessTime_TheId, "ChapterProcessTime", KaxChapterProcessTime_Context); +const EbmlCallbacks KaxChapterProcessCodecID::ClassInfos(KaxChapterProcessCodecID::Create, KaxChapterProcessCodecID_TheId, "ChapterProcessCodecID", KaxChapterProcessCodecID_Context); +const EbmlCallbacks KaxChapterProcessPrivate::ClassInfos(KaxChapterProcessPrivate::Create, KaxChapterProcessPrivate_TheId, "ChapterProcessPrivate", KaxChapterProcessPrivate_Context); const EbmlCallbacks KaxChapterProcessCommand::ClassInfos(KaxChapterProcessCommand::Create, KaxChapterProcessCommand_TheId, "ChapterProcessCommand", KaxChapterProcessCommand_Context); +const EbmlCallbacks KaxChapterProcessTime::ClassInfos(KaxChapterProcessTime::Create, KaxChapterProcessTime_TheId, "ChapterProcessTime", KaxChapterProcessTime_Context); +const EbmlCallbacks KaxChapterProcessData::ClassInfos(KaxChapterProcessData::Create, KaxChapterProcessData_TheId, "ChapterProcessData", KaxChapterProcessData_Context); KaxChapters::KaxChapters() :EbmlMaster(KaxChapters_Context) @@ -181,4 +201,8 @@ KaxChapterProcess::KaxChapterProcess() :EbmlMaster(KaxChapterProcess_Context) {} +KaxChapterProcessCommand::KaxChapterProcessCommand() +:EbmlMaster(KaxChapterProcessCommand_Context) +{} + END_LIBMATROSKA_NAMESPACE diff --git a/src/add-ons/media/plugins/matroska/libmatroska/KaxCluster.cpp b/src/add-ons/media/plugins/matroska/libmatroska/KaxCluster.cpp index 4183270b80..d520e7afb1 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/KaxCluster.cpp +++ b/src/add-ons/media/plugins/matroska/libmatroska/KaxCluster.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ /*! \file - \version \$Id: KaxCluster.cpp 640 2004-07-09 21:05:36Z mosu $ + \version \$Id: KaxCluster.cpp 1228 2005-10-14 19:36:51Z robux4 $ \author Steve Lhomme */ #include "matroska/KaxCluster.h" @@ -39,11 +39,19 @@ // sub elements START_LIBMATROSKA_NAMESPACE -EbmlSemantic KaxCluster_ContextList[4] = +#if MATROSKA_VERSION == 1 +EbmlSemantic KaxCluster_ContextList[5] = +#else // MATROSKA_VERSION +EbmlSemantic KaxCluster_ContextList[6] = +#endif // MATROSKA_VERSION { EbmlSemantic(true, true, KaxClusterTimecode::ClassInfos), + EbmlSemantic(false, true, KaxClusterSilentTracks::ClassInfos), EbmlSemantic(false, true, KaxClusterPrevSize::ClassInfos), - EbmlSemantic(true, false, KaxBlockGroup::ClassInfos), + EbmlSemantic(false, false, KaxBlockGroup::ClassInfos), +#if MATROSKA_VERSION == 2 + EbmlSemantic(false, false, KaxSimpleBlock::ClassInfos), +#endif EbmlSemantic(false, true, KaxClusterPosition::ClassInfos), }; @@ -59,10 +67,12 @@ KaxCluster::KaxCluster() ,bFirstFrameInside(false) ,bPreviousTimecodeIsSet(false) ,bTimecodeScaleIsSet(false) + ,bSilentTracksUsed(false) {} KaxCluster::KaxCluster(const KaxCluster & ElementToClone) :EbmlMaster(ElementToClone) + ,bSilentTracksUsed(ElementToClone.bSilentTracksUsed) { // update the parent of each children std::vector::const_iterator Itr = ElementList.begin(); @@ -80,6 +90,12 @@ KaxCluster::KaxCluster(const KaxCluster & ElementToClone) } } +bool KaxCluster::AddBlockBlob(KaxBlockBlob * NewBlob) +{ + Blobs.push_back(NewBlob); + return true; +} + bool KaxCluster::AddFrameInternal(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, const KaxBlockGroup * PastBlock, const KaxBlockGroup * ForwBlock, LacingType lacing) { if (!bFirstFrameInside) { @@ -136,16 +152,19 @@ bool KaxCluster::AddFrameInternal(const KaxTrackEntry & track, uint64 timecode, bool KaxCluster::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, LacingType lacing) { + assert(Blobs.size() == 0); // mutually exclusive for the moment return AddFrameInternal(track, timecode, buffer, MyNewBlock, NULL, NULL, lacing); } bool KaxCluster::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, const KaxBlockGroup & PastBlock, LacingType lacing) { + assert(Blobs.size() == 0); // mutually exclusive for the moment return AddFrameInternal(track, timecode, buffer, MyNewBlock, &PastBlock, NULL, lacing); } bool KaxCluster::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, KaxBlockGroup * & MyNewBlock, const KaxBlockGroup & PastBlock, const KaxBlockGroup & ForwBlock, LacingType lacing) { + assert(Blobs.size() == 0); // mutually exclusive for the moment return AddFrameInternal(track, timecode, buffer, MyNewBlock, &PastBlock, &ForwBlock, lacing); } @@ -154,19 +173,101 @@ bool KaxCluster::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuff */ uint32 KaxCluster::Render(IOCallback & output, KaxCues & CueToUpdate, bool bSaveDefault) { + uint32 Result = 0; + size_t TrkIndex, Index; + // update the Timecode of the Cluster before writing KaxClusterTimecode * Timecode = static_cast(this->FindElt(KaxClusterTimecode::ClassInfos)); *static_cast(Timecode) = GlobalTimecode() / GlobalTimecodeScale(); - uint32 Result = EbmlMaster::Render(output, bSaveDefault); - // For all Blocks add their position on the CueEntry - size_t Index; - - for (Index = 0; Index < ElementList.size(); Index++) { - if (EbmlId(*ElementList[Index]) == KaxBlockGroup::ClassInfos.GlobalId) { - CueToUpdate.PositionSet(*static_cast(ElementList[Index])); + if (Blobs.size() == 0) { + // old-school direct KaxBlockGroup + + // SilentTracks handling + // check the parent cluster for existing tracks and see if they are contained in this cluster or not + if (bSilentTracksUsed) + { + KaxTracks & MyTracks = *static_cast(ParentSegment->FindElt(KaxTracks::ClassInfos)); + for (TrkIndex = 0; TrkIndex < MyTracks.ListSize(); TrkIndex++) { + if (EbmlId(*MyTracks[TrkIndex]) == KaxTrackEntry::ClassInfos.GlobalId) + { + KaxTrackEntry & entry = *static_cast(MyTracks[TrkIndex]); + uint32 tracknum = entry.TrackNumber(); + for (Index = 0; Index < ElementList.size(); Index++) { + if (EbmlId(*ElementList[Index]) == KaxBlockGroup::ClassInfos.GlobalId) { + KaxBlockGroup & group = *static_cast(ElementList[Index]); + if (group.TrackNumber() == tracknum) + break; // this track is used + } + } + // the track wasn't found in this cluster + if (Index == ElementList.size()) + { + KaxClusterSilentTracks * SilentTracks = static_cast(this->FindFirstElt(KaxClusterSilentTracks::ClassInfos)); + assert(SilentTracks != NULL); // the flag bSilentTracksUsed should be set when creating the Cluster + KaxClusterSilentTrackNumber * trackelt = static_cast(SilentTracks->AddNewElt(KaxClusterSilentTrackNumber::ClassInfos)); + *static_cast(trackelt) = tracknum; + } + } + } } + + Result = EbmlMaster::Render(output, bSaveDefault); + // For all Blocks add their position on the CueEntry + + for (Index = 0; Index < ElementList.size(); Index++) { + if (EbmlId(*ElementList[Index]) == KaxBlockGroup::ClassInfos.GlobalId) { + CueToUpdate.PositionSet(*static_cast(ElementList[Index])); + } + } + } else { + // new school, using KaxBlockBlob + for (Index = 0; Index= 2 + if (Blobs[Index]->IsSimpleBlock()) + ElementList.push_back( &(KaxSimpleBlock&) *Blobs[Index] ); + else +#endif + ElementList.push_back( &(KaxBlockGroup&) *Blobs[Index] ); + } + + // SilentTracks handling + // check the parent cluster for existing tracks and see if they are contained in this cluster or not + if (bSilentTracksUsed) + { + KaxTracks & MyTracks = *static_cast(ParentSegment->FindElt(KaxTracks::ClassInfos)); + for (TrkIndex = 0; TrkIndex < MyTracks.ListSize(); TrkIndex++) { + if (EbmlId(*MyTracks[TrkIndex]) == KaxTrackEntry::ClassInfos.GlobalId) + { + KaxTrackEntry & entry = *static_cast(MyTracks[TrkIndex]); + uint32 tracknum = entry.TrackNumber(); + for (Index = 0; Index(this->FindFirstElt(KaxClusterSilentTracks::ClassInfos)); + assert(SilentTracks != NULL); // the flag bSilentTracksUsed should be set when creating the Cluster + KaxClusterSilentTrackNumber * trackelt = static_cast(SilentTracks->AddNewElt(KaxClusterSilentTrackNumber::ClassInfos)); + *static_cast(trackelt) = tracknum; + } + } + } + } + + Result = EbmlMaster::Render(output, bSaveDefault); + + // For all Blocks add their position on the CueEntry + for (Index = 0; Index */ #include "matroska/KaxClusterData.h" @@ -37,16 +37,31 @@ START_LIBMATROSKA_NAMESPACE -EbmlId KaxClusterTimecode_TheId(0xE7, 1); -EbmlId KaxClusterPrevSize_TheId(0xAB, 1); -EbmlId KaxClusterPosition_TheId(0xA7, 1); +EbmlId KaxClusterTimecode_TheId (0xE7, 1); +EbmlId KaxClusterSilentTracks_TheId (0x5854, 2); +EbmlId KaxClusterSilentTrackNumber_TheId(0x58D7, 2); +EbmlId KaxClusterPrevSize_TheId (0xAB, 1); +EbmlId KaxClusterPosition_TheId (0xA7, 1); + +EbmlSemantic KaxClusterSilentTracks_ContextList[1] = +{ + EbmlSemantic(false, false, KaxClusterSilentTrackNumber::ClassInfos), +}; const EbmlSemanticContext KaxClusterTimecode_Context = EbmlSemanticContext(0, NULL, &KaxCluster_Context, *GetKaxGlobal_Context, &KaxClusterTimecode::ClassInfos); +const EbmlSemanticContext KaxClusterSilentTracks_Context = EbmlSemanticContext(countof(KaxClusterSilentTracks_ContextList), KaxClusterSilentTracks_ContextList, &KaxCluster_Context, *GetKaxGlobal_Context, &KaxClusterSilentTracks::ClassInfos); +const EbmlSemanticContext KaxClusterSilentTrackNumber_Context = EbmlSemanticContext(0, NULL, &KaxClusterSilentTracks_Context, *GetKaxGlobal_Context, &KaxClusterSilentTrackNumber::ClassInfos); const EbmlSemanticContext KaxClusterPosition_Context = EbmlSemanticContext(0, NULL, &KaxCluster_Context, *GetKaxGlobal_Context, &KaxClusterPosition::ClassInfos); const EbmlSemanticContext KaxClusterPrevSize_Context = EbmlSemanticContext(0, NULL, &KaxCluster_Context, *GetKaxGlobal_Context, &KaxClusterPrevSize::ClassInfos); const EbmlCallbacks KaxClusterTimecode::ClassInfos(KaxClusterTimecode::Create, KaxClusterTimecode_TheId, "ClusterTimecode", KaxClusterTimecode_Context); +const EbmlCallbacks KaxClusterSilentTracks::ClassInfos(KaxClusterSilentTracks::Create, KaxClusterSilentTracks_TheId, "ClusterSilentTracks", KaxClusterSilentTracks_Context); +const EbmlCallbacks KaxClusterSilentTrackNumber::ClassInfos(KaxClusterSilentTrackNumber::Create, KaxClusterSilentTrackNumber_TheId, "ClusterSilentTrackNumber", KaxClusterSilentTrackNumber_Context); const EbmlCallbacks KaxClusterPrevSize::ClassInfos(KaxClusterPrevSize::Create, KaxClusterPrevSize_TheId, "ClusterPrevSize", KaxClusterPrevSize_Context); const EbmlCallbacks KaxClusterPosition::ClassInfos(KaxClusterPosition::Create, KaxClusterPosition_TheId, "ClusterPosition", KaxClusterPosition_Context); +KaxClusterSilentTracks::KaxClusterSilentTracks() +:EbmlMaster(KaxClusterSilentTracks_Context) +{} + END_LIBMATROSKA_NAMESPACE diff --git a/src/add-ons/media/plugins/matroska/libmatroska/KaxCues.cpp b/src/add-ons/media/plugins/matroska/libmatroska/KaxCues.cpp index e972102999..7aee21cbe0 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/KaxCues.cpp +++ b/src/add-ons/media/plugins/matroska/libmatroska/KaxCues.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ /*! \file - \version \$Id: KaxCues.cpp 647 2004-07-14 13:29:48Z mosu $ + \version \$Id: KaxCues.cpp 1265 2007-01-14 17:20:35Z mosu $ \author Steve Lhomme */ #include @@ -59,10 +59,12 @@ KaxCues::~KaxCues() assert(myTempReferences.size() == 0); // otherwise that means you have added references and forgot to set the position } -bool KaxCues::AddBlockGroup(const KaxBlockGroup & BlockReference) +bool KaxCues::AddBlockGroup(const KaxBlockGroup & BlockRef) { // Do not add the element if it's already present. - std::vector::iterator ListIdx; + std::vector::iterator ListIdx; + KaxBlockBlob &BlockReference = *(new KaxBlockBlob(BLOCK_BLOB_NO_SIMPLE)); + BlockReference.SetBlockGroup(*const_cast(&BlockRef)); for (ListIdx = myTempReferences.begin(); ListIdx != myTempReferences.end(); ListIdx++) if (*ListIdx == &BlockReference) @@ -72,10 +74,23 @@ bool KaxCues::AddBlockGroup(const KaxBlockGroup & BlockReference) return true; } -void KaxCues::PositionSet(const KaxBlockGroup & BlockReference) +bool KaxCues::AddBlockBlob(const KaxBlockBlob & BlockReference) +{ + // Do not add the element if it's already present. + std::vector::iterator ListIdx; + + for (ListIdx = myTempReferences.begin(); ListIdx != myTempReferences.end(); ListIdx++) + if (*ListIdx == &BlockReference) + return true; + + myTempReferences.push_back(&BlockReference); + return true; +} + +void KaxCues::PositionSet(const KaxBlockBlob & BlockReference) { // look for the element in the temporary references - std::vector::iterator ListIdx; + std::vector::iterator ListIdx; for (ListIdx = myTempReferences.begin(); ListIdx != myTempReferences.end(); ListIdx++) { if (*ListIdx == &BlockReference) { @@ -88,6 +103,24 @@ void KaxCues::PositionSet(const KaxBlockGroup & BlockReference) } } +void KaxCues::PositionSet(const KaxBlockGroup & BlockRef) +{ + // look for the element in the temporary references + std::vector::iterator ListIdx; + + for (ListIdx = myTempReferences.begin(); ListIdx != myTempReferences.end(); ListIdx++) { + const KaxInternalBlock &refTmp = **ListIdx; + if (refTmp.GlobalTimecode() == BlockRef.GlobalTimecode() && + refTmp.TrackNum() == BlockRef.TrackNumber()) { + // found, now add the element to the entry list + KaxCuePoint & NewPoint = AddNewChild(*this); + NewPoint.PositionSet(**ListIdx, GlobalTimecodeScale()); + myTempReferences.erase(ListIdx); + break; + } + } +} + /*! \warning Assume that the list has been sorted (Sort()) */ diff --git a/src/add-ons/media/plugins/matroska/libmatroska/KaxCuesData.cpp b/src/add-ons/media/plugins/matroska/libmatroska/KaxCuesData.cpp index 3325f44b88..17b688ce96 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/KaxCuesData.cpp +++ b/src/add-ons/media/plugins/matroska/libmatroska/KaxCuesData.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -27,7 +27,7 @@ /*! \file - \version \$Id: KaxCuesData.cpp 640 2004-07-09 21:05:36Z mosu $ + \version \$Id: KaxCuesData.cpp 1265 2007-01-14 17:20:35Z mosu $ \author Steve Lhomme */ #include @@ -36,6 +36,8 @@ #include "matroska/KaxContexts.h" #include "matroska/KaxBlock.h" #include "matroska/KaxBlockData.h" +#include "matroska/KaxCluster.h" +#include "matroska/KaxSegment.h" START_LIBMATROSKA_NAMESPACE @@ -156,6 +158,53 @@ void KaxCuePoint::PositionSet(const KaxBlockGroup & BlockReference, uint64 Globa NewRefs.AddReference(BlockReference.Reference(i).RefBlock(), GlobalTimecodeScale); } } + + KaxCodecState *CodecState = static_cast(BlockReference.FindFirstElt(KaxCodecState::ClassInfos)); + if (CodecState != NULL) { + KaxCueCodecState &CueCodecState = AddNewChild(NewPositions); + *static_cast(&CueCodecState) = BlockReference.GetParentCluster()->GetParentSegment()->GetRelativePosition(CodecState->GetElementPosition()); + } +#endif // MATROSKA_VERSION + + bValueIsSet = true; +} + +void KaxCuePoint::PositionSet(const KaxBlockBlob & BlobReference, uint64 GlobalTimecodeScale) +{ + const KaxInternalBlock &BlockReference = BlobReference; + + // fill me + KaxCueTime & NewTime = GetChild(*this); + *static_cast(&NewTime) = BlockReference.GlobalTimecode() / GlobalTimecodeScale; + + KaxCueTrackPositions & NewPositions = AddNewChild(*this); + KaxCueTrack & TheTrack = GetChild(NewPositions); + *static_cast(&TheTrack) = BlockReference.TrackNum(); + + KaxCueClusterPosition & TheClustPos = GetChild(NewPositions); + *static_cast(&TheClustPos) = BlockReference.ClusterPosition(); + +#if 0 // MATROSKA_VERSION >= 2 + // handle reference use + if (BlockReference.ReferenceCount() != 0) + { + unsigned int i; + for (i=0; i(NewPositions); + NewRefs.AddReference(BlockReference.Reference(i).RefBlock(), GlobalTimecodeScale); + } + } +#endif // MATROSKA_VERSION + +#if MATROSKA_VERSION >= 2 + if (!BlobReference.IsSimpleBlock()) { + const KaxBlockGroup &BlockGroup = BlobReference; + const KaxCodecState *CodecState = static_cast(BlockGroup.FindFirstElt(KaxCodecState::ClassInfos)); + if (CodecState != NULL) { + KaxCueCodecState &CueCodecState = AddNewChild(NewPositions); + *static_cast(&CueCodecState) = BlockGroup.GetParentCluster()->GetParentSegment()->GetRelativePosition(CodecState->GetElementPosition()); + } + } #endif // MATROSKA_VERSION bValueIsSet = true; @@ -165,13 +214,14 @@ void KaxCuePoint::PositionSet(const KaxBlockGroup & BlockReference, uint64 Globa /*! \todo handle codec state checking */ -void KaxCueReference::AddReference(const KaxBlockGroup & BlockReference, uint64 GlobalTimecodeScale) +void KaxCueReference::AddReference(const KaxBlockBlob & BlockReference, uint64 GlobalTimecodeScale) { + const KaxInternalBlock & theBlock = BlockReference; KaxCueRefTime & NewTime = GetChild(*this); - *static_cast(&NewTime) = BlockReference.GlobalTimecode() / GlobalTimecodeScale; + *static_cast(&NewTime) = theBlock.GlobalTimecode() / GlobalTimecodeScale; KaxCueRefCluster & TheClustPos = GetChild(*this); - *static_cast(&TheClustPos) = BlockReference.ClusterPosition(); + *static_cast(&TheClustPos) = theBlock.ClusterPosition(); #ifdef OLD // handle recursive reference use @@ -184,7 +234,7 @@ void KaxCueReference::AddReference(const KaxBlockGroup & BlockReference, uint64 } #endif /* OLD */ } -#endif // MATROSKA_VERSION +#endif bool KaxCuePoint::operator<(const EbmlElement & EltB) const { diff --git a/src/add-ons/media/plugins/matroska/libmatroska/KaxInfo.cpp b/src/add-ons/media/plugins/matroska/libmatroska/KaxInfo.cpp index 2f87fb1e7c..8b8242de10 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/KaxInfo.cpp +++ b/src/add-ons/media/plugins/matroska/libmatroska/KaxInfo.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libmatroska. ** @@ -29,7 +29,7 @@ /*! \file - \version \$Id: KaxInfo.cpp 640 2004-07-09 21:05:36Z mosu $ + \version \$Id: KaxInfo.cpp 1078 2005-03-03 13:13:04Z robux4 $ \author Steve Lhomme */ #include "matroska/KaxInfo.h" @@ -40,20 +40,22 @@ // sub elements START_LIBMATROSKA_NAMESPACE -const EbmlSemantic KaxInfo_ContextList[12] = +const EbmlSemantic KaxInfo_ContextList[14] = { - EbmlSemantic(false, true, KaxSegmentUID::ClassInfos), - EbmlSemantic(false, true, KaxSegmentFilename::ClassInfos), - EbmlSemantic(false, true, KaxPrevUID::ClassInfos), - EbmlSemantic(false, true, KaxPrevFilename::ClassInfos), - EbmlSemantic(false, true, KaxNextUID::ClassInfos), - EbmlSemantic(false, true, KaxNextFilename::ClassInfos), - EbmlSemantic(true, true, KaxTimecodeScale::ClassInfos), - EbmlSemantic(false, true, KaxDuration::ClassInfos), - EbmlSemantic(false, true, KaxDateUTC::ClassInfos), - EbmlSemantic(false, true, KaxTitle::ClassInfos), - EbmlSemantic(true, true, KaxMuxingApp::ClassInfos), - EbmlSemantic(true, true, KaxWritingApp::ClassInfos), + EbmlSemantic(false, true, KaxSegmentUID::ClassInfos), + EbmlSemantic(false, true, KaxSegmentFilename::ClassInfos), + EbmlSemantic(false, true, KaxPrevUID::ClassInfos), + EbmlSemantic(false, true, KaxPrevFilename::ClassInfos), + EbmlSemantic(false, true, KaxNextUID::ClassInfos), + EbmlSemantic(false, true, KaxNextFilename::ClassInfos), + EbmlSemantic(false, false, KaxSegmentFamily::ClassInfos), + EbmlSemantic(false, false, KaxChapterTranslate::ClassInfos), + EbmlSemantic(true, true, KaxTimecodeScale::ClassInfos), + EbmlSemantic(false, true, KaxDuration::ClassInfos), + EbmlSemantic(false, true, KaxDateUTC::ClassInfos), + EbmlSemantic(false, true, KaxTitle::ClassInfos), + EbmlSemantic(true, true, KaxMuxingApp::ClassInfos), + EbmlSemantic(true, true, KaxWritingApp::ClassInfos), }; const EbmlSemanticContext KaxInfo_Context = EbmlSemanticContext(countof(KaxInfo_ContextList), KaxInfo_ContextList, &KaxSegment_Context, *GetKaxGlobal_Context, &KaxInfo::ClassInfos); diff --git a/src/add-ons/media/plugins/matroska/libmatroska/KaxInfoData.cpp b/src/add-ons/media/plugins/matroska/libmatroska/KaxInfoData.cpp index 29e23bd176..5a1b597120 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/KaxInfoData.cpp +++ b/src/add-ons/media/plugins/matroska/libmatroska/KaxInfoData.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libmatroska. ** @@ -29,7 +29,7 @@ /*! \file - \version \$Id: KaxInfoData.cpp 640 2004-07-09 21:05:36Z mosu $ + \version \$Id: KaxInfoData.cpp 1078 2005-03-03 13:13:04Z robux4 $ \author Steve Lhomme \author John Cannon */ @@ -38,16 +38,28 @@ START_LIBMATROSKA_NAMESPACE -EbmlId KaxSegmentUID_TheId (0x73A4, 2); -EbmlId KaxSegmentFilename_TheId(0x7384, 2); -EbmlId KaxPrevUID_TheId (0x3CB923, 3); -EbmlId KaxPrevFilename_TheId (0x3C83AB, 3); -EbmlId KaxNextUID_TheId (0x3EB923, 3); -EbmlId KaxNextFilename_TheId (0x3E83BB, 3); -EbmlId KaxTimecodeScale_TheId (0x2AD7B1, 3); -EbmlId KaxDuration_TheId (0x4489, 2); -EbmlId KaxDateUTC_TheId (0x4461, 2); -EbmlId KaxTitle_TheId (0x7BA9, 2); +const EbmlSemantic KaxChapterTranslate_ContextList[3] = +{ + EbmlSemantic(false, false, KaxChapterTranslateEditionUID::ClassInfos), + EbmlSemantic(true, true, KaxChapterTranslateCodec::ClassInfos), + EbmlSemantic(true, true, KaxChapterTranslateID::ClassInfos), +}; + +EbmlId KaxSegmentUID_TheId (0x73A4, 2); +EbmlId KaxSegmentFilename_TheId (0x7384, 2); +EbmlId KaxPrevUID_TheId (0x3CB923, 3); +EbmlId KaxPrevFilename_TheId (0x3C83AB, 3); +EbmlId KaxNextUID_TheId (0x3EB923, 3); +EbmlId KaxNextFilename_TheId (0x3E83BB, 3); +EbmlId KaxSegmentFamily_TheId (0x4444, 2); +EbmlId KaxChapterTranslate_TheId(0x6924, 2); +EbmlId KaxChapterTranslateEditionUID_TheId(0x69FC, 2); +EbmlId KaxChapterTranslateCodec_TheId(0x69BF, 2); +EbmlId KaxChapterTranslateID_TheId(0x69A5, 2); +EbmlId KaxTimecodeScale_TheId (0x2AD7B1, 3); +EbmlId KaxDuration_TheId (0x4489, 2); +EbmlId KaxDateUTC_TheId (0x4461, 2); +EbmlId KaxTitle_TheId (0x7BA9, 2); const EbmlSemanticContext KaxSegmentUID_Context = EbmlSemanticContext(0, NULL, &KaxInfo_Context, *GetKaxGlobal_Context, &KaxSegmentUID::ClassInfos); const EbmlSemanticContext KaxSegmentFilename_Context = EbmlSemanticContext(0, NULL, &KaxInfo_Context, *GetKaxGlobal_Context, &KaxSegmentFilename::ClassInfos); @@ -55,6 +67,11 @@ const EbmlSemanticContext KaxPrevUID_Context = EbmlSemanticContext(0, NULL, &Kax const EbmlSemanticContext KaxPrevFilename_Context = EbmlSemanticContext(0, NULL, &KaxInfo_Context, *GetKaxGlobal_Context, &KaxPrevFilename::ClassInfos); const EbmlSemanticContext KaxNextUID_Context = EbmlSemanticContext(0, NULL, &KaxInfo_Context, *GetKaxGlobal_Context, &KaxNextUID::ClassInfos); const EbmlSemanticContext KaxNextFilename_Context = EbmlSemanticContext(0, NULL, &KaxInfo_Context, *GetKaxGlobal_Context, &KaxNextFilename::ClassInfos); +const EbmlSemanticContext KaxSegmentFamily_Context = EbmlSemanticContext(0, NULL, &KaxInfo_Context, *GetKaxGlobal_Context, &KaxSegmentFamily::ClassInfos); +const EbmlSemanticContext KaxChapterTranslate_Context = EbmlSemanticContext(countof(KaxChapterTranslate_ContextList), KaxChapterTranslate_ContextList, &KaxInfo_Context, *GetKaxGlobal_Context, &KaxChapterTranslate::ClassInfos); +const EbmlSemanticContext KaxChapterTranslateEditionUID_Context = EbmlSemanticContext(0, NULL, &KaxChapterTranslate_Context, *GetKaxGlobal_Context, &KaxChapterTranslateEditionUID::ClassInfos); +const EbmlSemanticContext KaxChapterTranslateCodec_Context = EbmlSemanticContext(0, NULL, &KaxChapterTranslate_Context, *GetKaxGlobal_Context, &KaxChapterTranslateCodec::ClassInfos); +const EbmlSemanticContext KaxChapterTranslateID_Context = EbmlSemanticContext(0, NULL, &KaxChapterTranslate_Context, *GetKaxGlobal_Context, &KaxChapterTranslateID::ClassInfos); const EbmlSemanticContext KaxTimecodeScale_Context = EbmlSemanticContext(0, NULL, &KaxInfo_Context, *GetKaxGlobal_Context, &KaxTimecodeScale::ClassInfos); const EbmlSemanticContext KaxDuration_Context = EbmlSemanticContext(0, NULL, &KaxInfo_Context, *GetKaxGlobal_Context, &KaxDuration::ClassInfos); const EbmlSemanticContext KaxDateUTC_Context = EbmlSemanticContext(0, NULL, &KaxInfo_Context, *GetKaxGlobal_Context, &KaxDateUTC::ClassInfos); @@ -67,9 +84,18 @@ const EbmlCallbacks KaxPrevUID::ClassInfos(KaxPrevUID::Create, KaxPrevUID_TheId, const EbmlCallbacks KaxPrevFilename::ClassInfos(KaxPrevFilename::Create, KaxPrevFilename_TheId, "PrevFilename", KaxPrevFilename_Context); const EbmlCallbacks KaxNextUID::ClassInfos(KaxNextUID::Create, KaxNextUID_TheId, "NextUID", KaxNextUID_Context); const EbmlCallbacks KaxNextFilename::ClassInfos(KaxNextFilename::Create, KaxNextFilename_TheId, "NextFilename", KaxNextFilename_Context); +const EbmlCallbacks KaxSegmentFamily::ClassInfos(KaxSegmentFamily::Create, KaxSegmentFamily_TheId, "SegmentFamily", KaxSegmentFamily_Context); +const EbmlCallbacks KaxChapterTranslate::ClassInfos(KaxChapterTranslate::Create, KaxChapterTranslate_TheId, "ChapterTranslate", KaxChapterTranslate_Context); +const EbmlCallbacks KaxChapterTranslateEditionUID::ClassInfos(KaxChapterTranslateEditionUID::Create, KaxChapterTranslateEditionUID_TheId, "ChapterTranslateEditionUID", KaxChapterTranslateEditionUID_Context); +const EbmlCallbacks KaxChapterTranslateCodec::ClassInfos(KaxChapterTranslateCodec::Create, KaxChapterTranslateCodec_TheId, "ChapterTranslateCodec", KaxChapterTranslateCodec_Context); +const EbmlCallbacks KaxChapterTranslateID::ClassInfos(KaxChapterTranslateID::Create, KaxChapterTranslateID_TheId, "ChapterTranslateID", KaxChapterTranslateID_Context); const EbmlCallbacks KaxTimecodeScale::ClassInfos(KaxTimecodeScale::Create, KaxTimecodeScale_TheId, "TimecodeScale", KaxTimecodeScale_Context); const EbmlCallbacks KaxDuration::ClassInfos(KaxDuration::Create, KaxDuration_TheId, "Duration", KaxDuration_Context); const EbmlCallbacks KaxDateUTC::ClassInfos(KaxDateUTC::Create, KaxDateUTC_TheId, "DateUTC", KaxDateUTC_Context); const EbmlCallbacks KaxTitle::ClassInfos(KaxTitle::Create, KaxTitle_TheId, "Title", KaxTitle_Context); +KaxChapterTranslate::KaxChapterTranslate() + :EbmlMaster(KaxChapterTranslate_Context) +{} + END_LIBMATROSKA_NAMESPACE diff --git a/src/add-ons/media/plugins/matroska/libmatroska/KaxSegment.cpp b/src/add-ons/media/plugins/matroska/libmatroska/KaxSegment.cpp index 036054ad55..4bafab1e7b 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/KaxSegment.cpp +++ b/src/add-ons/media/plugins/matroska/libmatroska/KaxSegment.cpp @@ -29,7 +29,7 @@ /*! \file - \version \$Id: KaxSegment.cpp 640 2004-07-09 21:05:36Z mosu $ + \version \$Id: KaxSegment.cpp 1096 2005-03-17 09:14:52Z robux4 $ \author Steve Lhomme */ #include "matroska/KaxSegment.h" @@ -70,7 +70,7 @@ const EbmlSemanticContext KaxMatroska_Context = EbmlSemanticContext(countof(KaxM const EbmlSemanticContext KaxSegment_Context = EbmlSemanticContext(countof(KaxSegment_ContextList), KaxSegment_ContextList, NULL, *GetKaxGlobal_Context, &KaxSegment::ClassInfos); EbmlId KaxSegment_TheId(0x18538067, 4); -const EbmlCallbacks KaxSegment::ClassInfos(KaxSegment::Create, KaxSegment_TheId, "Segment", KaxSegment_Context); +const EbmlCallbacks KaxSegment::ClassInfos(KaxSegment::Create, KaxSegment_TheId, "Segment\0rotomopogo", KaxSegment_Context); KaxSegment::KaxSegment() :EbmlMaster(KaxSegment_Context) diff --git a/src/add-ons/media/plugins/matroska/libmatroska/KaxTrackEntryData.cpp b/src/add-ons/media/plugins/matroska/libmatroska/KaxTrackEntryData.cpp index 9f64fb33f4..a26cfd9478 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/KaxTrackEntryData.cpp +++ b/src/add-ons/media/plugins/matroska/libmatroska/KaxTrackEntryData.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libmatroska. ** @@ -29,7 +29,7 @@ /*! \file - \version \$Id: KaxTrackEntryData.cpp 640 2004-07-09 21:05:36Z mosu $ + \version \$Id: KaxTrackEntryData.cpp 1201 2005-08-30 14:28:27Z robux4 $ \author Steve Lhomme \author John Cannon */ @@ -38,73 +38,105 @@ START_LIBMATROSKA_NAMESPACE +const EbmlSemantic KaxTrackTranslate_ContextList[3] = +{ + EbmlSemantic(false, false,KaxTrackTranslateEditionUID::ClassInfos), + EbmlSemantic(true , true, KaxTrackTranslateCodec::ClassInfos), + EbmlSemantic(true , true, KaxTrackTranslateTrackID::ClassInfos), +}; + EbmlId KaxTrackNumber_TheId (0xD7, 1); EbmlId KaxTrackUID_TheId (0x73C5, 2); EbmlId KaxTrackType_TheId (0x83, 1); EbmlId KaxTrackFlagDefault_TheId (0x88, 1); +EbmlId KaxTrackFlagForced_TheId (0x55AA, 2); EbmlId KaxTrackFlagLacing_TheId (0x9C, 1); EbmlId KaxTrackMinCache_TheId (0x6DE7, 2); EbmlId KaxTrackMaxCache_TheId (0x6DF8, 2); EbmlId KaxTrackDefaultDuration_TheId (0x23E383, 3); EbmlId KaxTrackTimecodeScale_TheId (0x23314F, 3); +EbmlId KaxMaxBlockAdditionID_TheId (0x55EE, 2); EbmlId KaxTrackName_TheId (0x536E, 2); EbmlId KaxTrackLanguage_TheId (0x22B59C, 3); EbmlId KaxCodecID_TheId (0x86, 1); EbmlId KaxCodecPrivate_TheId (0x63A2, 2); EbmlId KaxCodecName_TheId (0x258688, 3); +EbmlId KaxTrackAttachmentLink_TheId (0x7446, 2); +EbmlId KaxTrackOverlay_TheId (0x6FAB, 2); +EbmlId KaxTrackTranslate_TheId (0x6624, 2); +EbmlId KaxTrackTranslateEditionUID_TheId(0x66FC, 2); +EbmlId KaxTrackTranslateCodec_TheId (0x66BF, 2); +EbmlId KaxTrackTranslateTrackID_TheId (0x66A5, 2); #if MATROSKA_VERSION >= 2 EbmlId KaxTrackFlagEnabled_TheId (0xB9, 1); EbmlId KaxCodecSettings_TheId (0x3A9697, 3); EbmlId KaxCodecInfoURL_TheId (0x3B4040, 3); EbmlId KaxCodecDownloadURL_TheId (0x26B240, 3); EbmlId KaxCodecDecodeAll_TheId (0xAA, 1); -EbmlId KaxTrackOverlay_TheId (0x6FAB, 2); #endif // MATROSKA_VERSION const EbmlSemanticContext KaxTrackNumber_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackNumber::ClassInfos); const EbmlSemanticContext KaxTrackUID_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackUID::ClassInfos); const EbmlSemanticContext KaxTrackType_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackType::ClassInfos); const EbmlSemanticContext KaxTrackFlagDefault_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackFlagDefault::ClassInfos); +const EbmlSemanticContext KaxTrackFlagForced_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackFlagForced::ClassInfos); const EbmlSemanticContext KaxTrackFlagLacing_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackFlagLacing::ClassInfos); const EbmlSemanticContext KaxTrackMinCache_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackMinCache::ClassInfos); const EbmlSemanticContext KaxTrackMaxCache_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackMaxCache::ClassInfos); const EbmlSemanticContext KaxTrackDefaultDuration_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackDefaultDuration::ClassInfos); const EbmlSemanticContext KaxTrackTimecodeScale_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackTimecodeScale::ClassInfos); +const EbmlSemanticContext KaxMaxBlockAdditionID_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxMaxBlockAdditionID::ClassInfos); const EbmlSemanticContext KaxTrackName_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackName::ClassInfos); const EbmlSemanticContext KaxTrackLanguage_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackLanguage::ClassInfos); const EbmlSemanticContext KaxCodecID_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxCodecID::ClassInfos); const EbmlSemanticContext KaxCodecPrivate_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxCodecPrivate::ClassInfos); const EbmlSemanticContext KaxCodecName_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxCodecName::ClassInfos); +const EbmlSemanticContext KaxTrackAttachmentLink_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackAttachmentLink::ClassInfos); +const EbmlSemanticContext KaxTrackOverlay_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackOverlay::ClassInfos); +const EbmlSemanticContext KaxTrackTranslate_Context = EbmlSemanticContext(countof(KaxTrackTranslate_ContextList), KaxTrackTranslate_ContextList, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackTranslate::ClassInfos); +const EbmlSemanticContext KaxTrackTranslateEditionUID_Context = EbmlSemanticContext(0, NULL, &KaxTrackTranslate_Context, *GetKaxGlobal_Context, &KaxTrackTranslateEditionUID::ClassInfos); +const EbmlSemanticContext KaxTrackTranslateCodec_Context = EbmlSemanticContext(0, NULL, &KaxTrackTranslate_Context, *GetKaxGlobal_Context, &KaxTrackTranslateCodec::ClassInfos); +const EbmlSemanticContext KaxTrackTranslateTrackID_Context = EbmlSemanticContext(0, NULL, &KaxTrackTranslate_Context, *GetKaxGlobal_Context, &KaxTrackTranslateTrackID::ClassInfos); #if MATROSKA_VERSION >= 2 const EbmlSemanticContext KaxTrackFlagEnabled_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackFlagEnabled::ClassInfos); const EbmlSemanticContext KaxCodecSettings_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxCodecSettings::ClassInfos); const EbmlSemanticContext KaxCodecInfoURL_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxCodecInfoURL::ClassInfos); const EbmlSemanticContext KaxCodecDownloadURL_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxCodecDownloadURL::ClassInfos); const EbmlSemanticContext KaxCodecDecodeAll_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxCodecDecodeAll::ClassInfos); -const EbmlSemanticContext KaxTrackOverlay_Context = EbmlSemanticContext(0, NULL, &KaxTracks_Context, *GetKaxGlobal_Context, &KaxTrackOverlay::ClassInfos); #endif // MATROSKA_VERSION const EbmlCallbacks KaxTrackNumber::ClassInfos(KaxTrackNumber::Create, KaxTrackNumber_TheId, "TrackNumber", KaxTrackNumber_Context); const EbmlCallbacks KaxTrackUID::ClassInfos(KaxTrackUID::Create, KaxTrackUID_TheId, "TrackUID", KaxTrackUID_Context); const EbmlCallbacks KaxTrackType::ClassInfos(KaxTrackType::Create, KaxTrackType_TheId, "TrackType", KaxTrackType_Context); const EbmlCallbacks KaxTrackFlagDefault::ClassInfos(KaxTrackFlagDefault::Create, KaxTrackFlagDefault_TheId, "TrackFlagDefault", KaxTrackFlagDefault_Context); +const EbmlCallbacks KaxTrackFlagForced::ClassInfos(KaxTrackFlagForced::Create, KaxTrackFlagForced_TheId, "TrackFlagForced", KaxTrackFlagForced_Context); const EbmlCallbacks KaxTrackFlagLacing::ClassInfos(KaxTrackFlagLacing::Create, KaxTrackFlagLacing_TheId, "TrackFlagLacing", KaxTrackFlagLacing_Context); const EbmlCallbacks KaxTrackMinCache::ClassInfos(KaxTrackMinCache::Create, KaxTrackMinCache_TheId, "TrackMinCache", KaxTrackMinCache_Context); -const EbmlCallbacks KaxTrackMaxCache::ClassInfos(KaxTrackMaxCache::Create, KaxTrackMaxCache_TheId, "TrackMaxCache", KaxTrackMaxCache_Context); +const EbmlCallbacks KaxTrackMaxCache::ClassInfos(KaxTrackMaxCache::Create, KaxTrackMaxCache_TheId, "TrackMaxCache\0rotomodobopo", KaxTrackMaxCache_Context); const EbmlCallbacks KaxTrackDefaultDuration::ClassInfos(KaxTrackDefaultDuration::Create, KaxTrackDefaultDuration_TheId, "TrackDefaultDuration", KaxTrackDefaultDuration_Context); const EbmlCallbacks KaxTrackTimecodeScale::ClassInfos(KaxTrackTimecodeScale::Create, KaxTrackTimecodeScale_TheId, "TrackTimecodeScale", KaxTrackTimecodeScale_Context); +const EbmlCallbacks KaxMaxBlockAdditionID::ClassInfos(KaxMaxBlockAdditionID::Create, KaxMaxBlockAdditionID_TheId, "MaxBlockAdditionID", KaxMaxBlockAdditionID_Context); const EbmlCallbacks KaxTrackName::ClassInfos(KaxTrackName::Create, KaxTrackName_TheId, "TrackName", KaxTrackName_Context); const EbmlCallbacks KaxTrackLanguage::ClassInfos(KaxTrackLanguage::Create, KaxTrackLanguage_TheId, "TrackLanguage", KaxTrackLanguage_Context); const EbmlCallbacks KaxCodecID::ClassInfos(KaxCodecID::Create, KaxCodecID_TheId, "CodecID", KaxCodecID_Context); const EbmlCallbacks KaxCodecPrivate::ClassInfos(KaxCodecPrivate::Create, KaxCodecPrivate_TheId, "CodecPrivate", KaxCodecPrivate_Context); const EbmlCallbacks KaxCodecName::ClassInfos(KaxCodecName::Create, KaxCodecName_TheId, "CodecName", KaxCodecName_Context); +const EbmlCallbacks KaxTrackAttachmentLink::ClassInfos(KaxTrackAttachmentLink::Create, KaxTrackAttachmentLink_TheId, "TrackAttachmentLink", KaxTrackAttachmentLink_Context); +const EbmlCallbacks KaxTrackOverlay::ClassInfos(KaxTrackOverlay::Create, KaxTrackOverlay_TheId, "TrackOverlay", KaxTrackOverlay_Context); +const EbmlCallbacks KaxTrackTranslate::ClassInfos(KaxTrackTranslate::Create, KaxTrackTranslate_TheId, "TrackTranslate", KaxTrackTranslate_Context); +const EbmlCallbacks KaxTrackTranslateEditionUID::ClassInfos(KaxTrackTranslateEditionUID::Create, KaxTrackTranslateEditionUID_TheId, "TrackTranslateEditionUID", KaxTrackTranslateEditionUID_Context); +const EbmlCallbacks KaxTrackTranslateCodec::ClassInfos(KaxTrackTranslateCodec::Create, KaxTrackTranslateCodec_TheId, "TrackTranslateCodec", KaxTrackTranslateCodec_Context); +const EbmlCallbacks KaxTrackTranslateTrackID::ClassInfos(KaxTrackTranslateTrackID::Create, KaxTrackTranslateTrackID_TheId, "TrackTranslateTrackID", KaxTrackTranslateTrackID_Context); #if MATROSKA_VERSION >= 2 const EbmlCallbacks KaxTrackFlagEnabled::ClassInfos(KaxTrackFlagEnabled::Create, KaxTrackFlagEnabled_TheId, "TrackFlagEnabled", KaxTrackFlagEnabled_Context); const EbmlCallbacks KaxCodecSettings::ClassInfos(KaxCodecSettings::Create, KaxCodecSettings_TheId, "CodecSettings", KaxCodecSettings_Context); const EbmlCallbacks KaxCodecInfoURL::ClassInfos(KaxCodecInfoURL::Create, KaxCodecInfoURL_TheId, "CodecInfoURL", KaxCodecInfoURL_Context); const EbmlCallbacks KaxCodecDownloadURL::ClassInfos(KaxCodecDownloadURL::Create, KaxCodecDownloadURL_TheId, "CodecDownloadURL", KaxCodecDownloadURL_Context); const EbmlCallbacks KaxCodecDecodeAll::ClassInfos(KaxCodecDecodeAll::Create, KaxCodecDecodeAll_TheId, "CodecDecodeAll", KaxCodecDecodeAll_Context); -const EbmlCallbacks KaxTrackOverlay::ClassInfos(KaxTrackOverlay::Create, KaxTrackOverlay_TheId, "TrackOverlay", KaxTrackOverlay_Context); #endif // MATROSKA_VERSION +KaxTrackTranslate::KaxTrackTranslate() + :EbmlMaster(KaxTrackTranslate_Context) +{} + END_LIBMATROSKA_NAMESPACE diff --git a/src/add-ons/media/plugins/matroska/libmatroska/KaxTracks.cpp b/src/add-ons/media/plugins/matroska/libmatroska/KaxTracks.cpp index 537ba77feb..4fc79fa10c 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/KaxTracks.cpp +++ b/src/add-ons/media/plugins/matroska/libmatroska/KaxTracks.cpp @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libmatroska. ** @@ -29,7 +29,7 @@ /*! \file - \version \$Id: KaxTracks.cpp 740 2004-08-30 18:52:56Z mosu $ + \version \$Id: KaxTracks.cpp 1202 2005-08-30 14:39:01Z robux4 $ \author Steve Lhomme */ #include "matroska/KaxTracks.h" @@ -49,9 +49,9 @@ const EbmlSemantic KaxTracks_ContextList[1] = }; #if MATROSKA_VERSION == 1 -const EbmlSemantic KaxTrackEntry_ContextList[17] = +const EbmlSemantic KaxTrackEntry_ContextList[22] = #else // MATROSKA_VERSION -const EbmlSemantic KaxTrackEntry_ContextList[23] = +const EbmlSemantic KaxTrackEntry_ContextList[27] = #endif // MATROSKA_VERSION { EbmlSemantic(true , true, KaxTrackNumber::ClassInfos), @@ -61,23 +61,27 @@ const EbmlSemantic KaxTrackEntry_ContextList[23] = EbmlSemantic(true , true, KaxTrackFlagEnabled::ClassInfos), #endif // MATROSKA_VERSION EbmlSemantic(true , true, KaxTrackFlagDefault::ClassInfos), + EbmlSemantic(true , true, KaxTrackFlagForced::ClassInfos), EbmlSemantic(true , true, KaxTrackFlagLacing::ClassInfos), EbmlSemantic(true , true, KaxTrackMinCache::ClassInfos), EbmlSemantic(false, true, KaxTrackMaxCache::ClassInfos), EbmlSemantic(false, true, KaxTrackDefaultDuration::ClassInfos), EbmlSemantic(true , true, KaxTrackTimecodeScale::ClassInfos), + EbmlSemantic(true , true, KaxMaxBlockAdditionID::ClassInfos), EbmlSemantic(false, true, KaxTrackName::ClassInfos), EbmlSemantic(false, true, KaxTrackLanguage::ClassInfos), EbmlSemantic(true , true, KaxCodecID::ClassInfos), EbmlSemantic(false, true, KaxCodecPrivate::ClassInfos), EbmlSemantic(false, true, KaxCodecName::ClassInfos), + EbmlSemantic(false, true, KaxTrackAttachmentLink::ClassInfos), #if MATROSKA_VERSION >= 2 EbmlSemantic(false, true, KaxCodecSettings::ClassInfos), - EbmlSemantic(false, true, KaxCodecInfoURL::ClassInfos), - EbmlSemantic(false, true, KaxCodecDownloadURL::ClassInfos), + EbmlSemantic(false, false,KaxCodecInfoURL::ClassInfos), + EbmlSemantic(false, false,KaxCodecDownloadURL::ClassInfos), EbmlSemantic(true , true, KaxCodecDecodeAll::ClassInfos), - EbmlSemantic(false, true, KaxTrackOverlay::ClassInfos), #endif // MATROSKA_VERSION + EbmlSemantic(false, false,KaxTrackOverlay::ClassInfos), + EbmlSemantic(false, false,KaxTrackTranslate::ClassInfos), EbmlSemantic(false, true, KaxTrackAudio::ClassInfos), EbmlSemantic(false, true, KaxTrackVideo::ClassInfos), EbmlSemantic(false, true, KaxContentEncodings::ClassInfos), diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxAttached.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxAttached.h index 72ec25cfe5..26c40f8601 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxAttached.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxAttached.h @@ -112,6 +112,18 @@ class MATROSKA_DLL_API KaxFileData : public EbmlBinary { EbmlElement * Clone() const {return new KaxFileData(*this);} }; +class MATROSKA_DLL_API KaxFileReferral : public EbmlBinary { + public: + KaxFileReferral() {} + KaxFileReferral(const KaxFileReferral & ElementToClone) :EbmlBinary(ElementToClone){} + static EbmlElement & Create() {return *(new KaxFileReferral);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + bool ValidateSize() const {return true;} // we don't mind about what's inside + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxFileReferral(*this);} +}; + class MATROSKA_DLL_API KaxFileUID : public EbmlUInteger { public: KaxFileUID() {} diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxBlock.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxBlock.h index 980f361f0e..1ca08e386e 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxBlock.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxBlock.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -48,6 +48,8 @@ START_LIBMATROSKA_NAMESPACE class KaxCluster; class KaxReferenceBlock; +class KaxInternalBlock; +class KaxBlockBlob; class MATROSKA_DLL_API DataBuffer { protected: @@ -63,6 +65,7 @@ class MATROSKA_DLL_API DataBuffer { ,bValidValue(true) ,myFreeBuffer(aFreeBuffer) {} + virtual ~DataBuffer() {} virtual binary * Buffer() {return myBuffer;} virtual uint32 & Size() {return mySize;}; virtual const binary * Buffer() const {return myBuffer;} @@ -80,9 +83,6 @@ class MATROSKA_DLL_API DataBuffer { virtual DataBuffer * Clone(); }; -/*! - \warning the binary buffer should be allocated with the new binary* operator : "new binary[your_size]" -*/ class MATROSKA_DLL_API SimpleDataBuffer : public DataBuffer { public: SimpleDataBuffer(binary * aBuffer, uint32 aSize, uint32 aOffset, bool (*aFreeBuffer)(const DataBuffer & aBuffer) = myFreeBuffer) @@ -90,6 +90,7 @@ class MATROSKA_DLL_API SimpleDataBuffer : public DataBuffer { ,Offset(aOffset) ,BaseBuffer(aBuffer) {} + virtual ~SimpleDataBuffer() {} DataBuffer * Clone() {return new SimpleDataBuffer(*this);} @@ -99,7 +100,9 @@ class MATROSKA_DLL_API SimpleDataBuffer : public DataBuffer { static bool myFreeBuffer(const DataBuffer & aBuffer) { - delete[] static_cast(&aBuffer)->BaseBuffer; + binary *_Buffer = static_cast(&aBuffer)->BaseBuffer; + if (_Buffer != NULL) + free(_Buffer); return true; } @@ -144,10 +147,9 @@ class MATROSKA_DLL_API KaxBlockGroup : public EbmlMaster { \brief Addition of a frame with a backward+forward reference (B frame) */ bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, const KaxBlockGroup & PastBlock, const KaxBlockGroup & ForwBlock, LacingType lacing = LACING_AUTO); + bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, const KaxBlockBlob * PastBlock, const KaxBlockBlob * ForwBlock, LacingType lacing = LACING_AUTO); - void SetParent(KaxCluster & aParentCluster) { - ParentCluster = &aParentCluster; - } + void SetParent(KaxCluster & aParentCluster); void SetParentTrack(const KaxTrackEntry & aParentTrack) { ParentTrack = &aParentTrack; @@ -183,20 +185,22 @@ class MATROSKA_DLL_API KaxBlockGroup : public EbmlMaster { */ void ReleaseFrames(); + operator KaxInternalBlock &(); + + const KaxCluster *GetParentCluster() const { return ParentCluster; } + protected: KaxCluster * ParentCluster; const KaxTrackEntry * ParentTrack; }; -class MATROSKA_DLL_API KaxBlock : public EbmlBinary { +class KaxInternalBlock : public EbmlBinary { public: - KaxBlock() :bLocalTimecodeUsed(false), bGap(false), mLacing(LACING_AUTO), ParentCluster(NULL) {} - KaxBlock(const KaxBlock & ElementToClone); - ~KaxBlock(); - static EbmlElement & Create() {return *(new KaxBlock);} - const EbmlCallbacks & Generic() const {return ClassInfos;} - static const EbmlCallbacks ClassInfos; - operator const EbmlId &() const {return ClassInfos.GlobalId;} + KaxInternalBlock( bool bSimple ) :bLocalTimecodeUsed(false), mLacing(LACING_AUTO), mInvisible(false) + ,ParentCluster(NULL), bIsSimple(bSimple), bIsKeyframe(true), bIsDiscardable(false) + {} + KaxInternalBlock(const KaxInternalBlock & ElementToClone); + ~KaxInternalBlock(); bool ValidateSize() const; uint16 TrackNum() const {return TrackNumber;} @@ -220,7 +224,7 @@ class MATROSKA_DLL_API KaxBlock : public EbmlBinary { unsigned int NumberFrames() const { return SizeList.size();} DataBuffer & GetBuffer(unsigned int iIndex) {return *myBuffers[iIndex];} - bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing = LACING_AUTO); + bool AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing = LACING_AUTO, bool invisible = false); /*! \brief release all the frames of all Blocks @@ -229,8 +233,6 @@ class MATROSKA_DLL_API KaxBlock : public EbmlBinary { void SetParent(KaxCluster & aParentCluster); - EbmlElement * Clone() const {return new KaxBlock(*this);} - /*! \return Returns the lacing type that produces the smallest footprint. */ @@ -249,6 +251,10 @@ class MATROSKA_DLL_API KaxBlock : public EbmlBinary { \note return -1 if the position doesn't exist */ int64 GetFrameSize(size_t FrameNumber = 0); + + bool IsInvisible() const { return mInvisible; } + + uint64 ClusterPosition() const; protected: std::vector myBuffers; @@ -257,13 +263,92 @@ class MATROSKA_DLL_API KaxBlock : public EbmlBinary { int16 LocalTimecode; bool bLocalTimecodeUsed; uint16 TrackNumber; - bool bGap; LacingType mLacing; + bool mInvisible; uint64 FirstFrameLocation; uint32 RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault = false); KaxCluster * ParentCluster; + bool bIsSimple; + bool bIsKeyframe; + bool bIsDiscardable; +}; + +class MATROSKA_DLL_API KaxBlock : public KaxInternalBlock { + public: + KaxBlock() :KaxInternalBlock(false) {} + static EbmlElement & Create() {return *(new KaxBlock);} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + const EbmlCallbacks & Generic() const {return ClassInfos;} + EbmlElement * Clone() const {return new KaxBlock(*this);} +}; + +#if MATROSKA_VERSION >= 2 +class MATROSKA_DLL_API KaxSimpleBlock : public KaxInternalBlock { + public: + KaxSimpleBlock() :KaxInternalBlock(true) {} + static EbmlElement & Create() {return *(new KaxSimpleBlock);} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + const EbmlCallbacks & Generic() const {return ClassInfos;} + EbmlElement * Clone() const {return new KaxSimpleBlock(*this);} + + void SetKeyframe(bool b_keyframe) { bIsKeyframe = b_keyframe; } + void SetDiscardable(bool b_discard) { bIsDiscardable = b_discard; } + + bool IsKeyframe() const { return bIsKeyframe; } + bool IsDiscardable() const { return bIsDiscardable; } + + operator KaxInternalBlock &() { return *this; } +}; +#endif // MATROSKA_VERSION + +class MATROSKA_DLL_API KaxBlockBlob { +public: + KaxBlockBlob(BlockBlobType sblock_mode) :ParentCluster(NULL), SimpleBlockMode(sblock_mode) { + bUseSimpleBlock = (sblock_mode != BLOCK_BLOB_NO_SIMPLE); + Block.group = NULL; + } + + ~KaxBlockBlob() { +#if MATROSKA_VERSION >= 2 + if (bUseSimpleBlock) + delete Block.simpleblock; + else +#endif // MATROSKA_VERSION + delete Block.group; + } + + operator KaxBlockGroup &(); + operator const KaxBlockGroup &() const; +#if MATROSKA_VERSION >= 2 + operator KaxSimpleBlock &(); +#endif + operator KaxInternalBlock &(); + operator const KaxInternalBlock &() const; + + void SetBlockGroup( KaxBlockGroup &BlockRef ); + + void SetBlockDuration(uint64 TimeLength); + + void SetParent(KaxCluster & aParentCluster); + bool AddFrameAuto(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing = LACING_AUTO, const KaxBlockBlob * PastBlock = NULL, const KaxBlockBlob * ForwBlock = NULL); + + bool IsSimpleBlock() const {return bUseSimpleBlock;} + + bool ReplaceSimpleByGroup(); +protected: + KaxCluster * ParentCluster; + union { + KaxBlockGroup *group; +#if MATROSKA_VERSION >= 2 + KaxSimpleBlock *simpleblock; +#endif // MATROSKA_VERSION + } Block; + bool bUseSimpleBlock; + BlockBlobType SimpleBlockMode; }; class MATROSKA_DLL_API KaxBlockDuration : public EbmlUInteger { @@ -304,6 +389,7 @@ class MATROSKA_DLL_API KaxBlockVirtual : public EbmlBinary { const KaxCluster * ParentCluster; }; +#endif // MATROSKA_VERSION class MATROSKA_DLL_API KaxBlockAdditional : public EbmlBinary { public: @@ -342,7 +428,7 @@ class MATROSKA_DLL_API KaxBlockMore : public EbmlMaster { class MATROSKA_DLL_API KaxBlockAddID : public EbmlUInteger { public: - KaxBlockAddID() {} + KaxBlockAddID() :EbmlUInteger(1) {} KaxBlockAddID(const KaxBlockAddID & ElementToClone) :EbmlUInteger(ElementToClone) {} static EbmlElement & Create() {return *(new KaxBlockAddID);} const EbmlCallbacks & Generic() const {return ClassInfos;} @@ -350,7 +436,19 @@ class MATROSKA_DLL_API KaxBlockAddID : public EbmlUInteger { operator const EbmlId &() const {return ClassInfos.GlobalId;} EbmlElement * Clone() const {return new KaxBlockAddID(*this);} }; -#endif // MATROSKA_VERSION + +class MATROSKA_DLL_API KaxCodecState : public EbmlBinary { + public: + KaxCodecState() {} + KaxCodecState(const KaxCodecState & ElementToClone) :EbmlBinary(ElementToClone){} + static EbmlElement & Create() {return *(new KaxCodecState);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + bool ValidateSize() const {return true;} + + EbmlElement * Clone() const {return new KaxCodecState(*this);} +}; END_LIBMATROSKA_NAMESPACE diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxBlockData.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxBlockData.h index cb3232553e..b8749a986b 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxBlockData.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxBlockData.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -44,6 +44,7 @@ START_LIBMATROSKA_NAMESPACE class KaxReferenceBlock; class KaxBlockGroup; +class KaxBlockBlob; class MATROSKA_DLL_API KaxReferencePriority : public EbmlUInteger { public: @@ -74,12 +75,13 @@ class MATROSKA_DLL_API KaxReferenceBlock : public EbmlSInteger { */ virtual uint64 UpdateSize(bool bSaveDefault = false, bool bForceRender = false); - const KaxBlockGroup & RefBlock() const; - void SetReferencedBlock(const KaxBlockGroup & aRefdBlock) {RefdBlock = &aRefdBlock; bValueIsSet = true;} + const KaxBlockBlob & RefBlock() const; + void SetReferencedBlock(const KaxBlockBlob * aRefdBlock); + void SetReferencedBlock(const KaxBlockGroup & aRefdBlock); void SetParentBlock(const KaxBlockGroup & aParentBlock) {ParentBlock = &aParentBlock;} protected: - const KaxBlockGroup * RefdBlock; + const KaxBlockBlob * RefdBlock; const KaxBlockGroup * ParentBlock; void SetReferencedTimecode(int64 refTimecode) {Value = refTimecode; bTimecodeSet = true; bValueIsSet = true;}; bool bTimecodeSet; diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxChapters.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxChapters.h index 3ff34b4ff7..56474c059d 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxChapters.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxChapters.h @@ -1,9 +1,9 @@ /**************************************************************************** ** libmatroska : parse Matroska files, see http://www.matroska.org/ ** -** +** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libmatroska. ** @@ -39,7 +39,7 @@ #include "ebml/EbmlMaster.h" #include "ebml/EbmlUInteger.h" #include "ebml/EbmlUnicodeString.h" -#include "ebml/EbmlString.h" +#include "ebml/EbmlString.h" #include "ebml/EbmlBinary.h" using namespace LIBEBML_NAMESPACE; @@ -101,27 +101,15 @@ public: EbmlElement * Clone() const {return new KaxEditionFlagDefault(*this);} }; -class MATROSKA_DLL_API KaxEditionProcessed : public EbmlUInteger { +class MATROSKA_DLL_API KaxEditionFlagOrdered : public EbmlUInteger { public: - KaxEditionProcessed(): EbmlUInteger(0) {} - KaxEditionProcessed(const KaxEditionProcessed & ElementToClone) :EbmlUInteger(ElementToClone) {} - static EbmlElement & Create() {return *(new KaxEditionProcessed);} + KaxEditionFlagOrdered(): EbmlUInteger(0) {} + KaxEditionFlagOrdered(const KaxEditionFlagOrdered & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxEditionFlagOrdered);} const EbmlCallbacks & Generic() const {return ClassInfos;} static const EbmlCallbacks ClassInfos; operator const EbmlId &() const {return ClassInfos.GlobalId;} - EbmlElement * Clone() const {return new KaxEditionProcessed(*this);} -}; - -class MATROSKA_DLL_API KaxChapterProcessedPrivate : public EbmlBinary { -public: - KaxChapterProcessedPrivate() {} - KaxChapterProcessedPrivate(const KaxChapterProcessedPrivate & ElementToClone) :EbmlBinary(ElementToClone) {} - static EbmlElement & Create() {return *(new KaxChapterProcessedPrivate);} - const EbmlCallbacks & Generic() const {return ClassInfos;} - static const EbmlCallbacks ClassInfos; - operator const EbmlId &() const {return ClassInfos.GlobalId;} - EbmlElement * Clone() const {return new KaxChapterProcessedPrivate(*this);} - bool ValidateSize() const {return true;} + EbmlElement * Clone() const {return new KaxEditionFlagOrdered(*this);} }; class MATROSKA_DLL_API KaxChapterAtom : public EbmlMaster { @@ -190,6 +178,30 @@ public: EbmlElement * Clone() const {return new KaxChapterFlagEnabled(*this);} }; +class MATROSKA_DLL_API KaxChapterSegmentUID : public EbmlBinary { +public: + KaxChapterSegmentUID() {} + KaxChapterSegmentUID(const KaxChapterSegmentUID & ElementToClone) :EbmlBinary(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxChapterSegmentUID);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxChapterSegmentUID(*this);} + bool ValidateSize() const { return (Size == 16);} +}; + +class MATROSKA_DLL_API KaxChapterSegmentEditionUID : public EbmlBinary { +public: + KaxChapterSegmentEditionUID() {} + KaxChapterSegmentEditionUID(const KaxChapterSegmentEditionUID & ElementToClone) :EbmlBinary(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxChapterSegmentEditionUID);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxChapterSegmentEditionUID(*this);} + bool ValidateSize() const { return (Size == 16);} +}; + class MATROSKA_DLL_API KaxChapterPhysicalEquiv : public EbmlUInteger { public: KaxChapterPhysicalEquiv(): EbmlUInteger() {} @@ -278,6 +290,40 @@ public: EbmlElement * Clone() const {return new KaxChapterProcess(*this);} }; +class MATROSKA_DLL_API KaxChapterProcessCodecID : public EbmlUInteger { +public: + KaxChapterProcessCodecID() :EbmlUInteger(0) {} + KaxChapterProcessCodecID(const KaxChapterProcessCodecID & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxChapterProcessCodecID);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxChapterProcessCodecID(*this);} +}; + +class MATROSKA_DLL_API KaxChapterProcessPrivate : public EbmlBinary { +public: + KaxChapterProcessPrivate() {} + KaxChapterProcessPrivate(const KaxChapterProcessPrivate & ElementToClone) :EbmlBinary(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxChapterProcessPrivate);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxChapterProcessPrivate(*this);} + bool ValidateSize() const {return true;} +}; + +class MATROSKA_DLL_API KaxChapterProcessCommand : public EbmlMaster { +public: + KaxChapterProcessCommand(); + KaxChapterProcessCommand(const KaxChapterProcessCommand & ElementToClone) :EbmlMaster(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxChapterProcessCommand);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxChapterProcessCommand(*this);} +}; + class MATROSKA_DLL_API KaxChapterProcessTime : public EbmlUInteger { public: KaxChapterProcessTime() {} @@ -289,15 +335,15 @@ public: EbmlElement * Clone() const {return new KaxChapterProcessTime(*this);} }; -class MATROSKA_DLL_API KaxChapterProcessCommand : public EbmlBinary { +class MATROSKA_DLL_API KaxChapterProcessData : public EbmlBinary { public: - KaxChapterProcessCommand() {} - KaxChapterProcessCommand(const KaxChapterProcessCommand & ElementToClone) :EbmlBinary(ElementToClone) {} - static EbmlElement & Create() {return *(new KaxChapterProcessCommand);} + KaxChapterProcessData() {} + KaxChapterProcessData(const KaxChapterProcessData & ElementToClone) :EbmlBinary(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxChapterProcessData);} const EbmlCallbacks & Generic() const {return ClassInfos;} static const EbmlCallbacks ClassInfos; operator const EbmlId &() const {return ClassInfos.GlobalId;} - EbmlElement * Clone() const {return new KaxChapterProcessCommand(*this);} + EbmlElement * Clone() const {return new KaxChapterProcessData(*this);} bool ValidateSize() const {return true;} }; diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxCluster.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxCluster.h index 2b9e38d5e8..b8596a07c6 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxCluster.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxCluster.h @@ -40,6 +40,7 @@ #include "matroska/KaxTracks.h" #include "matroska/KaxBlock.h" #include "matroska/KaxCues.h" +#include "matroska/KaxClusterData.h" using namespace LIBEBML_NAMESPACE; @@ -131,7 +132,19 @@ class MATROSKA_DLL_API KaxCluster : public EbmlMaster { return TimecodeScale; } + bool SetSilentTrackUsed() + { + bSilentTracksUsed = true; + return FindFirstElt(KaxClusterSilentTracks::ClassInfos, true) != NULL; + } + + bool AddBlockBlob(KaxBlockBlob * NewBlob); + + const KaxSegment *GetParentSegment() const { return ParentSegment; } + protected: + KaxBlockBlob * currentNewBlob; + std::vector Blobs; KaxBlockGroup * currentNewBlock; const KaxSegment * ParentSegment; @@ -141,6 +154,7 @@ class MATROSKA_DLL_API KaxCluster : public EbmlMaster { bool bFirstFrameInside; // used to speed research bool bPreviousTimecodeIsSet; bool bTimecodeScaleIsSet; + bool bSilentTracksUsed; /*! \note method used internally diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxClusterData.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxClusterData.h index e9bf40ac5f..0e26a37355 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxClusterData.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxClusterData.h @@ -36,6 +36,7 @@ #define LIBMATROSKA_CLUSTER_DATA_H #include "matroska/KaxTypes.h" +#include "ebml/EbmlMaster.h" #include "ebml/EbmlUInteger.h" using namespace LIBEBML_NAMESPACE; @@ -53,6 +54,28 @@ class MATROSKA_DLL_API KaxClusterTimecode : public EbmlUInteger { EbmlElement * Clone() const {return new KaxClusterTimecode(*this);} }; +class MATROSKA_DLL_API KaxClusterSilentTracks : public EbmlMaster { + public: + KaxClusterSilentTracks(); + KaxClusterSilentTracks(const KaxClusterSilentTracks & ElementToClone) :EbmlMaster(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxClusterSilentTracks);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxClusterSilentTracks(*this);} +}; + +class MATROSKA_DLL_API KaxClusterSilentTrackNumber : public EbmlUInteger { + public: + KaxClusterSilentTrackNumber() {} + KaxClusterSilentTrackNumber(const KaxClusterSilentTrackNumber & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxClusterSilentTrackNumber);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxClusterSilentTrackNumber(*this);} +}; + class MATROSKA_DLL_API KaxClusterPosition : public EbmlUInteger { public: KaxClusterPosition() {} diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxConfig.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxConfig.h index 5b65cd6482..2896978109 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxConfig.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxConfig.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -63,7 +63,7 @@ #endif #if !defined(MATROSKA_VERSION) -#define MATROSKA_VERSION 1 +#define MATROSKA_VERSION 2 #endif // MATROSKA_VERSION diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxContexts.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxContexts.h index 882932bc94..ced77406ed 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxContexts.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxContexts.h @@ -42,6 +42,7 @@ using namespace LIBEBML_NAMESPACE; START_LIBMATROSKA_NAMESPACE +extern const EbmlSemanticContext MATROSKA_DLL_API KaxMatroska_Context; extern const EbmlSemanticContext MATROSKA_DLL_API KaxSegment_Context; extern const EbmlSemanticContext MATROSKA_DLL_API KaxAttachments_Context; extern const EbmlSemanticContext MATROSKA_DLL_API KaxAttached_Context; diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxCues.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxCues.h index b657fe27f5..c39c1af98f 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxCues.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxCues.h @@ -59,11 +59,13 @@ class MATROSKA_DLL_API KaxCues : public EbmlMaster { EbmlElement * Clone() const {return new KaxCues(*this);} bool AddBlockGroup(const KaxBlockGroup & BlockReference); + bool AddBlockBlob(const KaxBlockBlob & BlockReference); /*! \brief Indicate that the position for this Block is set */ void PositionSet(const KaxBlockGroup & BlockReference); + void PositionSet(const KaxBlockBlob & BlockReference); /*! \brief override to sort by timecode/track @@ -86,7 +88,7 @@ class MATROSKA_DLL_API KaxCues : public EbmlMaster { } protected: - std::vector myTempReferences; + std::vector myTempReferences; bool bGlobalTimecodeScaleIsSet; uint64 mGlobalTimecodeScale; }; diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxCuesData.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxCuesData.h index 5169f16b9f..4c2c069521 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxCuesData.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxCuesData.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -42,7 +42,9 @@ using namespace LIBEBML_NAMESPACE; START_LIBMATROSKA_NAMESPACE class KaxBlockGroup; +class KaxBlockBlob; class KaxCueTrackPositions; +class KaxInternalBlock; class MATROSKA_DLL_API KaxCuePoint : public EbmlMaster { public: @@ -54,6 +56,7 @@ class MATROSKA_DLL_API KaxCuePoint : public EbmlMaster { operator const EbmlId &() const {return ClassInfos.GlobalId;} EbmlElement * Clone() const {return new KaxCuePoint(*this);} void PositionSet(const KaxBlockGroup & BlockReference, uint64 GlobalTimecodeScale); + void PositionSet(const KaxBlockBlob & BlobReference, uint64 GlobalTimecodeScale); bool operator<(const EbmlElement & EltB) const; @@ -142,6 +145,7 @@ class MATROSKA_DLL_API KaxCueReference : public EbmlMaster { EbmlElement * Clone() const {return new KaxCueReference(*this);} void AddReference(const KaxBlockGroup & BlockReferenced, uint64 GlobalTimecodeScale); + void AddReference(const KaxBlockBlob & BlockReferenced, uint64 GlobalTimecodeScale); }; class MATROSKA_DLL_API KaxCueRefTime : public EbmlUInteger { diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxInfoData.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxInfoData.h index 07af462952..ee185a7867 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxInfoData.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxInfoData.h @@ -1,9 +1,9 @@ /**************************************************************************** ** libmatroska : parse Matroska files, see http://www.matroska.org/ ** -** +** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libmatroska. ** @@ -43,6 +43,7 @@ #include "ebml/EbmlUnicodeString.h" #include "ebml/EbmlBinary.h" #include "ebml/EbmlDate.h" +#include "ebml/EbmlMaster.h" using namespace LIBEBML_NAMESPACE; @@ -71,10 +72,10 @@ class MATROSKA_DLL_API KaxSegmentFilename : public EbmlUnicodeString { EbmlElement * Clone() const {return new KaxSegmentFilename(*this);} }; -class MATROSKA_DLL_API KaxPrevUID : public EbmlBinary { +class MATROSKA_DLL_API KaxPrevUID : public KaxSegmentUID { public: KaxPrevUID() {} - KaxPrevUID(const KaxPrevUID & ElementToClone) :EbmlBinary(ElementToClone){} + KaxPrevUID(const KaxPrevUID & ElementToClone) :KaxSegmentUID(ElementToClone){} static EbmlElement & Create() {return *(new KaxPrevUID);} bool ValidateSize() const { return (Size == 16);} const EbmlCallbacks & Generic() const {return ClassInfos;} @@ -94,10 +95,10 @@ class MATROSKA_DLL_API KaxPrevFilename : public EbmlUnicodeString { EbmlElement * Clone() const {return new KaxPrevFilename(*this);} }; -class MATROSKA_DLL_API KaxNextUID : public EbmlBinary { +class MATROSKA_DLL_API KaxNextUID : public KaxSegmentUID { public: KaxNextUID() {} - KaxNextUID(const KaxNextUID & ElementToClone) :EbmlBinary(ElementToClone){} + KaxNextUID(const KaxNextUID & ElementToClone) :KaxSegmentUID(ElementToClone){} static EbmlElement & Create() {return *(new KaxNextUID);} bool ValidateSize() const { return (Size == 16);} const EbmlCallbacks & Generic() const {return ClassInfos;} @@ -117,6 +118,63 @@ class MATROSKA_DLL_API KaxNextFilename : public EbmlUnicodeString { EbmlElement * Clone() const {return new KaxNextFilename(*this);} }; +class MATROSKA_DLL_API KaxSegmentFamily : public EbmlBinary { + public: + KaxSegmentFamily() {} + KaxSegmentFamily(const KaxSegmentFamily & ElementToClone) :EbmlBinary(ElementToClone){} + static EbmlElement & Create() {return *(new KaxSegmentFamily);} + bool ValidateSize() const { return (Size == 16);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxSegmentFamily(*this);} +}; + +class MATROSKA_DLL_API KaxChapterTranslate : public EbmlMaster { + public: + KaxChapterTranslate(); + KaxChapterTranslate(const KaxChapterTranslate & ElementToClone) :EbmlMaster(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxChapterTranslate);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxChapterTranslate(*this);} +}; + +class MATROSKA_DLL_API KaxChapterTranslateCodec : public EbmlUInteger { + public: + KaxChapterTranslateCodec() {} + KaxChapterTranslateCodec(const KaxChapterTranslateCodec & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxChapterTranslateCodec);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxChapterTranslateCodec(*this);} +}; + +class MATROSKA_DLL_API KaxChapterTranslateEditionUID : public EbmlUInteger { + public: + KaxChapterTranslateEditionUID() {} + KaxChapterTranslateEditionUID(const KaxChapterTranslateEditionUID & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxChapterTranslateEditionUID);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxChapterTranslateEditionUID(*this);} +}; + +class MATROSKA_DLL_API KaxChapterTranslateID : public EbmlBinary { + public: + KaxChapterTranslateID() {} + KaxChapterTranslateID(const KaxChapterTranslateID & ElementToClone) :EbmlBinary(ElementToClone){} + static EbmlElement & Create() {return *(new KaxChapterTranslateID);} + bool ValidateSize() const { return true;} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxChapterTranslateID(*this);} +}; + class MATROSKA_DLL_API KaxTimecodeScale : public EbmlUInteger { public: KaxTimecodeScale() :EbmlUInteger(1000000) {} diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxTag.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxTag.h index 9f47fe01ca..c9e724461b 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxTag.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxTag.h @@ -21,7 +21,8 @@ ** License along with this library; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** -** See http://www.matroska.org/license/lgpl/ for LGPL licensing information.** +** See http://www.matroska.org/license/lgpl/ for LGPL licensing information. +** ** Contact license@matroska.org if any conditions of this licensing are ** not clear to you. ** @@ -118,7 +119,8 @@ class MATROSKA_DLL_API KaxTagImageSpecific : public EbmlMaster { class MATROSKA_DLL_API KaxTagTargetTypeValue : public EbmlUInteger { public: KaxTagTargetTypeValue() :EbmlUInteger(50) {} - KaxTagTargetTypeValue(const KaxTagTargetTypeValue & ElementToClone) :EbmlUInteger(ElementToClone) {} + KaxTagTargetTypeValue(const KaxTagTargetTypeValue & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxTagTargetTypeValue);} const EbmlCallbacks & Generic() const {return ClassInfos;} static const EbmlCallbacks ClassInfos; @@ -140,7 +142,8 @@ class MATROSKA_DLL_API KaxTagTargetType : public EbmlString { class MATROSKA_DLL_API KaxTagTrackUID : public EbmlUInteger { public: KaxTagTrackUID() :EbmlUInteger(0) {} - KaxTagTrackUID(const KaxTagTrackUID & ElementToClone) :EbmlUInteger(ElementToClone) {} + KaxTagTrackUID(const KaxTagTrackUID & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxTagTrackUID);} const EbmlCallbacks & Generic() const {return ClassInfos;} static const EbmlCallbacks ClassInfos; @@ -663,7 +666,8 @@ class MATROSKA_DLL_API KaxTagLangue : public EbmlString { class MATROSKA_DLL_API KaxTagDefault : public EbmlUInteger { public: KaxTagDefault() :EbmlUInteger(1) {} - KaxTagDefault(const KaxTagTrackUID & ElementToClone) :EbmlUInteger(ElementToClone) {} + KaxTagDefault(const KaxTagTrackUID & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxTagDefault);} const EbmlCallbacks & Generic() const {return ClassInfos;} static const EbmlCallbacks ClassInfos; diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxTrackEntryData.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxTrackEntryData.h index 1f33944df6..0203ac8144 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxTrackEntryData.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxTrackEntryData.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libmatroska. ** @@ -42,6 +42,7 @@ #include "ebml/EbmlString.h" #include "ebml/EbmlUnicodeString.h" #include "ebml/EbmlBinary.h" +#include "ebml/EbmlMaster.h" using namespace LIBEBML_NAMESPACE; @@ -104,6 +105,17 @@ class MATROSKA_DLL_API KaxTrackFlagDefault : public EbmlUInteger { EbmlElement * Clone() const {return new KaxTrackFlagDefault(*this);} }; +class MATROSKA_DLL_API KaxTrackFlagForced : public EbmlUInteger { + public: + KaxTrackFlagForced() :EbmlUInteger(0) {} + KaxTrackFlagForced(const KaxTrackFlagForced & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxTrackFlagForced);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxTrackFlagForced(*this);} +}; + class MATROSKA_DLL_API KaxTrackFlagLacing : public EbmlUInteger { public: KaxTrackFlagLacing() :EbmlUInteger(1) {} @@ -159,6 +171,17 @@ class MATROSKA_DLL_API KaxTrackTimecodeScale : public EbmlFloat { EbmlElement * Clone() const {return new KaxTrackTimecodeScale(*this);} }; +class MATROSKA_DLL_API KaxMaxBlockAdditionID : public EbmlUInteger { + public: + KaxMaxBlockAdditionID() :EbmlUInteger(0) {} + KaxMaxBlockAdditionID(const KaxMaxBlockAdditionID & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxMaxBlockAdditionID);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxMaxBlockAdditionID(*this);} +}; + class MATROSKA_DLL_API KaxTrackName : public EbmlUnicodeString { public: KaxTrackName() {} @@ -215,6 +238,74 @@ class MATROSKA_DLL_API KaxCodecName : public EbmlUnicodeString { EbmlElement * Clone() const {return new KaxCodecName(*this);} }; +class MATROSKA_DLL_API KaxTrackAttachmentLink : public EbmlBinary { + public: + KaxTrackAttachmentLink() {} + KaxTrackAttachmentLink(const KaxTrackAttachmentLink & ElementToClone) :EbmlBinary(ElementToClone){} + static EbmlElement & Create() {return *(new KaxTrackAttachmentLink);} + bool ValidateSize() const {return true;} // we don't mind about what's inside + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxTrackAttachmentLink(*this);} +}; + +class MATROSKA_DLL_API KaxTrackOverlay : public EbmlUInteger { + public: + KaxTrackOverlay() {} + KaxTrackOverlay(const KaxTrackOverlay & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxTrackOverlay);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxTrackOverlay(*this);} +}; + +class MATROSKA_DLL_API KaxTrackTranslate : public EbmlMaster { + public: + KaxTrackTranslate(); + KaxTrackTranslate(const KaxTrackTranslate & ElementToClone) :EbmlMaster(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxTrackTranslate);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxTrackTranslate(*this);} +}; + +class MATROSKA_DLL_API KaxTrackTranslateCodec : public EbmlUInteger { + public: + KaxTrackTranslateCodec() {} + KaxTrackTranslateCodec(const KaxTrackTranslateCodec & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxTrackTranslateCodec);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxTrackTranslateCodec(*this);} +}; + +class MATROSKA_DLL_API KaxTrackTranslateEditionUID : public EbmlUInteger { + public: + KaxTrackTranslateEditionUID() {} + KaxTrackTranslateEditionUID(const KaxTrackTranslateEditionUID & ElementToClone) :EbmlUInteger(ElementToClone) {} + static EbmlElement & Create() {return *(new KaxTrackTranslateEditionUID);} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxTrackTranslateEditionUID(*this);} +}; + +class MATROSKA_DLL_API KaxTrackTranslateTrackID : public EbmlBinary { + public: + KaxTrackTranslateTrackID() {} + KaxTrackTranslateTrackID(const KaxTrackTranslateTrackID & ElementToClone) :EbmlBinary(ElementToClone){} + static EbmlElement & Create() {return *(new KaxTrackTranslateTrackID);} + bool ValidateSize() const { return true;} + const EbmlCallbacks & Generic() const {return ClassInfos;} + static const EbmlCallbacks ClassInfos; + operator const EbmlId &() const {return ClassInfos.GlobalId;} + EbmlElement * Clone() const {return new KaxTrackTranslateTrackID(*this);} +}; + #if MATROSKA_VERSION >= 2 class MATROSKA_DLL_API KaxCodecSettings : public EbmlUnicodeString { public: @@ -259,17 +350,6 @@ class MATROSKA_DLL_API KaxCodecDecodeAll : public EbmlUInteger { operator const EbmlId &() const {return ClassInfos.GlobalId;} EbmlElement * Clone() const {return new KaxCodecDecodeAll(*this);} }; - -class MATROSKA_DLL_API KaxTrackOverlay : public EbmlUInteger { - public: - KaxTrackOverlay() {} - KaxTrackOverlay(const KaxTrackOverlay & ElementToClone) :EbmlUInteger(ElementToClone) {} - static EbmlElement & Create() {return *(new KaxTrackOverlay);} - const EbmlCallbacks & Generic() const {return ClassInfos;} - static const EbmlCallbacks ClassInfos; - operator const EbmlId &() const {return ClassInfos.GlobalId;} - EbmlElement * Clone() const {return new KaxTrackOverlay(*this);} -}; #endif // MATROSKA_VERSION END_LIBMATROSKA_NAMESPACE diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxTypes.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxTypes.h index 42413faf95..cbb90b90c2 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxTypes.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxTypes.h @@ -3,7 +3,7 @@ ** ** ** -** Copyright (C) 2002-2003 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libmatroska. ** @@ -48,6 +48,12 @@ enum LacingType { LACING_AUTO }; +enum BlockBlobType { + BLOCK_BLOB_NO_SIMPLE = 0, + BLOCK_BLOB_SIMPLE_AUTO, + BLOCK_BLOB_ALWAYS_SIMPLE, +}; + END_LIBMATROSKA_NAMESPACE #endif // LIBMATROSKA_TYPES_H diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxVersion.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxVersion.h index fc515cbb3d..58add0da0b 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxVersion.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/KaxVersion.h @@ -1,7 +1,7 @@ /**************************************************************************** ** ** -** Copyright (C) 2002-2004 Steve Lhomme. All rights reserved. +** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. ** ** This file is part of libmatroska. ** @@ -40,9 +40,9 @@ START_LIBMATROSKA_NAMESPACE -#define LIBMATROSKA_VERSION 000704 +#define LIBMATROSKA_VERSION 0x000801 -static const std::string KaxCodeVersion = "0.7.4"; +static const std::string KaxCodeVersion = "0.8.1"; static const std::string KaxCodeDate = __TIMESTAMP__; /*! diff --git a/src/add-ons/media/plugins/matroska/libmatroska/matroska/c/libmatroska_t.h b/src/add-ons/media/plugins/matroska/libmatroska/matroska/c/libmatroska_t.h index 64a3424926..9c4fc2c1f8 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/matroska/c/libmatroska_t.h +++ b/src/add-ons/media/plugins/matroska/libmatroska/matroska/c/libmatroska_t.h @@ -58,6 +58,7 @@ typedef enum track_type { track_logo = 0x10, ///< Overlay-pictures, displayed over video track_subtitle = 0x11, ///< Text-subtitles. One track contains one language and only one track can be active (player-side configuration) + track_buttons = 0x12, ///< Buttons meta-infos. track_control = 0x20 ///< Control-codes for menus and other stuff } track_type; diff --git a/src/add-ons/media/plugins/matroska/matroska_reader.cpp b/src/add-ons/media/plugins/matroska/matroska_reader.cpp index 4515ad89c4..5af6aae97c 100644 --- a/src/add-ons/media/plugins/matroska/matroska_reader.cpp +++ b/src/add-ons/media/plugins/matroska/matroska_reader.cpp @@ -34,7 +34,7 @@ #include "matroska_codecs.h" #include "matroska_util.h" -//#define TRACE_MKV_READER +#define TRACE_MKV_READER #ifdef TRACE_MKV_READER #define TRACE printf #else @@ -74,7 +74,7 @@ struct mkv_cookie mkvReader::mkvReader() - : fFileCache(0) + : fInputStream(0) , fFile(0) , fFileInfo(0) { @@ -85,7 +85,7 @@ mkvReader::mkvReader() mkvReader::~mkvReader() { mkv_Close(fFile); - free(fFileCache); + free(fInputStream); } @@ -103,13 +103,13 @@ mkvReader::Sniff(int32 *streamCount) char err_msg[100]; - fFileCache = CreateFileCache(Source()); - if (!fFileCache) { + fInputStream = CreateFileCache(Source()); + if (!fInputStream) { TRACE("mkvReader::Sniff: failed to create file cache\n"); return B_ERROR; } - fFile = mkv_Open(fFileCache, err_msg, sizeof(err_msg)); + fFile = mkv_Open(fInputStream, err_msg, sizeof(err_msg)); if (!fFile) { TRACE("mkvReader::Sniff: open failed, error: %s\n", err_msg); return B_ERROR; @@ -195,7 +195,7 @@ status_t mkvReader::SetupVideoCookie(mkv_cookie *cookie) { char err_msg[100]; - cookie->file = mkv_Open(fFileCache, err_msg, sizeof(err_msg)); + cookie->file = mkv_Open(fInputStream, err_msg, sizeof(err_msg)); if (!cookie->file) { TRACE("mkvReader::SetupVideoCookie: open failed, error: %s\n", err_msg); return B_ERROR; @@ -269,7 +269,7 @@ status_t mkvReader::SetupAudioCookie(mkv_cookie *cookie) { char err_msg[100]; - cookie->file = mkv_Open(fFileCache, err_msg, sizeof(err_msg)); + cookie->file = mkv_Open(fInputStream, err_msg, sizeof(err_msg)); if (!cookie->file) { TRACE("mkvReader::SetupVideoCookie: open failed, error: %s\n", err_msg); return B_ERROR; @@ -345,11 +345,11 @@ mkvReader::GetStreamInfo(void *_cookie, int64 *frameCount, bigtime_t *duration, status_t -mkvReader::Seek(void *_cookie, +mkvReader::Seek(void *cookie, uint32 seekTo, int64 *frame, bigtime_t *time) { - mkv_cookie *cookie = (mkv_cookie *)_cookie; + mkv_cookie *mkvcookie = (mkv_cookie *)cookie; TRACE("mkvReader::Seek: seekTo%s%s%s%s, time %Ld, frame %Ld\n", (seekTo & B_MEDIA_SEEK_TO_TIME) ? " B_MEDIA_SEEK_TO_TIME" : "", @@ -359,25 +359,25 @@ mkvReader::Seek(void *_cookie, *time, *frame); if (seekTo & B_MEDIA_SEEK_TO_FRAME) { - *time = bigtime_t(*frame * (1000000.0 / cookie->frame_rate)); + *time = bigtime_t(*frame * (1000000.0 / mkvcookie->frame_rate)); } if (seekTo & B_MEDIA_SEEK_CLOSEST_BACKWARD) { - mkv_Seek(cookie->file, *time * 1000, MKVF_SEEK_TO_PREV_KEYFRAME); + mkv_Seek(mkvcookie->file, *time * 1000, MKVF_SEEK_TO_PREV_KEYFRAME); } else if (seekTo & B_MEDIA_SEEK_CLOSEST_FORWARD) { - mkv_Seek(cookie->file, *time * 1000, 0); - mkv_SkipToKeyframe(cookie->file); + mkv_Seek(mkvcookie->file, *time * 1000, 0); + mkv_SkipToKeyframe(mkvcookie->file); } else { - mkv_Seek(cookie->file, *time * 1000, 0); + mkv_Seek(mkvcookie->file, *time * 1000, 0); } int64 timecode; - timecode = mkv_GetLowestQTimecode(cookie->file); + timecode = mkv_GetLowestQTimecode(mkvcookie->file); if (timecode < 0) return B_ERROR; *time = timecode / 1000; - *frame = get_frame_count_by_frame_rate(timecode, cookie->frame_rate); + *frame = get_frame_count_by_frame_rate(timecode, mkvcookie->frame_rate); return B_OK; } @@ -411,9 +411,9 @@ mkvReader::GetNextChunk(void *_cookie, } res = mkv_ReadData(cookie->file, FilePos, cookie->buffer, FrameSize); - if (res < 0) + if (res > 0) return B_ERROR; - + *chunkBuffer = cookie->buffer; *chunkSize = FrameSize; diff --git a/src/add-ons/media/plugins/matroska/matroska_reader.h b/src/add-ons/media/plugins/matroska/matroska_reader.h index 2409498e52..e65b7aa209 100644 --- a/src/add-ons/media/plugins/matroska/matroska_reader.h +++ b/src/add-ons/media/plugins/matroska/matroska_reader.h @@ -61,7 +61,7 @@ private: status_t SetupTextCookie(mkv_cookie *cookie); private: - FileCache * fFileCache; + InputStream * fInputStream; MatroskaFile * fFile; const SegmentInfo * fFileInfo; };