draft adding clips and simple editing operations

WIP: lots of tests, no implementation, doesn't compile...
This commit is contained in:
Fischlurch 2007-09-25 23:39:46 +02:00
parent 38b47b7f93
commit 3fdd16ff48
21 changed files with 867 additions and 32 deletions

View file

@ -65,6 +65,7 @@ namespace backend_interface
* of the file refered by FileHandle.
* @return ChanDesc which may contain \c NULL values if
* the file doesn't contain this much channels.
* @todo throw or return NULL-ChanDesc if Filehandle is invalid?
*/
virtual ChanDesc queryChannel (FileHandle, uint chanNo) throw();

View file

@ -203,7 +203,14 @@ namespace test
std::cout << "TEST \""<<key<<"\" "<<key<<" <<END\n";
Launcher* test = (i->second);
VALID (test, i->first);
(*test)()->run(noCmdline); // run it to insert test generated output
try
{
(*test)()->run(noCmdline); // run it to insert test generated output
}
catch (...)
{
std::cout << "PLANNED ============= " << cinelerra_error() << "\n";
}
std::cout << "END\n";
}
}

View file

@ -24,8 +24,10 @@
#ifndef UTIL_HPP_
#define UTIL_HPP_
#include <set>
#include <string>
#include <cstring>
#include <algorithm>
#include "nobugcfg.h" ///////////////////TODO: just temporarily!!!!
@ -59,7 +61,6 @@ namespace util
return !pContainer || pContainer->empty();
}
template <>
inline bool
isnil (const char* pCStr)
{
@ -83,6 +84,24 @@ namespace util
return map.find(key) != map.end();
}
/** shortcut for set value containment test */
template <typename T>
inline bool
contains (std::set<T>& set, const T& val)
{
return set.end() != set.find (val);
}
/** shortcut for brute-force containment test
* in any sequencial container */
template <typename SEQ>
inline bool
contains (SEQ& cont, typename SEQ::value_type& val)
{
SEQ::iterator end = cont.end();
return end != std::find(cont.begin(),end, val);
}
/** shortcut for operating on all elements of a container.
* Isn't this already defined somewhere? It's so obvious..

View file

@ -25,6 +25,7 @@
#include "proc/asset/media.hpp"
#include "proc/asset/clip.hpp"
#include "proc/asset/unknown.hpp"
#include "proc/mobject/session/clip.hpp"
#include "common/util.hpp"
#include "nobugcfg.h"
@ -58,7 +59,34 @@ namespace asset
}
}
typedef shared_ptr<mobject::session::Clip> PClip;
typedef shared_ptr<asset::ProcPatt> PProcPatt;
PClip
Media::createClip ()
{
UNIMPLEMENTED ("create clip from media asset");
PClip clip; //TODO:null
ENSURE (clip);
return clip;
}
PProcPatt
Media::howtoProc ()
{
UNIMPLEMENTED ("calculate and return processing pattern for media asset");
PProcPatt ppatt; //TODO:null
ENSURE (ppatt);
return ppatt;
}
MediaFactory Media::create; ///< storage for the static MediaFactory instance

View file

@ -40,9 +40,12 @@
class mobject::session::Clip;
namespace asset
{
class Clip;
class Media;
class MediaFactory;
@ -73,6 +76,9 @@ namespace asset
return static_cast<const ID<Media>& > (Asset::getID());
}
shared_ptr<mobject::session::Clip> createClip ();
shared_ptr<asset::ProcPatt> howtoProc ();
protected:
Media (const Asset::Ident& idi, const string& file) : Asset(idi), filename_(file) {}
friend class MediaFactory;

View file

@ -5,6 +5,10 @@ TESTING "Proc Layer combined operations Test Suite" ./test-components --group=op
TEST "MediaAccessMock_test" MediaAccessMock_test <<END
out: accessing "test-1" ...
out: Channel-0: nameID=video codecID=ID
out: accessing "test-2" ...
out: Channel-0: nameID=video codecID=H264
out: Channel-1: nameID=audio-L codecID=PCM
out: Channel-2: nameID=audio-R codecID=PCM
END

View file

@ -0,0 +1,125 @@
/*
MediaAccessMock.hpp - a test (stub) target object for testing the factories
Copyright (C) CinelerraCV
2007, Christian Thaeter <ct@pipapo.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
/** @file mediaacessmock.cpp
** Mock implementation of the Interface normally used to query media file
** informations from the data backend. The Mock implementation instead holds
** a map of fixed response which will be deliverd when querying some magic
** filenames.
**
** @see mediaaccessmocktest.cpp validating the Mock
** @see MediaAccessFactory the real thing
**
*/
#include "backend/mediaaccessmock.hpp"
#include "common/util.hpp"
#include "nobugcfg.h"
#include <iostream>
#include <vector>
#include <map>
using cinelerra::error::Invalid;
using util::for_each;
using util::isnil;
using std::cout;
using std::string;
using std::vector;
using std::map;
namespace backend_interface
{
namespace test
{
typedef MediaAccessFacade::FileHandle FileHandle;
typedef MediaAccessFacade::ChanHandle ChanHandle;
namespace // implementation deatils
{
typedef vector<ChanDesc> Response;
const ChanDesc NULLResponse;
struct TestCases : map<string,Response>
{
TestCases ()
{
// ------------------------------------------------------------------TESTCASES
(*this)["test-1"].push_back (ChanDesc ("video","ID", genH()));
(*this)["test-2"].push_back (ChanDesc ("video","H264", genH()));
(*this)["test-2"].push_back (ChanDesc ("audio-L","PCM", genH()));
(*this)["test-2"].push_back (ChanDesc ("audio-R","PCM", genH()));
// ------------------------------------------------------------------TESTCASES
}
bool known (string key)
{
const_iterator i = find (key);
return (i != end());
}
private:
int _i_;
ChanHandle genH()
{
return reinterpret_cast<ChanHandle> (++_i_);
}
};
// instantiate TestCasses table
TestCases testCases;
} // (end) implementation namespace
FileHandle
MediaAccessMock::queryFile (const char* name) throw(Invalid)
{
if (isnil (name))
throw Invalid ("empty filename passed to MediaAccessFacade.");
if (!testCases.known(name))
return 0;
else
return reinterpret_cast<void*> (&testCases[name]);
}
ChanDesc
MediaAccessMock::queryChannel (FileHandle h, uint chanNo) throw()
{
const Response* res (reinterpret_cast<Response*> (h));
if (!res || res->size() <= chanNo)
return NULLResponse;
else
return (*res)[chanNo];
}
} // namespace test
} // namespace backend_interface

