An AudioVideoFlowinstance represents a media connection with a single remote participant.

AudioVideoFlow State Transitions

The AudioVideoFlow state transitions are shown in the following illustration.

  1. The transition from Idleto Activeoccurs when the AudioVideoFlowinstance determines that media can now be exchanged (or should be able to be exchanged) with the remote peer. The most common causes for this transition are:

    • Media (RTP or RTCP) is received from the remote peer.

    • For an incoming call, acknowledgement from the caller that it has received a provisional or final acceptance of the call (by the application calling, respectively, BeginEstablishEarlyMediaor BeginAccept). That is, a SIP PRACK or ACK message is received from the caller.

    • Special case: The remote endpoint negotiates the audio channel to be disabled. Disabled media means that no transport connection will be established; in SDP, the media is identified with a ‘c=IN IP4 0.0.0.0’ connection address line.

  2. The transition from Activeto Terminatedoccurs when a call ends after the media session is established. The most common causes for this transition are:

    • One of the endpoints terminates the call.

    • The media session fails due to loss of media (for example, an RTP timeout).

    • An unrecoverable error (for example, a SIP timeout) occurs during a renegotiation (re-INVITE) request sent to the remote peer.

  3. The transition from Idleto Terminatedoccurs when there is a failure in establishing the call. The most common causes for this transition are:

    • The call is rejected.

    • There is a failure in the offer/answer negotiation (for example, a failure to negotiate encryption parameters (SRTP)).

    • The application terminates the call before the media session is established.

    • The media session fails to establish a working transport connection between endpoints.

Important:
A transition of the state of an AudioVideoFlowinstance to Activedoes not imply that the associated AudioVideoCallhas been accepted or established. The AudioVideoFlowinstance’s state can change to Activebefore the call is established. In this situation, any media exchanged on the AudioVideoFlowis called “early media”. The application should avoid sending “important” media (such as a prompt that must be responded to) during this early media phase, because the remote endpoint might not render it. For important media, the application should wait for both the AudioVideoFlowto transition to the Activestate and for the AudioVideoCallto transition to the Establishedstate. During early media, the application might defer sending any media at all, or might instead just send some background music.

AudioVideoFlow Constructors

The AudioVideoFlowclass has no public constructors.

AudioVideoFlow Properties

The following are the public properties on the AudioVideoFlowclass.

Copy Code
// Gets the current hold status.
public HoldType HoldStatus {get;}

// Gets the AudioVideoFlow's TonePolicy.
public TonePolicy TonePolicy {get;}

// Gets whether tone is enabled.
public bool ToneEnabled {get;}

// Gets the current encryption policy.
public MediaEncryption EncryptionPolicy {get;}

// Gets the Audio control.
public AudioControl Audio {get;}

// Gets the Player currently attached to this object.
public Player Player {get;}

// Gets the Recorder currently attached to this object.
public Recorder Recorder {get;}

// Gets the DTMF currently attached to this object.
public ToneController ToneController {get;}

// Gets the speech recognition connector attached to this
AudioVideoFlow.
public SpeechRecognitionConnector SpeechRecognitionConnector {get;}

// Gets the speech synthesis connector attached to this
AudioVideoFlow.
public SpeechSynthesisConnector SpeechSynthesisConnector {get;}

The Audioproperty provides access to an AudioControlinstance, which provides access to the audio channel and can be used to mute and unmute the audio channel.

The Recorderproperty provides access to a Recorderinstance, which can be used to record audio and video data.

The Playerproperty provides access to a Playerinstance, which can be used to play audio data captured previously.

The ToneControllerproperty provides access to a ToneControllerinstance. A ToneController can be used to send and receive Dual-Tone Multiple-Frequency (DTMF) tones.

The SpeechRecognitionConnectorproperty provides access to a SpeechRecognitionConnectorinstance, which can use one or more grammars to analyze human speech for semantic meaning.

The SpeechSynthesisConnectorproperty provides access to a SpeechSynthesisConnectorinstance, which can be used to convert text to speech.

Player, Recorder, ToneController, SpeechRecognitionConnector, and SpeechSynthesisConnectorare considered to be devices. Although these devices are represented as properties on the AudioVideoFlowclass, they are not automatically instantiated. Before any of these devices can be used, it must be created, and then attached to an AudioVideoFlowinstance. The following code example shows the steps required to create a Playerand attach it to an existing AudioVideoFlowinstance.

Copy Code
Player myPlayer = new Player();
myPlayer.AttachFlow(avFlow);

When the device is no longer needed, the AudioVideoFlowinstance that is attached to the device must be detached, as this does not happen automatically. The following sample shows how this is done.

Copy Code
myPlayer.DetachFlow(avFlow);

For more information about these devices, see Audio Devices in UCMA 2.0 Core.

AudioVideoFlow Methods

The following are the public methods on the AudioVideoFlowclass.

Copy Code
// Applies changes based on a template.
public IAsyncResult BeginApplyChanges(
	AudioVideoFlowTemplate template,
	AsyncCallback userCallback,
	object o);

// Applies changes based on a template.
public IAsyncResult BeginApplyChanges(
	AudioVideoFlowTemplate template,
	IEnumerable<SignalingHeader> headers,
	AsyncCallback userCallback,
	object o);

// Waits for the pending BeginApplyChanges operation
// to complete.
public void EndApplyChanges(IAsyncResult result);

// Copies the properties from the template to an AudioVideoFlow.
// Must raise an exception if the AudioVideoFlow is not in the Idle
state.
public void Initialize(AudioVideoFlowTemplate template);

// Holds the AudioVideoFlow.
public IAsyncResult BeginHold(
	HoldType holdType,
	AsyncCallback userCallback,
	object o);

// Holds the AudioVideoFlow.
public IAsyncResult BeginHold(
	HoldType holdType,
	IEnumerable<SignalingHeader> headers,
	AsyncCallback userCallback,
	object o);

// Ends the hold.
public void EndHold(IAsyncResult result);

// Retrieves the AudioVideoFlow.
public IAsyncResult BeginRetrieve(AsyncCallback userCallback,
object o);

// Retrieves the AudioVideoFlow.
public IAsyncResult BeginRetrieve(
	IEnumerable<SignalingHeader> headers,
	AsyncCallback userCallback,
	object o);

// Ends the retrieval.
public void EndRetrieve(IAsyncResult result);

An application that intends to configure the AudioVideoFlowby using Initializemust process the AudioVideoFlowConfigurationRequestedevent synchronously. AudioVideoFlowConfigurationRequestedis an AudioVideoCallevent. The application can assume that the AudioVideoFlow Statewill not change from Idleduring the event callback, so no state check is necessary. Only an invalid template configuration can possibly cause Initializeto throw an exception.

If BeginHold, BeginRetrieve, or BeginApplyChangesare called shortly after the Stateof an AudioVideoFlowinstance is Active, each of these methods can fail, producing the error message, “A renegotiate is already in progresss.” To work around this problem, embed each call to BeginHold, BeginRetrieve, and BeginApplyChangesin a try- catchblock inside a loop. This way, if an exception is thrown, another attempt at calling the method can take place after the renegotiation has completed.

AudioVideoFlow Events

The following are the public events on the AudioVideoFlowclass.

Copy Code
//Raised by AudioVideoFlow when any configuration changes.
// Changes can occur due to remote user, internal configurations,
ApplyChanges, Hold, and Retrieve.
public event
EventHandler<AudioVideoFlowConfigurationChangedEventArgs>
ConfigurationChanged;