Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

PlayList Class Reference

The PlayList class handles a collection of movie files. More...

#include <playlist.h>

Collaboration diagram for PlayList:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 PlayList ()
 Default Constructor.
 PlayList (const PlayList &)
 Copy Constructor.
PlayListoperator= (const PlayList &)
 Assignment Operator.
 ~PlayList ()
 The PlayList Destructor Deletes the XML document if we have one.
xmlNodePtr GetBody () const
 Get the SMIL body element.
int GetNumFrames () const
 Counts the number of frames in the playlist.
char * GetFileNameOfFrame (int frameNum) const
bool GetFrame (int frameNum, Frame &frame)
 Get one frame.
bool GetMediaObject (int frameNum, FileHandler **media)
 Get the FileHandler to which the current frame belongs.
int GetClipBegin (int frameNum) const
int GetClipEnd (int frameNum) const
bool SetClipBegin (int frameNum, const char *value)
bool SetClipEnd (int frameNum, const char *value)
int FindStartOfScene (int frameNum) const
int FindEndOfScene (int frameNum) const
void AutoSplit (int first, int last)
bool SplitSceneBefore (int frameNum)
bool JoinScenesAt (int frameNum)
bool GetPlayList (int first, int last, PlayList &playlist) const
 Get a playlist.
bool InsertPlayList (PlayList &playlist, int before)
 Insert a playlist.
bool Delete (int first, int last)
bool LoadMediaObject (char *filename)
bool LoadPlayList (char *filename)
bool SavePlayList (char *filename, bool isLegacyFormat=false)
bool SavePlayListEli (char *filename, bool isPAL)
 Save a playlist en mjpegtools ELI format.
bool SavePlayListSrt (const char *filename)
void CleanPlayList (xmlNodePtr node)
 Recursively deletes unnecessary items from our XML tree.
void CleanPlayList ()
 Clean the playlist properly - this allows a new doc to be loaded.
bool IsFileUsed (string filename) const
 Checks if the filename exists in the current playlist.
bool IsDirty () const
 Returns the current setting of the dirty flag.
void SetDirty (bool value)
 Sets the dirty flag on the playlist.
string GetDocName () const
 Returns the doc name associated to the playlist.
void GetLastCleanPlayList (PlayList &playlist)
void SetDocName (string)
 Protected set doc name method.
string GetProjectDirectory ()
 Obtain the current project directory.
string GetSeqAttribute (int frameNum, const char *) const
bool SetSeqAttribute (int frameNum, const char *, const char *)
bool SetDocId (const char *value)
string GetDocId () const
bool SetDocTitle (const char *value)
string GetDocTitle () const

Protected Attributes

bool dirty

Private Member Functions

void RefreshCount ()
void AutoSplit (int first, time_t startTime, int last, time_t endTime, int fps)

Private Attributes

string doc_name
xmlDocPtr doc
int count
SMIL::MediaClippingTime time

Detailed Description

The PlayList class handles a collection of movie files.

Definition at line 47 of file playlist.h.


Constructor & Destructor Documentation

PlayList::PlayList  ) 
 

Default Constructor.

Definition at line 880 of file playlist.cc.

References doc, and SMIL20_NAMESPACE_HREF.

00880                    : dirty( false ), doc_name( "" ), count( 0 )
00881 {
00882     xmlNsPtr    ns;
00883     xmlNodePtr  root;
00884 
00885     // cerr << "*PlayList::PlayList()" << endl;
00886 
00887     doc = xmlNewDoc( ( const xmlChar* ) "1.0" );
00888     root = xmlNewNode( NULL, ( const xmlChar* ) "smil" );
00889     ns = xmlNewNs( root, SMIL20_NAMESPACE_HREF, ( const xmlChar* ) NULL );
00890     xmlDocSetRootElement( doc, root );
00891     xmlAddChild( root, xmlNewNode( NULL, ( const xmlChar* ) "body" ) );
00892 }

PlayList::PlayList const PlayList  ) 
 

Copy Constructor.

Definition at line 897 of file playlist.cc.

References clone(), dirty, doc, doc_name, GetBody(), GetDocName(), parse(), RefreshCount(), and SMIL20_NAMESPACE_HREF.

00898 {
00899     xmlNsPtr    ns;
00900     xmlNodePtr  root;
00901 
00902     doc = xmlNewDoc( ( const xmlChar* ) "1.0" );
00903     root = xmlNewNode( NULL, ( const xmlChar* ) "smil" );
00904     ns = xmlNewNs( root, ( const xmlChar* ) SMIL20_NAMESPACE_HREF, ( const xmlChar* ) NULL );
00905     xmlDocSetRootElement( doc, root );
00906     parse( playList.GetBody(), clone, &root );
00907     dirty = playList.dirty;
00908     doc_name = playList.GetDocName( );
00909     RefreshCount( );
00910 }

PlayList::~PlayList  ) 
 

The PlayList Destructor Deletes the XML document if we have one.

Definition at line 941 of file playlist.cc.

References doc.

00942 {
00943     // cerr << "*PlayList::~PlayList()" << endl;
00944     if ( doc != NULL )
00945     {
00946         xmlFreeDoc( doc );
00947         doc = NULL;
00948     }
00949 }


Member Function Documentation

void PlayList::AutoSplit int  first,
time_t  startTime,
int  last,
time_t  endTime,
int  fps
[private]
 

Definition at line 1219 of file playlist.cc.

References MovieInfo::absFrame, AutoSplit(), MovieInfo::clipFrame, MovieInfo::fileName, findFile(), GetBody(), GetFileMap(), FileHandler::GetFrame(), GetFramePool(), parse(), and SplitSceneBefore().

01220 {
01221     time_t diffTime = static_cast<time_t>( difftime( endTime, startTime ) );
01222     if ( ( ( diffTime * fps ) - ( end - start ) ) > fps || diffTime < 0.0 )
01223     {
01224         if ( ( end - start ) > 1 )
01225         {
01226             time_t mid = start + ( end - start ) / 2;
01227             time_t midTime;
01228             // reduce the scope of temporary varables here to reduce memory usage when recurring:
01229             {
01230                 MovieInfo midFile;
01231                 struct tm recDate;
01232                 Frame *frame = GetFramePool( ) ->GetFrame( );
01233 
01234                 memset( &midFile, 0, sizeof( MovieInfo ) );
01235                 midFile.absFrame = mid;
01236 
01237                 parse( GetBody(), findFile, &midFile );
01238 
01239                 string index( ( char* ) midFile.fileName );
01240                 FileHandler *mediaFile = GetFileMap() ->GetMap() [ index ];
01241                 mediaFile->GetFrame( *frame, midFile.clipFrame );
01242                 frame->GetRecordingDate( recDate );
01243                 midTime = mktime( &recDate );
01244 
01245                 GetFramePool( ) ->DoneWithFrame( frame );
01246             }
01247 
01248             // bail out on invalid recording date/time
01249             if ( midTime < 0 )
01250                 return ;
01251 
01252             AutoSplit ( start, startTime, mid, midTime, fps );
01253             AutoSplit ( mid, midTime, end, endTime, fps );
01254         }
01255         else
01256         {
01257             SplitSceneBefore( end );
01258         }
01259     }
01260 }

void PlayList::AutoSplit int  first,
int  last
 

Definition at line 1170 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, MovieInfo::clipFrame, MovieInfo::fileName, findFile(), GetBody(), GetFileMap(), FileHandler::GetFrame(), GetFramePool(), Frame::GetRecordingDate(), Frame::IsPAL(), and parse().

Referenced by AutoSplit(), and LoadMediaObject().

