outline: use of the raw type info for fetching a ImplFacade
This commit is contained in:
parent
47a416bba3
commit
feb64fac01
9 changed files with 78 additions and 34 deletions
|
|
@ -102,8 +102,7 @@ namespace lumiera {
|
|||
public:
|
||||
Symbol libraryID;
|
||||
|
||||
/** placeholder definition for implementation specific type information */
|
||||
struct TypeTag { };
|
||||
class TypeTag ;
|
||||
|
||||
/** placeholder definition for the contents of a data buffer */
|
||||
struct DataBuffer { };
|
||||
|
|
@ -125,14 +124,15 @@ namespace lumiera {
|
|||
|
||||
|
||||
/**
|
||||
*
|
||||
* Special case of an implementation type being only partialiy specified
|
||||
* Besides requiring some aspect of the implementation type, there is the
|
||||
* promise to fill in defaults to build a complete implementation type
|
||||
* if necessary.
|
||||
*/
|
||||
class StreamType::ImplConstraint
|
||||
: public StreamType::ImplFacade
|
||||
{
|
||||
public:
|
||||
Symbol libraryID;
|
||||
|
||||
virtual bool canConvert (ImplFacade const& other) const =0;
|
||||
virtual bool canConvert (StreamType const& other) const =0;
|
||||
|
||||
|
|
@ -153,6 +153,28 @@ namespace lumiera {
|
|||
//TODO: do we need functions to represent and describe this constraint?
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* opaque placeholder (type erasure)
|
||||
* for implementation specific type info.
|
||||
* Intended to be passed to a concrete
|
||||
* MediaImplLib to build an ImplFacade.
|
||||
*/
|
||||
class StreamType::ImplFacade::TypeTag
|
||||
{
|
||||
void* rawTypeStruct_;
|
||||
|
||||
public:
|
||||
Symbol libraryID;
|
||||
|
||||
template<class TY>
|
||||
TypeTag (Symbol lID, TY& rawType)
|
||||
: rawTypeStruct_(&rawType),
|
||||
libraryID(lID)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
2
src/lib/external/libgavl.cpp
vendored
2
src/lib/external/libgavl.cpp
vendored
|
|
@ -58,7 +58,7 @@ namespace lib {
|
|||
* @todo how to distinguish the audio and the video case?
|
||||
*/
|
||||
ImplFacadeGAVL const&
|
||||
LibGavl::getImplFacade (TypeTag*)
|
||||
LibGavl::getImplFacade (TypeTag&)
|
||||
{
|
||||
TODO ("any chance to verify that the TypeTag actually points to a GAVL frame type descriptor?");
|
||||
UNIMPLEMENTED ("wire up an impl facade with the correct GAVL lib functions for the data type in question");
|
||||
|
|
|
|||
2
src/lib/external/libgavl.hpp
vendored
2
src/lib/external/libgavl.hpp
vendored
|
|
@ -78,7 +78,7 @@ namespace lib {
|
|||
public:
|
||||
virtual Symbol getLibID() const { return "GAVL"; }
|
||||
|
||||
virtual ImplFacadeGAVL const& getImplFacade (TypeTag*);
|
||||
virtual ImplFacadeGAVL const& getImplFacade (TypeTag&);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace control {
|
|||
public:
|
||||
virtual Symbol getLibID() const =0;
|
||||
|
||||
virtual ImplFacade const& getImplFacade (TypeTag*) =0;
|
||||
virtual ImplFacade const& getImplFacade (TypeTag&) =0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ namespace control {
|
|||
|
||||
STypeManager::STypeManager()
|
||||
: reg_(0)
|
||||
{
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ namespace control {
|
|||
lumiera::Appconfig::lifecycle(ON_STREAMTYPES_RESET);
|
||||
}
|
||||
|
||||
/** \par
|
||||
/** \par
|
||||
* LifecycleHook, on which all the basic setup and configuration
|
||||
* providing the pristine state of the stream type system has to be registered.
|
||||
* @note plugins providing additional streamtype configuration should register
|
||||
|
|
@ -63,8 +63,8 @@ namespace control {
|
|||
* the C interface functions
|
||||
*/
|
||||
Symbol ON_STREAMTYPES_RESET ("ON_STREAMTYPES_RESET");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -100,13 +100,11 @@ namespace control {
|
|||
|
||||
|
||||
StreamType::ImplFacade const&
|
||||
STypeManager::getImpl (Symbol libID, StreamType::ImplFacade::TypeTag rawType)
|
||||
STypeManager::fetchImpl (StreamType::ImplFacade::TypeTag rawType)
|
||||
{
|
||||
UNIMPLEMENTED ("STypeManager basic functionality: wire up implementation facade (impl type) from given raw type of the library");
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace control
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ namespace control {
|
|||
public:
|
||||
static lumiera::Singleton<STypeManager> instance;
|
||||
|
||||
typedef StreamType::ImplFacade ImplFacade;
|
||||
|
||||
/** (re)-access a media stream type using
|
||||
* just a symbolic ID. Effectively this queries a default */
|
||||
StreamType const& getType (Symbol sTypeID) ;
|
||||
|
|
@ -55,22 +57,23 @@ namespace control {
|
|||
|
||||
/** build or retrieve a complete StreamType incorporating the given implementation type */
|
||||
StreamType const& getType (StreamType::ImplFacade const& implType) ;
|
||||
|
||||
|
||||
/** build or retrieve an implementation (facade)
|
||||
* utilizing a specific MediaImplLib and implementing the given Prototype.
|
||||
* @todo find out if this one is really necessary, because it is especially tricky */
|
||||
StreamType::ImplFacade const& getImpl (Symbol libID, StreamType::Prototype const& protoType) ;
|
||||
ImplFacade const& getImpl (Symbol libID, StreamType::Prototype const& protoType) ;
|
||||
|
||||
/** build or retrieve an implementation (facade)
|
||||
* wrapping up the actual implementation as designated by the rawType tag,
|
||||
* which needs to be an implementation type of the mentioned MediaImplLib */
|
||||
StreamType::ImplFacade const& getImpl (Symbol libID, StreamType::ImplFacade::TypeTag rawType) ;
|
||||
template<class TY>
|
||||
ImplFacade const& getImpl (Symbol libID, TY& rawType) ;
|
||||
|
||||
|
||||
|
||||
////////////////TODO: design a mechanism allowing to add MediaImplLib implementations by plugin......
|
||||
protected:
|
||||
STypeManager();
|
||||
STypeManager() ;
|
||||
~STypeManager();
|
||||
|
||||
friend class lumiera::singleton::StaticCreate<STypeManager>;
|
||||
|
|
@ -81,10 +84,21 @@ namespace control {
|
|||
* excludes everything added by the session
|
||||
*/
|
||||
void reset() ;
|
||||
|
||||
|
||||
private:
|
||||
ImplFacade const& fetchImpl (StreamType::ImplFacade::TypeTag);
|
||||
};
|
||||
|
||||
extern Symbol ON_STREAMTYPES_RESET; ///< triggered to load the generic pristine default
|
||||
extern Symbol ON_STREAMTYPES_RESET; ///< triggered to load the generic pristine default
|
||||
|
||||
|
||||
template<class TY>
|
||||
StreamType::ImplFacade const&
|
||||
STypeManager::getImpl (Symbol libID, TY& rawType)
|
||||
{
|
||||
return fetchImpl (ImplFacade::TypeTag (libID,rawType));
|
||||
}
|
||||
|
||||
|
||||
} // namespace control
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ namespace lumiera {
|
|||
namespace test_format {
|
||||
|
||||
using control::STypeManager;
|
||||
typedef StreamType::ImplFacade const& ImplType;
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
|
|
@ -56,15 +57,18 @@ namespace lumiera {
|
|||
{
|
||||
STypeManager& typeManager = STypeManager::instance();
|
||||
|
||||
gavl_video_format_t rawType = createRawType();
|
||||
TODO ("use this to retrieve an ImplFacade from the STypeManager");
|
||||
gavl_video_format_t rawType = test_createRawType();
|
||||
ImplType iTy (typeManager.getImpl (GAVL, rawType));
|
||||
|
||||
UNIMPLEMENTED ("at least preliminary implementation of the MediaImplLib interface for lib GAVL");
|
||||
|
||||
TODO ("how to do a simple consistency check on the returned ImplFacade? can we re-create the GAVL frame type?");
|
||||
ASSERT (GAVL==iTy.libraryID);
|
||||
}
|
||||
|
||||
void basicImplTypeProperties ()
|
||||
{
|
||||
StreamType::ImplFacade& iType = createImplType ();
|
||||
ImplType iTy = test_createImplType ();
|
||||
|
||||
UNIMPLEMENTED ("get a lib descriptor");
|
||||
UNIMPLEMENTED ("check the lib of the type");
|
||||
|
|
|
|||
|
|
@ -45,12 +45,16 @@ namespace lumiera {
|
|||
|
||||
const int TEST_FRAME_DUR = GAVL_TIME_SCALE / 25;
|
||||
}
|
||||
|
||||
Symbol GAVL = "GAVL";
|
||||
|
||||
|
||||
|
||||
/** Helper: create an raw GAVL type descriptor
|
||||
* usable for generating a Lumiera StreamType
|
||||
*/
|
||||
inline gavl_video_format_t
|
||||
createRawType ()
|
||||
test_createRawType ()
|
||||
{
|
||||
gavl_video_format_t type;
|
||||
|
||||
|
|
@ -63,10 +67,10 @@ namespace lumiera {
|
|||
type.image_height = TEST_IMG_WIDTH; // Height of the image in pixels
|
||||
type.frame_width = TEST_IMG_WIDTH; // Width of the frame buffer in pixels, might be larger than image_width
|
||||
type.frame_height = TEST_IMG_WIDTH; // Height of the frame buffer in pixels, might be larger than image_height
|
||||
|
||||
|
||||
type.pixel_width = 1; // Relative width of a pixel (pixel aspect ratio is pixel_width/pixel_height)
|
||||
type.pixel_height = 1; // Relative height of a pixel (pixel aspect ratio is pixel_width/pixel_height)
|
||||
|
||||
|
||||
type.frame_duration = TEST_FRAME_DUR; // Duration of a frame in timescale tics.
|
||||
type.timescale = GAVL_TIME_SCALE; // Timescale in tics per second (is defined to be 1000000 as of 9/2008)
|
||||
|
||||
|
|
@ -77,10 +81,11 @@ namespace lumiera {
|
|||
/** Helper: create an implementation frame
|
||||
* and build the corresponding streamtype
|
||||
*/
|
||||
inline StreamType::ImplFacade&
|
||||
createImplType ()
|
||||
inline StreamType::ImplFacade const&
|
||||
test_createImplType ()
|
||||
{
|
||||
UNIMPLEMENTED ("create a test stream type from a given GAVL type tag");
|
||||
gavl_video_format_t rawType = test_createRawType();
|
||||
return control::STypeManager::instance().getImpl (GAVL, rawType);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1841,7 +1841,7 @@ __5/2008__: the allocation mechanism can surely be improved later, but for now I
|
|||
&rarr; see also LoadingMedia
|
||||
</pre>
|
||||
</div>
|
||||
<div title="MediaImplLib" modifier="Ichthyostega" modified="200809230221" created="200809220304" tags="def spec" changecount="3">
|
||||
<div title="MediaImplLib" modifier="Ichthyostega" modified="200809251942" created="200809220304" tags="def spec" changecount="5">
|
||||
<pre>The Proc-Layer is designed such as to avoid unnecessary assumptions regarding the properties of the media data and streams. Thus, for anything which is not completely generic, we rely on an abstract [[type description|StreamTypeDescriptor]], which provides a ''Facade'' to an actual library implementation. This way, the fundamental operations can be invoked, like allocating a buffer to hold media data.
|
||||
|
||||
In the context of Lumiera and especially in the Proc-Layer, __media implementation library__ means
|
||||
|
|
@ -1849,12 +1849,12 @@ In the context of Lumiera and especially in the Proc-Layer, __media implementati
|
|||
* such as to provide the minimal set of operations
|
||||
** allocating a frame buffer
|
||||
** describing the type of the data within such a buffer
|
||||
* and this subsystem or external library has been integrated to be used by Lumiera by writing adaptation code for accessing these basic operations through the [[implementation facade interface|StreamTypeImplFacade]]
|
||||
* and this subsystem or external library has been integrated to be used through Lumiera by writing adaptation code for accessing these basic operations through the [[implementation facade interface|StreamTypeImplFacade]]
|
||||
* such a link to an type implementation is registered and maintained by the [[stream type manager|STypeManager]]
|
||||
|
||||
!Problem of the implementation data types
|
||||
Because we deliberately won't make any asumptions about the implementation library (besides the ones imposed indirectly by the facade interface), we can't integrate the data types of the library first class into the type system. All we can do is to use marker types and rely on the builder to have checked the compatibility of the actual data beforehand.
|
||||
It would be possible to circumvent this problem by requiring all supported implementation libraries to be known at compile time, because then the actual media implementation type could be linked to a facade type by generic programming. Indeed, Lumiera follows this route with regards to the possible kinds of MObject or [[Asset]] &mdash; but here to the contraty, being able to include support for a new media data type just by adding a plugin by far outweights the benefits of compile-time checked implementation type selection. So, as a consequence of this design decision we //note the possibility of the media file type discovery code to be misconfigured// and select the //wrong implementation library at runtime.// And thus the render engine needs to be prepared for the source reading node of any pipe to flounder completely, and protect the rest of the system accordingly
|
||||
It would be possible to circumvent this problem by requiring all supported implementation libraries to be known at compile time, because then the actual media implementation type could be linked to a facade type by generic programming. Indeed, Lumiera follows this route with regards to the possible kinds of MObject or [[Asset]] &mdash; but to the contraty, for the problem in question here, being able to include support for a new media data type just by adding a plugin by far outweights the benefits of compile-time checked implementation type selection. So, as a consequence of this design decision we //note the possibility of the media file type discovery code to be misconfigured// and select the //wrong implementation library at runtime.// And thus the render engine needs to be prepared for the source reading node of any pipe to flounder completely, and protect the rest of the system accordingly
|
||||
</pre>
|
||||
</div>
|
||||
<div title="MemoryManagement" modifier="Ichthyostega" modified="200808110208" created="200708100225" tags="impl decision discuss" changecount="14">
|
||||
|
|
@ -3406,7 +3406,7 @@ Within the Proc-Layer, media streams are treated largely in a similar manner. Bu
|
|||
An implementation constraint can //stand-in// for a completely specified implementation type (meaning it's a sub interface of the latter). But actually using it in this way may cause a call to the [[defaults manager|DefaultsImplementation]] to fill in any missing information. An example would be to call {{{createFrame()}}} on the type constraint object, which means being able to allocate memory to hold a data frame, with properties in compliance with the given type constraint. Of cousre, then we need to know all the properties of this stream type, which is where the defaults manager is queried. This allows session customisation to kick in, but may fail under certain cicumstances.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="StreamTypeImplFacade" modifier="Ichthyostega" modified="200808151818" created="200808151520" tags="def" changecount="6">
|
||||
<div title="StreamTypeImplFacade" modifier="Ichthyostega" modified="200809251940" created="200808151520" tags="def" changecount="7">
|
||||
<pre>Common interface for dealing with the implementation of media stream data. From a high level perspective, the various kinds of media ({{{VIDEO, IMAGE, AUDIO, MIDI,...}}}) exhibit similar behaviour, while on the implementation level not even the common classification can be settled down to a complete general and useful scheme. Thus, we need separate library implementations for deailing with the various sorts of media data, all providing at least a set of basic operations:
|
||||
* set up a buffer
|
||||
* create or accept a frame
|
||||
|
|
@ -3414,6 +3414,7 @@ An implementation constraint can //stand-in// for a completely specified impleme
|
|||
* ...?
|
||||
|
||||
&rarr; see also &raquo;[[Stream Type|StreamType]]&laquo;
|
||||
//Note:// there is a sort-of "degraded" variant just requiring some &rarr; [[implementation constraint|StreamTypeImplConstraint]] to hold
|
||||
</pre>
|
||||
</div>
|
||||
<div title="StreamTypeUse" modifier="Ichthyostega" modified="200809230152" created="200809130312" tags="draft discuss dynamic" changecount="19">
|
||||
|
|
|
|||
Loading…
Reference in a new issue