Rendering Video to a Graphics Surface Tutorial

This tutorial shows you how to use the Video Renderer utility class to create a new surface for rendering and render a video buffer onto the display.

Before you start, you must:

You use the CVideoRenderer utility class to render video to a graphics surface. CVideoRenderer has two modes:

  • Timed

    In timed mode, a frame is rendered at a specific time called its presentation time. A frame's presentation time is the system clock time when that frame must be visible on the display. CVideoRenderer launches its own high-priority thread to handle timed rendering.

  • Non-timed

    In non-timed mode, a frame is rendered as soon as possible. Non-timed mode requires a CActiveScheduler to be present in the calling thread.

CVideoRenderer uses the MVideoRendererObserver interface to provide notifications about the status of video buffers. MVideoRendererObserver provides the following notifications:

Callback Description

MVideoRendererObserver::MvroBufferDisplayed(TInt,const TTime &)

A buffer has been rendered onto the display.

MVideoRendererObserver::MvroBufferSkipped(TInt)

A buffer was skipped in the rendering process. This could be because it missed its presentation time or an error occurred.

MVideoRendererObserver::MvroVideoBufferAvailable()

A new buffer is available which can be used to store a video frame for rendering.

Note: You must implement MVideoRendererObserver to receive these notifications.

  1. Create a new Video Renderer instance by calling CVideoRenderer::NewL(MVideoRendererObserver&, TBool). Set the aTimed parameter to ETrue for timed mode or EFalse for non-timed mode.
    //Create new timed Video Renderer
    CVideoRenderer* renderer = CVideoRenderer::NewL(observer, ETrue);
    If in timed mode, CVideoRenderer launches its own high-priority thread.
  2. Get the list of supported surface formats by calling CVideoRenderer::GetSupportedFormatsL(RArray<TUncompressedVideoFormat>&). The Video Renderer maintains a list of supported formats in an RSS file. For more information, see Video Renderer Resource File.
    //Get an array of supported formats
    renderer->GetSupportedFormatsL(array);
    GetSupportedFormatsL() returns an array of supported formats. Use the supported format you require as an input parameter when creating your surface.
  3. Create a new surface for rendering by calling CVideoRenderer::CreateSurfaceL(const TSize&, TInt, const TUncompressedVideoFormat&, TSurfaceId&)
    TSurfaceId surfaceId;
    renderer->CreateSurfaceL(size, buffers, format, surfaceId);
    CVideoRenderer::CreateSurfaceL() returns a Surface ID for the new surface. You use the Surface ID whenever you need to refer to the surface, for example, when you need to destroy it.
  4. Retrieve the next free buffer from the Video Renderer by calling CVideoRenderer::NextBuffer().
    TVideoFrameBuffer* buffer = renderer->NextBuffer();
    // use buffer

    Note you should only perform this step after your observer's MvroVideoBufferAvailable() routine has been called.

    CVideoRenderer::NextBuffer() returns the next available buffer.
  5. Render the buffer onto the display by calling CVideoRenderer::UpdateBuffer(TVideoFrameBuffer *,const TTime &). If you created your Video Renderer in timed mode, set aPresentationTime to be the required presentation time for the buffer. If you created your Video Renderer in non-timed mode, then aPresentationTime is ignored and the buffer is displayed as soon as possible.
    FillWithData(buffer->Buffer()); // Fills buffer with data
    renderer->UpdateBuffer(buffer, presentationTime);
    When the buffer has been displayed, you are notified via the MVideoRendererObserver::MvroBufferDisplayed(TInt,const TTime &) callback.

You have now created a surface and rendered a video buffer onto the display.