Programming Indeo® Video Interactive With ActiveMovie*: Decompressing
If you are a multimedia application developer who wishes to include the advanced features of the Indeo® video interactive codec into your 32bit application, read this document. It explains what you need to know in order to control the playback parameters of the Indeo video interactive codec programmatically from the ActiveMovie* interface, so that you can integrate features such as access key protection or local decode. This document assumes you are familiar with ActiveMovie.
Indeo video interactive is Intel's latest digital video capture, compression, and decompression software. The technology is based on a compressor-decompressor, or codec, a software driver used to compress digital video data for storage, and decompress it for playback on a multimedia PC. Indeo video interactive uses an efficient encoding algorithm and yields high quality images. It includes a wide variety of features designed for interactive multimedia applications, such as real-time video effects, access key file protection, local decode, and the ability to specify transparency for portions of a video frame.
This document consists of four sections:
The ActiveMovie Interface to Indeo Video Interactive
Introduces ActiveMovie and outlines the process whereby your multimedia application can access the Indeo video interactive codec in the ActiveMovie environment.Codec States and Data Structures
Introduces the state structures used to pass information to and from the codec, and describes how to initialize them.Changing Playback Parameters
Provides specific details and C source code examples for accessing and modifying individual decode parameters.References
Points you to other documents that provide information on related topics.
In the ActiveMovie environment, an application uses the ActiveMovie COM interface to build a graph containing various filters--known as a filter graph. Each filter performs one service for the application, for example, getting the data from the source file, transforming the data, or rendering the data in some manner. The Indeo video codec is represented in this environment by an Indeo video filter; in the context of ActiveMovie, therefore, the expressions Indeo video codec and Indeo video filter are synonyms.
Every filter has one or more interfaces, and each interface serves a specific purpose. The Indeo video filter has an encode interface and a decode interface. Both are customized to allow applications to access the special features of Indeo video interactive.
To use the Indeo video codec in the ActiveMovie environment, an application takes the following basic steps:
The following code shows how to get a pointer to the decode interface of the Indeo video filter (the IIndeoDecode interface) after a movie file has been opened. This interface is then used in subsequent calls to get and set the Indeo video interactive decode parameters.
// IFilterGraph *pGraph is a graph populated with filters to render // a particular media file. See the ActiveMovie SDK Help reference // for the IGraphBuilder interface and its RenderFile method. // See if the Indeo codec filter is in the graph. pGraph->EnumFilters(&pEnum); // While there are more filters, get the next filter in the graph. while ((hr = pEnum->Next(1, &pFilter, &pcFetched))== S_OK) { // Does this filter expose the IIndeoDecode interface? hr = pFilter->QueryInterface(IID_IIndeoDecode, &pIndeo); pFilter->Release(); // If the interface is exposed, break out of the loop. if (hr == S_OK) break; } //This interface must be released even though it was not obtained in the usual way with QueryInterface. pEnum->Release();
NOTE: For a complete application example, see the source code for IPlay, an example application that plays back video files, taking advantage of most of the special features provided by Indeo video interactive. The executable application is available in the file iplay.exe, and the C++ source code is available in the file iplaysrc.exe.
In one respect, ActiveMovie is a significant departure from the Video for Windows model: while Video for Windows is frame-based, ActiveMovie is time-based. While it remains straightforward to access sequence state in the ActiveMovie environment, accessing frame state is less straightforward. A COM filter graph is intended to encapsulate the service it provides, thus, certain features that depend on accessing frame state, such as transparency, are more difficult to implement.
Two predefined data structures represent these states: R4_DEC_SEQ_DATA represents sequence state and R4_DEC_FRAME_DATA represents frame state. They are defined in the file ax_spec.h.
While decoding, you can examine or change the codec state by using one of the methods getDecodeFrame or setDecodeFrame, getDecodeSequence or setDecodeSequence, passing as the parameter the address of one of these two predefined state structures. See ax_spec.h for methods on the interface IIndeoDecode.
Both data structures contain header members that your application initializes in the same way regardless of the operation to be performed, as well as other members whose initialization and use is operation-specific.
The Decode Sequence Data Structure
The R4_DEC_SEQ_DATA data structure contains
members that describe the state of the codec for sequences of decode operations.
A sequence starts when the IMediaControl interface invokes the method Run
and continues until it invokes the method Pause or Stop. You can change
the sequence state of the codec at any point in a sequence, but the change
has no effect until the next sequence begins.
The following C code example demonstrates how to initialize the header members of the R4_DEC_SEQ_DATA structure before sending either setDecodeSequence or getDecodeSequence. (Initialize other members of this structure according to the type of action required, as detailed in the next section.)
R4_DEC_SEQ_DATA r4SeqData; r4SeqData.dwSize = sizeof(R4_DEC_SEQ_DATA); r4SeqData.dwFourCC = FOURCC_IV41; r4SeqData.dwVersion = SPECIFIC_INTERFACE_VERSION; r4SeqData.mtType = MT_DECODE_SEQ_VALUE; r4SeqData.oeEnvironment = OE_32; r4SeqData.dwFlags = 0;
The Decode Frame Data Structure
The R4_DEC_FRAME_DATA data structure contains
members that describe the state of the codec for decode operations. The
codec incorporates changes to its frame state as the Indeo video codec/filter
decodes.
The following C code example demonstrates how to initialize the header members of the R4_DEC_FRAME_DATA structure before sending either setDecodeFrame or getDecodeFrame. (Initialize other members of this structure according to the type of action required, as detailed in the next section.)
R4_DEC_FRAME_DATA r4FrmData; r4FrmData.dwSize = sizeof(R4_DEC_FRAME_DATA); r4FrmData.dwFourCC = FOURCC_IV41; r4FrmData.dwVersion = SPECIFIC_INTERFACE_VERSION; r4FrmData.mtType = MT_DECODE_FRAME_VALUE; r4FrmData.oeEnvironment = OE_32; r4FrmData.dwFlags = 0;
The Current and Default Codec States
In both the R4_DEC_SEQ_DATA and R4_DEC_FRAME_DATA
structures, the member mtType indicates whether action is taken on the
current or the default state of the codec. Values of MT_DECODE_FRAME_VALUE
or MT_DECODE_SEQ_VALUE specify actions taken on the current codec state.
The other defined values, MT_DECODE_FRAME_DEFAULT or MT_DECODE_SEQ_DEFAULT,
specify that actions are taken on the default codec state. When you act
on the default codec state it becomes the current state.
The examples below demonstrate how to use the methods getDecodeFrame, setDecodeFrame, getDecodeSequence, or setDecodeSequence to get and set sequence or frame parameters. These examples all follow the same general pattern:
Modifying the Decode Sequence Parameters
The following examples demonstrate how
to use the setDecodeSequence message to modify selected decode
parameters. These examples all assume that the r4State variable was initialized
prior to sending the message to the codec, as shown in the section above
entitled "Codec States and Data Structures."
NOTE: For the sake of clarity, the examples below do not check return values for errors. Your application, however, needs to check all return values for errors.
Transparent Pixel Fill Method
Setting the fill method for transparent
pixels determines whether the codec writes only the nontransparent pixels
to the output buffer, or writes the transparent pixels also. This determines
whether the user sees the nontransparent shape against a solid background
written by the codec, as illustrated in Figure 1, or against no background
at all. If the codec does not write the background pixels, they are not
updated, leaving visible those pixels that represented the foreground objects
in previous frames.
Figure 1. Transparent Pixel Fill Method: Codec Writes Background
If the codec writes the transparent pixels, the color it uses to represent them is based on the method of encoding: black if encoded with the TM_BITMASK option, or one of the transparent colors if encoded with any other option.
If the codec does not write the transparent pixels, your application is responsible for the state of the buffer before the frame is decoded. If you wish your application to supply its own background, such as a bitmap, then you must either write your own filter to replace the Indeo video codec, or else write an additional filter that can mix the pixels appropriately after the video data is decoded by the Indeo video filter.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_SEQ_DATA r4SeqData is an initialized decode sequence structure */ /* Set the valid field flags*/ r4SeqData.dwFlags = DECSEQ_FILL_TRANSPARENT | DECSEQ_VALID; /* Set the transparency fill field */ r4State.fFillTransparentPixels = 1; /* 1 = fill, 0 = don't fill */ pIndeo->set_DecodeSequence(&r4SeqData);
Decode Scalability
The decode scalability parameter allows
the application to turn on or off the quality scalability feature of the
codec. Quality scalability allows Indeo video interactive to reduce
image quality rather than drop frames if insufficient processor resource
is available to decode all the compressed frame data within the time limit.
By default, the time limit is determined by the frame rate with which the video was encoded. If your application requires faster decoding, you can set a more stringent time limit as discussed in the section entitled "Setting the decode time limit," below.
Turn decode scalability on with the fScalability variable.
NOTE: Turning decode scalability on affects only playback of those video clips that were encoded with scalability on.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_SEQ_DATA r4SeqData is an initialized decode sequence structure */ /* Set the valid field flags */ r4SeqData.dwFlags = DECSEQ_SCALABILITY | DECSEQ_VALID; /* Set the scalability field */ r4SeqData.fScalability = 1; /* 0 = disable, 1 = enable */ pIndeo->set_DecodeSequence(&r4SeqData);
Access Key Protection
This feature allows an application to supply
an access key for video clips that have been encoded with access key protection
enabled. It has no effect on clips not encoded with the access key feature.
An access key must have a numeric value only. Valid values are in the range of 0 through (232-1). If a clip has been encoded with access key protection enabled and the proper access key is not supplied when decoding, the codec returns the error ICERR_INTERNAL as soon as it receives the next decompression message.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_SEQ_DATA r4SeqData is an initialized decode sequence structure */ /* Set the valid field flags */ r4SeqData.dwFlags = DECSEQ_KEY | DECSEQ_VALID; /* Set the enable key field and the key itself */ r4SeqData.fEnabledKey = 1; /* 0 = disable, 1 = enable */ r4SeqData.dwKey = 032455; pIndeo->set_DecodeSequence(&r4SeqData);
Alternate Line Zoom-by-two
NOTE: Alternate line zoom-by-two is not implemented in this release.
Modifying the Decode Frame Parameters
Setting the address of the transparency
bounding rectangle
As shown in Figure 2, the bounding
rectangle is the smallest rectangle that can contain the nontransparent
pixels.
Figure 2. Bounding Rectangle of Nontransparent
Figure
The application must specify the address of an R4_RECT structure to which the codec can return the origin, width, and height of the bounding rectangle in the last frame decoded: that is, which rectangular region of the frame was written over. This allows the application to repaint the background after the nontransparent shape has moved.
Once you have set the address of the bounding rectangle, the codec updates the bounding rectangle's position after each frame is decoded so that the application can continue to clean up the background as necessary.
If the codec returns all zeroes, no pixels were written in the last frame because the nontransparent shape did not appear.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_FRAME_DATA r4FrmData is an initialized decode frame structure */ R4_RECT r4Rect; /* Set the valid field flags */ r4FrmData.dwFlags = DECFRAME_BOUNDING_RECT | DECFRAME_VALID; /* Set the bounding rect field */ r4FrmData.pr4BoundingRect = &r4Rect; pIndeo->set_DecodeFrame(&r4FrmData);
Setting the Address of the Transparency
Bitmask
The Indeo video interactive codec can handle
transparency while decoding frames, or the application can handle the transparency
itself after frames have been decoded; in either case, however, you must
specify how the transparency is to be handled. The Indeo video interactive
codec can decode only transparent video that was encoded using the Indeo
video interactive codec with the transparency option enabled. It cannot
decode transparent video generated by any other means.
If you decide to handle the transparency in your application, this message provides the codec with the address of memory in which to write a onebit bitmask for the last frame decoded, and the address of a flag to be set if bitmask information is available. Enough memory must be allocated for one bit to represent each pixel of a frame. The bitmask specifies which areas of the frame have nontransparent video information: a value of zero means a pixel is transparent and a value of one means that it is not.
Each row must begin on a DWORD boundary, and the total number of bytes must be a multiple of four. If it isn't, round up to the nearest multiple of four.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_FRAME_DATA r4FrmData is an initialized decode frame structure */ /* Set the valid field flags */ r4FrmData.dwFlags = DECFRAME_TRANS_BITMASK | DECFRAME_VALID; /* Set the transparency bitmask and updated bitmask fields */ r4FrmData.pfUpdatedTransparencyBitmask = &fBitmask; r4FrmData.pbmTransparencyBitmask = pbmBitmask; pIndeo->set_DecodeFrame(&r4FrmData);
Setting the Decode Time Limit
An application can specify the number of
milliseconds in which the codec must decompress and color-convert each
frame. If scalability was not enabled during compression, the codec ignores
the time limit. If a frame cannot be decoded in the time specified and
quality scalability is on, image quality is reduced.
The milliseconds specified are wall clock milliseconds, not CPU cycles. The codec consults the system clock to determine the elapsed time.
If you set the time limit to zero, the codec uses the frame rate with which the video was encoded to determine the time limit. This is the default. For example, a frame rate of ten frames per second indicates a time limit of one hundred milliseconds.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_FRAME_DATA r4FrmData is an initialized decode frame structure */ /* Set the valid field flags */ r4FrmData.dwFlags = DECFRAME_TIME_LIMIT | DECFRAME_VALID; /* Set the time limit field (milliseconds) */ r4FrmData.dwTimeLimit = dwTimeLimit; pIndeo->set_DecodeFrame(&r4FrmData);Setting the Position and Dimensions of the Decode Rectangle for Local Decode
A decode rectangle cannot be smaller than the minimum size specified during encoding. It can be changed only immediately before a key frame; if you try to change it before any other frame, the codec queues your request, which takes effect at the next key frame. The decode rectangle cannot extend outside the image and must wholly enclose the view rectangle, which is discussed below. If all fields are zero, the entire image is decoded.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_FRAME_DATA r4FrmData is an initialized decode frame structure R4_RECT r4DecodeRect is the decode rectangle */ /* Initialize the decode rectangle */ r4DecodeRect.dwX = x; /* X of upper left corner*/ r4DecodeRect.dwY = y; /* Y of upper left corner */ r4DecodeRect.dwWidth = dx; /* Width */ r4DecodeRect.dwHeight = dy; /* Height */ /* Set the valid field flags */ r4FrmData.dwFlags = DECFRAME_DECODE_RECT | DECFRAME_VALID; /* Set the decode rect field */ r4FrmData.rDecodeRect = &r4DecodeRect; pIndeo->set_DecodeFrame(&r4FrmData);
Setting the Position and Dimensions of
the View Rectangle for Local Decode
Within a decode rectangle, Indeo video
interactive can further limit the pixels it writes to the output buffer.
This smaller area is called the view rectangle. Specify the origin,
width and height of the view rectangle relative to the original image.
The view rectangle cannot extend outside the decode rectangle; if it does,
the codec returns the error ICERR_BADPARAM when the next decompression
message is received. If all fields are zero, the view rectangle defaults
to the entire decode rectangle.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_FRAME_DATA r4FrmData is an initialized decode frame structure R4_RECT r4ViewRect is the view rectangle */ /* Initialize the view rectangle */ r4ViewRect.dwX = x; /* X of upper left corner*/ r4ViewRect.dwY = y; /* Y of upper left corner */ r4ViewRect.dwWidth = dx; /* Width */ r4ViewRect.dwHeight = dy; /* Height */ /* Set the valid field flags */ r4FrmData.dwFlags = DECFRAME_VIEW_RECT | DECFRAME_VALID; /* Set the view rect field */ r4FrmData.rViewRect = &r4ViewRect; pIndeo->set_DecodeFrame(&r4FrmData);
Setting the Brightness, Saturation, and
Contrast Levels
Indeo video interactive supports changing
the brightness, contrast, and saturation of the video clip during playback.
Valid values for all three parameters range from -255 to 255.
Brightness is an additive adjustment to luminance. Contrast and saturation are nonlinear adjustments.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_FRAME_DATA r4FrmData is an initialized decode frame structure b, s, c are long in the range -255 to 255 */ /* Set the valid field flags */ r4FrmData.dwFlags = DECFRAME_BRIGHTNESS | DECFRAME_SATURATION | DECFRAME_CONTRAST | DECFRAME_VALID; /* Set the brightness, saturation, and contrast fields */ r4FrmData.lBrightness = b; r4FrmData.lSaturation = s; r4FrmData.lContrast = c; pIndeo->set_DecodeFrame(&r4FrmData);
Retrieving the Decode Sequence Parameters
The following examples show how to use
the getDecodeSequence method to retrieve the current decode sequence
parameters.
NOTE: The access key parameters cannot be retrieved.
Transparent Pixel Fill Method
To retrieve the current fill mode, set
the appropriate flag in the dwFlags field and send the getDecodeSequence
message. On successful return, the fFillTransparentPixels member of the
r4State structure indicates the current mode.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_SEQ_DATA r4SeqData is an initialized decode sequence structure */ /* Set the valid field flags */ r4SeqData.dwFlags = DECSEQ_FILL_TRANSPARENT |DECSEQ_VALID; pIndeo->get_DecodeSequence(&r4SeqData);
Decode Scalability
To retrieve the current decode scalability
mode, set the appropriate flag in the dwFlags field and send the getDecodeSequence
message. On successful return, the fScalability member of the r4State structure
indicates the current mode.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_SEQ_DATA r4SeqData is an initialized decode sequence structure */ /* Set the valid field flags */ r4SeqData.dwFlags = DECSEQ_SCALABILITY | DECSEQ_VALID; pIndeo->get_DecodeSequence(&r4SeqData);
Alternate Line Zoom-by-two
NOTE: Alternate line zoom-by-two is not implemented in this release.
Retrieving the Decode Frame Parameters
The following examples show how to use
the getDecodeFrame message to retrieve the current decode frame
parameters.
NOTE: The address of the transparency bounding rectangle and the transparency bitmask cannot be retrieved. These parameters were originally furnished by the application.
Retrieving the Decode Time Limit
To retrieve the current decode time limit,
set the appropriate flag in the dwFlags field and call the getDecodeFrame
method. On successful return, the lTimeLimit member of the r4State structure
contains the current value.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_FRAME_DATA r4FrmData is an initialized decode frame structure */ /* Set the valid field flags */ r4FrmData.dwFlags = DECFRAME_TIME_LIMIT | DECFRAME_VALID; pIndeo->get_DecodeFrame(&r4FrmData);
Retrieving the Position and Dimensions
of the Decode Rectangle for Local Decode
To retrieve the current origin, width,
and height of the decode rectangle, set the corresponding flag in the dwFlags
field, supply the address of R4_RECT in which to place the values, and
call the getDecodeFrame method. On successful return, the R4_RECT
contains the current position and dimensions of the decode rectangle.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_FRAME_DATA r4FrmData is an initialized decode frame structure */ /* Set the valid field flags */ r4FrmData.dwFlags = DECFRAME_DECODE_RECT | DECFRAME_VALID; pIndeo->get_DecodeFrame(&r4FrmData);
Retrieving the Position and Dimensions
of the View Rectangle for Local Decode
To retrieve the current position and dimensions
of the view rectangle, set the corresponding flag in the dwFlags field,
supply the address of R4_RECT in which to place the values, and call the
getDecodeFrame method. On successful return, the R4_RECT contains
the current position and dimensions of the view rectangle.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_FRAME_DATA r4FrmData is an initialized decode frame structure */ /* Set the valid field flags */ r4FrmData.dwFlags = DECFRAME_VIEW_RECT | DECFRAME_VALID; pIndeo->get_DecodeFrame(&r4FrmData);
Retrieving the Brightness, Saturation,
and Contrast Levels
To retrieve the current values for brightness,
saturation, and contrast, set the corresponding flags in the dwFlags field
and call the getDecodeFrame method. On successful return, the
lBrightness, lSaturation, and lContrast members of the r4State structure
contain the current values.
/* IIndeoDecode *pIndeo is a valid pointer to an IVI decoder interface R4_DEC_FRAME_DATA r4FrmData is an initialized decode frame structure */ /* Set the valid field flags */ r4FrmData.dwFlags = DECFRAME_BRIGHTNESS | DECFRAME_SATURATION | DECFRAME_CONTRAST | DECFRAME_VALID; pIndeo->get_DecodeFrame(&r4FrmData);
For latest information, also see:
For more information on COM, see:
* Legal Stuff © 1997 Intel Corporation