clarify the handling of specific output operation modes (e.g. number of channels)
This commit is contained in:
parent
74a982409e
commit
d27e3b15a9
10 changed files with 126 additions and 61 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
|
|
@ -38,14 +38,6 @@ namespace play {
|
|||
|
||||
|
||||
|
||||
namespace { // hidden local details of the service implementation....
|
||||
|
||||
} // (End) hidden service impl details
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
OutputSlot::~OutputSlot() { } // emit VTables here....
|
||||
|
||||
|
|
@ -68,15 +60,26 @@ namespace play {
|
|||
}
|
||||
|
||||
|
||||
/** */
|
||||
/** claim this OutputSlot for active use as output sink(s).
|
||||
* At any point, a given slot can only be used for a single
|
||||
* ongoing output process (which may serve several channels though).
|
||||
* The assumption is for the OutputSlot to be picked through a query
|
||||
* to some OutputManater, so the parameters (resolution, sample rate...)
|
||||
* should be suited for the intended use. Thus no additional configuration
|
||||
* is necessary.
|
||||
* @return Allocation representing the "connected state" from the client's POV.
|
||||
* The client may retrieve the effectively required Timings from there,
|
||||
* as well as the actual output sinks, ready for use.
|
||||
* @remarks calls back into #buildState, where the concrete OutputSlot
|
||||
* is expected to provide a private Connection implementation,
|
||||
* subclassing OutputSlot::Allocation
|
||||
*/
|
||||
OutputSlot::Allocation&
|
||||
OutputSlot::allocate()
|
||||
{
|
||||
if (!isFree())
|
||||
throw error::Logic ("Attempt to open/allocate an OutputSlot already in use.");
|
||||
|
||||
UNIMPLEMENTED ("internal interface to determine the number of channel-connections");
|
||||
|
||||
state_.reset (this->buildState());
|
||||
return *state_;
|
||||
}
|
||||
|
|
@ -110,7 +113,6 @@ namespace play {
|
|||
connection.discard(data2emit);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,9 +26,39 @@
|
|||
** using this concept allows to separate and abstract the data calculation and the organisation
|
||||
** of playback and rendering from the specifics of the actual output sink. Actual output
|
||||
** possibilities can be added and removed dynamically from various components (backend, GUI),
|
||||
** all using the same resolution and mapping mechanisms
|
||||
** all using the same resolution and mapping mechanisms
|
||||
**
|
||||
** @see diagnostic-output-slot.hpp ////TODO
|
||||
** Each OutputSlot is an unique and distinguishable entity. It corresponds explicitly to an
|
||||
** external output, or a group of such outputs (e.g. left and right sound card output channels),
|
||||
** or an output file or similar capability accepting media content. Initially, an output slot
|
||||
** needs to be provided, configured and registered, using an implementation suitable for the
|
||||
** kind of media data to be output (sound, video) and also suitable for the special circumstances
|
||||
** of the output capability (render a file, display video in a GUI widget, send video to some
|
||||
** full screen display, establish a Jack port, just use some kind of "sound out"). An output
|
||||
** slot is always limited to a single kind of media, and to a single connection unit, but
|
||||
** this connection may still be comprised of multiple channels
|
||||
** (e.g. stereoscopic video, multichannel sound).
|
||||
**
|
||||
** In order to be usable as output sink, an output slot needs to be \em allocated: At any time,
|
||||
** there may be only a single client using a given output slot this way. To stress this point:
|
||||
** output slots don't provide any kind of inherent mixing capability; any adaptation, mixing,
|
||||
** overlaying and sharing needs to be done within the nodes network producing the output data
|
||||
** to be fed into the slot. (in special cases, some external output capabilities — e.g. the
|
||||
** Jack audio connection system — may still provide additional mixing capabilities,
|
||||
** but that's beyond the scope of the Lumiera application)
|
||||
**
|
||||
** Once allocated, the output slot returns a set of concrete sink handles (one for each
|
||||
** physical channel expecting data). The calculating process feeds its results into those handles.
|
||||
** Size and other characteristics of the data frames are assumed to be suitable, which typically
|
||||
** won't be verified at that level anymore. Besides that, the allocation of an output slot reveals
|
||||
** detailed timing expectations. The client is required to comply to these timings when \em emitting
|
||||
** data — he's even required to provide a current time specification, alongside with the data.
|
||||
** Based on this information, the output slot has the ability to handle timing failures gracefully;
|
||||
** the concrete output slot implementation is expected to provide some kind of de-click or
|
||||
** de-flicker facility, which kicks in automatically when a timing failure is detected.
|
||||
**
|
||||
** @see OutputSlotProtocol_test
|
||||
** @see diagnostic-output-slot.hpp
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -42,25 +72,18 @@
|
|||
#include "proc/engine/buffer-provider.hpp"
|
||||
#include "proc/play/timings.hpp"
|
||||
#include "lib/iter-source.hpp"
|
||||
//#include "lib/sync.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
//#include <string>
|
||||
//#include <vector>
|
||||
//#include <tr1/memory>
|
||||
|
||||
|
||||
namespace proc {
|
||||
namespace play {
|
||||
|
||||
|
||||
using proc::engine::BuffHandle;
|
||||
using proc::engine::BufferProvider;
|
||||
using lib::time::TimeValue;
|
||||
//using std::string;
|
||||
|
||||
//using std::vector;
|
||||
//using std::tr1::shared_ptr;
|
||||
|
||||
using boost::scoped_ptr;
|
||||
|
||||
|
||||
|
|
@ -71,10 +94,16 @@ namespace play {
|
|||
|
||||
|
||||
|
||||
/********************************************************************
|
||||
/********************************************************************************
|
||||
* Interface: Generic output sink.
|
||||
*
|
||||
* @todo write type comment
|
||||
* An OutputSlot represents the possibility to send data through multiple
|
||||
* channels to some kind of external sink (video in GUI window, video full screen,
|
||||
* sound, Jack, rendering to file). Clients are expected to retrieve a suitably
|
||||
* preconfigured implementation from some OutputManager instance. An OutputSlot
|
||||
* needs to be \em claimed for output by invoking #allocate, which returns a
|
||||
* representation of the connection state. This operation is exclusive.
|
||||
* The actual \link DataSink output sinks \endlink can be retrieved
|
||||
* through the Allocation object returned from there.
|
||||
*/
|
||||
class OutputSlot
|
||||
: boost::noncopyable
|
||||
|
|
@ -87,6 +116,9 @@ namespace play {
|
|||
|
||||
scoped_ptr<ConnectionState> state_;
|
||||
|
||||
/** build the \em connected state,
|
||||
* based on the existing configuration
|
||||
* within this concrete OutputSlot */
|
||||
virtual ConnectionState* buildState() =0;
|
||||
|
||||
|
||||
|
|
@ -133,7 +165,7 @@ namespace play {
|
|||
|
||||
public:
|
||||
BuffHandle lockBufferFor(FrameID);
|
||||
void emit(FrameID, BuffHandle const&, TimeValue currentTime = Time::MAX); ///////////////TICKET #855
|
||||
void emit(FrameID, BuffHandle const&, TimeValue currentTime = Time::ANYTIME);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ namespace play {
|
|||
Play::Controller
|
||||
PlayService::connect (ModelPorts dataGenerators, POutputManager outputPossibilities)
|
||||
{
|
||||
Timings playbackTimings; /////////////////////////////////////////////////////////////TODO
|
||||
Timings playbackTimings; //////////////////////////////////////////////////////////////////////TICKET #875
|
||||
|
||||
return pTable_->establishProcess(
|
||||
PlayProcess::initiate(dataGenerators,
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ namespace play {
|
|||
Timings nominalTimings = activeOutputConnection.getTimingConstraints()
|
||||
.constrainedBy(playbackTimings_);
|
||||
|
||||
return EngineService::instance().calculate(port, nominalTimings, activeOutputConnection, renderQuality_);
|
||||
return EngineService::instance().calculate (port, nominalTimings, activeOutputConnection, renderQuality_);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -227,20 +227,39 @@ namespace play {
|
|||
|
||||
/********************************************************************
|
||||
* Helper for unit tests: Mock output sink.
|
||||
*
|
||||
* @todo write type comment
|
||||
* Complete implementation of the OutputSlot interface, with some
|
||||
* additional stipulations to support unit testing.
|
||||
* - the implementation uses a special protocol output buffer,
|
||||
* which stores each "frame" in memory for later investigation
|
||||
* - the output data in the buffers handed over from client
|
||||
* actually hold an TestFrame instance
|
||||
* - the maximum number of channels and the maximum number
|
||||
* of acceptable frames is limited to 5 and 100.
|
||||
* @warning any Captured (test) data from all individual instances
|
||||
* remains in memory until shutdown of the current executable
|
||||
*/
|
||||
class DiagnosticOutputSlot
|
||||
: public OutputSlot
|
||||
{
|
||||
|
||||
static const uint MAX_CHANNELS = 5;
|
||||
|
||||
|
||||
/** @note a real OutputSlot implementation
|
||||
* would rely on some kind of embedded
|
||||
* configuration here */
|
||||
uint
|
||||
getOutputChannelCount()
|
||||
{
|
||||
return MAX_CHANNELS;
|
||||
}
|
||||
|
||||
|
||||
/** hook into the OutputSlot frontend */
|
||||
ConnectionState*
|
||||
buildState()
|
||||
{
|
||||
return new SimulatedOutputSequences(MAX_CHANNELS);
|
||||
return new SimulatedOutputSequences(
|
||||
getOutputChannelCount());
|
||||
}
|
||||
|
||||
/** @internal is self-managed and non-copyable.
|
||||
|
|
@ -254,7 +273,7 @@ namespace play {
|
|||
accessSequence (uint channel)
|
||||
{
|
||||
REQUIRE (!isFree(), "diagnostic OutputSlot not (yet) connected");
|
||||
REQUIRE (channel <= MAX_CHANNELS);
|
||||
REQUIRE (channel <= getOutputChannelCount());
|
||||
return static_cast<SimulatedOutputSequences&> (*state_).at(channel);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,64 +2,64 @@ format 74
|
|||
|
||||
classcanvas 128005 class_ref 176133 // OutputSlot
|
||||
draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
|
||||
xyz 157.7 37 2000
|
||||
xyz 155.04 38.2 2000
|
||||
end
|
||||
fragment 128261 "output management"
|
||||
xyzwh 123 14 1990 244 292
|
||||
xyzwh 126.62 17.82 1990 240 288
|
||||
end
|
||||
classcanvas 129029 class_ref 185221 // Allocation
|
||||
draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
|
||||
xyz 260 126 2005
|
||||
xyz 247.02 129.02 2005
|
||||
end
|
||||
classcanvas 129541 class_ref 178565 // DataSink
|
||||
draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
|
||||
xyz 14 191 2005
|
||||
xyz 13.16 194.12 2005
|
||||
end
|
||||
classcanvas 129925 class_ref 185349 // Connection
|
||||
draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
|
||||
xyz 443 184 2000
|
||||
xyz 419.32 189.12 2000
|
||||
end
|
||||
classcanvas 130309 class_ref 185477 // OutputSlotImpl
|
||||
draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
|
||||
color green
|
||||
xyz 149 422 2000
|
||||
xyz 149.12 420.84 2000
|
||||
end
|
||||
classcanvas 130565 class_ref 185605 // ConnectionState
|
||||
draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
|
||||
xyz 261 250 2000
|
||||
xyz 249.88 248.84 2000
|
||||
end
|
||||
classcanvas 130949 class_ref 185733 // ConcreteConnection
|
||||
draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
|
||||
color lightgreen
|
||||
xyz 432 357 2000
|
||||
xyz 408.32 358 2000
|
||||
end
|
||||
classcanvas 131205 class_ref 185861 // ConnectionStateManager
|
||||
draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
|
||||
xyz 240 351 2000
|
||||
xyz 228.88 351 2000
|
||||
end
|
||||
classcanvas 132613 class_ref 178693 // BufferProvider
|
||||
draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
|
||||
xyz 534 456 2000
|
||||
xyz 484.36 459.64 2000
|
||||
end
|
||||
fragment 132997 "concrete output driver"
|
||||
xyzwh 123 309 1995 508 205
|
||||
xyzwh 126.68 309.48 1995 464 204
|
||||
end
|
||||
note 133125 "Client
|
||||
front-end"
|
||||
xyzwh 15 270 2000 75 43
|
||||
xyzwh 15.36 270.88 2000 75 43
|
||||
note 133381 "Knowledge specific to this external output and driver"
|
||||
xyzwh 564 338 2000 129 57
|
||||
xyzwh 536.04 322.88 2000 138 58
|
||||
relationcanvas 129157 relation_ref 212485 // <dependency>
|
||||
decenter_begin 726
|
||||
from ref 128005 z 2006 stereotype "<<when-in-use>>" xyz 229 73 3000 to point 227 82
|
||||
line 132485 z 2006 to point 295 82
|
||||
from ref 128005 z 2006 stereotype "<<when-in-use>>" xyz 230 72 3000 to point 227.72 82.12
|
||||
line 132485 z 2006 to point 294.96 83.12
|
||||
line 132357 z 2006 to ref 129029
|
||||
no_role_a no_role_b
|
||||
no_multiplicity_a no_multiplicity_b
|
||||
end
|
||||
relationcanvas 129669 relation_ref 212613 // <directional composition>
|
||||
geometry HV
|
||||
from ref 129029 z 2006 stereotype "<<for_each_channel>>" xyz 70 155 3000 to point 52 153
|
||||
from ref 129029 z 2006 stereotype "<<for_each_channel>>" xyz 65 158 3000 to point 51 155
|
||||
line 130821 z 2006 to ref 129541
|
||||
no_role_a no_role_b
|
||||
no_multiplicity_a no_multiplicity_b
|
||||
|
|
@ -67,7 +67,7 @@ end
|
|||
line 130053 ---+ decenter_end 876
|
||||
from ref 129029 z 2006 to ref 128005
|
||||
relationcanvas 130181 relation_ref 212741 // <unidirectional association>
|
||||
from ref 129541 z 2006 stereotype "<<smart-Handle>>" xyz 92 206 3000 to ref 129925
|
||||
from ref 129541 z 2006 stereotype "<<smart-Handle>>" xyz 188 210 3000 to ref 129925
|
||||
no_role_a no_role_b
|
||||
no_multiplicity_a no_multiplicity_b
|
||||
end
|
||||
|
|
@ -99,13 +99,13 @@ end
|
|||
relationcanvas 131845 relation_ref 213637 // <dependency>
|
||||
geometry HV
|
||||
decenter_end 197
|
||||
from ref 130309 z 2001 to point 264 438
|
||||
from ref 130309 z 2001 to point 252 433
|
||||
line 132101 z 2001 to ref 131205
|
||||
no_role_a no_role_b
|
||||
no_multiplicity_a no_multiplicity_b
|
||||
end
|
||||
relationcanvas 132741 relation_ref 213765 // <unidirectional association>
|
||||
from ref 130949 z 2001 to point 574 423
|
||||
from ref 130949 z 2001 to point 524.68 414
|
||||
line 133253 z 2001 to ref 132613
|
||||
no_role_a no_role_b
|
||||
no_multiplicity_a no_multiplicity_b
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ diagrams
|
|||
objectdiagram_ref 138885 // ModelAssetRelations
|
||||
730 488 100 4 0 0
|
||||
classdiagram_ref 143877 // Player Entities
|
||||
663 648 100 4 0 0
|
||||
663 654 100 4 0 0
|
||||
objectdiagram_ref 144005 // Play Process Structure
|
||||
562 424 100 4 0 0
|
||||
sequencediagram_ref 145157 // output data exchange
|
||||
586 416 100 4 0 0
|
||||
active classdiagram_ref 151685 // Player Output
|
||||
723 654 100 4 0 0
|
||||
643 590 92 4 0 0
|
||||
end
|
||||
show_stereotypes
|
||||
selected
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
format 74
|
||||
"lumiera"
|
||||
revision 73
|
||||
revision 74
|
||||
modified_by 5 "hiv"
|
||||
cpp_root_dir "../../src/"
|
||||
|
||||
|
|
|
|||
|
|
@ -3362,7 +3362,7 @@ While actually data frames are //pulled,// on a conceptual level data is assumed
|
|||
As both of these specifications are given by [[Pipe]]-~IDs, the actual designation information may be reduced. Much can be infered from the circumstances, because any pipe includes a StreamType, and an output designation for an incompatible stream type is irrelevant. (e.g. and audio output when the pipe currently in question deals with video)
|
||||
</pre>
|
||||
</div>
|
||||
<div title="OutputManagement" modifier="Ichthyostega" modified="201111040000" created="201007090155" tags="Model Rendering Player spec draft" changecount="38">
|
||||
<div title="OutputManagement" modifier="Ichthyostega" modified="201112222226" created="201007090155" tags="Model Rendering Player spec draft" changecount="39">
|
||||
<pre>//writing down some thoughts//
|
||||
|
||||
* ruled out the system outputs as OutputDesignation.
|
||||
|
|
@ -3397,6 +3397,12 @@ The relation between the central OutputDirector and the peripheral OutputManager
|
|||
|
||||
For a viewer widget in the GUI this yields exactly the expeted behaviour, but in other cases, e.g. for sound output, we need more general, more globally scoped output slots. In these cases, when a local mapping is absent, the query for output resolution is passed on up to the OutputDirector, drawing on the collection of globally available output slots for that specific kind of media.
|
||||
{{red{open question 11/11: is it possible to retrieve a slot from another peripheral node?}}}
|
||||
|
||||
!!!output modes
|
||||
Most output connections and drivers embody some kind of //operation mode:// Display is characterised by resolution and colour depth, sound by number of channels and sampling rate, amongst others. There might be a mismatch with the output expectations represented by [[output designations|OutputDesignation]] within the model. Nontheless we limit those actual operation modes strictly to the OutputManager realm. They should not leak out into the model within the session.
|
||||
In practice, this decision might turn out to be rather rigid, but some additional mechanisms allow for more flexibility
|
||||
* when [[connecting|ViewerPlayConnection]] timeline to viewer and output, stream type conversions may be added automatically or manually
|
||||
* since resolution of an output designation into an OutputSlot is initiated by querying an output manager, this query might include additional constraints, which //some// (not all) concrete output implementations might evaluate to provide an more suitably configured output slot variant.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="OutputManager" modifier="Ichthyostega" modified="201106212317" created="201106122359" tags="Player Model def" changecount="7">
|
||||
|
|
@ -3416,7 +3422,7 @@ Note that an OutputSlot acts as a unit for registration and also for allocating
|
|||
The //registration//&nbsp; of an output slot installs a functor or association rule, which later on allows to claim and connect up to a preconfigured number of channels. This allocation or usage of a slot is exclusive (i.e. only a single client at a time can allocate a slot, even if not using all the possible channels). Each output manager instance may or may not be configured with a //fall-back rule:// when no association or mapping can be established locally, the connection request might be passed down to the global OutputDirector. Again, we can expect this to be the standard behaviour for sound, while video likely will rather be handled locally, e.g. within a GUI widget (but we're not bound to configure it exactly this way)
|
||||
</pre>
|
||||
</div>
|
||||
<div title="OutputMapping" modifier="Ichthyostega" modified="201106180044" created="201011080238" tags="Model spec draft" changecount="29">
|
||||
<div title="OutputMapping" modifier="Ichthyostega" modified="201112222050" created="201011080238" tags="Model spec draft" changecount="32">
|
||||
<pre>An output mapping serves to //resolve//&nbsp; [[output designations|OutputDesignation]].
|
||||
|
||||
!Mapping situations
|
||||
|
|
@ -3428,7 +3434,7 @@ The //registration//&nbsp; of an output slot installs a functor or associati
|
|||
:Thus, in this case we resolve similar to a bus connection, possibly overridden by already pre-existing or predefined connections.
|
||||
;switch board
|
||||
:a viewer might receive multiple outputs and overlays, necessitating a user operated control to select what's actually to be displayed
|
||||
:Thus, in this case we need a backwards resolution at the lower end of the output network, to connect to the model port as defined by this viewer SwitchBoard
|
||||
:Thus, in this case we need a backwards resolution at the lower end of the output network, to connect to the model port as selected through the viewer's SwitchBoard
|
||||
;global pipes or virtual media
|
||||
:when binding a Sequence as Timeline or VirtualClip, a mapping from output designations used within the Sequence to virtual channels or global pipes is required
|
||||
:Thus, in this case we need to associate output designations with ~Pipe-IDs encountered in the context according to some rules &mdash; again maybe overridden by pre-existing connections
|
||||
|
|
@ -3443,12 +3449,12 @@ All these mapping steps are listed here, because they exhibit a common pattern.
|
|||
* there is an //unconnected//&nbsp; state.
|
||||
|
||||
!Implementation notes
|
||||
Thus the mapping is a copyable value object, based on a associative array. It may be attached to a model object and persisted alongside. The mapping is assumed to run a defaults query when necessary. To allow for that, it should be configured with a query template (string). Frequently, special //default pipe// markers will be used at places where no distinct pipe-ID is specified explicitly. Besides that, invocations might supply additional predicates (e.g. {{{ord(2)}}} to point at "the second stream of this kind") thereby hinting the defaults resolution. Moreover, the mapping needs a way to retrieve the set of possible results, allowing to filter the results of the rules based default. Mappings might be defined explicitly. Instead of storing a //bottom value,// an {{{isDefined()}}} predicate might be preferable.
|
||||
Thus the mapping is a copyable value object, using an associative array. It may be attached to a model object and persisted alongside. The mapping is assumed to run a defaults query when necessary. To allow for that, it should be configured with a query template (string). Frequently, special //default pipe// markers will be used at places where no distinct pipe-ID is specified explicitly. Besides that, invocations might supply additional predicates (e.g. {{{ord(2)}}} to point at "the second stream of this kind") thereby hinting the defaults resolution. Moreover, the mapping needs a way to retrieve the set of possible results, allowing to filter the results of the rules based default. Mappings might be defined explicitly. Instead of storing a //bottom value,// an {{{isDefined()}}} predicate might be preferable.
|
||||
|
||||
First and foremost, mapping can be seen as a //functional abstraction.// As it's used at implementation level, encapsulation of detail types in't the primary concern, so it's a candidate for generic programming: For each of those use cases outlined above, a distinct mapping type is created by instantiating the {{{OutputMapping<DEF>}}} template with a specifically tailored definition context ({{{DEF}}}), which takes on the role of a strategy. Individual instances of this concrete mapping type may be default created and copied freely. This instantiation process includes picking up the concrete result type and building a functor object for resolving on the fly. Thus, in the way typical for generic programming, the more involved special details are moved out of sight, while being still in scope for the purpose of inlining. But there //is// a concern better to be encapsulated and concealed at the usage site, namely accessing the rules system. Thus mapping leads itself to the frequently used implementation pattern where there is a generic frontend as header, calling into opaque functions embedded within a separate compilation unit.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="OutputSlot" modifier="Ichthyostega" modified="201112200358" created="201106162339" tags="def Concepts Player spec img" changecount="49">
|
||||
<div title="OutputSlot" modifier="Ichthyostega" modified="201112222235" created="201106162339" tags="def Concepts Player spec img" changecount="51">
|
||||
<pre>Within the Lumiera player and output subsystem, actually sending data to an external output requires to allocate an ''output slot''
|
||||
This is the central metaphor for the organisation of actual (system level) outputs; using this concept allows to separate and abstract the data calculation and the organisation of playback and rendering from the specifics of the actual output sink. Actual output possibilities (video in GUI window, video fullscreen, sound, Jack, rendering to file) can be added and removed dynamically from various components (backend, GUI), all using the same resolution and mapping mechanisms (&rarr; OutputManagement)
|
||||
|
||||
|
|
@ -3468,6 +3474,9 @@ Besides the sink handles, allocation of an output slot defines some timing const
|
|||
|
||||
The assumption is for the client to have elaborate timing capabilities at his disposal. More specifically, the client is assumed to be a job running within the engine scheduler and thus can be configured to run //after// another job has finished, and to run within certain time limits. Thus the client is able to provide a //current nominal time// -- which is suitably close to the actual wall clock time. The output slot implementation can be written such as to work out from this time specification if the call is timely or overdue -- and react accordingly.
|
||||
|
||||
!!!output modes
|
||||
some concrete output connections and drivers embody a specific operation mode (e.g. sample rate or number of channels). The decision and setup of these operational configuration is initiated together with the [[resolution|OutputMapping]] of an OutputDesignation within the OutputManager, finally leading to an output slot (reference), which can be assumed to be suitably configured, before the client allocates this slot for active use. Moreover, an individual output sink (corresponding to a single channel) may just remain unused -- until there is an {{{emit()}}} call and successful data handover, this channel will just feature silence or remain black. (More flexible system, e.g. Jack, allow to generate an arbitrary number of output pins -- Lumiera will support this by allowing to set up additional output slots and attach this information to the current session &rarr; SessionConfigurationAttachment)
|
||||
|
||||
!!!Lifecycle and storage
|
||||
The concrete OutputSlot implementation is owned and managed by the facility actually providing the output possibility in question. For example, the GUI provides viewer widgets, while some sound output backend provides sound ports. The associated OutputSlot implementation object is required to stay alive as long as it's registered with some OutputManager. It needs to be de-registered explicitly prior to destruction -- and this deregistration may block until all clients using this slot did terminate. Beyond that, an output slot implementation is expected to handle all kinds of failures gracefully -- preferably just emitting a signal (callback functor).
|
||||
{{red{TODO 7/11: Deregistration is an unsolved problem....}}}
|
||||
|
|
@ -5368,6 +5377,9 @@ The Session object is a singleton &mdash; actually it is a »~PImpl«-Facade
|
|||
&rarr; see [[relation of timeline, sequences and objects|TimelineSequences]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="SessionConfigurationAttachment" modifier="Ichthyostega" created="201112222242" tags="SessionLogic draft" changecount="2">
|
||||
<pre>While the core of the persistent session state corresponds just to the HighLevelModel, there is additionaly attached state, annotations and specific bindings, which allow to connect the session model to the local application configuration on each system. A typical example would be the actual output channels, connections and drivers to use on a specific system. In a Studio setup, these setup and wiring might be quite complex, it may be specific to just a single project, and the user might want to work on the same project on different systems. This explains why we can't just embody these configuration information right into the actual model.</pre>
|
||||
</div>
|
||||
<div title="SessionContentsQuery" modifier="Ichthyostega" modified="201006190547" created="201006190526" tags="SessionLogic spec draft" changecount="6">
|
||||
<pre>Querying and retrieving objects within the session model is always bound to a [[scope|PlacementScope]]. When using the //dedicated API,// this scope is immediately defined by the object used to issue the query, like e.g. when searching the contents of a track. But when using the //generic API,// this scope is rather implicit, because in this case a (stateful) QueryFocus object is used to invoke the queries. Somewhat in-between, the top-level session API itself exposes dedicated query functions working on the whole-session scope (model root).
|
||||
Based on the PlacementIndex, the treelike scope structure can be explored efficiently; each Placement attached to the session knows its parent scope. But any additional filtering currently is implemented on top of this basic scope exploration, which obviously may degenerate when searching large scopes and models. Filtering may happen implicitly; all scope queries are parametrised to a specific kind of MObject, while the PlacementIndex deals with all kinds of {{{Placement<MObject>}}} uniformly. Thus, more specifically typed queries automatically have to apply a type filter based on the RTTI of the discovered placements. The plan is later to add specialised sub-indices and corresponding specific query functions to speed up the most frequently used kinds of queries.
|
||||
|
|
|
|||
Loading…
Reference in a new issue