01171 {
01172     MovieInfo firstFile;
01173     MovieInfo lastFile;
01174     Frame *frame = GetFramePool( ) ->GetFrame( );
01175     struct tm   recDate;
01176     time_t  startTime;
01177     time_t  endTime;
01178 
01179     // cerr << "PlayList::AutoSplit(int start=" << start << ", int end=" << end << ")" ;
01180     // cerr << endl;
01181 
01182     memset( &firstFile, 0, sizeof( MovieInfo ) );
01183     firstFile.absBegin = 0;
01184     firstFile.absEnd = 0;
01185     firstFile.absFrame = start;
01186 
01187     parse( GetBody(), findFile, &firstFile );
01188     string index1( ( char* ) firstFile.fileName );
01189     FileHandler *mediaFile1 = GetFileMap() ->GetMap() [ index1 ];
01190     mediaFile1->GetFrame( *frame, firstFile.clipFrame );
01191     frame->GetRecordingDate( recDate );
01192     startTime = mktime( &recDate );
01193 
01194     memset( &lastFile, 0, sizeof( MovieInfo ) );
01195     lastFile.absBegin = 0;
01196     lastFile.absEnd = 0;
01197     lastFile.absFrame = end;
01198 
01199     parse( GetBody(), findFile, &lastFile );
01200 
01201     string index2( ( char* ) lastFile.fileName );
01202     FileHandler *mediaFile2 = GetFileMap() ->GetMap() [ index2 ];
01203     mediaFile2->GetFrame( *frame, lastFile.clipFrame );
01204     frame->GetRecordingDate( recDate );
01205     endTime = mktime( &recDate );
01206 
01207     int fps = frame->IsPAL() ? 25 : 30;
01208 
01209     GetFramePool( ) ->DoneWithFrame( frame );
01210 
01211     // bail out on invalid recording date/time
01212     if ( startTime < 0 || endTime < 0 )
01213         return ;
01214 
01215     AutoSplit ( start, startTime, end, endTime, fps );
01216 }

void PlayList::CleanPlayList  ) 
 

Clean the playlist properly - this allows a new doc to be loaded.

Definition at line 2164 of file playlist.cc.

References Delete(), dirty, doc_name, GetNumFrames(), and RefreshCount().

Referenced by CleanPlayList(), and LoadPlayList().

02165 {
02166     if ( GetNumFrames() > 0 )
02167         Delete( 0, GetNumFrames() );
02168     dirty = false;
02169     doc_name = "";
02170     RefreshCount( );
02171 }

void PlayList::CleanPlayList xmlNodePtr  node  ) 
 

Recursively deletes unnecessary items from our XML tree.

We need only <smil>, <seq> and <video> nodes, delete everything else, in particular the text nodes too.

Parameters:
node start deleting here

Definition at line 2121 of file playlist.cc.

References CleanPlayList(), and RefreshCount().

02122 {
02123     while ( node != NULL )
02124     {
02125 
02126         xmlNodePtr nodeToDelete = NULL;
02127 
02128         CleanPlayList( node->children );
02129         if ( xmlStrcmp( node->name, ( const xmlChar* ) "smil" ) == 0 )
02130         {
02131             //do nothing
02132         }
02133         else if ( xmlStrcmp( node->name, ( const xmlChar* ) "body" ) == 0 )
02134         {
02135             //do nothing
02136         }
02137         else if ( xmlStrcmp( node->name, ( const xmlChar* ) "seq" ) == 0 )
02138         {
02139             if ( node->children == NULL )
02140             {
02141                 nodeToDelete = node;
02142             }
02143         }
02144         else if ( xmlStrcmp( node->name, ( const xmlChar* ) "video" ) == 0 )
02145         {
02146             // do nothing
02147         }
02148         else
02149             nodeToDelete = node;
02150         node = node->next;
02151 
02152         if ( nodeToDelete != NULL )
02153         {
02154             xmlUnlinkNode( nodeToDelete );
02155             xmlFreeNode( nodeToDelete );
02156         }
02157     }
02158     RefreshCount( );
02159 }

bool PlayList::Delete int  first,
int  last
 

Definition at line 1659 of file playlist.cc.

References dirty, GetBody(), GetNumFrames(), RefreshCount(), and SplitSceneBefore().

Referenced by CleanPlayList(), GetLastCleanPlayList(), PageTrim::insertScene(), EditorBackup::Redo(), PageTrim::saveScene(), SplitSceneBefore(), and EditorBackup::Undo().

01660 {
01661     int absClipBegin;
01662     int clipBegin;
01663     int clipEnd;
01664     static int firstCall = 0;
01665 
01666     // cerr << "bool PlayList::Delete(int first=" << first << ", int last=" << last << ")" << endl;
01667 
01668     // SplitSceneBefore calls Delete, avoid recursion
01669 
01670     if ( GetNumFrames() == 0 )
01671         return false;
01672 
01673     if ( firstCall == 0 )
01674     {
01675         firstCall = 1;
01676         SplitSceneBefore( first );
01677         firstCall = 0;
01678     }
01679 
01680     xmlNodePtr srcNode = GetBody();
01681     absClipBegin = 0;
01682     xmlNodePtr nextSequence = NULL;
01683     for ( xmlNodePtr srcSeq = srcNode->children; srcSeq != NULL; srcSeq = nextSequence )
01684     {
01685 
01686         dirty = true;
01687 
01688         // In case we need to delete this node, get the next pointer before starting
01689         nextSequence = srcSeq->next;
01690 
01691         if ( xmlStrcmp( srcSeq->name, ( const xmlChar* ) "seq" ) == 0 )
01692         {
01693             xmlNodePtr nextVideo = NULL;
01694 
01695             for ( xmlNodePtr srcVideo = srcSeq->children; srcVideo != NULL; srcVideo = nextVideo )
01696             {
01697 
01698                 // In case we have to delete this node
01699                 nextVideo = srcVideo->next;
01700 
01701                 if ( xmlStrcmp( srcVideo->name, ( const xmlChar* ) "video" ) == 0 )
01702                 {
01703 
01704                     ostringstream sb1, sb2;
01705                     xmlChar *s;
01706 
01707                     sb1 << ( s = xmlGetProp( srcVideo, ( const xmlChar* ) "clipBegin" ) ) << ends;
01708                     clipBegin = atoi( sb1.str().c_str() );
01709                     if ( s )
01710                         xmlFree( s );
01711                     s = xmlGetProp( srcVideo, ( const xmlChar* ) "clipEnd" );
01712                     clipEnd = atoi( ( char * ) s );
01713                     sb2 << ( s = xmlGetProp( srcVideo, ( const xmlChar* ) "clipEnd" ) ) << ends;
01714                     clipEnd = atoi( sb2.str().c_str() );
01715                     if ( s )
01716                         xmlFree( s );
01717 
01718                     // case 1: selection covers this file completely. Remove this file from playlist.
01719 
01720                     if ( first <= absClipBegin && last >= absClipBegin + clipEnd - clipBegin )
01721                     {
01722                         xmlUnlinkNode( srcVideo );
01723                         xmlFreeNode( srcVideo );
01724                         // cerr << "case 1 " << endl;
01725                     }
01726 
01727                     // case 2: selection starts before or at start of file and ends somewhere in the file.
01728                     // New start of file is now end of selection + 1
01729 
01730                     else if ( first <= absClipBegin && last >= absClipBegin && last <= absClipBegin + clipEnd - clipBegin )
01731                     {
01732 
01733                         ostringstream sb;
01734 
01735                         sb << last - absClipBegin + clipBegin + 1 << ends;
01736                         xmlSetProp( srcVideo, ( const xmlChar* ) "clipBegin", ( const xmlChar* ) sb.str().c_str() );
01737                         // cerr << "case 2 " << endl;
01738                     }
01739 
01740                     // case 3: selection starts somewhere in the file and ends at or after the file
01741                     // New end of file is now start of selection - 1
01742 
01743                     else if ( first > absClipBegin && first <= absClipBegin + clipEnd - clipBegin && last >= absClipBegin + clipEnd - clipBegin )
01744                     {
01745 
01746                         ostringstream sb;
01747 
01748                         sb << first - absClipBegin + clipBegin - 1 << ends;
01749                         xmlSetProp( srcVideo, ( const xmlChar* ) "clipEnd", ( const xmlChar* ) sb.str().c_str() );
01750                         // cerr << "case 3 " << endl;
01751                     }
01752 
01753                     // case 4: selection starts somewhere in the file and ends in the file.
01754                     // We must split this node such that end of first file is start of selection - 1
01755                     // and start of second file is end of selection + 1
01756 
01757                     else if ( first > absClipBegin && last < absClipBegin + clipEnd - clipBegin )
01758                     {
01759 
01760                         ostringstream sb1, sb2;
01761                         xmlChar *s;
01762 
01763                         xmlNodePtr video = xmlNewNode( NULL, ( const xmlChar* ) "video" );
01764                         xmlNewProp( video, ( const xmlChar* ) "src", ( s = xmlGetProp( srcVideo, ( const xmlChar* ) "src" ) ) );
01765                         if ( s )
01766                             xmlFree( s );
01767                         sb1 << last - absClipBegin + clipBegin + 1 << ends;
01768                         xmlNewProp( video, ( const xmlChar* ) "clipBegin", ( const xmlChar* ) sb1.str().c_str() );
01769                         xmlNewProp( video, ( const xmlChar* ) "clipEnd", ( s = xmlGetProp( srcVideo, ( const xmlChar* ) "clipEnd" ) ) );
01770                         if ( s )
01771                             xmlFree( s );
01772                         xmlAddNextSibling( srcVideo, video );
01773                         sb2 << first - absClipBegin + clipBegin - 1 << ends;
01774                         xmlSetProp( srcVideo, ( const xmlChar* ) "clipEnd", ( const xmlChar* ) sb2.str().c_str() );
01775                         // cerr << "case 4 " << endl;
01776                     }
01777 
01778                     absClipBegin += clipEnd - clipBegin + 1;
01779                 }
01780             }
01781 
01782             // if the node is now empty, delete it (can delete - see nextSequence above)
01783 
01784             if ( srcSeq->children == NULL )
01785             {
01786                 xmlUnlinkNode( srcSeq );
01787                 xmlFreeNode( srcSeq );
01788             }
01789         }
01790     }
01791 
01792     RefreshCount( );
01793 
01794     return true;
01795 }