View file

@ -0,0 +1,52 @@
/*
MEDIAACCESSMOCK.hpp - a test (stub) target object for testing the factories
Copyright (C) CinelerraCV
2007, Christian Thaeter <ct@pipapo.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef BACKEND_TEST_MEDIAACCESSMOCK_H
#define BACKEND_TEST_MEDIAACCESSMOCK_H
#include "backend/mediaaccessfacade.hpp"
namespace backend_interface
{
namespace test
{
/**
* Mock implementation of the MediaAccessFacade.
* Provides preconfigured responses for some Test-Filenames.
*/
class MediaAccessMock : public MediaAccessFacade
{
public:
FileHandle queryFile (const char* name) throw(cinelerra::error::Invalid);
ChanDesc queryChannel (FileHandle, uint chanNo) throw();
};
} // namespace test
} // namespace backend_interface
#endif

View file

@ -0,0 +1,103 @@
/*
MediaAccessMock(Test) - checking our Test Mock replacing the MediaAccessFacade
Copyright (C) CinelerraCV
2007, Christian Thaeter <ct@pipapo.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "backend/mediaaccessfacade.hpp"
#include "backend/mediaaccessmock.hpp"
#include "common/test/run.hpp"
//#include "common/util.hpp"
#include "nobugcfg.h"
//#include <boost/format.hpp>
#include <iostream>
//using boost::format;
//using util::isnil;
using std::string;
using std::cout;
namespace backend_interface
{
namespace test
{
/********************************************************************************
* @test inject a Mock object replacing the backend_interface::MediaAccessFacade.
* Verify if the Mock object behaves as expected when calling the Facade.
*/
class MediaAccessMock_test : public Test
{
typedef MediaAccessFacade MAF;
virtual void run(Arg arg)
{
MAF::instance.injectSubclass (new MediaAccessMock);
queryScenario ("test-1");
queryScenario ("test-2");
MAF::instance.injectSubclass (0);
}
/** perform the test: query for an (alledged) file
* and retrieve the mock answer.
*/
void queryScenario (string filename)
{
MAF& maf (MAF::instance());
MAF::FileHandle fhandle = maf.queryFile (filename.c_str());
if (!fhandle)
cout << "File \""<<filename<<"\" not accessible\n";
else
{
cout << "accessing \""<<filename<<"\" ...\n";
for (int i=0; true; ++i)
{
ChanDesc chan = maf.queryChannel (fhandle, i);
if (!chan.handle) break;
cout << " Channel-" << i
<< ": nameID=" << chan.chanID
<< " codecID=" << chan.codecID
<< "\n";
} } }
};
/** Register this test class... */
LAUNCHER (MediaAccessMock_test, "unit operate");
} // namespace test
} // namespace backend_interface

