i
i
i
i
i
i
i
i
16.5. A Stereoscopic Movie Player 449
In response to a command to play a movie, the application program will use
DirectShow to build and run an appropriate FilterGraph. By combining the
FilterGraph (which also renders the audio) and the OpenGL display, we will
have an application program that takes a single AVI file with left-o ver-right
stereoscopic frames, encoded using any codec (so long as that codec is in-
stalled on the computer) and plays it back in either a window or by filling
the screen. Figure 16.8 shows the filter components of the DirectShow graph
that we need.
Next we turn to the design of the custom renderer filter.
// Although a GIUD for the filter will not be used we must still declare
// one because the base class requires it.
struct
__declspec(uuid("{C7DF1EAC-A2AB-4c53-8FA3-BED09F89C012}")) CLSID_OpenGLRenderer;
class CRendererOpenGL : public CBaseVideoRenderer
{
public: // Class constuctor and destructor
// pointer to application object
CRendererOpenGL(CMoviePlayer
*
pPres,
LPUNKNOWN pUnk,HRESULT
*
phr); // standard COM pointers
˜CRendererOpenGL();
public: // these methods must be overidden -
// see individual listings for details
// Is the Video Format acceptable?
HRESULT CheckMediaType(const CMediaType
*
pmt );
// Video format notification
HRESULT SetMediaType(const CMediaType
*
pmt );
// New video sample (THIS FILLS THE BUFFER
HRESULT DoRenderSample(IMediaSample
*
pMediaSample);
// USED BY OPENGL
private: // member variables
// pointer to a C++ object we will use to encapsulate the whole Filter graph
CMoviePlayer
*
m_pCP;
LONG m_lVidWidth; // Video/movie width
LONG m_lVidHeight; // Video/movie height
// Pitch is the number of bytes in the video buffer required to step to next row
LONG m_lVidPitch;
};
Listing 16.4. The derived class for the renderer filter. The member variables record
the dimension of the movie/video frames and the pitch specifies how the addresses in
RAM change from one row of pixels to the next. This allows the rows in an image to
be organized into memor y blocks that are not necessarily stored contiguously.