int PlayList::FindEndOfScene int  frameNum  )  const
 

Definition at line 1151 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, MovieInfo::fileName, findSceneEnd(), GetBody(), and parse().

Referenced by ExportAudio::doExport(), and PageTrim::loadScene().

01152 {
01153     MovieInfo data;
01154 
01155     // cerr << "int PlayList::FindEndOfScene(int frameNum)" << endl;
01156 
01157     data.absBegin = 0;
01158     data.absEnd = 0;
01159     data.absFrame = frameNum;
01160 
01161     parse( GetBody(), findSceneEnd, &data );
01162 
01163     if ( strcmp( data.fileName, "" ) )
01164         return data.absEnd;
01165     else
01166         return 999999;
01167 }

int PlayList::FindStartOfScene int  frameNum  )  const
 

Definition at line 1131 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, MovieInfo::fileName, findSceneStart(), GetBody(), and parse().

Referenced by PageTrim::loadScene(), and KinoCommon::moveToFrame().

01132 {
01133     MovieInfo data;
01134 
01135     // cerr << "int PlayList::FindStartOfScene(int frameNum)" << endl;
01136 
01137     memset( &data, 0, sizeof( MovieInfo ) );
01138     data.absBegin = 0;
01139     data.absEnd = 0;
01140     data.absFrame = frameNum;
01141 
01142     parse( GetBody(), findSceneStart, &data );
01143 
01144     if ( strcmp( data.fileName, "" ) )
01145         return data.absBegin;
01146     else
01147         return 0;
01148 }

xmlNodePtr PlayList::GetBody  )  const
 

Get the SMIL body element.

Returns:
a node pointer to the body element

Definition at line 955 of file playlist.cc.

References doc.

Referenced by AutoSplit(), Delete(), FindEndOfScene(), FindStartOfScene(), GetClipBegin(), GetClipEnd(), GetDocId(), GetDocTitle(), GetFileNameOfFrame(), GetFrame(), GetMediaObject(), GetPlayList(), GetSeqAttribute(), InsertPlayList(), IsFileUsed(), JoinScenesAt(), LoadMediaObject(), LoadPlayList(), operator=(), PlayList(), RefreshCount(), SavePlayListEli(), SavePlayListSrt(), SetClipBegin(), SetClipEnd(), SetDocId(), SetDocTitle(), SetSeqAttribute(), and SplitSceneBefore().

00956 {
00957     return xmlDocGetRootElement( doc )->children;
00958 }

int PlayList::GetClipBegin int  frameNum  )  const
 

Definition at line 1059 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, MovieInfo::clipBegin, findSceneStart(), GetBody(), and parse().

Referenced by PageTrim::loadScene().

01060 {
01061     MovieInfo data;
01062 
01063     memset( &data, 0, sizeof( MovieInfo ) );
01064     data.absBegin = 0;
01065     data.absEnd = 0;
01066     data.absFrame = frameNum;
01067 
01068     if ( parse( GetBody(), findSceneStart, &data ) )
01069         return data.clipBegin;
01070     else
01071         return 0;
01072 }

int PlayList::GetClipEnd int  frameNum  )  const
 

Definition at line 1075 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, MovieInfo::clipEnd, findSceneEnd(), GetBody(), and parse().

Referenced by PageTrim::loadScene().

01076 {
01077     MovieInfo data;
01078 
01079     memset( &data, 0, sizeof( MovieInfo ) );
01080     data.absBegin = 0;
01081     data.absEnd = 0;
01082     data.absFrame = frameNum;
01083 
01084     if ( parse( GetBody(), findSceneEnd, &data ) )
01085         return data.clipEnd;
01086     else
01087         return 0;
01088 }

string PlayList::GetDocId  )  const
 

Definition at line 2331 of file playlist.cc.

References GetBody().

Referenced by KinoCommon::loadPlayList(), and KinoCommon::publishPlayList().

02332 {
02333     if ( GetBody() )
02334     {
02335         const char *value = ( const char* ) xmlGetProp( GetBody(), ( const xmlChar * ) "id" );
02336         if ( value )
02337             return value;
02338     }
02339     return "";
02340 }

string PlayList::GetDocName  )  const
 

Returns the doc name associated to the playlist.

NB: This should reflect the first .smil file received via the Load or Save methods above.

Returns:
the file name of the playlist

Definition at line 2232 of file playlist.cc.

References doc_name.

Referenced by GetPlayList(), GetProjectDirectory(), InsertPlayList(), operator=(), PlayList(), and KinoCommon::publishPlayList().

02233 {
02234     return doc_name;
02235 }

string PlayList::GetDocTitle  )  const
 

Definition at line 2355 of file playlist.cc.

References GetBody().

Referenced by KinoCommon::loadPlayList(), and KinoCommon::publishPlayList().

02356 {
02357     if ( GetBody() )
02358     {
02359         const char *value = ( const char* ) xmlGetProp( GetBody(), ( const xmlChar * ) "title" );
02360         if ( value )
02361             return value;
02362     }
02363     return "";
02364 }

char * PlayList::GetFileNameOfFrame int  frameNum  )  const
 

Definition at line 978 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, MovieInfo::fileName, findFile(), GetBody(), and parse().

00979 {
00980     // cerr << "char* PlayList::GetFileNameOfFrame(int frameNum)" << endl;
00981     MovieInfo data;
00982 
00983     memset( &data, 0, sizeof( MovieInfo ) );
00984     data.absBegin = 0;
00985     data.absEnd = 0;
00986     data.absFrame = frameNum;
00987 
00988     parse( GetBody(), findFile, &data );
00989     return strdup( data.fileName );
00990 }

bool PlayList::GetFrame int  frameNum,
Frame frame
 

Get one frame.

gets one frame of the playlist.

Parameters:
absFrame the frame number to get
frame the frame
Returns:
true if a frame could be copied, false otherwise

Definition at line 1002 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, MovieInfo::clipFrame, MovieInfo::fileName, findFile(), GetBody(), GetFileMap(), FileHandler::GetFrame(), FileHandler::GetTotalFrames(), and parse().

Referenced by ExportStills::doExport(), ExportPipe::doExport(), ExportAVI::doExport(), ExportAudio::doExport(), Export1394::doExport(), FXSelectedFrames::GetAudio(), FXSelectedFrames::GetScaledImage(), kino2raw(), AsyncAudioResample< input_t, output_t >::ReadAudio(), PageTrim::showFrame(), and PageTrim::showFrameInfo().

