next up previous contents index
Next: Use guidelines Up: Full Motion Player Application Previous: Source and destination settings   Contents   Index


Streaming video

This driver has been specially designed and optimized for streaming video.

The data interface is based on a push model: the application must create a Task or Thread and then push the data it receives from the network (or from the disk) into the driver.

Basically the application will create a Task dedicated to listen to a Live Source of MPEG data and bring it to system memory to be transferred to the MPEG driver.

Synchronization
  1. The application must send play (FMPPlay) or pause (FMPPause) to the driver before sending any data.

  2. The application must stop sending data to the driver before sending a stop command (FMPStop).

  3. The driver takes care of the memory management : the application has to ask a buffer to the driver. Then the application can fill this buffer with data and then can push the buffer back to the driver.

  4. Overflow is handled by the data source: overflow condition happens when the memory manager cannot deliver a buffer (FMPGetBuffer block until a buffer is available or return an error code if the bBlockingCall argument is set to FALSE).

  5. Underflow is handled by the MPEG driver: underflow condition happens when the video decoder is in starvation.

    The application can prevent this condition to happen by re-buffering data when a low-water mark condition is reached.

    It is recommended to use double-buffering to prevent underflow conditions.

  6. The application cannot call any FMPStop or FMPClose before pushing back all the buffers to driver. If FMPStop or FMPClose is called between a FMPGetBuffer/FMPPush call sequence, the driver will not be able to release its memory.

PES Support

To enable PES playback, open the driver (FMPOpen) with the FMPF_PES option.

When you get a buffer from the driver (FMPGetBuffer) you have to specify if you want a video or an audio buffer in the FMP_BUFFER structure.

Here is a small code snippet :


FMP_BUFFER FMPBuf;

if (FMPOpen (FMPF_PES, 1024*32, 8, 0, 0) != FMPE_OK)
{
FMPClose ();
goto exit_now;
}
FMPPlay ();
while (1)
{
FMPBuf.dwFlagsEx = FMP_VIDEO_PES;
if (FMPGetBuffer (&FMPBuf, TRUE) == FMPE_OK)
{
nbytes = fread (FMPBuf.pBuffer, 1, 1024*32, file_handle);
FMPBuf.dwDataSize = nbytes;
if (FMPPush (&FMPBuf) != FMPE_OK)
{
printf ("FMPPush() error");
printf ("FMPBuf.pBuffer = 0x%08lx", FMPBuf.pBuffer);
}
}
}

The pes packets must not have 0 as the packet length.

If there are 0 length (in the case of video packets inside a transport stream) then there is a special PES format that the MPEG driver can accept:

The PES file format is meant to model how PES data coming from a transport stream will be pushed to the MPEG driver for decoding. For both audio and video files, the data can be formatted as follows.

A data block may or may not contain an entire packet, but it will never contain more than one packet.

In other words, each data block may contain at most one PES packet.

If the whole PES packet cannot fit in the data block, then the next data block(s) will contain the rest of the packet. PES packets always start on data block boundaries.

DataBlock = { 00 00 01 BA | Flags (4 bytes) | PacketDataLength (4 bytes) | packet data }

DataBlockLength = 4 + 4 + 4 + PacketDataLength

Thus a stream that an application would push to the MPEG driver would look like the following.

PushedVideoStream = DataBlock, DataBlock, DataBlock, ..., DataBlock PushedAudioStream = DataBlock, DataBlock, DataBlock, ..., DataBlock

When the application calls FMPPush, the buffer will be filled with a single DataBlock. The length of the FMP_BUFFER will be set to DataBlockLength. The application will also set the dwFlagsEx to flag either audio or video as appropriate.

Flag values are as follow:

  1. - Continuation packet (flag 0)
  2. - Discontinuity (flag 1)
  3. - Packet start (flag 2)
  4. - Packet checksum error (flag 3)

Here is the beginning of a video sequence.

** 0 - Len 1944 (0x798) Flags 0x00000002 Offset 12 (0xc)

** 1 - Len 1640 (0x668) Flags 0x00000002 Offset 1968 (0x7b0)

** 2 - Len 3000 (0xbb8) Flags 0x00000002 Offset 3620 (0xe24)

** 3 - Len 1656 (0x678) Flags 0x00000002 Offset 6632 (0x19e8)

** 4 - Len 1616 (0x650) Flags 0x00000002 Offset 8300 (0x206c)

** 5 - Len 1992 (0x7c8) Flags 0x00000002 Offset 9928 (0x26c8)

** 6 - Len 1824 (0x720) Flags 0x00000002 Offset 11932 (0x2e9c)

** 7 - Len 1672 (0x688) Flags 0x00000002 Offset 13768 (0x35c8)

** 8 - Len 3400 (0xd48) Flags 0x00000002 Offset 15452 (0x3c5c)

** 9 - Len 2192 (0x890) Flags 0x00000002 Offset 18864 (0x49b0)

** 10 - Len 2264 (0x8d8) Flags 0x00000002 Offset 21068 (0x524c)

** 11 - Len 3944 (0xf68) Flags 0x00000002 Offset 23344 (0x5b30)

** 12 - Len 3264 (0xcc0) Flags 0x00000002 Offset 27300 (0x6aa4)

** 13 - Len 3496 (0xda8) Flags 0x00000002 Offset 30576 (0x7770)

** 14 - Len 16356 (0x3fe4) Flags 0x00000002 Offset 34084 (0x8524)

** 15 - Len 16356 (0x3fe4) Flags 0x00000000 Offset 50452 (0xc514)

** 16 - Len 16356 (0x3fe4) Flags 0x00000000 Offset 66820 (0x10504)

** 17 - Len 16356 (0x3fe4) Flags 0x00000000 Offset 83188 (0x144f4)

** 18 - Len 12696 (0x3198) Flags 0x00000000 Offset 99556 (0x184e4)

** 19 - Len 2024 (0x7e8) Flags 0x00000002 Offset 112264 (0x1b688)

For each line, the application would do an FMPPush, pushing the entire data block as described above.

Note that blocks 14 - 18 are actually a single PES packet. The others are all individual PES packets.

Implementing trick modes

This section explains how to enter and exit trick mode using the push model.

By entering trick mode, you indicate the MPEG decoder to decode only I frames. B and P frames will be ignored. This is very useful for simulating fast forward and fast rewind.

To have a seamless effect (that means not stopping the streaming), the command has to be embedded inside the stream. In the FMP_BUFFER structure, there is a dwFlags paramaters that can be or'ed to FMP_TRICKMODE_START to start the trick mode and FMP_TRICKMODE_END to end it.

When you flag your buffer with FMP_TRICKMODE_START, the driver will :

  1. - Stop decoding B and P frame from byte 0 of the flagged buffer.
  2. - Stop decoding audio from byte 0 of the flagged buffer.
  3. - Stop synchronizing Video to Audio.

These effects will stay in place until a buffer is flagged FMP_TRICKMODE_END :

When you flag your buffer with FMP_TRICKMODE_START, the driver will :

  1. - Start decoding B and P frame from byte 0 of the flagged buffer.
  2. - Start decoding audio from byte 0 of the flagged buffer.
  3. - Start synchronizing Video to Audio.

This will resume normal playback.


next up previous contents index
Next: Use guidelines Up: Full Motion Player Application Previous: Source and destination settings   Contents   Index
mabelsha 2002-03-26