View file

@ -107,6 +107,7 @@ namespace asset
NOTREACHED;
}
catch (cinelerra::error::Invalid& xxx) {ASSERT (xxx.getID()==CINELERRA_ERROR_UNKNOWN_ASSET_ID);}
cinelerra_error (); // reset errorflag
// checking the Ident-Fields

View file

@ -0,0 +1,96 @@
/*
MakeClip(Test) - create a Clip from a Media Asset
Copyright (C) CinelerraCV
2007, Christian Thaeter <ct@pipapo.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "common/test/run.hpp"
#include "common/util.hpp"
#include "proc/assetmanager.hpp"
#include "proc/asset/media.hpp"
#include "proc/mobject/session/clip.hpp"
//#include "proc/asset/assetdiagnostics.hpp"
using util::contains;
using util::isnil;
using std::string;
namespace asset
{
namespace test
{
/***********************************************************************
* @test creating a Clip MObject and an associated Clip Asset from
* a given asset::Media.
* @see asset::Media#createClip
*/
class MakeClip_test : public Test
{
typedef shared_ptr<asset::Media> PM;
typedef shared_ptr<mobject::session::Clip> PC;
virtual void run (Arg arg)
{
PM mm = asset::Media::create("test-1", VIDEO);
PC cc = mm->createClip();
PM cm = cc->getMedia();
ASSERT (cm);
ASSERT (0 < cc->length);
ASSERT (cm->ident.category.hasKind (VIDEO));
ASSERT (cm->getFilename() == mm->getFilename());
ASSERT (cm->howtoProc() == mm->howtoProc());
ASSERT (cm->ident.org == mm->ident.org);
ASSERT (dependencyCheck (mm,cm));
TRACE (assetmem, "leaving MakeClip_test::run()");
TRACE (mobjectmem, "leaving MakeClip_test::run()");
}
bool dependencyCheck (PM media, PM clip)
{
TODO ("check asset dependencies, when this feature is implemented");
return true; //TODO
return (0 < clip->getParents().size())
&& (media == clip->getParents()[0])
&& (contains (media->getDependant(), clip));
;
}
};
/** Register this test class... */
LAUNCHER (MakeClip_test, "function asset");
} // namespace test
} // namespace asset

View file