01003 {
01004     MovieInfo data;
01005 
01006     // cerr << "bool PlayList::GetFrame(" << frameNum << ", Frame &frame)" << endl;
01007 
01008     memset( &data, 0, sizeof( MovieInfo ) );
01009     data.absBegin = 0;
01010     data.absEnd = 0;
01011     data.absFrame = frameNum;
01012 
01013     parse( GetBody(), findFile, &data );
01014 
01015     if ( strcmp( data.fileName, "" ) )
01016     {
01017         // NB: In our playlist, we enforce an internal absolute path - there is no need
01018         // to convert the file name here
01019         string index( ( char * ) data.fileName );
01020         FileHandler *mediaFile = GetFileMap() ->GetMap() [ index ];
01021         if ( data.clipFrame >= mediaFile->GetTotalFrames() )
01022             data.clipFrame = mediaFile->GetTotalFrames() - 1;
01023         return ( mediaFile->GetFrame( frame, data.clipFrame ) >= 0 );
01024     }
01025 
01026     return false;
01027 }

void PlayList::GetLastCleanPlayList PlayList playlist  ) 
 

Definition at line 2250 of file playlist.cc.

References Delete(), doc_name, GetNumFrames(), and LoadPlayList().

02251 {
02252     if ( playlist.GetNumFrames() > 0 )
02253         playlist.Delete( 0, playlist.GetNumFrames() );
02254 
02255     // If we have a file, load it, otherwise we have valid contents already...
02256     if ( doc_name != "" )
02257         playlist.LoadPlayList( ( char * ) doc_name.c_str() );
02258 }

bool PlayList::GetMediaObject int  frameNum,
FileHandler **  media
 

Get the FileHandler to which the current frame belongs.

Parameters:
absFrame the frame number to get
media a pointer to a FileHandler to be set
Returns:
true if an FileHandler could be copied, false otherwise

Definition at line 1036 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, MovieInfo::fileName, findFile(), GetBody(), GetFileMap(), and parse().

Referenced by PageTrim::loadScene(), and PageTrim::showFrameInfo().

01037 {
01038     MovieInfo data;
01039 
01040     memset( &data, 0, sizeof( MovieInfo ) );
01041     data.absBegin = 0;
01042     data.absEnd = 0;
01043     data.absFrame = frameNum;
01044 
01045     parse( GetBody(), findFile, &data );
01046 
01047     if ( strcmp( data.fileName, "" ) )
01048     {
01049         // Again, the absolute path is ensure internally - no need to convert
01050         string index( ( char * ) data.fileName );
01051         *media = GetFileMap() ->GetMap() [ index ];
01052         return true;
01053     }
01054 
01055     return false;
01056 }

int PlayList::GetNumFrames  )  const
 

Counts the number of frames in the playlist.

Returns:
the number of frames in the playlist

Definition at line 972 of file playlist.cc.

References count.

Referenced by CleanPlayList(), Delete(), FXSelectedFrames::GetAudio(), GetLastCleanPlayList(), GetPlayList(), FXSelectedFrames::GetScaledImage(), InsertPlayList(), PageTrim::insertScene(), JoinScenesAt(), kino2raw(), PageTrim::loadFile(), LoadMediaObject(), PageTrim::loadScene(), EditorBackup::Redo(), PageTrim::saveScene(), SplitSceneBefore(), EditorBackup::Store(), and EditorBackup::Undo().

00973 {
00974     return count;
00975 }

bool PlayList::GetPlayList int  first,
int  last,
PlayList playlist
const
 

Get a playlist.

Returns a subset of the frames as a playlist. The parameters first and last must be within the available frames in the playlist.

Parameters:
first number of first frame
last number of last frame
playlist the playlist object to be filled
Returns:
true if the frames could be copied, false otherwise

Definition at line 1405 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, MovieInfo::clipBegin, MovieInfo::clipEnd, MovieInfo::clipFrame, dirty, MovieInfo::fileName, fillMap(), findFile(), directory_utils::get_directory_from_file(), GetBody(), GetDocName(), GetNumFrames(), parse(), RefreshCount(), and MovieInfo::video.

Referenced by PageTrim::loadScene(), SplitSceneBefore(), and EditorBackup::Store().

01406 {
01407     MovieInfo firstFile, lastFile;
01408     bool copyFlag = false;
01409 
01410     if ( GetNumFrames() == 0 )
01411         return false;
01412 
01413     playlist.dirty = false;
01414 
01415     // cerr << " bool PlayList::Copy(int first, int last, PlayList &playlist) " << endl;
01416 
01417     memset( &firstFile, 0, sizeof( MovieInfo ) );
01418     firstFile.absBegin = 0;
01419     firstFile.absEnd = 0;
01420     firstFile.absFrame = first;
01421 
01422     parse( GetBody(), findFile, &firstFile );
01423 
01424     memset( &lastFile, 0, sizeof( MovieInfo ) );
01425     lastFile.absBegin = 0;
01426     lastFile.absEnd = 0;
01427     lastFile.absFrame = last;
01428 
01429     parse( GetBody(), findFile, &lastFile );
01430 
01431     if ( strcmp( firstFile.fileName, "" ) && strcmp( lastFile.fileName, "" ) )
01432     {
01433 
01434         xmlNodePtr srcNode = GetBody();
01435         xmlNodePtr dstNode = playlist.GetBody();
01436         xmlNodePtr nextSeq = NULL;
01437 
01438         for ( xmlNodePtr srcSeq = srcNode->children; srcSeq != NULL; srcSeq = nextSeq )
01439         {
01440             nextSeq = srcSeq->next;
01441             if ( xmlStrcmp( srcSeq->name, ( const xmlChar* ) "seq" ) == 0 )
01442             {
01443                 xmlNodePtr seq = xmlNewNode( NULL, ( const xmlChar* ) "seq" );
01444                 xmlAddChild( dstNode, seq );
01445                 xmlNodePtr nextVideo = NULL;
01446 
01447                 for ( xmlNodePtr srcVideo = srcSeq->children; srcVideo != NULL; srcVideo = nextVideo )
01448                 {
01449                     nextVideo = srcVideo->next;
01450                     if ( xmlStrcmp( srcVideo->name, ( const xmlChar* ) "video" ) == 0 )
01451                     {
01452 
01453                         // case 1: selection contains more than one file. This one is neither the first nor the last.
01454 
01455                         if ( copyFlag && srcVideo != firstFile.video && srcVideo != lastFile.video )
01456                         {
01457                             xmlNodePtr video = xmlNewNode( NULL, ( const xmlChar* ) "video" );
01458                             xmlAddChild( seq, video );
01459                             for ( xmlAttr* attr = srcVideo->properties; attr; attr = attr->next )
01460                                 xmlNewProp( video, attr->name, xmlGetProp( attr->parent, attr->name) );
01461                         }
01462 
01463                         // case 2: selection contains more than one file and this is the first file
01464 
01465                         else if ( srcVideo == firstFile.video && srcVideo != lastFile.video )
01466                         {
01467 
01468                             ostringstream sb1, sb2;
01469 
01470                             xmlNodePtr video = xmlNewNode( NULL, ( const xmlChar* ) "video" );
01471                             xmlNewProp( video, ( const xmlChar* ) "src", ( const xmlChar* ) firstFile.fileName );
01472                             sb1 << firstFile.clipFrame << ends;
01473                             xmlNewProp( video, ( const xmlChar* ) "clipBegin", ( const xmlChar* ) sb1.str().c_str() );
01474                             sb2 << firstFile.clipEnd << ends;
01475                             xmlNewProp( video, ( const xmlChar* ) "clipEnd", ( const xmlChar* ) sb2.str().c_str() );
01476                             xmlAddChild( seq, video );
01477                             copyFlag = true;
01478                         }
01479 
01480                         // case 3: selection contains more than one file and this is the last file
01481 
01482                         else if ( srcVideo != firstFile.video && srcVideo == lastFile.video )
01483                         {
01484 
01485                             ostringstream sb1, sb2;
01486 
01487                             xmlNodePtr video = xmlNewNode( NULL, ( const xmlChar* ) "video" );
01488                             xmlNewProp( video, ( const xmlChar* ) "src", ( const xmlChar* ) lastFile.fileName );
01489                             sb1 << lastFile.clipBegin << ends;
01490                             xmlNewProp( video, ( const xmlChar* ) "clipBegin", ( const xmlChar* ) sb1.str().c_str() );
01491                             sb2 << lastFile.clipFrame << ends;
01492                             xmlNewProp( video, ( const xmlChar* ) "clipEnd", ( const xmlChar* ) sb2.str().c_str() );
01493                             xmlAddChild( seq, video );
01494                             copyFlag = false;
01495                         }
01496 
01497                         // case 4: selection contains exactly one file
01498 
01499                         else if ( srcVideo == firstFile.video && srcVideo == lastFile.video )
01500                         {
01501 
01502                             ostringstream sb1, sb2;
01503 
01504                             xmlNodePtr video = xmlNewNode( NULL, ( const xmlChar* ) "video" );
01505                             xmlNewProp( video, ( const xmlChar* ) "src", ( const xmlChar* ) firstFile.fileName );
01506                             sb1 << firstFile.clipFrame << ends;
01507                             xmlNewProp( video, ( const xmlChar* ) "clipBegin", ( const xmlChar* ) sb1.str().c_str() );
01508                             sb2 << lastFile.clipFrame << ends;
01509                             xmlNewProp( video, ( const xmlChar* ) "clipEnd", ( const xmlChar* ) sb2.str().c_str() );
01510                             xmlAddChild( seq, video );
01511                         }
01512                     }
01513                 }
01514 
01515                 // if this sequence does not have any video clips, remove it
01516 
01517                 if ( seq->children == NULL )
01518                 {
01519                     xmlUnlinkNode( seq );
01520                     xmlFreeNode( seq );
01521                 }
01522                 else
01523                 // copy the seq attributes
01524                 {
01525                     for ( xmlAttr* attr = srcSeq->properties; attr; attr = attr->next )
01526                         xmlNewProp( seq, attr->name, xmlGetProp( attr->parent, attr->name) );
01527                 }
01528             }
01529         }
01530         // PASS PATH
01531         string path = directory_utils::get_directory_from_file( GetDocName() );
01532         parse( playlist.GetBody(), fillMap, &path );
01533     }
01534     playlist.RefreshCount( );
01535     return true;
01536 }

