September 29, 2020
Hot Topics:

Video Playbacks on Windows Mobile 5.0: A Guide for Beginners

  • By Alex Gusev
  • Send Email »
  • More Articles »

Video on Windows Mobile 5.0

Windows Mobile 5.0 has a lot of new features, both exciting and disappointing. Here, I will discuss its bright side in regard to its multimedia support. Prior to WM 5.0 you have the only option: Windows Medial Player control. You saw it in one of my previous articles. Well, you always had a nice choice to develop your own player from scratch, which is, believe me, a very interesting but quite complicated task; or, you could use third-party libraries or components; for example, TCPMP or PocketTV.

Since WM 5.0 went live, the situation has gotten much better. WMP wasn't bad or useless, but you couldn't play AVI or MPEG files. The new SDK gives you more ways to display video playbacks on a mobile device. Frankly, you might find similar support even on Windows CE.NET 4.2 with some devices—for example, the Fujitsu iPAD—but it really wasn't common practice.

So, what does WM 5.0 offer you in the multimedia arena? The answer is a set of DirectShow interfaces. They enable you to make relatively high quality video playbacks and capture multimedia streams. Theoretically, DirectShow for WM 5.0 provides support for AVI and MPEG-1 along with previously supported WMV, WAV, and other formats. The real situation may be slightly different. For example, if a handheld device has no video camera, you can be quite sure that MPEG-1 files won't be played. As usual, the actual media format support depends on the device vendor. The next thing to note is that recently DirectShow for WM 5.0 is available only in native code.

DirectShow contains many different interfaces. It provides much more control and flexibility than the WMP control. Here, you will focus on how to display video playbacks, hence putting aside such topics as developing various converters and so forth.

As you can learn from the DirectShow documentation, the main building block there is a Filter. This is a COM component that performs all the work on the media stream for you. Filters can be used to read files, decode, and so forth, so this is the real "workhorse" of the DirectShow API.

Typical Application Structure

When utilizing the DirectShow API in your own application, in most cases you will follow some common steps, like these:

  • Create an IGraphBuilder instance
  • Query additional required interfaces through it; for example, IMediaControl, IMediaEvent, and IVideoWindow
  • Control everything by calling IGraphBuilder methods and responding to events
  • Clean up all COM objects

If you need a more complicated or advanced scenario, you may refer to the DirectShow SDK documentation for more details. You do need to remember that video rendering is performed in separate threads because DirectShow creates new threads for IGraphBuilder and all filters. Thus, those threads need to get enough time to run. If your application does some heavy processing at the same time, video playback will not be an acceptable quality.

Sample Application

Now, dig in into the coding. The first code snippet shows how to play a media file within given window:

#include <dshow.h>
CComPtr<IGraphBuilder>   pGraph;
CComPtr<IMediaControl>   pMediaControl;
CComPtr<IVideoWindow>    pVidWin;

void PlayMediaFile(HWND hwndOwner, LPCTSTR lpszFileName)
    HRESULT hr = S_OK;

    // Create the filter graph manager.
    hr = pGraph.CoCreateInstance(CLSID_FilterGraph);
    if ( FAILED(hr) )
       // add some error handling here

    hr = pGraph->QueryInterface(IID_IMediaControl,
                                (void **)&pMediaControl);
    hr = pGraph->QueryInterface(IID_IVideoWindow,
                                (void **)&pVidWin);

    // Build the graph.
    hr = pGraph->RenderFile(lpszFileName, NULL);

    if ( SUCCEEDED(hr) )
       // Set the video window.
       pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);

       RECT rc;
       GetClientRect(hwndOwner, &rc);
       pVidWin->SetWindowPosition(0, 0, rc.right, rc.bottom);

       // Run the graph.
       hr = pMediaControl->Run();
    // add here some error processing

As you can see, it strictly follows a typical scenario. First, an IGraphBuilder instance is created. If it was successful, the snippet queries the IMediaControl and IVideoWindow pointers. The next step is to build the required filter graph by calling the pGraph->Render() method. Usually, you would want to display a playback within some child window in your application, so an IVideoWindow instance allows you to set a parent for the video window. Finally, IMediaControl starts the actual playback processing.

Note: This operation is handled on separate thread, so you have to take care not to exit before the filter graph is processed.

The IGraphBuilder::Render() method may return an error, such as VFW_E_CANNOT_RENDER, in case problems occur. A full list of error codes can be found in the vfwmsgs.h header file. If rendering was successful, below you may see its result of playing the clock.avi taken from the desktop:

Page 1 of 2

This article was originally published on March 15, 2006

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date