# Changing time within a stream

An interactive application is almost never played in linear order from beginning to end. Instead, the end-users of your application may be interested in a variety of interactions discussed in this section:

- Starting and stopping a stream
- Jumping to a new location

## Starting and stopping a stream

To start, stop, or pause a stream, use the functions `DSStartStream()` and `DSStopStream()`. How you use `DSStopStream()` depends on whether you expect to resume playing. If you use SOPT_FLUSH as the last argument, all buffers will be flushed. If you use SOPT_NOFLUSH, buffers remain unchanged.

The following example is from NuPlayer.c, which is part of the NuPlayer application.

Example 1: Starting and stopping a stream.

``

    else if ( jp->startBtn )
            {
            /* Pause / Unpause the stream
             */
            if ( ctx->streamCBPtr->streamFlags & STRM_RUNNING )
                {
                /* Note: we don't use the SOPT_FLUSH option when we stop
                 * here so that the "A" button acts like a pause/resume
                 * key. Using the SOPT_FLUSH option will cause buffered
                 * data to be flushed, so that once resumed, any queued
                 * audio will vanish. This is not what is usually desired
                 * for pause/resume.
                 */
                status = DSStopStream( ctx->messageItem, NULL, ctx->streamCBPtr,

                                SOPT_NOFLUSH );
                CHECK_DS_RESULT( "DSStopStream", status );
                }
            else
                {
                status = DSStartStream( ctx->messageItem, NULL,

                        ctx->streamCBPtr, SOPT_NOFLUSH );
                CHECK_DS_RESULT( "DSStartStream", status );
                }

### Using Weaver script commands to place markers

To specify the exact points at which a stream may start or stop, it is best to use the `writestopchunk` or `writehaltchunk` Weaver script commands.

Note: The Weaver always places markers at the beginning of a block, even if the time you specify actually falls in the middle of a block. This makes using markers advisable in all situations.

The following figure shows a Weaver script that include commands for placing markers.

Figure 3: Weaver script writing control chunks.

The `writestopchunk` command writes a STOP chunk to the output stream. You specify the time in audio clock ticks.

The `writehaltchunk` command writes a HALT chunk, which is sent to a specific subscriber. This can be used to halt the streamer thread from delivering chunks to all subscribers until a reply is received from the specified subscriber.

The `writemarkertable` command ensures the Weaver writes a table of marker positions with both time and position (file offset).

Note: When dealing with software compressed video, note that it's important to place markers at key frames. Examine the stream file to find out where key frames are located.

### For more information

The `writegotochunk` command is discussed in the next section.

## Jumping to a new location

To move to a different location in the application (branching), use the function `DSGoMarker()`. While starting or stopping a stream under certain conditions at certain points can happen under a variety of circumstances, branching is usually triggered by user input.

### Placing markers

Before your application can branch, you have to place markers in the stream file to branch to. You have to include `writegotochunk` commands into the Weaver script; the the markers are then placed in the stream file when the Weaver tool generates it. You specify the stream time at which the branching should happen and the place to which the stream should branch. The command in the figure above, for example, places a marker at stream time 3000 that jumps back to stream time 0.

### Using different options to DSGoMarker()

Different options to `DSGoMarker()` allow you to move in your stream in different ways:

- GOMARKER_ABSOLUTE goes to a specific marker number.

- GOMARKER_FORWARD and GOMARKER_BACKWARD moves forward or backward by the specified number of markers.

- GOMARKER_FORW_TIME, and GOMARKER_BACK_TIME, and GOMARKER_ABS_TIME move forward or backward by a specified number of clock ticks or to a specified time.

### Updating all threads participating in a streaming process

When a positioning operation-for example, with `DSGoMarker()`-has completed, the time associated with the marker position is transmitted to all other threads by a call to `DSClockSync()`. This function informs all subscriber threads that a change in the stream's temporal position has occurred and gives them the opportunity to take appropriate actions, such as flushing any "stale" data.

### Flushing

Flushing should only occur when a positioning operation completes, not when a marker is simply played through. This distinction is made by storing the last "go marker" destination in the stream control block. The control subscriber calls `DSIsMarker()` to test whether a time-stamped flush control chunk matches the last branch destination. If so, `DSIsMarker()` returns `TRUE` and clears the branch destination logic to prevent further matches; otherwise, it returns `FALSE`. This permits conditional flushing based on whether or not a marker position is played through or is the destination of a branch. The receipt of the flush control chunk indicates that a positioning operation is complete.