string PlayList::GetProjectDirectory  ) 
 

Obtain the current project directory.

Returns:
the directory to place files containing this playlist

Definition at line 2265 of file playlist.cc.

References directory_utils::expand_directory(), directory_utils::get_directory_from_file(), GetDocName(), Preferences::getInstance(), and directory_utils::join_file_to_directory().

Referenced by KinoCommon::getLastDirectory().

02266 {
02267     string output = "";
02268 
02269     if ( GetDocName() != "" )
02270         output = directory_utils::get_directory_from_file( GetDocName( ) );
02271 
02272     if ( output == "" && strcmp( Preferences::getInstance().defaultDirectory, "" ) )
02273         output = directory_utils::expand_directory( Preferences::getInstance().defaultDirectory );
02274 
02275     if ( output == "" )
02276         output = directory_utils::join_file_to_directory( "", "" );
02277 
02278     return output;
02279 }

string PlayList::GetSeqAttribute int  frameNum,
const char * 
const
 

Definition at line 2281 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, findSceneStart(), GetBody(), parse(), and MovieInfo::sequence.

02282 {
02283     MovieInfo data;
02284 
02285     memset( &data, 0, sizeof( MovieInfo ) );
02286     data.absBegin = 0;
02287     data.absEnd = 0;
02288     data.absFrame = frameNum;
02289 
02290     if ( parse( GetBody(), findSceneStart, &data ) && data.sequence )
02291     {
02292         const char *value = ( const char* ) xmlGetProp( data.sequence, ( const xmlChar * ) name );
02293         if ( value )
02294             return value;
02295     }
02296     return "";
02297 }

bool PlayList::InsertPlayList PlayList playlist,
int  before
 

Insert a playlist.

Inserts all frames contained in the parameter playlist. To insert the frames at the start of the playlist, use a before value of 0. To append it at the end of the playlist. pass the first unused (= number of frames contained) index.

Parameters:
playlist The playlist to insert
before insert playlist before this frame

Definition at line 1550 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, dirty, doc_name, fillMap(), findFile(), directory_utils::get_directory_from_file(), GetBody(), GetDocName(), GetNumFrames(), parse(), RefreshCount(), MovieInfo::sequence, SplitSceneBefore(), and MovieInfo::video.

Referenced by EditorBackup::Redo(), and EditorBackup::Undo().

01551 {
01552     // cerr << "bool PlayList::Paste(PlayList &playlist, int before(=" << before << "))" << endl;
01553 
01554     if ( playlist.GetNumFrames() == 0 )
01555         return false;
01556 
01557     // PASS PATH
01558     string path = directory_utils::get_directory_from_file( GetDocName() );
01559     parse( playlist.GetBody(), fillMap, &path );
01560 
01561     MovieInfo file;
01562 
01563     memset( &file, 0, sizeof( MovieInfo ) );
01564     file.absBegin = 0;
01565     file.absEnd = 0;
01566     file.absFrame = before;
01567     file.sequence = NULL;
01568     file.video = NULL;
01569 
01570     // Fill the map with any new files now, before we change the doc
01571     parse( GetBody(), findFile, &file );
01572 
01573     xmlNodePtr node = playlist.GetBody();
01574     bool first = true;
01575     xmlNodePtr next = NULL;
01576     xmlNodePtr sequence = file.sequence;
01577 
01578     if ( GetNumFrames() > 0 )
01579     {
01580         dirty = true;
01581     }
01582     else
01583     {
01584         dirty = playlist.dirty;
01585 
01586         if ( doc_name == "" )
01587             doc_name = playlist.GetDocName( );
01588 
01589     }
01590 
01591     for ( xmlNodePtr ptr = node->children; ptr != NULL; ptr = next )
01592     {
01593 
01594         //cerr << endl << "Sibling" << endl;
01595         //xmlElemDump(stderr, NULL, ptr);
01596         //cerr << endl;
01597 
01598         // Get the next sibling before adding
01599         next = ptr->next;
01600 
01601         // If first and at start of scene insert, otherwise append
01602         // cerr << "Scene i'm pasting into starts at " << file.absBegin << " [" << file.absEnd << "]" << endl;
01603 
01604         if ( first && sequence == NULL )
01605         {
01606             // This strange approach avoids using xmlCopyNode, which adds extra namespace declarations
01607             xmlNodePtr tmp = xmlNewNode( NULL, ( const xmlChar* ) "seq" );
01608             xmlAddChild( GetBody(), tmp );
01609             sequence = xmlAddNextSibling( tmp, ptr );
01610             xmlUnlinkNode( tmp );
01611             xmlFreeNode( tmp );
01612         }
01613         else if ( first && before == file.absBegin && before != ( file.absEnd + 1 ) )
01614         {
01615             // cerr << "Inserting before " << before << endl;
01616             sequence = xmlAddPrevSibling( sequence, ptr );
01617         }
01618         else if ( first && before != ( file.absEnd + 1 ) )
01619         {
01620             // cerr << "Splitting scene that start at " << file.absBegin << " and ends at " << file.absEnd << " at " << before << endl;
01621             // cerr << endl << "Before Split" << endl;
01622             // xmlElemDump(stderr, NULL, sequence);
01623             // cerr << endl;
01624 
01625             // Split the current scene
01626             SplitSceneBefore( before );
01627 
01628             // Find our new position
01629             memset( &file, 0, sizeof( MovieInfo ) );
01630             file.absBegin = 0;
01631             file.absFrame = before;
01632             file.sequence = NULL;
01633             file.video = NULL;
01634 
01635             parse( GetBody(), findFile, &file );
01636 
01637             // cerr << endl << "After Split" << endl;
01638             // xmlElemDump(stderr, NULL, sequence);
01639             // cerr << endl;
01640 
01641             // Add before the scene returned
01642             sequence = xmlAddPrevSibling( file.sequence, ptr );
01643         }
01644         else
01645         {
01646             // cerr << "Inserting after " << before << endl;
01647             sequence = xmlAddNextSibling( sequence, ptr );
01648         }
01649 
01650         // We're definitely no longer first
01651         first = false;
01652     }
01653 
01654     RefreshCount( );
01655     return true;
01656 }

bool PlayList::IsDirty  )  const
 

Returns the current setting of the dirty flag.

Returns:
true if the playlist is dirty

Definition at line 2209 of file playlist.cc.

References dirty.

Referenced by EditorBackup::Redo(), EditorBackup::Store(), and EditorBackup::Undo().

