Adding Effect and Transition Objects

 
Microsoft DirectShow 9.0

Adding Effect and Transition Objects

To add an effect or transition object, perform the following steps.

1. Create a Timeline Object

DES makes a distinction between the object that represents the effect or transition in the timeline (called the timeline object), and the that implements that effect or transition (called the subobject). For effects, the timeline object supports the IAMTimelineEffect interface. For transitions, it supports the IAMTimelineTrans interface. Both types support the IAMTimelineObj interface. These interfaces are used to insert the objects into the timeline, and to set timeline-related properties. To create the timeline object, call the IAMTimeline::CreateEmptyNode method with the type TIMELINE_MAJOR_TYPE_EFFECT or TIMELINE_MAJOR_TYPE_TRANSITION.

The following example creates a transition object:

IAMTimelineObj *pTransObj = NULL;
pTimeline->CreateEmptyNode(&pTransObj, TIMELINE_MAJOR_TYPE_TRANSITION);

2. Specify the Subobject

The timeline object acts as a wrapper for another object, called the subobject, which does the real work. The subobject implements a data transform that produces the desired effect or transition. For a list of transitions and effects supplied with DES, see Transitions and Effects.

To set the subobject, call the IAMTimelineObj::SetSubObjectGUID method on the timeline object, passing it the class identifier (CLSID) of the subobject. DirectShow provides an enumerator for video effects and video transitions, which you can use to obtain the CLSID. For more information, see Enumerating Effects and Transitions.

The following example sets the SMPTE Wipe Transition as the subobject :

hr = pTransObj->SetSubObjectGUID(CLSID_DxtJpeg);  // SMPTE Wipe

3. Set the Start and Stop Times

To set the start and stop times, call the IAMTimelineObj::SetStartStop method. These times are relative to the start time of the parent object. Effects can overlap within the same object, but transitions cannot.

The following example sets the start time to 5 seconds and the stop time to 10 seconds:

const REFERENCE_TIME ONE_SECOND = 10000000
hr = pTransObj->SetStartStop(5 * ONE_SECOND, 10 * ONE_SECOND);

When a transition is rendered, the progress of the transition at each frame is calculated based on a Progress property, which is normalized to a range of 0.0 to 1.0. DES uses the start time of each frame to calculate the progress value. This means if the transition stop time is equal to the source stop time, the Progress value will never reach exactly 1.0, because the start time of the last frame is slightly than the stop time. To make the transition reach 1.0, set the transition stop time to be at least one frame earlier than the source stop time.

4. Insert the Object into the Timeline

To insert the object into the timeline, call one of the following methods on the parent, depending on the object type:

In the IAMTimelineEffectable::EffectInsBefore method, you must specify the priority of the effect. When effects overlap on the same object, they are applied in order of priority. The Volume Envelope audio effect is an exception; see the Volume Envelope Effect reference for details. Within a composition, all audio tracks are mixed before the audio effects for that composition are applied.

Because transitions cannot overlap on the same object, they do not have a priority value.

The following example adds the transition object to a track:

IAMTimelineTransable *pTransable = NULL;
hr = pTrack->QueryInterface(IID_IAMTimelineTransable, (void **)&pTransable);
hr = pTransable->TransAdd(pTransObj);  
pTransable->Release();

The example queries the track object for the IAMTimelineTransable interface before calling AddTrans.

5. Set Properties

Many effects and transitions support custom properties. For information, see Setting Properties on Effects and Transitions.

Example

The following code example adds a SMPTE Wipe Transition to a track. It assumes that the track object already exists in the timeline.

IAMTimeline *pTL;
IAMTimelineTrack *pTrack;

// Create timeline with track (not shown).

// Create the transition object. 
IAMTimelineObj *pTransObj = NULL;
hr = pTL->CreateEmptyNode(&pTransObj, TIMELINE_MAJOR_TYPE_TRANSITION);

// Set the subobject. 
hr = pTransObj->SetSubObjectGUID(CLSID_DxtJpeg);  // SMPTE Wipe

// Set the start and stop times. 
hr = pTransObj->SetStartStop(50000000, 100000000);

// Insert the transition object into the timeline. 
IAMTimelineTransable *pTransable = NULL;
hr = pTrack->QueryInterface(IID_IAMTimelineTransable, (void **)&pTransable);
hr = pTransable->TransAdd(pTransObj);  
pTransable->Release();
pTransObj->Release();