-/****************************************************************************
-** libmatroska : parse Matroska files, see http://www.matroska.org/
-**
-** <file/class description>
-**
-** Copyright (C) 2002-2003 Steve Lhomme. All rights reserved.
-**
-** This file is part of libmatroska.
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** 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.**
-** Contact license@matroska.org if any conditions of this licensing are
-** not clear to you.
-**
-**********************************************************************/
-
-/*!
- \file
- \version \$Id: FileKax.cpp 640 2004-07-09 21:05:36Z mosu $
- \author Steve Lhomme <robux4 @ users.sf.net>
-*/
-//#include "StdInclude.h"
-#include "matroska/FileKax.h"
-//#include "Cluster.h"
-//#include "Track.h"
-//#include "Block.h"
-//#include "Frame.h"
-//#include "Version.h"
-
-START_LIBMATROSKA_NAMESPACE
-
-//typedef Track *TrackID;
-
-FileMatroska::FileMatroska(IOCallback & output)
- :myFile(output)
-#ifdef OLD
- ,myCurrReadBlock(NULL)
- ,myMinClusterSize(5*1024) // 5KB is the min size of a cluster
- ,myMaxClusterSize(2*1024*1024) // 2MB is the max size of a cluster
- ,myCurrReadBlockTrack(0)
- ,myCurrWriteCluster(2*1024*1024) // myMaxClusterSize
- ,myCurrReadCluster(NULL)
- ,myReadBlockNumber(0)
-#endif // OLD
-{
-#ifdef OLD
- myStreamInfo.MainHeaderSize = TypeHeader::default_size() +
- ActualHeader::default_size() +
- ExtendedInfo::default_size() +
- ContentInfo::default_size();
- myStreamInfo.TrackEntrySize = Track::default_size();
- myStreamInfo.BlockHeadSize = BLOCK_HEADER_SIZE;
- myStreamInfo.ClusterHeadSize = CLUSTER_HEADER_SIZE;
- myStreamInfo.ClusterFootSize = CLUSTER_TRAILER_SIZE;
-#endif // OLD
-}
-
-FileMatroska::~FileMatroska()
-{
-// if (myCurrCluster != NULL)
-// throw 0; // there are some data left to write
-// if (myCurrReadCluster != NULL || myCurrReadBlock != NULL)
-// throw 0; // there are some data left to write
-}
-
-#ifdef OLD
-void FileMatroska::SetMaxClusterSize(const uint32 value)
-{
- myMaxClusterSize = value;
- myCurrWriteCluster.setMaxSize(value);
-}
-
-void FileMatroska::Close(const uint32 aTimeLength)
-{
- Flush();
-
- // get the file size
- myFile.setFilePointer(0,seek_end);
- myMainHeader.type_SetSize(myFile.getFilePointer());
-
- // rewrite the header at the beginning
- myFile.setFilePointer(0,seek_beginning);
-
- // get the Track-entry size
- uint32 track_entries_size = 0;
- for (size_t i=0; i<myTracks.size(); i++)
- {
- track_entries_size += myTracks[i]->default_size();
- }
-
- myStreamInfo.TrackEntriesSize = track_entries_size;
- myStreamInfo.TimeLength = aTimeLength;
- myMainHeader.Render(myFile, myStreamInfo);
-
- for (i=0; i<myTracks.size(); i++)
- {
- delete myTracks[i];
- }
-}
-
-/*!
- \warning after rendering the head, some parameters are locked
-*/
-uint32 FileMatroska::RenderHead(const std::string & aEncoderApp)
-{
- try {
- uint32 track_entries_size = 0;
- for (size_t i=0; i<myTracks.size(); i++)
- {
- track_entries_size += myTracks[i]->default_size();
- }
-
- std::string aStr = LIB_NAME;
- aStr += " ";
- aStr += VERSION;
- myStreamInfo.EncoderLib = aStr;
-
- myStreamInfo.EncoderApp = aEncoderApp;
-
- myStreamInfo.TrackEntryPosition = 0 + myStreamInfo.MainHeaderSize;
- myStreamInfo.TrackEntriesSize = myTracks.size() * myStreamInfo.TrackEntrySize;
-
- myStreamInfo.CodecEntryPosition = myStreamInfo.MainHeaderSize + myStreamInfo.TrackEntriesSize;
- myStreamInfo.CodecEntrySize = 4;
- for (i=0; i<myTracks.size(); i++)
- {
- myStreamInfo.CodecEntrySize += myTracks[i]->CodecSize();
- }
-
- // Main Header
- uint32 result = myMainHeader.Render(myFile, myStreamInfo);
-
- // Track Entries
- for (i=0; i<myTracks.size(); i++)
- {
- myTracks[i]->RenderEntry(myFile, i+1);
- }
- myStreamInfo.ClusterPosition = myStreamInfo.CodecEntryPosition + myStreamInfo.CodecEntrySize;
-
- // Codec Header
- result = CodecHeader::Render(myFile, myTracks);
-
- return result;
- }
- catch (exception & Ex)
- {
- throw Ex;
- }
-}
-
-/*!
- \return 0 if the track was not created, or a valid track number
-*/
-Track * FileMatroska::CreateTrack(const track_type aType)
-{
- myTracks.push_back(new Track(aType));
- return myTracks.back();
-}
-
-/*Track *FileMatroska::findTrack(Track * aTrack) const
-{
- for (size_t i=0; i<myTracks.size(); i++)
- {
- if (myTracks[i] == aTrack)
- return myTracks[i];
- }
-
- return NULL;
-}*/
-
-void FileMatroska::track_SetName(Track * aTrack, const std::string & aName)
-{
- if (IsMyTrack(aTrack))
- {
- aTrack->SetName(aName);
- }
-}
-
-void FileMatroska::track_SetLaced(Track * aTrack, bool bLaced)
-{
- if (IsMyTrack(aTrack))
- {
- aTrack->SetLaced(bLaced);
- }
-}
-
-bool FileMatroska::AddFrame(Track * aTrack, const uint32 aTimecode, const binary *aFrame, const uint32 aFrameSize,
- bool aKeyFrame, bool aBFrame)
-{
- try {
- // make sure we know that track
- if (IsMyTrack(aTrack))
- {
- // pass the cluster to the track
- // handle the creation of a new cluster if needed
- if (aTrack->AddFrame(aTimecode, aFrame, aFrameSize, aKeyFrame, aBFrame))
- {
- while (!aTrack->SerialiseBlock(myCurrWriteCluster))
- {
- /// \todo handle errors
- uint32 aNbBlock;
- myStreamInfo.ClusterSize += myCurrWriteCluster.Render(myFile, aNbBlock);
- myStreamInfo.NumberBlock += aNbBlock;
- myCurrWriteCluster.Flush();
- }
- }
- return true;
- }
- return false;
- }
- catch (exception & Ex)
- {
- throw Ex;
- }
-}
-
-void FileMatroska::Flush()
-{
- uint32 aNbBlock;
- myStreamInfo.ClusterSize += myCurrWriteCluster.Render(myFile,aNbBlock);
- myStreamInfo.NumberBlock += aNbBlock;
-}
-
-uint32 FileMatroska::ReadHead()
-{
- try {
- uint32 result = myMainHeader.Read(myFile, myStreamInfo);
-
- return result;
- }
- catch (exception & Ex)
- {
- throw Ex;
- }
-}
-
-uint32 FileMatroska::ReadTracks()
-{
- try {
- uint32 result = 0;
-
- // seek to the start of the Track Entries
- myFile.setFilePointer(myStreamInfo.TrackEntryPosition);
- // get the number of Track Entries
- uint8 TrackNumber = myStreamInfo.TrackEntriesSize / myStreamInfo.TrackEntrySize;
- // read all the Track Entries
- myTracks.clear();
- for (uint8 TrackIdx = 0; TrackIdx<TrackNumber; TrackIdx ++) {
- Track * tmpTrack = Track::ReadEntry(myFile, TrackIdx+1, myStreamInfo);
- if (tmpTrack == NULL)
- throw 0;
-
- myTracks.push_back(tmpTrack);
- }
-
- return result;
- }
- catch (exception & Ex)
- {
- throw Ex;
- }
-}
-
-uint32 FileMatroska::ReadCodec()
-{
- try {
- // seek to the start of the Track Entries
- myFile.setFilePointer(myStreamInfo.CodecEntryPosition);
-
- uint32 result = CodecHeader::Read(myFile, myTracks);
-
- return result;
- }
- catch (exception & Ex)
- {
- throw Ex;
- }
-}
-
-inline bool FileMatroska::IsMyTrack(const Track * aTrack) const
-{
- if (aTrack == 0)
- throw 0;
-
- for (std::vector<Track*>::const_iterator i = myTracks.begin(); i != myTracks.end(); i ++)
- {
- if (*i == aTrack)
- break;
- }
-
- if (i != myTracks.end())
- return true;
- else
- return false;
-}
-
-void FileMatroska::SelectReadingTrack(Track * aTrack, bool select)
-{
- if (IsMyTrack(aTrack))
- {
- // here we have the right track
- // check if it's not already selected
- for (std::vector<uint8>::iterator j = mySelectedTracks.begin();
- j != mySelectedTracks.end(); j ++)
- {
- if (*j == aTrack->TrackNumber())
- break;
- }
-
- if (select && j == mySelectedTracks.end())
- mySelectedTracks.push_back(aTrack->TrackNumber());
- else if (!select && j != mySelectedTracks.end())
- mySelectedTracks.erase(j);
-
- std::sort(mySelectedTracks.begin(), mySelectedTracks.end());
- }
-}
-
-inline bool FileMatroska::IsReadingTrack(const uint8 aTrackNumber) const
-{
- for (std::vector<uint8>::const_iterator trackIdx = mySelectedTracks.begin();
- trackIdx != mySelectedTracks.end() && *trackIdx < aTrackNumber;
- trackIdx++)
- {}
-
- if (trackIdx == mySelectedTracks.end())
- return false;
- else
- return true;
-}
-
-//
-
-void FileMatroska::Track_GetInfo(const Track * aTrack, TrackInfo & aTrackInfo) const
-{
- if (IsMyTrack(aTrack))
- {
- aTrack->GetInfo(aTrackInfo);
- }
-}
-
-// Audio related getters/setters
-
-void FileMatroska::Track_GetInfo_Audio(const Track * aTrack, TrackInfoAudio & aTrackInfo) const
-{
- if (IsMyTrack(aTrack))
- {
- aTrack->GetInfoAudio(aTrackInfo);
- }
-}
-
-void FileMatroska::Track_SetInfo_Audio(Track * aTrack, const TrackInfoAudio & aTrackInfo)
-{
- if (IsMyTrack(aTrack))
- {
- aTrack->SetInfoAudio(aTrackInfo);
- }
-}
-
-// Video related getters/setters
-
-void FileMatroska::Track_GetInfo_Video(const Track * aTrack, TrackInfoVideo & aTrackInfo) const
-{
- if (IsMyTrack(aTrack))
- {
- aTrack->GetInfoVideo(aTrackInfo);
- }
-}
-
-void FileMatroska::Track_SetInfo_Video(Track * aTrack, const TrackInfoVideo & aTrackInfo)
-{
- if (IsMyTrack(aTrack))
- {
- aTrack->SetInfoVideo(aTrackInfo);
- }
-}
-
-/*!
- \todo exit when there is no Block left
-*/
-bool FileMatroska::ReadFrame(Track * & aTrack, uint32 & aTimecode, const binary * & aFrame, uint32 & aFrameSize,
- bool & aKeyFrame, bool & aBFrame)
-{
- if (myCurrReadBlockTrack == 0)
- {
- do {
- if (myReadBlockNumber >= myStreamInfo.NumberBlock)
- {
-// myReadBlockNumber = myStreamInfo.NumberBlock;
- return false;
- }
-
- // get the next frame in the file
- if (!myCurrReadCluster.BlockLeft())
- {
- myCurrReadCluster.Flush();
- try {
- myCurrReadCluster.FindHead(myFile);
- }
- catch (exception & Ex)
- {
- return false;
- }
- }
-
- myCurrReadCluster.GetBlock( myCurrReadBlock, myCurrReadBlockSize, myCurrReadBlockTrack );
- myReadBlockNumber++;
- } while (!IsReadingTrack(myCurrReadBlockTrack));
-
- // get the track associated (normally from myTracks)
- aTrack = myTracks[myCurrReadBlockTrack-1];
- // get the next frame from the current block
- aTrack->HandleBlock(myCurrReadBlock, myCurrReadBlockSize);
- }
- else
- {
- // get the track associated (normally from myTracks)
- aTrack = myTracks[myCurrReadBlockTrack-1];
- }
-
- Frame * myReadFrame;
- aTrack->GetNextFrame(aTimecode, myReadFrame, aKeyFrame, aBFrame);
- aFrame = myReadFrame->buf();
- aFrameSize = myReadFrame->length();
-
- if (aTrack->NoFrameLeft())
- {
- aTrack->FlushBlock();
- myCurrReadBlockTrack = 0;
- }
-
- return true;
-}
-#endif // OLD
-
-END_LIBMATROSKA_NAMESPACE
+/****************************************************************************\r
+** libmatroska : parse Matroska files, see http://www.matroska.org/\r
+**\r
+** <file/class description>\r
+**\r
+** Copyright (C) 2002-2003 Steve Lhomme. All rights reserved.\r
+**\r
+** This file is part of libmatroska.\r
+**\r
+** This library is free software; you can redistribute it and/or\r
+** modify it under the terms of the GNU Lesser General Public\r
+** License as published by the Free Software Foundation; either\r
+** version 2.1 of the License, or (at your option) any later version.\r
+** \r
+** This library is distributed in the hope that it will be useful,\r
+** but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+** Lesser General Public License for more details.\r
+** \r
+** You should have received a copy of the GNU Lesser General Public\r
+** License along with this library; if not, write to the Free Software\r
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+**\r
+** See http://www.matroska.org/license/lgpl/ for LGPL licensing information.**\r
+** Contact license@matroska.org if any conditions of this licensing are\r
+** not clear to you.\r
+**\r
+**********************************************************************/\r
+\r
+/*!\r
+ \file\r
+ \version \$Id: FileKax.cpp 640 2004-07-09 21:05:36Z mosu $\r
+ \author Steve Lhomme <robux4 @ users.sf.net>\r
+*/\r
+//#include "StdInclude.h"\r
+#include "matroska/FileKax.h"\r
+//#include "Cluster.h"\r
+//#include "Track.h"\r
+//#include "Block.h"\r
+//#include "Frame.h"\r
+//#include "Version.h"\r
+\r
+START_LIBMATROSKA_NAMESPACE\r
+\r
+//typedef Track *TrackID;\r
+\r
+FileMatroska::FileMatroska(IOCallback & output)\r
+ :myFile(output)\r
+#ifdef OLD\r
+ ,myCurrReadBlock(NULL)\r
+ ,myMinClusterSize(5*1024) // 5KB is the min size of a cluster\r
+ ,myMaxClusterSize(2*1024*1024) // 2MB is the max size of a cluster\r
+ ,myCurrReadBlockTrack(0)\r
+ ,myCurrWriteCluster(2*1024*1024) // myMaxClusterSize\r
+ ,myCurrReadCluster(NULL)\r
+ ,myReadBlockNumber(0)\r
+#endif // OLD\r
+{\r
+#ifdef OLD\r
+ myStreamInfo.MainHeaderSize = TypeHeader::default_size() +\r
+ ActualHeader::default_size() + \r
+ ExtendedInfo::default_size() + \r
+ ContentInfo::default_size();\r
+ myStreamInfo.TrackEntrySize = Track::default_size();\r
+ myStreamInfo.BlockHeadSize = BLOCK_HEADER_SIZE;\r
+ myStreamInfo.ClusterHeadSize = CLUSTER_HEADER_SIZE;\r
+ myStreamInfo.ClusterFootSize = CLUSTER_TRAILER_SIZE;\r
+#endif // OLD\r
+}\r
+\r
+FileMatroska::~FileMatroska()\r
+{\r
+// if (myCurrCluster != NULL)\r
+// throw 0; // there are some data left to write\r
+// if (myCurrReadCluster != NULL || myCurrReadBlock != NULL)\r
+// throw 0; // there are some data left to write\r
+}\r
+\r
+#ifdef OLD\r
+void FileMatroska::SetMaxClusterSize(const uint32 value)\r
+{\r
+ myMaxClusterSize = value;\r
+ myCurrWriteCluster.setMaxSize(value);\r
+}\r
+\r
+void FileMatroska::Close(const uint32 aTimeLength)\r
+{\r
+ Flush();\r
+\r
+ // get the file size\r
+ myFile.setFilePointer(0,seek_end);\r
+ myMainHeader.type_SetSize(myFile.getFilePointer());\r
+\r
+ // rewrite the header at the beginning\r
+ myFile.setFilePointer(0,seek_beginning);\r
+\r
+ // get the Track-entry size\r
+ uint32 track_entries_size = 0;\r
+ for (size_t i=0; i<myTracks.size(); i++)\r
+ {\r
+ track_entries_size += myTracks[i]->default_size();\r
+ }\r
+\r
+ myStreamInfo.TrackEntriesSize = track_entries_size;\r
+ myStreamInfo.TimeLength = aTimeLength;\r
+ myMainHeader.Render(myFile, myStreamInfo);\r
+\r
+ for (i=0; i<myTracks.size(); i++)\r
+ {\r
+ delete myTracks[i];\r
+ }\r
+}\r
+\r
+/*!\r
+ \warning after rendering the head, some parameters are locked\r
+*/\r
+filepos_t FileMatroska::RenderHead(const std::string & aEncoderApp)\r
+{\r
+ try {\r
+ uint32 track_entries_size = 0;\r
+ for (size_t i=0; i<myTracks.size(); i++)\r
+ {\r
+ track_entries_size += myTracks[i]->default_size();\r
+ }\r
+\r
+ std::string aStr = LIB_NAME;\r
+ aStr += " ";\r
+ aStr += VERSION;\r
+ myStreamInfo.EncoderLib = aStr;\r
+\r
+ myStreamInfo.EncoderApp = aEncoderApp;\r
+\r
+ myStreamInfo.TrackEntryPosition = 0 + myStreamInfo.MainHeaderSize;\r
+ myStreamInfo.TrackEntriesSize = myTracks.size() * myStreamInfo.TrackEntrySize;\r
+\r
+ myStreamInfo.CodecEntryPosition = myStreamInfo.MainHeaderSize + myStreamInfo.TrackEntriesSize;\r
+ myStreamInfo.CodecEntrySize = 4;\r
+ for (i=0; i<myTracks.size(); i++)\r
+ {\r
+ myStreamInfo.CodecEntrySize += myTracks[i]->CodecSize();\r
+ }\r
+\r
+ // Main Header\r
+ filepos_t result = myMainHeader.Render(myFile, myStreamInfo);\r
+\r
+ // Track Entries\r
+ for (i=0; i<myTracks.size(); i++)\r
+ {\r
+ myTracks[i]->RenderEntry(myFile, i+1);\r
+ }\r
+ myStreamInfo.ClusterPosition = myStreamInfo.CodecEntryPosition + myStreamInfo.CodecEntrySize;\r
+\r
+ // Codec Header\r
+ result = CodecHeader::Render(myFile, myTracks);\r
+\r
+ return result;\r
+ }\r
+ catch (exception & Ex)\r
+ {\r
+ throw Ex;\r
+ }\r
+}\r
+\r
+/*!\r
+ \return 0 if the track was not created, or a valid track number\r
+*/\r
+Track * FileMatroska::CreateTrack(const track_type aType)\r
+{\r
+ myTracks.push_back(new Track(aType));\r
+ return myTracks.back();\r
+}\r
+\r
+/*Track *FileMatroska::findTrack(Track * aTrack) const\r
+{\r
+ for (size_t i=0; i<myTracks.size(); i++)\r
+ {\r
+ if (myTracks[i] == aTrack)\r
+ return myTracks[i];\r
+ }\r
+\r
+ return NULL;\r
+}*/\r
+\r
+void FileMatroska::track_SetName(Track * aTrack, const std::string & aName)\r
+{\r
+ if (IsMyTrack(aTrack))\r
+ {\r
+ aTrack->SetName(aName);\r
+ }\r
+}\r
+\r
+void FileMatroska::track_SetLaced(Track * aTrack, bool bLaced)\r
+{\r
+ if (IsMyTrack(aTrack))\r
+ {\r
+ aTrack->SetLaced(bLaced);\r
+ }\r
+}\r
+\r
+bool FileMatroska::AddFrame(Track * aTrack, const uint32 aTimecode, const binary *aFrame, const uint32 aFrameSize,\r
+ bool aKeyFrame, bool aBFrame)\r
+{\r
+ try {\r
+ // make sure we know that track\r
+ if (IsMyTrack(aTrack))\r
+ {\r
+ // pass the cluster to the track\r
+ // handle the creation of a new cluster if needed\r
+ if (aTrack->AddFrame(aTimecode, aFrame, aFrameSize, aKeyFrame, aBFrame))\r
+ {\r
+ while (!aTrack->SerialiseBlock(myCurrWriteCluster))\r
+ {\r
+ /// \todo handle errors\r
+ uint32 aNbBlock;\r
+ myStreamInfo.ClusterSize += myCurrWriteCluster.Render(myFile, aNbBlock);\r
+ myStreamInfo.NumberBlock += aNbBlock;\r
+ myCurrWriteCluster.Flush();\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+ catch (exception & Ex)\r
+ {\r
+ throw Ex;\r
+ }\r
+}\r
+\r
+void FileMatroska::Flush()\r
+{\r
+ uint32 aNbBlock;\r
+ myStreamInfo.ClusterSize += myCurrWriteCluster.Render(myFile,aNbBlock);\r
+ myStreamInfo.NumberBlock += aNbBlock;\r
+}\r
+\r
+uint32 FileMatroska::ReadHead()\r
+{\r
+ try {\r
+ uint32 result = myMainHeader.Read(myFile, myStreamInfo);\r
+\r
+ return result;\r
+ }\r
+ catch (exception & Ex)\r
+ {\r
+ throw Ex;\r
+ }\r
+}\r
+\r
+uint32 FileMatroska::ReadTracks()\r
+{\r
+ try {\r
+ uint32 result = 0;\r
+\r
+ // seek to the start of the Track Entries\r
+ myFile.setFilePointer(myStreamInfo.TrackEntryPosition);\r
+ // get the number of Track Entries\r
+ uint8 TrackNumber = myStreamInfo.TrackEntriesSize / myStreamInfo.TrackEntrySize;\r
+ // read all the Track Entries\r
+ myTracks.clear();\r
+ for (uint8 TrackIdx = 0; TrackIdx<TrackNumber; TrackIdx ++) {\r
+ Track * tmpTrack = Track::ReadEntry(myFile, TrackIdx+1, myStreamInfo);\r
+ if (tmpTrack == NULL)\r
+ throw 0;\r
+ \r
+ myTracks.push_back(tmpTrack);\r
+ }\r
+\r
+ return result;\r
+ }\r
+ catch (exception & Ex)\r
+ {\r
+ throw Ex;\r
+ }\r
+}\r
+\r
+uint32 FileMatroska::ReadCodec()\r
+{\r
+ try {\r
+ // seek to the start of the Track Entries\r
+ myFile.setFilePointer(myStreamInfo.CodecEntryPosition);\r
+\r
+ uint32 result = CodecHeader::Read(myFile, myTracks);\r
+\r
+ return result;\r
+ }\r
+ catch (exception & Ex)\r
+ {\r
+ throw Ex;\r
+ }\r
+}\r
+\r
+inline bool FileMatroska::IsMyTrack(const Track * aTrack) const\r
+{\r
+ if (aTrack == 0)\r
+ throw 0;\r
+\r
+ for (std::vector<Track*>::const_iterator i = myTracks.begin(); i != myTracks.end(); i ++)\r
+ {\r
+ if (*i == aTrack)\r
+ break;\r
+ }\r
+\r
+ if (i != myTracks.end())\r
+ return true;\r
+ else\r
+ return false;\r
+}\r
+\r
+void FileMatroska::SelectReadingTrack(Track * aTrack, bool select)\r
+{\r
+ if (IsMyTrack(aTrack))\r
+ {\r
+ // here we have the right track\r
+ // check if it's not already selected\r
+ for (std::vector<uint8>::iterator j = mySelectedTracks.begin();\r
+ j != mySelectedTracks.end(); j ++)\r
+ {\r
+ if (*j == aTrack->TrackNumber())\r
+ break;\r
+ }\r
+\r
+ if (select && j == mySelectedTracks.end())\r
+ mySelectedTracks.push_back(aTrack->TrackNumber());\r
+ else if (!select && j != mySelectedTracks.end())\r
+ mySelectedTracks.erase(j);\r
+\r
+ std::sort(mySelectedTracks.begin(), mySelectedTracks.end());\r
+ }\r
+}\r
+\r
+inline bool FileMatroska::IsReadingTrack(const uint8 aTrackNumber) const\r
+{\r
+ for (std::vector<uint8>::const_iterator trackIdx = mySelectedTracks.begin();\r
+ trackIdx != mySelectedTracks.end() && *trackIdx < aTrackNumber;\r
+ trackIdx++)\r
+ {}\r
+\r
+ if (trackIdx == mySelectedTracks.end())\r
+ return false;\r
+ else\r
+ return true;\r
+}\r
+\r
+//\r
+\r
+void FileMatroska::Track_GetInfo(const Track * aTrack, TrackInfo & aTrackInfo) const\r
+{\r
+ if (IsMyTrack(aTrack))\r
+ {\r
+ aTrack->GetInfo(aTrackInfo);\r
+ }\r
+}\r
+\r
+// Audio related getters/setters\r
+\r
+void FileMatroska::Track_GetInfo_Audio(const Track * aTrack, TrackInfoAudio & aTrackInfo) const\r
+{\r
+ if (IsMyTrack(aTrack))\r
+ {\r
+ aTrack->GetInfoAudio(aTrackInfo);\r
+ }\r
+}\r
+\r
+void FileMatroska::Track_SetInfo_Audio(Track * aTrack, const TrackInfoAudio & aTrackInfo)\r
+{\r
+ if (IsMyTrack(aTrack))\r
+ {\r
+ aTrack->SetInfoAudio(aTrackInfo);\r
+ }\r
+}\r
+\r
+// Video related getters/setters\r
+\r
+void FileMatroska::Track_GetInfo_Video(const Track * aTrack, TrackInfoVideo & aTrackInfo) const\r
+{\r
+ if (IsMyTrack(aTrack))\r
+ {\r
+ aTrack->GetInfoVideo(aTrackInfo);\r
+ }\r
+}\r
+\r
+void FileMatroska::Track_SetInfo_Video(Track * aTrack, const TrackInfoVideo & aTrackInfo)\r
+{\r
+ if (IsMyTrack(aTrack))\r
+ {\r
+ aTrack->SetInfoVideo(aTrackInfo);\r
+ }\r
+}\r
+\r
+/*!\r
+ \todo exit when there is no Block left\r
+*/\r
+bool FileMatroska::ReadFrame(Track * & aTrack, uint32 & aTimecode, const binary * & aFrame, uint32 & aFrameSize,\r
+ bool & aKeyFrame, bool & aBFrame)\r
+{\r
+ if (myCurrReadBlockTrack == 0)\r
+ {\r
+ do {\r
+ if (myReadBlockNumber >= myStreamInfo.NumberBlock)\r
+ {\r
+// myReadBlockNumber = myStreamInfo.NumberBlock;\r
+ return false;\r
+ }\r
+\r
+ // get the next frame in the file\r
+ if (!myCurrReadCluster.BlockLeft())\r
+ {\r
+ myCurrReadCluster.Flush();\r
+ try {\r
+ myCurrReadCluster.FindHead(myFile);\r
+ }\r
+ catch (exception & Ex)\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ myCurrReadCluster.GetBlock( myCurrReadBlock, myCurrReadBlockSize, myCurrReadBlockTrack );\r
+ myReadBlockNumber++;\r
+ } while (!IsReadingTrack(myCurrReadBlockTrack));\r
+\r
+ // get the track associated (normally from myTracks)\r
+ aTrack = myTracks[myCurrReadBlockTrack-1];\r
+ // get the next frame from the current block\r
+ aTrack->HandleBlock(myCurrReadBlock, myCurrReadBlockSize);\r
+ }\r
+ else\r
+ {\r
+ // get the track associated (normally from myTracks)\r
+ aTrack = myTracks[myCurrReadBlockTrack-1];\r
+ }\r
+ \r
+ Frame * myReadFrame;\r
+ aTrack->GetNextFrame(aTimecode, myReadFrame, aKeyFrame, aBFrame);\r
+ aFrame = myReadFrame->buf();\r
+ aFrameSize = myReadFrame->length();\r
+\r
+ if (aTrack->NoFrameLeft())\r
+ {\r
+ aTrack->FlushBlock();\r
+ myCurrReadBlockTrack = 0;\r
+ }\r
+\r
+ return true;\r
+}\r
+#endif // OLD\r
+\r
+END_LIBMATROSKA_NAMESPACE\r