Displaying Video in an Audio/Video Session

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

In an A/V session, you should display the video stream originating with the remote participant, whether the remote participant is an individual user or a multipoint control unit (MCU) component of a conference. You can also display a preview of the video stream originating on the local client. You use the video channel of the remote participant of the A/V session to display both the remote video stream and the outgoing video preview.

Unified Communications Client API utilizes the video rendering capability exposed by the Microsoft DirectShow application programming interface. The UccApi handles the details of the necessary DirectShow programming but exposes a property that returns an IVideoWindow interface instance you can use to customize the appearance of a video rendering control.

To display video in an A/V session, you need to:

  • Obtain the media channel that carries the video stream from the remote participant media channel collection.
  • Cast the IUccMediaChannel instance to IUccVideoMediaChannel to expose necessary video functionality.
  • Obtain IVideoWindow from an instance of IUccVideoMediaChannel. For more information about programming with this interface, see IVideoWindow Interface.
  • Create and open a new Windows form to display the video created in the preceding steps.
    The IVideoWindow instance is a Windows control that can be programmatically placed on the form you create.

The following example creates a video window to display the video stream originated on a remote client. Note that get_VideoWindow specifies the UCCMD_RECEIVE media direction. To create a video window that displays video originated on the local client, use the remote participant video channel, but specify the media direction of UCCMD_SEND.

private void showVideo(IUccSessionParticipant pRemoteParticipant)
{
    IUccMediaChannel videoChannnel = findVideoChannel(
                                     pRemoteParticipant as IUccAudioVideoSessionParticipant,
                                     UCC_MEDIA_TYPES.UCCMT_VIDEO);
    if (videoChannnel != null)
    { 

        //set incomming video window
        IUccVideoMediaChannel pVideoChannel = videoChannnel as IUccVideoMediaChannel;

        IVideoWindow m_VideoWindowReceive = pVideoChannel.get_VideoWindow(
              UCC_MEDIA_DIRECTIONS.UCCMD_RECEIVE);

        m_VideoWindowReceive.Visible = -1;
        m_VideoWindowReceive.AutoShow = -1;
        m_VideoWindowReceive.Owner = (int)this.Handle;
        m_VideoWindowReceive.MessageDrain = (int)this.Handle;
        m_VideoWindowReceive.SetWindowPosition(10, 14, 349, 357);
        try
        {
            m_VideoWindowReceive.SetWindowForeground(-1);
        }
        catch (COMException e)
        {
            MessageBox.Show(e.ErrorCode.ToString(), " COMException on SetWindowForeground");
        }


        // Set preview window for outbound video stream.
        IVideoWindow m_VideoWindowSend = pVideoChannel.get_VideoWindow(
            UCC_MEDIA_DIRECTIONS.UCCMD_SEND);


        m_VideoWindowSend.AutoShow = -1;
        m_VideoWindowSend.Owner = (int)this.Handle;
        m_VideoWindowSend.MessageDrain = (int)this.Handle;
        m_VideoWindowSend.SetWindowPosition(370, 14, 349, 357);
        try
        {
            this.m_VideoWindowSend.SetWindowForeground(-1);
            m_VideoWindowSend.Visible = -1;
        }
        catch (COMException e)
        {
            MessageBox.Show(e.ErrorCode.ToString(), " COMException on SetWindowForeground");
        }
    }
}
private IUccMediaChannel findVideoChannel(
                 IUccAudioVideoSessionParticipant p,
                 UCC_MEDIA_TYPES pMediaType)
{
    IUccMediaChannel returnValue = null;

    foreach (IUccMediaChannel c in p.Channels)
    {
        if (c.MediaType == pMediaType)
        {
            returnValue = c;
             break;
        }
    }

    return returnValue;
}

Although not required, it is considered a good practice to do the following:

  • Check the session maximum bandwidth. Read the MaximumBandwidth property. If the maximum bits per second are insufficient for audio and video, you can set the MaximumBandwidth property to a higher value.
  • Check the signal level of the audio channel in both the send and receive directions to ensure that capture and render volumes are sufficient. For more information, see get_SignalLevel.
  • Check the media port range. If a media port range is specified for the endpoint, the range must be at least four ports wide. For more information, see GetMediaPortRange.
  • Check the acoustic echo cancellation property of the session. For more information, see AcousticEchoCancellationEnabled.
  • Check the media connectivity server. If a participant in the media session is on the other side of a firewall, you need to verify that the endpoint object is configured with a media connectivity server that corresponds to a NAT protocol on the network media relay server. For more information, see Media Connectivity Objects.

See Also

Concepts

Conducting an Audio/Video Session
Channels in Media Sessions