@ -22,13 +22,15 @@
#include "common/test/run.hpp"
//#include "common/factory.hpp"
//#include "common/util.hpp"
#include "proc/mobject/session/session.hpp"
#include "proc/mobject/session/testclip.hpp"
#include "common/util.hpp"
//#include <boost/format.hpp>
#include <iostream>
//using boost::format;
using util::contains;
using std::string;
using std::cout;
@ -52,6 +54,13 @@ namespace mobject
{
virtual void run(Arg arg)
{
Session& sess = Session::getCurrent();
PMO clip = TestClip::create();
PPla pla = Placement::create(FIXED, Time(1), clip);
sess.add (pla);
ASSERT (contains (sess.getEDL(), pla));
// TODO: Clip-Asset and Placement magic??
}
};

View file

@ -22,7 +22,9 @@
#include "common/test/run.hpp"
//#include "common/factory.hpp"
#include "proc/assetmanager.hpp"
#include "proc/mobject/session/session.hpp"
#include "proc/mobject/session/testsession1.hpp"
//#include "common/util.hpp"
//#include <boost/format.hpp>
@ -52,6 +54,20 @@ namespace mobject
{
virtual void run(Arg arg)
{
buildTestseesion1();
Session& sess = Session::getCurrent();
AssetManager& aMang = AssetManager::instance();
PPla clipPlacement = sess.getEDL().find(SESSION1_CLIP); // global Var asigned in buildTestsession1()
PAsset clipAsset = aMang.getAsset(clipPlacement->subject->getMedia());
IDA clipAID = clipAsset->getID();
ASSERT (clipPlacement);
sess.remove (clipPlacement);
ASSERT (!sess.getEDL().find(SESSION1_CLIP)); // EDL forgot the Clip/Placement
ASSERT (!aMang.known (clipAID)); // corresponding Clip Asset has disappeared
ASSERT (!aMang.getAsset(clipPlacement->subject->getMedia())); // internal cross-links removed
}
};

View file

@ -22,13 +22,18 @@
#include "common/test/run.hpp"
//#include "common/factory.hpp"
//#include "common/util.hpp"
#include "proc/mobject/session/session.hpp"
#include "proc/mobject/session/testsession1.hpp"
#include "common/util.hpp"
//#include <boost/format.hpp>
#include <boost/bind.hpp>
#include <iostream>
//using boost::format;
using boost::bind;
using util::contains;
using util::for_each;
using std::string;
using std::cout;
@ -53,7 +58,26 @@ namespace mobject
{
virtual void run(Arg arg)
{
clearSession();
buildTestseesion1();
Session& sess = Session::getCurrent();
ASSERT (sess.isValid());
sess.rebuildFixture();
TODO ("check the fixture has been touched. e.g. by hash.");
TODO ("query all Placements of all Clips (via AssetManager). Verify explicit plac contained in Fixture.");
for_each (sess.getFixture(),
bind (&check_is_from_EDL, _1, sess.getEDL()));
TODO ("can we check the other direction, from EDL to Fixture??");
}
static void
check_is_from_EDL (PPla explicitPlacement, EDL& edl)
{
PPla originalPlacement = explicitPlacement->subject->placement;
ASSERT (contains(edl, originalPlacement));
}
};

View file

