From 4cf2271b57103ea49d23a4fbfee04caa182479bb Mon Sep 17 00:00:00 2001 From: David McPaul Date: Tue, 2 Jun 2009 09:34:16 +0000 Subject: [PATCH] Bring matroska library up to latest version. Allows V2 matroska file playback git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30943 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../libMatroskaParser/MatroskaParser.c | 274 +++++++++--------- .../libMatroskaParser/MatroskaParser.h | 84 +++--- .../media/plugins/matroska/libebml/Jamfile | 2 + .../plugins/matroska/libebml/ebml/EbmlTypes.h | 4 +- .../plugins/matroska/libmatroska/Jamfile | 1 + .../plugins/matroska/matroska_reader.cpp | 62 ++-- 6 files changed, 214 insertions(+), 213 deletions(-) diff --git a/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.c b/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.c index 00f1714620..a49fec6614 100644 --- a/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.c +++ b/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.c @@ -1,32 +1,32 @@ /* - * Copyright (c) 2004-2006 Mike Matsnev. All Rights Reserved. + * Copyright (c) 2004-2009 Mike Matsnev. All Rights Reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Absolutely no warranty of function or purpose is made by the author - * Mike Matsnev. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * $Id: MatroskaParser.c,v 1.61 2006/10/28 10:39:45 mike Exp $ + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Absolutely no warranty of function or purpose is made by the author + * Mike Matsnev. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: MatroskaParser.c,v >1.61 Unknown mike Exp $ + * */ #include @@ -50,7 +50,7 @@ #include "MatroskaParser.h" #ifdef MATROSKA_COMPRESSION_SUPPORT -#include "zlib.h" +#include #endif #define EBML_VERSION 1 @@ -96,8 +96,7 @@ static char *mystrdup(struct InputStream *is,const char *src) { return dst; } -#ifdef _WIN32 -static void strlcpy(char *dst,const char *src,unsigned size) { +static void mystrlcpy(char *dst,const char *src,unsigned size) { unsigned i; for (i=0;i+1 0) @@ -687,7 +685,7 @@ static ulonglong readVLUIntImp(MatroskaFile *mf,int *mask) { c = readch(mf); if (c == EOF) - return EOF; + return 0; // XXX should errorjmp()? if (c == 0) errorjmp(mf,"Invalid first byte of EBML integer: 0"); @@ -1078,6 +1076,8 @@ static void parseSegmentInfo(MatroskaFile *mf,ulonglong toplen) { } static void parseFirstCluster(MatroskaFile *mf,ulonglong toplen) { + ulonglong end = filepos(mf) + toplen; + mf->seen.Cluster = 1; mf->firstTimecode = 0; @@ -1089,7 +1089,7 @@ static void parseFirstCluster(MatroskaFile *mf,ulonglong toplen) { readVLUInt(mf); // track number mf->firstTimecode += readSInt(mf, 2); - skipbytes(mf,start + toplen - filepos(mf)); + skipbytes(mf,end - filepos(mf)); return; case 0xa0: // BlockGroup FOREACH(mf,len) @@ -1097,7 +1097,7 @@ static void parseFirstCluster(MatroskaFile *mf,ulonglong toplen) { readVLUInt(mf); // track number mf->firstTimecode += readSInt(mf,2); - skipbytes(mf,start + toplen - filepos(mf)); + skipbytes(mf,end - filepos(mf)); return; ENDFOR(mf); break; @@ -1247,7 +1247,7 @@ static void parseTrackEntry(MatroskaFile *mf,ulonglong toplen) { ulonglong v; char *cp = NULL, *cs = NULL; size_t cplen = 0, cslen = 0, cpadd = 0; - unsigned CompScope = 0, num_comp = 0; + unsigned CompScope, num_comp = 0; if (mf->nTracks >= MAX_TRACKS) errorjmp(mf,"Too many tracks."); @@ -1424,7 +1424,7 @@ static void parseTrackEntry(MatroskaFile *mf,ulonglong toplen) { // handle compressed CodecPrivate if (t.CompEnabled && t.CompMethod == COMP_ZLIB && (CompScope & 2) && cplen > 0) { z_stream zs; - char tmp[64], *ncp; + Bytef tmp[64], *ncp; int code; uLong ncplen; @@ -1432,7 +1432,7 @@ static void parseTrackEntry(MatroskaFile *mf,ulonglong toplen) { if (inflateInit(&zs) != Z_OK) errorjmp(mf, "inflateInit failed"); - zs.next_in = cp; + zs.next_in = (Bytef *)cp; zs.avail_in = cplen; do { @@ -1450,7 +1450,7 @@ static void parseTrackEntry(MatroskaFile *mf,ulonglong toplen) { inflateReset(&zs); - zs.next_in = cp; + zs.next_in = (Bytef *)cp; zs.avail_in = cplen; zs.next_out = ncp; zs.avail_out = ncplen; @@ -1460,7 +1460,7 @@ static void parseTrackEntry(MatroskaFile *mf,ulonglong toplen) { inflateEnd(&zs); - cp = ncp; + cp = (char *)ncp; cplen = ncplen; } #endif @@ -1491,7 +1491,7 @@ static void parseTrackEntry(MatroskaFile *mf,ulonglong toplen) { } if (cslen) { tp->CompMethodPrivate = (char *)(tp+1) + cplen; - tp->CompMethodPrivateSize = cslen; + tp->CompMethodPrivateSize = (unsigned)cslen; memcpy(tp->CompMethodPrivate, cs, cslen); } @@ -1982,85 +1982,84 @@ static void parsePointers(MatroskaFile *mf) { static void parseSegment(MatroskaFile *mf,ulonglong toplen) { ulonglong nextpos; unsigned nSeekHeads = 0, dontstop = 0; + jmp_buf jb; - // we want to read data until we find a seekhead or a trackinfo - FOREACH(mf,toplen) - case 0x114d9b74: // SeekHead - if (mf->flags & MKVF_AVOID_SEEKS) { - skipbytes(mf,len); - break; - } + memcpy(&jb,&mf->jb,sizeof(jb)); - nextpos = filepos(mf) + len; - do { - mf->pSeekHead = 0; - parseSeekHead(mf,len); - ++nSeekHeads; - if (mf->pSeekHead) { // this is possibly a chained SeekHead - seek(mf,mf->pSeekHead); - id = readID(mf); - if (id==EOF) // chained SeekHead points to EOF? - break; - if (id != 0x114d9b74) // chained SeekHead doesnt point to a SeekHead? - break; - len = readSize(mf); - } else if (mf->pSegmentInfo && mf->pTracks && mf->pCues && mf->pCluster) { // we have pointers to all key elements - // XXX EVIL HACK - // Some software doesnt index tags via SeekHead, so we continue - // reading the segment after the second SeekHead - if (mf->pTags || nSeekHeads<2 || filepos(mf)>=start+toplen) { - parsePointers(mf); - return; + if (setjmp(mf->jb)) + mf->flags &= ~MPF_ERROR; + else { + // we want to read data until we find a seekhead or a trackinfo + FOREACH(mf,toplen) + case 0x114d9b74: // SeekHead + if (mf->flags & MKVF_AVOID_SEEKS) { + skipbytes(mf,len); + break; + } + + nextpos = filepos(mf) + len; + do { + mf->pSeekHead = 0; + parseSeekHead(mf,len); + ++nSeekHeads; + if (mf->pSeekHead) { // this is possibly a chained SeekHead + seek(mf,mf->pSeekHead); + id = readID(mf); + if (id==EOF) // chained SeekHead points to EOF? + break; + if (id != 0x114d9b74) // chained SeekHead doesnt point to a SeekHead? + break; + len = readSize(mf); } - // reset nextpos pointer to current position - nextpos = filepos(mf); - dontstop = 1; - } - } while (mf->pSeekHead); - seek(mf,nextpos); // resume reading segment - break; - case 0x1549a966: // SegmentInfo - mf->pSegmentInfo = cur; - parseSegmentInfo(mf,len); - break; - case 0x1f43b675: // Cluster - if (!mf->pCluster) - mf->pCluster = cur; - if (mf->seen.Cluster) - skipbytes(mf,len); - else - parseFirstCluster(mf,len); - break; - case 0x1654ae6b: // Tracks - mf->pTracks = cur; - parseTracks(mf,len); - break; - case 0x1c53bb6b: // Cues - mf->pCues = cur; - parseCues(mf,len); - break; - case 0x1941a469: // Attachments - mf->pAttachments = cur; - parseAttachments(mf,len); - break; - case 0x1043a770: // Chapters - mf->pChapters = cur; - parseChapters(mf,len); - break; - case 0x1254c367: // Tags - mf->pTags = cur; - parseTags(mf,len); - break; - ENDFOR1(mf); - // if we have pointers to all key elements - if (!dontstop && mf->pSegmentInfo && mf->pTracks && mf->pCluster) - break; - ENDFOR2(); + } while (mf->pSeekHead && nSeekHeads < 10); + seek(mf,nextpos); // resume reading segment + break; + case 0x1549a966: // SegmentInfo + mf->pSegmentInfo = cur; + parseSegmentInfo(mf,len); + break; + case 0x1f43b675: // Cluster + if (!mf->pCluster) + mf->pCluster = cur; + if (mf->seen.Cluster) + skipbytes(mf,len); + else + parseFirstCluster(mf,len); + break; + case 0x1654ae6b: // Tracks + mf->pTracks = cur; + parseTracks(mf,len); + break; + case 0x1c53bb6b: // Cues + mf->pCues = cur; + parseCues(mf,len); + break; + case 0x1941a469: // Attachments + mf->pAttachments = cur; + parseAttachments(mf,len); + break; + case 0x1043a770: // Chapters + mf->pChapters = cur; + parseChapters(mf,len); + break; + case 0x1254c367: // Tags + mf->pTags = cur; + parseTags(mf,len); + break; + ENDFOR1(mf); + // if we have pointers to all key elements + if (!dontstop && mf->pSegmentInfo && mf->pTracks && mf->pCluster) + break; + ENDFOR2(); + } + + memcpy(&mf->jb,&jb,sizeof(jb)); + parsePointers(mf); } static void parseBlockAdditions(MatroskaFile *mf, ulonglong toplen, ulonglong timecode, unsigned track) { - ulonglong add_id = 1, add_pos = 0, add_len = 0; + ulonglong add_id = 1, add_pos, add_len; unsigned char have_add; FOREACH(mf, toplen) @@ -2095,7 +2094,6 @@ static void parseBlockGroup(MatroskaFile *mf,ulonglong toplen,ulonglong timecode ulonglong v; ulonglong duration = 0; ulonglong dpos; -// unsigned add_id = 0; struct QueueEntry *qe,*qf = NULL; unsigned char have_duration = 0, have_block = 0; unsigned char gap = 0; @@ -2152,10 +2150,10 @@ found: errorjmp(mf,"Unexpected EOF while reading Block flags"); if (blockex) - ref = !(c & 0x80); + ref = (unsigned char)!(c & 0x80); - gap = c & 0x1; - lacing = (c >> 1) & 3; + gap = (unsigned char)(c & 0x1); + lacing = (unsigned char)((c >> 1) & 3); if (lacing) { c = readch(mf); @@ -2474,7 +2472,7 @@ static void reindex(MatroskaFile *mf) { jmp_buf jb; ulonglong pos = mf->pCluster; ulonglong step = 10*1024*1024; - ulonglong size, tc = 0, isize; + ulonglong size, tc, isize; longlong next_cluster; int id, have_tc, bad; struct Cue *cue; @@ -2762,7 +2760,7 @@ MatroskaFile *mkv_OpenEx(InputStream *io, { MatroskaFile *mf = io->memalloc(io,sizeof(*mf)); if (mf == NULL) { - strlcpy(err_msg,"Out of memory",msgsize); + mystrlcpy(err_msg,"Out of memory",msgsize); return NULL; } @@ -2776,7 +2774,7 @@ MatroskaFile *mkv_OpenEx(InputStream *io, seek(mf,base); parseFile(mf); } else { // parser error - strlcpy(err_msg,mf->errmsg,msgsize); + mystrlcpy(err_msg,mf->errmsg,msgsize); mkv_Close(mf); return NULL; } @@ -2917,7 +2915,7 @@ void mkv_Seek(MatroskaFile *mf,ulonglong timecode,unsigned flags) { mkv_SetTrackMask(mf,mf->trackMask); - if (flags & MKVF_SEEK_TO_PREV_KEYFRAME) { + if (flags & (MKVF_SEEK_TO_PREV_KEYFRAME | MKVF_SEEK_TO_PREV_KEYFRAME_STRICT)) { // we do this in two stages // a. find the last keyframes before the require position // b. seek to them @@ -2932,7 +2930,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; + mf->tcCluster = mf->Cues[j].Time; for (;;) { if ((ret = fillQueues(mf,0)) < 0 || ret == RBRESYNC) @@ -2940,7 +2938,7 @@ void mkv_Seek(MatroskaFile *mf,ulonglong timecode,unsigned flags) { // drain queues until we get to the required timecode for (n=0;nnTracks;++n) { - if (mf->Queues[n].head && mf->Queues[n].head->StartQueues[n].head && (mf->Queues[n].head->StartQueues[n].head)) m_seendf[n] = 1; else @@ -2956,9 +2954,14 @@ void mkv_Seek(MatroskaFile *mf,ulonglong timecode,unsigned flags) { QFree(mf,QGet(&mf->Queues[n])); } - if (mf->Queues[n].head && (mf->Tracks[n]->Type != TT_AUDIO || mf->Queues[n].head->Start<=timecode)) - if (!IS_DELTA(mf->Queues[n].head)) - m_kftime[n] = mf->Queues[n].head->Start; + // We've drained the queue, so the frame at head is the next one past the requered point. + // In strict mode we are done, but when seeking is not strict we use the head frame + // if it's not an audio track (we accept preroll within a frame for audio), and the head frame + // is a keyframe + if (!(flags & MKVF_SEEK_TO_PREV_KEYFRAME_STRICT)) + if (mf->Queues[n].head && (mf->Tracks[n]->Type != TT_AUDIO || mf->Queues[n].head->Start<=timecode)) + if (!IS_DELTA(mf->Queues[n].head)) + m_kftime[n] = mf->Queues[n].head->Start; } for (n=0;nnTracks;++n) @@ -2987,7 +2990,7 @@ again:; EmptyQueues(mf); mf->readPosition = mf->Cues[j].Position + mf->pSegment; - mf->tcCluster = mf->Cues[j].Time / mf->Seg.TimecodeScale; + mf->tcCluster = mf->Cues[j].Time; for (mask=0;;) { if ((ret = fillQueues(mf,mask)) < 0 || ret == RBRESYNC) @@ -3182,30 +3185,30 @@ CompressedStream *cs_Create(/* in */ MatroskaFile *mf, ti = mkv_GetTrackInfo(mf, tracknum); if (ti == NULL) { - strlcpy(errormsg, "No such track.", msgsize); + mystrlcpy(errormsg, "No such track.", msgsize); return NULL; } if (!ti->CompEnabled) { - strlcpy(errormsg, "Track is not compressed.", msgsize); + mystrlcpy(errormsg, "Track is not compressed.", msgsize); return NULL; } if (ti->CompMethod != COMP_ZLIB) { - strlcpy(errormsg, "Unsupported compression method.", msgsize); + mystrlcpy(errormsg, "Unsupported compression method.", msgsize); return NULL; } cs = mf->cache->memalloc(mf->cache,sizeof(*cs)); if (cs == NULL) { - strlcpy(errormsg, "Ouf of memory.", msgsize); + mystrlcpy(errormsg, "Ouf of memory.", msgsize); return NULL; } memset(&cs->zs,0,sizeof(cs->zs)); code = inflateInit(&cs->zs); if (code != Z_OK) { - strlcpy(errormsg, "ZLib error.", msgsize); + mystrlcpy(errormsg, "ZLib error.", msgsize); mf->cache->memfree(mf->cache,cs); return NULL; } @@ -3243,7 +3246,6 @@ int mkv_ReadData(MatroskaFile *mf,ulonglong FilePos, void *Buffer,unsig 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) @@ -3267,7 +3269,7 @@ int cs_ReadData(CompressedStream *cs,char *buffer,unsigned bufsize) cs->decoded_ptr += todo; } else { /* setup output buffer */ - cs->zs.next_out = cs->decoded_buffer; + cs->zs.next_out = (Bytef *)cs->decoded_buffer; cs->zs.avail_out = sizeof(cs->decoded_buffer); /* try to read more data */ @@ -3277,11 +3279,11 @@ int cs_ReadData(CompressedStream *cs,char *buffer,unsigned bufsize) todo = sizeof(cs->frame_buffer); 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)); + mystrlcpy(cs->errmsg, "File read failed", sizeof(cs->errmsg)); return -1; } - cs->zs.next_in = cs->frame_buffer; + cs->zs.next_in = (Bytef *)cs->frame_buffer; cs->zs.avail_in = todo; cs->frame_pos += todo; @@ -3291,7 +3293,7 @@ int cs_ReadData(CompressedStream *cs,char *buffer,unsigned bufsize) /* try to decode more data */ code = inflate(&cs->zs,Z_NO_FLUSH); if (code != Z_OK && code != Z_STREAM_END) { - strlcpy(cs->errmsg, "ZLib error.", sizeof(cs->errmsg)); + mystrlcpy(cs->errmsg, "ZLib error.", 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 85081a021c..20416a3059 100644 --- a/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.h +++ b/src/add-ons/media/plugins/matroska/libMatroskaParser/MatroskaParser.h @@ -1,31 +1,31 @@ /* - * Copyright (c) 2004-2006 Mike Matsnev. All Rights Reserved. + * Copyright (c) 2004-2009 Mike Matsnev. All Rights Reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Absolutely no warranty of function or purpose is made by the author - * Mike Matsnev. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * $Id: MatroskaParser.h,v 1.19 2006/03/11 10:57:13 mike Exp $ + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Absolutely no warranty of function or purpose is made by the author + * Mike Matsnev. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: MatroskaParser.h,v >1.19 Unknown mike Exp $ * */ @@ -128,13 +128,12 @@ struct TrackInfo { void *CompMethodPrivate; unsigned CompMethodPrivateSize; unsigned MaxBlockAdditionID; - struct { - unsigned int Enabled:1; - unsigned int Default:1; - unsigned int Lacing:1; - unsigned int DecodeAll:1; - unsigned int CompEnabled:1; - }; + + unsigned int Enabled:1; + unsigned int Default:1; + unsigned int Lacing:1; + unsigned int DecodeAll:1; + unsigned int CompEnabled:1; union { struct { @@ -148,9 +147,8 @@ struct TrackInfo { unsigned int CropL, CropT, CropR, CropB; unsigned int ColourSpace; MKFLOAT GammaValue; - struct { - unsigned int Interlaced:1; - }; + + unsigned int Interlaced:1; } Video; struct { MKFLOAT SamplingFreq; @@ -233,14 +231,12 @@ struct Chapter { char SegmentUID[16]; - struct { - unsigned int Hidden:1; - unsigned int Enabled:1; + unsigned int Hidden:1; + unsigned int Enabled:1; - // Editions - unsigned int Default:1; - unsigned int Ordered:1; - }; + // Editions + unsigned int Default:1; + unsigned int Ordered:1; }; typedef struct Chapter Chapter; @@ -319,7 +315,8 @@ X ulonglong mkv_GetSegmentTop(MatroskaFile *mf); * all tracks are set to return EOF * on next read */ -#define MKVF_SEEK_TO_PREV_KEYFRAME 1 +#define MKVF_SEEK_TO_PREV_KEYFRAME 1 +#define MKVF_SEEK_TO_PREV_KEYFRAME_STRICT 2 X void mkv_Seek(/* in */ MatroskaFile *mf, /* in */ ulonglong timecode /* in ns */, @@ -366,7 +363,6 @@ X int mkv_ReadFrame(/* in */ MatroskaFile *mf, int mkv_ReadData(MatroskaFile *mf,ulonglong FilePos, void *Buffer,unsigned int Count); - #ifdef MATROSKA_COMPRESSION_SUPPORT /* Compressed streams support */ struct CompressedStream; diff --git a/src/add-ons/media/plugins/matroska/libebml/Jamfile b/src/add-ons/media/plugins/matroska/libebml/Jamfile index f01bda023d..b24e03457c 100644 --- a/src/add-ons/media/plugins/matroska/libebml/Jamfile +++ b/src/add-ons/media/plugins/matroska/libebml/Jamfile @@ -1,5 +1,7 @@ SubDir HAIKU_TOP src add-ons media plugins matroska libebml ; +SubDirHdrs [ FDirName $(SUBDIR) ebml ] ; + StaticLibrary libebml.a : Debug.cpp EbmlBinary.cpp diff --git a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlTypes.h b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlTypes.h index 6194dec23f..c2e7540b6c 100644 --- a/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlTypes.h +++ b/src/add-ons/media/plugins/matroska/libebml/ebml/EbmlTypes.h @@ -36,8 +36,8 @@ #include #include -#include "ebml/c/libebml_t.h" -#include "ebml/EbmlConfig.h" +#include "c/libebml_t.h" +#include "EbmlConfig.h" #include "EbmlEndian.h" // binary needs to be defined START_LIBEBML_NAMESPACE diff --git a/src/add-ons/media/plugins/matroska/libmatroska/Jamfile b/src/add-ons/media/plugins/matroska/libmatroska/Jamfile index 4276002113..6860142659 100644 --- a/src/add-ons/media/plugins/matroska/libmatroska/Jamfile +++ b/src/add-ons/media/plugins/matroska/libmatroska/Jamfile @@ -1,6 +1,7 @@ SubDir HAIKU_TOP src add-ons media plugins matroska libmatroska ; SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) libebml ] ; +SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) libebml ebml ] ; StaticLibrary libmatroska.a : FileKax.cpp diff --git a/src/add-ons/media/plugins/matroska/matroska_reader.cpp b/src/add-ons/media/plugins/matroska/matroska_reader.cpp index 187138465c..2da2060532 100644 --- a/src/add-ons/media/plugins/matroska/matroska_reader.cpp +++ b/src/add-ons/media/plugins/matroska/matroska_reader.cpp @@ -78,7 +78,7 @@ struct mkv_cookie }; static uint8 -matroska_samplerate_to_samplerateindex(float samplerate) +matroska_samplerate_to_samplerateindex(double samplerate) { if (samplerate <= 7350.0) { return 12; @@ -142,15 +142,15 @@ mkvReader::CreateFakeAACDecoderConfig(const TrackInfo *track, uint8 **fakeExtraD profile = 3; } - uint8 sampleRateIndex = matroska_samplerate_to_samplerateindex(track->Audio.SamplingFreq); + uint8 sampleRateIndex = matroska_samplerate_to_samplerateindex(track->AV.Audio.SamplingFreq); - TRACE("Profile %d, SampleRate %f, SampleRateIndex %d\n",profile, track->Audio.SamplingFreq, sampleRateIndex); + TRACE("Profile %d, SampleRate %f, SampleRateIndex %d\n",profile, track->AV.Audio.SamplingFreq, sampleRateIndex); // profile 5 bits // SampleRateIndex 4 bits // Channels 4 Bits (*fakeExtraData)[0] = (profile << 3) | ((sampleRateIndex & 0x0E) >> 1); - (*fakeExtraData)[1] = ((sampleRateIndex & 0x01) << 7) | (track->Audio.Channels << 3); + (*fakeExtraData)[1] = ((sampleRateIndex & 0x01) << 7) | (track->AV.Audio.Channels << 3); if (strstr(track->CodecID, "SBR")) { TRACE("Extension SBR Needs more configuration\n"); // Sync Extension 0x2b7 11 bits @@ -160,7 +160,7 @@ mkvReader::CreateFakeAACDecoderConfig(const TrackInfo *track, uint8 **fakeExtraD // if SampleRateIndex = 15 // ExtendedSamplingFrequency 24 bits - sampleRateIndex = matroska_samplerate_to_samplerateindex(track->Audio.OutputSamplingFreq); + sampleRateIndex = matroska_samplerate_to_samplerateindex(track->AV.Audio.OutputSamplingFreq); (*fakeExtraData)[2] = 0x56; (*fakeExtraData)[3] = 0xE5; if (sampleRateIndex != 15) { @@ -168,7 +168,7 @@ mkvReader::CreateFakeAACDecoderConfig(const TrackInfo *track, uint8 **fakeExtraD return 5; } - uint32 sampleRate = uint32(track->Audio.OutputSamplingFreq); + uint32 sampleRate = uint32(track->AV.Audio.OutputSamplingFreq); (*fakeExtraData)[4] = 0x80 | (sampleRateIndex << 3) | ((sampleRate & 0xFFF0 ) >> 4); (*fakeExtraData)[5] = (sampleRate & 0x0FFF) << 4; @@ -185,7 +185,7 @@ mkvReader::CreateFakeAACDecoderConfig(const TrackInfo *track, uint8 **fakeExtraD const char * mkvReader::Copyright() { - return "Matroska reader, " B_UTF8_COPYRIGHT " by Marcus Overhagen"; + return "Matroska reader, " B_UTF8_COPYRIGHT " by Marcus Overhagen\nUsing MatroskaParser " B_UTF8_COPYRIGHT " by Mike Matsnev"; } status_t @@ -296,23 +296,23 @@ mkvReader::SetupVideoCookie(mkv_cookie *cookie) cookie->audio = false; - TRACE("video StereoMode: %d\n", cookie->track_info->Video.StereoMode); - TRACE("video DisplayUnit: %d\n", cookie->track_info->Video.DisplayUnit); - TRACE("video AspectRatioType: %d\n", cookie->track_info->Video.AspectRatioType); - TRACE("video PixelWidth: %d\n", cookie->track_info->Video.PixelWidth); - TRACE("video PixelHeight: %d\n", cookie->track_info->Video.PixelHeight); - TRACE("video DisplayWidth: %d\n", cookie->track_info->Video.DisplayWidth); - TRACE("video DisplayHeight: %d\n", cookie->track_info->Video.DisplayHeight); - TRACE("video ColourSpace: %d\n", cookie->track_info->Video.ColourSpace); - TRACE("video GammaValue: %.4f\n", cookie->track_info->Video.GammaValue); + TRACE("video StereoMode: %d\n", cookie->track_info->AV.Video.StereoMode); + TRACE("video DisplayUnit: %d\n", cookie->track_info->AV.Video.DisplayUnit); + TRACE("video AspectRatioType: %d\n", cookie->track_info->AV.Video.AspectRatioType); + TRACE("video PixelWidth: %d\n", cookie->track_info->AV.Video.PixelWidth); + TRACE("video PixelHeight: %d\n", cookie->track_info->AV.Video.PixelHeight); + TRACE("video DisplayWidth: %d\n", cookie->track_info->AV.Video.DisplayWidth); + TRACE("video DisplayHeight: %d\n", cookie->track_info->AV.Video.DisplayHeight); + TRACE("video ColourSpace: %d\n", cookie->track_info->AV.Video.ColourSpace); + TRACE("video GammaValue: %.4f\n", cookie->track_info->AV.Video.GammaValue); - TRACE("video Interlaced: %d\n", cookie->track_info->Video.Interlaced); + TRACE("video Interlaced: %d\n", cookie->track_info->AV.Video.Interlaced); cookie->frame_rate = get_frame_rate(cookie->track_info->DefaultDuration); cookie->duration = get_duration_in_us(fFileInfo->Duration); cookie->frame_count = get_frame_count_by_default_duration(fFileInfo->Duration, cookie->track_info->DefaultDuration); - cookie->line_count = cookie->track_info->Video.PixelHeight; + cookie->line_count = cookie->track_info->AV.Video.PixelHeight; TRACE("mkvReader::Sniff: TimecodeScale %Ld\n", fFileInfo->TimecodeScale); TRACE("mkvReader::Sniff: Duration %Ld\n", fFileInfo->Duration); @@ -334,10 +334,10 @@ mkvReader::SetupVideoCookie(mkv_cookie *cookie) uint16 width_aspect_ratio; uint16 height_aspect_ratio; get_pixel_aspect_ratio(&width_aspect_ratio, &height_aspect_ratio, - cookie->track_info->Video.PixelWidth, - cookie->track_info->Video.PixelHeight, - cookie->track_info->Video.DisplayWidth, - cookie->track_info->Video.DisplayHeight); + cookie->track_info->AV.Video.PixelWidth, + cookie->track_info->AV.Video.PixelHeight, + cookie->track_info->AV.Video.DisplayWidth, + cookie->track_info->AV.Video.DisplayHeight); // cookie->format.u.encoded_video.max_bit_rate = // cookie->format.u.encoded_video.avg_bit_rate = @@ -349,8 +349,8 @@ mkvReader::SetupVideoCookie(mkv_cookie *cookie) cookie->format.u.encoded_video.output.pixel_width_aspect = width_aspect_ratio; cookie->format.u.encoded_video.output.pixel_height_aspect = height_aspect_ratio; // cookie->format.u.encoded_video.output.display.format = 0; - cookie->format.u.encoded_video.output.display.line_width = cookie->track_info->Video.PixelWidth; - cookie->format.u.encoded_video.output.display.line_count = cookie->track_info->Video.PixelHeight; + cookie->format.u.encoded_video.output.display.line_width = cookie->track_info->AV.Video.PixelWidth; + cookie->format.u.encoded_video.output.display.line_count = cookie->track_info->AV.Video.PixelHeight; cookie->format.u.encoded_video.output.display.bytes_per_row = 0; cookie->format.u.encoded_video.output.display.pixel_offset = 0; cookie->format.u.encoded_video.output.display.line_offset = 0; @@ -373,14 +373,14 @@ mkvReader::SetupAudioCookie(mkv_cookie *cookie) cookie->audio = true; - TRACE("audio SamplingFreq: %.3f\n", cookie->track_info->Audio.SamplingFreq); - TRACE("audio OutputSamplingFreq: %.3f\n", cookie->track_info->Audio.OutputSamplingFreq); - TRACE("audio Channels: %d\n", cookie->track_info->Audio.Channels); - TRACE("audio BitDepth: %d\n", cookie->track_info->Audio.BitDepth); + TRACE("audio SamplingFreq: %.3f\n", cookie->track_info->AV.Audio.SamplingFreq); + TRACE("audio OutputSamplingFreq: %.3f\n", cookie->track_info->AV.Audio.OutputSamplingFreq); + TRACE("audio Channels: %d\n", cookie->track_info->AV.Audio.Channels); + TRACE("audio BitDepth: %d\n", cookie->track_info->AV.Audio.BitDepth); TRACE("CodecID: %s\n", cookie->track_info->CodecID); - cookie->frame_rate = cookie->track_info->Audio.SamplingFreq; + cookie->frame_rate = cookie->track_info->AV.Audio.SamplingFreq; cookie->duration = get_duration_in_us(fFileInfo->Duration); cookie->frame_count = get_frame_count_by_frame_rate(fFileInfo->Duration, cookie->frame_rate); @@ -394,8 +394,8 @@ mkvReader::SetupAudioCookie(mkv_cookie *cookie) } cookie->format.u.encoded_audio.output.frame_rate = cookie->frame_rate; - cookie->format.u.encoded_audio.output.channel_count = cookie->track_info->Audio.Channels; - cookie->format.u.encoded_audio.bit_rate = cookie->track_info->Audio.BitDepth * cookie->format.u.encoded_audio.output.channel_count * cookie->frame_rate; + cookie->format.u.encoded_audio.output.channel_count = cookie->track_info->AV.Audio.Channels; + cookie->format.u.encoded_audio.bit_rate = cookie->track_info->AV.Audio.BitDepth * cookie->format.u.encoded_audio.output.channel_count * cookie->frame_rate; cookie->private_data = (uint8 *)cookie->track_info->CodecPrivate; cookie->private_data_size = cookie->track_info->CodecPrivateSize;