On Sat, 2002-07-27 at 22:20, Timothy M. Shead wrote:
> First off, kudos for modelling time as a continuous range instead of
> discrete frames, which is a common mistake in a wide variety of software.
This approach was taken just to avoid passing through the additional
arguments and duplicating the conversion to the double in every effect.
This was indeed fortunate as it meant that adding the additional start
and end points of the effect was very trivial (inspired by reading the
Your discussion below introduces an additional argument, and I totally
agree with you that it's a requirement.
It brings up an issue though - just how stable are the interfaces? Are
we going to need an increasing number of arguments and methods in
successive releases. If so, we're going to cause some headaches for
external plug-in developers...
My gut feeling is that we should create objects to carry the increasing
number of arguments (even if we really have defined everything, it's
still easier to create new effects if the methods have a simpler
signature). This means we can extend our classes in future releases and
not (necessarily anyway) break backward compatibility.
It also helps in the audio area where the number of arguments are
already pretty excessive. In some cases, it would be convenient to allow
the plug-in to dictate the frequency of its output, rather than be told
that it must provide whatever the arbitrary input is... passing an
object which provides a getter/setter methods to control what the
plug-in can do would rectify that situation immediately.
> To obtain the best possible quality, though, it's important to realize
> that a "frame" is not a label on a number line - it's a finite range of
> time. Assuming that an effect covers the span from time 0.0 to time
> 1.0, a four frame effect would look like:
> | | | | |
> | Frame 0 | Frame 1 | Frame 2 | Frame 3 |
> Time ------------------------------------------------------------->
> 0.0 0.25 0.5 0.75 1.0
> This impacts the quality of a plugin's output because the plugin needs
> to account for the finite duration of a frame in order to properly
> handle things like interlace and motion blur. For any non-static
> effect, point-sampling introduces aliasing in the time domain.
> A couple of things fall out of this - first, passing a single "position"
> argument to a plugin cannot fully describe the range of time that it
> needs to render the effect for. My suggestion is to add a second
> argument, "frame_delta", that represents the duration of the frame
> within the current range [0, 1]. I've enclosed a patch that updates the
> plugin APIs with a "frame_delta", which is the inverse of the frame
> count. Of course, there could be other ways to parameterize a frame:
> start_time & end_time, frame_number & total_frames, etc.
> The second issue is that, assuming the existing definition of time in
> the range [0, 1], the "position" argument should never reach 1 - since
> it represents the "leading edge" if each frame, it will always be less
> than 1, even for the last frame - in the diagram, it would be 0.75 (the
> enclosed patch doesn't address this, yet).
> Assuming all this is acceptable, I have a special version of timfx ready
> which takes advantage of "frame_delta" to interlace the Image Luma wipes
> - when viewed on a video monitor, it produces a dramatic improvement in
Haven't tested yet, but will feedback on this as soon as I do. Your
arguments for the interface modification are very convincing and
definitely get my vote, but like I said above, I think it might a good
time to coalesce the argument list into objects.
> A third item is the "reverse" argument in ImageTransition::GetFrame()
> ... having this argument is an excellent idea, because you cannot
> generally reverse the output of an effect by running time backwards (and
> even if you could, "reverse" may not mean the same thing to all plugins)
> So on one hand I think it would be appropriate to provide this
> argument to all plugin types, as it's generally applicable. On the
> other hand, there are lots of effects (like all of the static ones) for
> which the concept of "reverse" makes no sense - so perhaps the "reverse"
> argument should be removed from all of the plugin types, and implemented
> on an as-needed basis by plugin authors.
Yes, the reverse is an aggravating one which has come out of my reading
of the smil docs. For example in their bar wipe transitions, they
specify two 'sub-types' (left/right and up/down) and the converse are
dictated by the direction (forward/reverse). As you point out, this is
not simply a case of running time backwards [though it is in some
cases], nor is it applicable to all. I feel it would have been simpler
for us if the SMIL documents did dictate the complete set of sub-types,
rather than relying on a plug-in to 'correctly' (in its context) deal
with this additional argument.
However, the reason for pushing this out of the plug-ins individual
requirements was to mirror the SMIL specification transition element and
attributes. The basic transition element looks like:
<transition type= subtype= dur= startProgress= endProgress= direction=
The theory is this - the kino core is responsible for dealing with the
common attributes (you'll notice that all of these more or less
correlate to widgets in the magick tabs). The exception is subtype, the
collection/selection of which will need to be exposed from the plug-in
interface. The params handling (input/output) will also be defined by
the plug-in in a future revision (as an alternative to
Whether this approach will be practical is a bit difficult to say.
Pushing the selection of the direction down to the plug-in requirement
simply means that most plug-ins will end up collecting this parameter
(and I guess, in a variety of inconsistent ways...).
When I introduced it, I was vaguely toying with the idea of adding a
method to the interface which would allow the plug-in to control the
availability of that argument (ie: bool IsReversible()) - then a plug-in
could simply return true or false and the corresponding widget in kino
would be enabled/disabled on a needs basis.
On top of this, the handling of the 'previous frame' is a pain, since it
does dictate that time runs backward for many fx (I think... gets a bit
confusing here, esp. with regard to fade which is a special case across
the board [according to SMIL anyway..]). Also, according to SMIL, the
fadeColor attribute is only applicable to the Fade transition (being a
fundamental difference between Magick and SMIL which doesn't have the
special case there...).
One other point that's been bothering me - the current design doesn't
allow multiple use of an effect. This is because we have one object for
each effect throughout the life cycle of the application and state is
retained in this this object. Perhaps we should register a factory
rather than the object directly? This means we could construct/destruct
the plug-in objects on a needs basis... This also resolves the missing
'Finished' method which really should be there for the objects to have
any chance of cleaning themselves up at the end of their use (ie: we
should have a sequence of calls like InterpretWidgets, GetFrame
Anyway, I'm sure there's a lot to discuss in the whole area, and I'm
very keen to stabilise things quickly. I'm not expecting to do this
before the initial release (the HOWTO contains this warning up front for
precisely this reason).
Many thanks for your comments,