@ -0,0 +1,134 @@
/*
SessionManager(Test) - accessing, loading and saving the Session/EDL
Copyright (C) CinelerraCV
2007, Christian Thaeter <ct@pipapo.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "common/test/run.hpp"
#include "proc/mobject/session/session.hpp"
#include "proc/mobject/session/testsession1.hpp"
//#include "common/util.hpp"
//#include <boost/format.hpp>
#include <iostream>
//using boost::format;
using std::string;
using std::cout;
namespace mobject
{
namespace session
{
namespace test
{
/*******************************************************************************
* Check the session management operations provided by mobject::session::Seesion
* This includes accessing the current Session (somewhat a singleton).
* @todo load a Mock session
* @todo create a session and save (serialize) it
* @todo load a real test session
*/
class SessionManager_test : public Test
{
virtual void run(Arg arg)
{
getCurrentSession ();
clearSession();
loadMockSession();
clearSession();
buildTestseesion1();
string serialized;
saveSession (serialized);
loadSession (serialized);
ASSERT (checkTestsession1());
}
/** @test accessing the current (global) session
*/
void getCurrentSession ()
{
Session& sess = Session::getCurrent();
ASSERT (sess.isValid());
}
/** @test clear current session contents
* without resetting global session config.
* @todo implement all session content, implement
* mobject and asset deletion operations.
*/
void clearSession ()
{
UNIMPLEMENTED ("clear objects in current session");
}
/** @test reset global session config and start with
* a pristine default session.
* @todo define the "global session config", implement session default ctor
*/
void resetSession ()
{
UNIMPLEMENTED ("construct a pristine session");
}
/** @test use a mock session serializer to load
* a preconfigured test session. Verify
* objects are wired correctly.
* @todo implement rebuilding session, implement mock session serializer
*/
void loadMockSession ()
{
UNIMPLEMENTED ("rebuild session using a mock serializer");
}
/** @test load serialized session using the
* real session serializer implementation.
* @param src string with serialized session data
* @todo implement real session serializer
*/
void loadSession (const string& src)
{
UNIMPLEMENTED ("loding real sesion");
}
/** @test serialize (save) the current session
* @param dest string recieving the generated serialized stream
* @todo implement real session serializer
*/
void saveSession (string& dest)
{
UNIMPLEMENTED ("serialize current session");
}
};
/** Register this test class... */
LAUNCHER (SessionManager_test, "function session");
} // namespace test
} // namespace session
} // namespace mobject

View file

@ -0,0 +1,79 @@
/*
SessionStructure(Test) - verifying basic Session/EDL structure
Copyright (C) CinelerraCV
2007, Christian Thaeter <ct@pipapo.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "common/test/run.hpp"
#include "proc/mobject/session/session.hpp"
#include "proc/assetmanager.hpp"
//#include "common/util.hpp"
//#include <boost/format.hpp>
#include <iostream>
//using boost::format;
using std::string;
using std::cout;
namespace mobject
{
namespace session
{
namespace test
{
using proc_interface::AssetManager;
using proc_interface::PAsset;
/*******************************************************************************
* @test access the current session and verify the correct
* structure of the most important components: The session
* contains an EDL, we can get at the Fixture, we have at least
* one Track and the corresponding Track asset is available.
* @todo define further criteria to be checked
* @todo implement EDL, Fixture, Session#rebuildFixture, asset::Track
*/
class SessionStructure_test : public Test
{
virtual void run(Arg arg)
{
Session& sess = Session::getCurrent();
ASSERT (0 <= sess.getEDL().size()); // TODO implement
ASSERT (0 <= sess.getFixture().size()); // TODO implement
ASSERT (0 < sess.getTracks().size()); // TODO implement
PAsset track = sess.getTracks()[0];
AssetManager& aMang = AssetManager::instance();
ASSERT (track == aMang.getAsset (track->getID()));
}
};
/** Register this test class... */
LAUNCHER (SessionStructure_test, "unit session");
} // namespace test
} // namespace session
} // namespace mobject

View file