02210 {
02211     return dirty;
02212 }

bool PlayList::IsFileUsed string  filename  )  const
 

Checks if the filename exists in the current playlist.

Parameters:
filename file name to search for
Returns:
true if file exists

Definition at line 2199 of file playlist.cc.

References checkIfFileUsed(), GetBody(), and parse().

Referenced by KinoFileMap::GetUnusedFxFiles().

02200 {
02201     return parse( GetBody(), checkIfFileUsed, &filename );
02202 }

bool PlayList::JoinScenesAt int  frameNum  ) 
 

Definition at line 1310 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, dirty, findSceneEnd(), findSceneStart(), GetBody(), GetNumFrames(), parse(), RefreshCount(), and MovieInfo::sequence.

01311 {
01312     MovieInfo scene1;
01313     MovieInfo scene2;
01314     MovieInfo scene2end;
01315 
01316     if ( GetNumFrames() == 0 )
01317         return false;
01318 
01319     // cerr << "PlayList::JoinScenesAt(int frameNum=" << frameNum << ")" << endl;
01320 
01321     memset( &scene1, 0, sizeof( MovieInfo ) );
01322     scene1.absBegin = 0;
01323     scene1.absEnd = 0;
01324     scene1.absFrame = frameNum;
01325     parse( GetBody(), findSceneStart, &scene1 );
01326 
01327     memset( &scene2, 0, sizeof( MovieInfo ) );
01328     scene2.absBegin = 0;
01329     scene2.absEnd = 0;
01330     scene2.absFrame = frameNum;
01331     parse( GetBody(), findSceneEnd, &scene2 );
01332     int end = scene2.absEnd + 1;
01333 
01334     memset( &scene2end, 0, sizeof( MovieInfo ) );
01335     scene2end.absBegin = 0;
01336     scene2end.absEnd = 0;
01337     scene2end.absFrame = end;
01338     parse( GetBody(), findSceneEnd, &scene2end );
01339 
01340     if ( scene1.sequence != scene2end.sequence )
01341     {
01342 
01343         dirty = true;
01344 
01345         // cerr << ">>>> Joining scene at " << scene1.absBegin << " with scene at "
01346         // << scene2.absBegin << " which ends at " << scene2end.absEnd << endl;
01347 
01348         // concatenate the contents of scene2 into scene1
01349         xmlNode *lastchild = xmlGetLastChild( scene1.sequence );
01350         xmlNodePtr next = NULL;
01351         for ( xmlNodePtr ptr = scene2end.sequence->children; ptr != NULL; ptr = next )
01352         {
01353             next = ptr->next;
01354             lastchild = xmlAddNextSibling( lastchild, ptr );
01355             ptr = next;
01356         }
01357         // Merge the metadata properties
01358         for ( xmlAttr* attr = scene2end.sequence->properties; attr; attr = attr->next )
01359         {
01360             const char *valueB = ( const char* ) xmlGetProp( attr->parent, ( const xmlChar * ) attr->name );
01361             // Only if the value is meaningful
01362             if ( valueB && strcmp( valueB, "" ) )
01363             {
01364                 // See if the property exists on clip A
01365                 const char *valueA = ( const char* ) xmlGetProp( scene1.sequence, ( const xmlChar * ) attr->name );
01366                 if ( valueA && strcmp( valueA, "" ) )
01367                 {
01368                     xmlChar* value = new xmlChar[ strlen(valueA) + strlen(valueB) + 1 ];
01369                     strcpy( (char*) value, (const char*) valueA );
01370                     strcat( (char*) value, " " );
01371                     strcat( (char*) value, (const char*) valueB );
01372                     xmlSetProp( scene1.sequence, attr->name, ( const xmlChar * ) value );
01373                     delete[] value;
01374                 }
01375                 else
01376                 {
01377                     xmlSetProp( scene1.sequence, attr->name, ( const xmlChar * ) valueB );
01378                 }
01379             }
01380         }
01381         xmlUnlinkNode( scene2end.sequence );
01382         xmlFreeNode( scene2end.sequence );
01383         RefreshCount( );
01384 
01385         return true;
01386     }
01387     else
01388     {
01389         return false;
01390     }
01391 }

bool PlayList::LoadMediaObject char *  filename  ) 
 

Definition at line 1798 of file playlist.cc.

References AutoSplit(), dirty, directory_utils::get_absolute_path_to_file(), GetBody(), GetFileMap(), GetNumFrames(), FileHandler::GetTotalFrames(), FileHandler::Open(), and RefreshCount().

Referenced by PageTrim::loadFile(), KinoCommon::loadMediaObject(), and PageMagick::StartRender().

01799 {
01800     // cerr << "bool PlayList::LoadAVI(" << filename << ")" << endl;
01801 
01802     xmlNodePtr  seq;
01803     xmlNodePtr  node;
01804     ostringstream   sb;
01805     FileHandler *mediaFile = NULL;
01806     int existingFrames;
01807     int framesInFile;
01808 
01809     dirty = true;
01810 
01811     // This object should be located in a directory relative to cwd or absolute
01812     string index = directory_utils::get_absolute_path_to_file( "", ( char * ) filename );
01813     if ( GetFileMap() ->GetMap().find( index ) == GetFileMap() ->GetMap().end( ) )
01814     {
01815         if ( strrchr( filename, '.' ) )
01816         {
01817             if ( strncasecmp( strrchr( filename, '.' ), ".avi", 4 ) == 0 )
01818                 mediaFile = new AVIHandler();
01819             else if ( strncasecmp( strrchr( filename, '.' ), ".dv", 3 ) == 0 ||
01820                     strncasecmp( strrchr( filename, '.' ), ".dif", 4 ) == 0 )
01821                 mediaFile = new RawHandler();
01822 #ifdef HAVE_LIBQUICKTIME
01823             else if ( strncasecmp( strrchr( filename, '.' ), ".mov", 4 ) == 0 )
01824                 mediaFile = new QtHandler();
01825 #endif
01826         }
01827 
01828         if ( mediaFile == NULL )
01829             return false;
01830         if ( mediaFile->Open( filename ) == false )
01831             return false;
01832         GetFileMap() ->GetMap() [ index ] = mediaFile;
01833     }
01834     else
01835     {
01836         mediaFile = GetFileMap() ->GetMap() [ index ];
01837     }
01838 
01839     framesInFile = mediaFile->GetTotalFrames();
01840     existingFrames = GetNumFrames();
01841 
01842     seq = xmlNewNode( NULL, ( const xmlChar* ) "seq" );
01843     xmlAddChild( GetBody(), seq );
01844     node = xmlNewNode( NULL, ( const xmlChar* ) "video" );
01845     xmlNewProp( node, ( const xmlChar* ) "src", ( const xmlChar* ) index.c_str() );
01846     xmlNewProp( node, ( const xmlChar* ) "clipBegin", ( const xmlChar* ) "0" );
01847     sb << framesInFile - 1 << ends;
01848     xmlNewProp( node, ( const xmlChar* ) "clipEnd", ( const xmlChar* ) sb.str().c_str() );
01849     xmlAddChild( seq, node );
01850 
01851     if ( framesInFile > 0 )
01852     {
01853         RefreshCount( );
01854         AutoSplit( existingFrames, existingFrames + framesInFile - 1 );
01855     }
01856     return true;
01857 }

bool PlayList::LoadPlayList char *  filename  ) 
 

Definition at line 1860 of file playlist.cc.

References CleanPlayList(), convertSmilTimeToFrames(), dirty, doc, fillMap(), directory_utils::get_directory_from_file(), GetBody(), parse(), RefreshCount(), and SMIL20_NAMESPACE_HREF.

Referenced by GetLastCleanPlayList(), kino2raw(), KinoCommon::loadPlayList(), and EditorBackup::Restore().

01861 {
01862     // cerr << "bool PlayList::LoadPlayList(" << filename << ")" << endl;
01863 
01864     dirty = false;
01865 
01866     xmlNsPtr ns;
01867     xmlNodePtr node;
01868 
01869     xmlFreeDoc( doc );
01870     doc = xmlParseFile( filename );
01871     if ( !doc )
01872     {
01873         cerr << "file does not exist or failed to parse XML" << endl;
01874         return false;
01875     }
01876 
01877     node = xmlDocGetRootElement( doc );
01878     if ( node == NULL )
01879     {
01880         cerr << "empty document" << endl;
01881         xmlFreeDoc( doc );
01882         doc = NULL;
01883         return false;
01884     }
01885     ns = xmlSearchNsByHref( doc, node, SMIL20_NAMESPACE_HREF );
01886     if ( ns == NULL )
01887     {
01888         cerr << "document of the wrong type, Namespace not found" << endl;
01889         xmlFreeDoc( doc );
01890         doc = NULL;
01891         return false;
01892     }
01893     if ( xmlStrcmp( node->name, ( const xmlChar * ) "smil" ) )
01894     {
01895         cerr << "document of the wrong type, root node != smil" << endl;
01896         xmlFreeDoc( doc );
01897         doc = NULL;
01898         return false;
01899     }
01900     CleanPlayList( node );
01901 
01902     // PASS PATH
01903     string path = directory_utils::get_directory_from_file( filename );
01904     parse( GetBody(), fillMap, &path );
01905     dirty = false;
01906 
01907     // Legacy documents have smil2 namespace prefix declaration
01908     if ( xmlSearchNs( doc, node, ( const xmlChar * ) "smil2" ) == NULL )
01909     {
01910         // New age compliant documents use SMIL time values, but we continue
01911         // to use frame numbers internally.
01912         parse( node, convertSmilTimeToFrames, NULL );
01913     }
01914     else
01915     {
01916         // We need to insert a body element into the legacy document
01917         xmlNodePtr root = xmlDocGetRootElement( doc );
01918         xmlNodePtr seq = root->children;
01919         if ( !seq )
01920             return false;
01921         if ( xmlStrcmp( seq->name, ( const xmlChar* ) "seq" ) == 0 )
01922         {
01923             xmlNodePtr body = xmlNewNode( NULL, ( const xmlChar * ) "body" );
01924             while ( seq )
01925             {
01926                 xmlNodePtr next = seq->next;
01927                 xmlUnlinkNode( seq );
01928                 xmlAddChild( body, seq );
01929                 seq = next;
01930             }
01931             xmlAddChild( root, body );
01932         }
01933         dirty = true;
01934     }
01935 
01936     RefreshCount( );
01937 
01938     return true;
01939 }

PlayList & PlayList::operator= const PlayList  ) 
 

Assignment Operator.

Definition at line 915 of file playlist.cc.

References clone(), dirty, doc, doc_name, GetBody(), GetDocName(), parse(), RefreshCount(), and SMIL20_NAMESPACE_HREF.

00916 {
00917     // cerr << "*PlayList::operator=(const PlayList& playList)" << endl;
00918 
00919     if ( doc != playList.doc )
00920     {
00921         xmlNsPtr    ns;
00922         xmlNodePtr  root;
00923 
00924         xmlFreeDoc( doc );
00925         doc = xmlNewDoc( ( const xmlChar* ) "1.0" );
00926         root = xmlNewNode( NULL, ( const xmlChar* ) "smil" );
00927         ns = xmlNewNs( root, ( const xmlChar* ) SMIL20_NAMESPACE_HREF, ( const xmlChar* ) NULL );
00928         xmlDocSetRootElement( doc, root );
00929         parse( playList.GetBody(), clone, &root );
00930         dirty = playList.dirty;
00931         doc_name = playList.GetDocName( );
00932         RefreshCount( );
00933     }
00934     return *this;
00935 }

void PlayList::RefreshCount  )  [private]
 

Definition at line 961 of file playlist.cc.

References count, countFrames(), doc, GetBody(), and parse().

Referenced by CleanPlayList(), Delete(), GetPlayList(), InsertPlayList(), JoinScenesAt(), LoadMediaObject(), LoadPlayList(), operator=(), PlayList(), SetClipBegin(), and SetClipEnd().

00962 {
00963     count = 0;
00964     if ( doc != NULL )
00965         parse( GetBody(), countFrames, &count );
00966 }

bool PlayList::SavePlayList char *  filename,
bool  isLegacyFormat = false
 

Definition at line 1964 of file playlist.cc.

References clone(), convertFramesToSmilTime(), dirty, doc_name, directory_utils::get_directory_from_file(), GetEditorBackup(), Preferences::getInstance(), parse(), relativeMap(), and SMIL20_NAMESPACE_HREF.

Referenced by ExportPipe::doExport(), and KinoCommon::publishPlayList().

01965 {
01966     // Try to save file
01967     bool ret = false;
01968     // Copy the xml doc
01969     xmlDocPtr copy_doc = xmlNewDoc( ( const xmlChar* ) "1.0" );
01970     xmlNodePtr root = xmlNewNode( NULL, ( const xmlChar* ) "smil" );
01971     xmlNewNs( root, ( const xmlChar* ) SMIL20_NAMESPACE_HREF, ( const xmlChar* ) NULL );
01972     xmlDocSetRootElement( copy_doc, root );
01973 
01974     if ( isLegacyFormat )
01975     {
01976         // Clone without body
01977         parse( this->GetBody()->children, clone, &root );   
01978 
01979         // Add legacy namespace declaration
01980         xmlNewNs( xmlDocGetRootElement( copy_doc ), SMIL20_NAMESPACE_HREF, ( const xmlChar* ) "smil2" );
01981     }
01982     else
01983     {
01984         // Clone including body
01985         parse( this->GetBody(), clone, &root );
01986 
01987         // Convert frame numbers used internally to SMIL time values.
01988         parse( copy_doc->children, convertFramesToSmilTime, NULL );
01989     }
01990 
01991     if ( Preferences::getInstance().relativeSave )
01992     {
01993         // Obtain path relative to filenames directory
01994         string path = directory_utils::get_directory_from_file( filename );
01995         // Convert the copy to relative
01996         parse( copy_doc->children, relativeMap, &path );
01997         // Save the copy
01998         ret = xmlSaveFormatFile( filename, copy_doc, 1 ) != -1;
01999     }
02000     else
02001     {
02002         // Can save directly
02003         ret = xmlSaveFormatFile( filename, copy_doc, 1 ) != -1;
02004     }
02005     // Delete the copy
02006     xmlFreeDoc( copy_doc );
02007 
02008     // If saved...
02009     if ( !isLegacyFormat && ret )
02010     {
02011         // ... and doc name is unspecified, we have now and we're not dirty any more
02012         // though all undos are dirty
02013         if ( doc_name == "" )
02014         {
02015             doc_name = string( filename );
02016             dirty = false;
02017             GetEditorBackup( ) ->SetAllDirty( );
02018         }
02019         // ... and doc name is the same as file name then we're not dirty any more any more
02020         // though all undos are dirty
02021         else if ( !strcmp( filename, doc_name.c_str() ) )
02022         {
02023             dirty = false;
02024             GetEditorBackup( ) ->SetAllDirty( );
02025         }
02026         // ... otherwise we're still dirty - undos stay the same
02027     }
02028 
02029     return ret;
02030 }

bool PlayList::SavePlayListEli char *  filename,
bool  isPAL
 

Save a playlist en mjpegtools ELI format.

Returns a subset of the frames as a playlist. The parameters first and last must be within the available frames in the playlist.

Parameters:
first number of first frame
last number of last frame
Returns:
true if the frames could be copied, false otherwise

Definition at line 2042 of file playlist.cc.

References convertEli(), count, doc, GetBody(), and parse().

02043 {
02044     EliInfos eli;
02045     if ( doc != NULL )
02046     {
02047         parse( GetBody(), convertEli, &eli );
02048     }
02049 
02050     /* Open a file */
02051     ofstream eli_file( filename );
02052     if ( !eli_file )
02053     {
02054         return false;
02055     }
02056 
02057     eli_file << "LAV Edit List" << endl;
02058     eli_file << ( isPAL ? "PAL" : "NTSC" ) << endl;
02059 
02060     /* The number of clips */
02061     eli_file << eli.size() << endl;
02062 
02063     /* Now, all the clips, without numbers  */
02064     EliInfosIterator End = eli.end();
02065     EliInfosIterator i;
02066     for ( i = eli.begin(); i != End; i++ )
02067     {
02068         eli_file << ( *i ).file << endl;
02069     }
02070 
02071     /* Now, number \s begin \s end\n */
02072     int count = 0;
02073     for ( i = eli.begin(); i != End; i++ )
02074     {
02075         eli_file << count
02076         << " " << ( *i ).clipBegin
02077         << " " << ( *i ).clipEnd << endl;
02078         ++count;
02079     }
02080 
02081     /* Check the final status */
02082     if ( eli_file.bad() )
02083     {
02084         return false;
02085     }
02086 
02087     /* We are done */
02088     eli_file.close();
02089 
02090     return true;
02091 }