@ -0,0 +1,63 @@
/*
TestClip - bookkeeping (asset) view of a media clip.
Copyright (C) CinelerraCV
2007, Christian Thaeter <ct@pipapo.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "proc/mobject/session/testclip.hpp"
#include "proc/asset/media.hpp"
#include "proc/asset/clip.hpp"
namespace mobject
{
namespace session
{
namespace test
{
typedef shared_ptr<mobject::session::Clip> PC;
typedef shared_ptr<asset::Media> PM;
typedef MediaAccessFacade MAF;
/** @todo find a way to link to an existing clip object.
* Idea: use the clip's copy operation, i.e. feed it
* to mobject::session::clip copy ctor
*/
TestClip::TestClip ()
{
// install Mock-Interface to cinelerra backend
MAF::instance.injectSubclass (new MediaAccessMock);
PM media = asset::Media::create("test-2", VIDEO); // query magic filename
PC clip = media->createClip();
//TODO how to link to *this ???
MAF::instance.injectSubclass (0); // remove Mock-Interface
}
/** storage for the TestClip-Factory */
TestClip::Factory TestClip::create;
} // namespace test
} // namespace session
} // namespace mobject

View file

@ -41,19 +41,40 @@ namespace mobject
{
namespace session
{
/**
* Sample or Test Clip for checking
* various EDL, session and builder operations.
*
*/
class TestClip
namespace test
{
public:
};
/**
* Sample or Test Clip for checking
* various EDL, session and builder operations.
* Can be used as Mock object to record invoked operations.
*
*/
class TestClip ////TODO inherit from mobject::session::Clip
{
/** smart ptr factory allowed to invoke TestClip's ctor */
struct Factory : cinelerra::Factory<TestClip>
{
typedef shared_ptr<TestClip> PType;
PType operator() () { return PType (new TestClip, &destroy); }
protected:
static void destroy (TestClip* tc) { delete tc; }
};
TestClip ();
friend class Factory;
public:
static Factory create;
};
} // namespace test
} // namespace session
} // namespace mobject

View file