bool PlayList::SavePlayListSrt const char *  filename  ) 
 

Definition at line 2094 of file playlist.cc.

References convertSrt(), doc, SrtContext::file, GetBody(), and parse().

02095 {
02096     SrtContext srt( filename );
02097 
02098     /* Open a file */
02099     if ( !srt.file )
02100     {
02101         return false;
02102     }
02103     if ( doc )
02104     {
02105         parse( GetBody(), convertSrt, &srt );
02106     }
02107     
02108     return !srt.file.bad();
02109 }

bool PlayList::SetClipBegin int  frameNum,
const char *  value
 

Definition at line 1091 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, findSceneStart(), GetBody(), parse(), RefreshCount(), and MovieInfo::video.

Referenced by PageTrim::loadScene().

01092 {
01093     MovieInfo data;
01094 
01095     memset( &data, 0, sizeof( MovieInfo ) );
01096     data.absBegin = 0;
01097     data.absEnd = 0;
01098     data.absFrame = frameNum;
01099 
01100     if ( parse( GetBody(), findSceneStart, &data ) )
01101     {
01102         xmlSetProp( data.video, ( const xmlChar * ) "clipBegin", ( const xmlChar * ) value );
01103         RefreshCount( );
01104         return true;
01105     }
01106     else
01107         return false;
01108 }

bool PlayList::SetClipEnd int  frameNum,
const char *  value
 

Definition at line 1111 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, findSceneEnd(), GetBody(), parse(), RefreshCount(), and MovieInfo::video.

Referenced by PageTrim::loadScene().

01112 {
01113     MovieInfo data;
01114 
01115     memset( &data, 0, sizeof( MovieInfo ) );
01116     data.absBegin = 0;
01117     data.absEnd = 0;
01118     data.absFrame = frameNum;
01119 
01120     if ( parse( GetBody(), findSceneEnd, &data ) )
01121     {
01122         xmlSetProp( data.video, ( const xmlChar * ) "clipEnd", ( const xmlChar * ) value );
01123         RefreshCount( );
01124         return true;
01125     }
01126     else
01127         return false;
01128 }

void PlayList::SetDirty bool  value  ) 
 

Sets the dirty flag on the playlist.

Parameters:
value value of dirty flag

Definition at line 2219 of file playlist.cc.

References dirty.

Referenced by PageEditor::CopyFrames(), EditorBackup::Redo(), EditorBackup::Store(), and EditorBackup::Undo().

02220 {
02221     dirty = value;
02222 }

bool PlayList::SetDocId const char *  value  ) 
 

Definition at line 2319 of file playlist.cc.

References dirty, and GetBody().

02320 {
02321     if ( GetBody() )
02322     {
02323         xmlSetProp( GetBody(), ( const xmlChar * ) "id", ( const xmlChar * ) value );
02324         dirty = true;
02325         return true;
02326     }
02327     return false;
02328 }

void PlayList::SetDocName string  m_doc_name  ) 
 

Protected set doc name method.

The playlist class uses the first file name of load or save, so operations like save as shouldn't trigger this method.

Parameters:
m_doc_name doc name to use

Definition at line 2245 of file playlist.cc.

References doc_name.

Referenced by PageEditor::CopyFrames(), and KinoCommon::savePlayListAs().

02246 {
02247     doc_name = m_doc_name;
02248 }

bool PlayList::SetDocTitle const char *  value  ) 
 

Definition at line 2343 of file playlist.cc.

References dirty, and GetBody().

02344 {
02345     if ( GetBody() )
02346     {
02347         xmlSetProp( GetBody(), ( const xmlChar * ) "title", ( const xmlChar * ) value );
02348         dirty = true;
02349         return true;
02350     }
02351     return false;
02352 }

bool PlayList::SetSeqAttribute int  frameNum,
const char *  ,
const char * 
 

Definition at line 2300 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, dirty, findSceneStart(), GetBody(), parse(), and MovieInfo::sequence.

02301 {
02302     MovieInfo data;
02303 
02304     memset( &data, 0, sizeof( MovieInfo ) );
02305     data.absBegin = 0;
02306     data.absEnd = 0;
02307     data.absFrame = frameNum;
02308 
02309     if ( parse( GetBody(), findSceneStart, &data ) && data.sequence )
02310     {
02311         xmlSetProp( data.sequence, ( const xmlChar * ) name, ( const xmlChar * ) value );
02312         dirty = true;
02313         return true;
02314     }
02315     return false;
02316 }

bool PlayList::SplitSceneBefore int  frameNum  ) 
 

Definition at line 1263 of file playlist.cc.

References MovieInfo::absBegin, MovieInfo::absEnd, MovieInfo::absFrame, Delete(), dirty, MovieInfo::fileName, findSceneEnd(), findSceneStart(), GetBody(), GetNumFrames(), GetPlayList(), parse(), and MovieInfo::sequence.

Referenced by AutoSplit(), Delete(), and InsertPlayList().

01264 {
01265     MovieInfo data;
01266 
01267     // cerr << "PlayList::SplitSceneBefore(int frameNum=" << frameNum << ")" << endl;
01268 
01269     if ( GetNumFrames() == 0 )
01270         return false;
01271 
01272     memset( &data, 0, sizeof( MovieInfo ) );
01273     data.absBegin = 0;
01274     data.absEnd = 0;
01275     data.absFrame = frameNum;
01276     parse( GetBody(), findSceneStart, &data );
01277     int begin = data.absBegin;
01278 
01279     memset( &data, 0, sizeof( MovieInfo ) );
01280     data.absBegin = 0;
01281     data.absEnd = 0;
01282     data.absFrame = frameNum;
01283     parse( GetBody(), findSceneEnd, &data );
01284     int end = data.absEnd;
01285 
01286     if ( strcmp( data.fileName, "" ) && begin != frameNum )
01287     {
01288 
01289         dirty = true;
01290 
01291         // Copy the right hand side of the current scene
01292         xmlNode *firstSequence = data.sequence;
01293         PlayList playlist;
01294         GetPlayList( frameNum, end, playlist );
01295 
01296         // Paste it after the current scene
01297         xmlAddNextSibling( firstSequence, playlist.GetBody()->children );
01298 
01299         // in the first sequence, delete from frameNum to end of scene
01300         Delete( frameNum, end );
01301 
01302         return true;
01303     }
01304     else
01305     {
01306         return false;
01307     }
01308 }


Member Data Documentation

int PlayList::count [private]
 

Definition at line 101 of file playlist.h.

Referenced by GetNumFrames(), RefreshCount(), and SavePlayListEli().

bool PlayList::dirty [protected]
 

Definition at line 94 of file playlist.h.

Referenced by CleanPlayList(), Delete(), GetPlayList(), InsertPlayList(), IsDirty(), JoinScenesAt(), LoadMediaObject(), LoadPlayList(), operator=(), PlayList(), SavePlayList(), SetDirty(), SetDocId(), SetDocTitle(), SetSeqAttribute(), and SplitSceneBefore().

xmlDocPtr PlayList::doc [private]
 

Definition at line 100 of file playlist.h.

Referenced by GetBody(), LoadPlayList(), operator=(), PlayList(), RefreshCount(), SavePlayListEli(), SavePlayListSrt(), and ~PlayList().

string PlayList::doc_name [private]
 

Definition at line 99 of file playlist.h.

Referenced by CleanPlayList(), GetDocName(), GetLastCleanPlayList(), InsertPlayList(), operator=(), PlayList(), SavePlayList(), and SetDocName().

SMIL::MediaClippingTime PlayList::time [private]
 

Definition at line 102 of file playlist.h.


The documentation for this class was generated from the following files:
Generated on Sun Mar 11 22:13:22 2007 for Kino by  doxygen 1.4.2