@ -1,5 +1,5 @@
/*
TESTSESSION1.hpp - complete session configuration use for various tests
TESTSESSION1.hpp - complete session configuration used for various tests
Copyright (C) CinelerraCV
2007, Christian Thaeter <ct@pipapo.org>
@ -21,8 +21,8 @@
*/
#ifndef MOBJECT_SESSION_TESTCLIP_H
#define MOBJECT_SESSION_TESTCLIP_H
#ifndef MOBJECT_SESSION_TESTSESSION_H
#define MOBJECT_SESSION_TESTSESSION_H
#include "proc/mobject/session/session.hpp"
@ -42,18 +42,29 @@ namespace mobject
{
namespace session
{
typedef std::auto_ptr<Session> PSession; /////TODO
/**
* Create a Test Session configuration usable for various Tests.
* This Session holds two Clips and corresponds to "Example1"
* in the UML design.
* in the UML design. All changes are done to the (global)
* current session.
*/
PSession Testsession1 ()
void buildTestseesion1 ()
{
UNIMPLEMENTED ("Test-Session 1");
};
/**
* Analyze the current (gloal) Session to verify the
* configuration of "Test-Session 1"
*/
bool checkTestseesion1 ()
{
UNIMPLEMENTED ("Test-Session 1");
return false;
};

View file

@ -1,20 +1,20 @@
window_sizes 1140 783 270 860 633 71
diagrams
classdiagram_ref 130309 // Asset Kinds
860 633 100 4 180 0
classdiagram_ref 128133 // Session structure
688 506 100 4 120 0
active classdiagram_ref 130437 // Media-Asset Relations
860 633 100 4 0 0
active classdiagram_ref 128133 // Session structure
860 633 100 4 341 0
classdiagram_ref 130437 // Media-Asset Relations
860 633 100 4 0 0
classdiagram_ref 128389 // Render Entities
688 506 100 4 120 0
end
show_stereotypes
selected
package_ref 129 // cinelerra3
package_ref 129 // cinelerra3
open
package_ref 128005 // design
package_ref 128005 // design
classview_ref 128901 // Assets
classview_ref 128005 // Session
classview_ref 129029 // Interface

View file

@ -763,6 +763,34 @@ Cinelerra uses this term in a related manner but with a somewhat shifted focus (
In this usage, the EDL is almost synonymous to the ''Session'', just the latter emphasizes more the state aspect, as it can be thought as a current state of the EDL contained in a file or data structure together with additional Option values and settings for the GUI. The Session is what you save and load, while the EDL rather denotes a structure of Objects placed in time.
</pre>
</div>
<div title="EditingOperations" modifier="Ichthyostega" modified="200709251706" created="200709251610" tags="design decision" changecount="2">
<pre>These are the tools provided to any client of the Proc layer for handling and manipulating the entities in the EDL. When defining such operations, //the goal should be to arrive at some uniformity in the way things are done.// Ideally, when writing client code, one should be able to guess how to achieve some desired result.
!guiding principle
The approach taken to define any operation is based primarily on the ''~OO-way of doing things'': entities operate themselfs. You don't advise some manager, session or other &amp;raquo;god class&amp;laquo; to manipulate them. And, secondly, the scope of each operation will be as large as possible, but not larger. This often means performing quite some elementary operations &amp;mdash; sometimes a convenience shortcut provided by the higher levels of the application may come in handy &amp;mdash; and basically this gives rise to several different paths of doing the same thing, all of which need to be equivalent.
!main tasks
* you ''create a clip'' either from a source media or from another clip (copy, maybe clone?). The new clip always reflects the full size (and other properties) of the source used for creating.
* you can request a clip to ''resize'', which always relates to its current dimensions.
* you can ''place or attach'' the clip to some point or other entity by creating a [[Placement]] from the clip.
* you can ''adjust'' a placement relative to some other placement, meta object (i.e. selection), label or media, and this may cause the placement to resize or even delete the clip as necessary
* you can perform ''adjustments'' on the whole EDL.
All these operations propagate to directly dependant objects and may schedule global reconfigurations.
!state, locking, policies
While performing any manipulative task, the state of the object is considered inconsistent, but it is guaranteed to be consistent after any such operation, irrespective of the result. There is no automatic atomicity and, consequently each propagation is considered a separate operation.
!!parallelism
At the level of fine grained operations on individual entities, there is ''no support for parallelism''. Individual entities don't lock themselves. Tasks perform locking and are to be scheduled. Thus, we need an isolation layer towards all inherently multithreaded parts of the system, like the GUI or the renderengine.
This has some obvious and some subtle consequences. Of course, manipulating //tasks// will be queued and scheduled somewhere. But as we rely on object identity and reference semantics for the entities in the EDL, some value changes are visible to operations going on in parallel threads (e.g. rendering) and each operation on the EDL entities //has to be aware of this.//
Consequently, sometimes there needs to be done a ''self-replacement by copy'' followed by manipulation of the new copy, while ongoing processes use the unaltered original object until they receive some sort of reset.
!!undo
Basically, each elementary operation has to record the informations necessary to be undone. It does so by registering a Memento with some central UndoManager facility. This Memento object contains a functor pre-bound with the needed parameter values. (Besides, the UndoManager is free to implement a second level of security by taking independent state snapshots).
{{red{to be defined in more detail later...}}}
</pre>
</div>
<div title="Example1" modifier="Ichthyostega" modified="200706220253" created="200706220239" tags="example" changecount="3">
<pre>The &amp;raquo;Timeline&amp;laquo; is a sequence of ~MObjects -- here clips -- together with an ExplicitPlacement, locating each clip at a given time and track. (Note: I simplified the time format and wrote frame numbers to make it more clear)
[img[Example1: Objects in the EDL/Fixture|uml/fig128773.png]]
@ -951,7 +979,7 @@ For this Cinelerra3 design, we could consider making GOP just another raw media
&amp;rarr;see in [[Wikipedia|http://en.wikipedia.org/wiki/Group_of_pictures]]
</pre>
</div>
<div title="ImplementationDetails" modifier="Ichthyostega" modified="200709200223" created="200708080322" tags="overview" changecount="7">
<div title="ImplementationDetails" modifier="Ichthyostega" modified="200709251549" created="200708080322" tags="overview" changecount="8">
<pre>This wiki page is the entry point to detail notes covering some technical decisions, details and problems encountered in the course of the implementation of the Cinelerra Renderengine, the Builder and the related parts.
* [[Packages, Interfaces and Namespaces|InterfaceNamespaces]]
@ -959,6 +987,7 @@ For this Cinelerra3 design, we could consider making GOP just another raw media
* [[Creating and registering Assets|AssetCreation]]
* [[Creating new Objects|ObjectCreation]]
* [[Multichannel Media|MultichannelMedia]]
* [[Editing Operations|EditingOperations]]
</pre>
</div>
@ -2035,7 +2064,7 @@ DAMAGE.
//Note, we have yet to specify how exactly the building and rendering will work together with the backend. There are several possibilities how to structure the Playlist//
</pre>
</div>
<div title="ProblemsTodo" modifier="Ichthyostega" modified="200709212330" created="200708050524" tags="design discuss" changecount="14">
<div title="ProblemsTodo" modifier="Ichthyostega" modified="200709251721" created="200708050524" tags="design discuss" changecount="15">
<pre>Open issues, Things to be worked out, Problems still to be solved...
!!Parameter Handling
@ -2062,7 +2091,14 @@ Users accustomed with modern GUI applications typically expect that //everything
!!Compound and Multiplicity
Simple relations can be hard wired. But, on the contrary, it would be as naive to define a Clip as having a Video track and two audio tracks, as it would be naive to overlook the problem of holding video and corresponding audio together. And, moreover, the default case has to be processed in a //straight forward// fashion, with as few tests and decisions as possible. So, basically each component participating in getting the core processing done has to mirror the structure pattern of the other parts, so that processing can be done without testing and forking. But this leaves us with the problem where to put the initial knowledge about the structural pattern used for building up the compound structures and &amp;mdash; especially &amp;mdash; the problem how to treat different kinds of structural patterns, how to detect the pattern to be applied and how to treat multiple instances of the same structural pattern.
One example of this problem is the [[handling of multichannel media|MultichannelMedia]]. Following the above reasoning, we end with having a [[&quot;structural processing pattern&quot;|ProcPatt]], typically one video stream with MPEG decoder and a pair of audio streams which need either to be routed to some &quot;left&quot; and &quot;right&quot; output ports, or have to be passed through a panning filter accordingly. Now the problem is: //create a new instance of this structure for each new media, or detect which media to subsume under a existing pattern instance.//</pre>
One example of this problem is the [[handling of multichannel media|MultichannelMedia]]. Following the above reasoning, we end with having a [[&quot;structural processing pattern&quot;|ProcPatt]], typically one video stream with MPEG decoder and a pair of audio streams which need either to be routed to some &quot;left&quot; and &quot;right&quot; output ports, or have to be passed through a panning filter accordingly. Now the problem is: //create a new instance of this structure for each new media, or detect which media to subsume under a existing pattern instance.//
!!Parallelism
We need to work out guidelines for dealing with operations going on simultaneously. Certainly, this will divide the application in several different regions. As always, the primary goal is to avoid multithread problems altogether. Typically, this can be achieved by making matters explicit: externalizing state, make the processing subsystems stateless, queue and schedule tasks, use isolation layers.
* the StateProxy is a key for the individual render processes state, which is managed in separate [[StateFrame]]s in the backend. The [[processing network|ProcNode]] is stateless.
* the [[Fixture]] provides an isolation layer between the renderengine and the Session/EDL
* all EditingOperations are not threadsafe intentionally, because they are [[scheduled|ProcLayerScheduler]]
</pre>
</div>
<div title="ProcAsset" modifier="Ichthyostega" created="200709221343" tags="def classes" changecount="1">
<pre>All Assets of kind asset::Proc represent //processing algorithms// in the bookkeeping view. They enable loading, browsing and maybe even parametrizing all the Effects, Plugins and Codecs available for use within the Cinelerra Session.