# Using RTCP for audio/video synchronization

Use RTCP to communicate skew information to the host application and IP destination through RTP endpoints. To use RTCP, enable RTP endpoints as follows:

- Enable RTP receive endpoints to calculate audio and video skew values for incoming data streams and communicate these values to the host application.

- Enable RTP video send endpoints to communicate video skew values to the IP destination.

You can enable RTP endpoints to provide skew information either during endpoint creation or after endpoint creation.

Note: A full-duplex RTCP session is only supported with full-duplex RTP endpoints. A simplex RTP endpoint pair (simplex send endpoint and simplex receive endpoint) does not support a full-duplex RTCP session.

## Enabling RTP endpoints to detect and communicate skew values for incoming data streams

Note: This feature is for all audio and video full-duplex and simplex receive RTP endpoints. The examples are shown for full-duplex endpoints.

### During endpoint creation

When creating an endpoint, configure the startRtcp bit field in the RTCP_ENDPOINT_PARMS (or RTCP_V6_ENDPOINT_PARMS) structure so that an endpoint can detect skew offset values for incoming data streams and report them to the host application. The endpoint communicates these values by sending MSPEVN_SKEW_OFFSET events.

Use the following macros to configure the startRtcp bit field:

- RTCP_ENABLE to enable RTCP for the endpoint.

- RTCP_ENABLE_RCV_SKEW_CALC to enable the calculation of skew offsets for the endpoint.

Configure both endpoints in an audio/video stream pair to obtain meaningful skew data. For more information, see Calculating audio/video skew.

For more information about creating and configuring RTP endpoints, see RTPRTCP_ENDPOINT_PARMS or RTPRTCP_V6_ENDPOINT_PARMS, the MSPP Developer's Reference Manual, and the Fusion Developer's Manual.

### After endpoint creation

After creating endpoints, send the MSP_CMD_RTPFDX_CALC_SKEW_OFFSET command to an endpoint so that it can detect skew offset values for incoming data streams and report them to the host application. This command uses the msp_ENDPOINT_RTPFDX_ENABLE_SKEW_CALC structure to indicate whether to enable or disable the skew offset calculation.

Send the MSP_CMD_RTPFDX_CALC_SKEW_OFFSET command to both endpoints in an audio/video stream pair to obtain meaningful audio/video skew data. For more information, see Calculating audio/video skew.

The MSP_CMD_RTPFDX_CALC_SKEW_OFFSET command can return the following events:

Event | Description
MSPEVN_SENDCOMMAND_DONE | MSP_CMD_RTPFDX_CALC_SKEW_OFFSET command was successfully sent to the specified RTP endpoint on the CG board.
MSPEVN_SKEW_OFFSET | Unsolicited event indicating the timing offset (in ms) for the incoming data stream.

For more information, see Creating and sending MSPP commands.

### Calculating audio/video skew

The following table describes how the audio/video skew value is calculated based on information sent from both endpoints in an audio/video stream pair:

Stage | Process
1 | First endpoint in an audio/video stream pair calculates a skew offset value based on the RTP packet and RTCP sender report timing of an incoming stream.
2 | CG board uses an unsolicited MSPEVN_SKEW_OFFSET event to report the skew offset value to the application. The MSPEVN_SKEW_OFFSET event contains the following structure: typedef struct { DWORD FilterId; DWORD offset; //Offset value in ms } msp_RTP_SKEW_OFFSET;
3 | Second endpoint in the audio/video stream pair calculates a skew offset value based on the RTP packet and RTCP sender report timing of an incoming stream.
4 | CG board uses an unsolicited MSPEVN_SKEW_OFFSET event to report the skew offset value to the application.
5 | Application subtracts the audio skew offset value from the video skew offset value. This yields the audio/video skew value in ms. A positive result means the video lags behind the audio. A negative result means the audio lags behind the video.
6 | Application does either of the following: Corrects for the incoming audio/video skew on the CG board, possibly by adjusting audio/video jitter buffer latencies. For information about setting the audio jitter buffer latency, see the MSPP Developer's Reference Manual. For information about setting the video jitter buffer latency, see Setting the video jitter buffer latency. Signals the audio/video skew value to a receiving 3G-324M terminal by using h324_h223SkewIndication.

#### Examples

The following example shows how to use the MSP_CMD_RTPFDX_CALC_SKEW_OFFSET command so that the video endpoint with the MSP handle ephd detects video skew offset values on an incoming data stream:

msp_ENDPOINT_RTPFDX_ENABLE_SKEW_CALC skewCalc;
skewCalc.enable = RTCP_ENABLE_RCV_SKEW_CALC(0);
//Endian Adjust
skewCalc.enable = H2NMS_DWORD(skewCalc.enable);
command = mspBuildCommand(msp_ENDPOINT_RTPFDX_VIDEO_H263,
MSP_CMD_RTPFDX_CALC_SKEW_OFFSET);
ret = mspSendCommand(ephd, command, &skewCalc, sizeof(skewCalc));
expectedEvent = (MSPEVN_SENDCOMMAND_DONE |
MSP_CMD_RTPFDX_CALC_SKEW_OFFSET);
if (WaitForSpecificEvent(gw, CtaQueueHd, expectedEvent, &event) != 0)
printf("\n\tERROR: mspSendCommand failed to send valid completion event\n");

The following example shows how to use the MSP_CMD_RTPFDX_CALC_SKEW_OFFSET command so that the audio endpoint with the MSP handle ephd1 detects audio skew offset values on an incoming data stream:

msp_ENDPOINT_RTPFDX_ENABLE_SKEW_CALC skewCalc;
skewCalc.enable = RTCP_ENABLE_RCV_SKEW_CALC(0);
//Endian Adjust
skewCalc.enable = H2NMS_DWORD(skewCalc.enable);
command = mspBuildCommand(msp_ENDPOINT_RTPFDX),
MSP_CMD_RTPFDX_CALC_SKEW_OFFSET);
ret = mspSendCommand(ephd1, command, &skewCalc, sizeof(skewCalc));
expectedEvent = (MSPEVN_SENDCOMMAND_DONE |
MSP_CMD_RTPFDX_CALC_SKEW_OFFSET);
if (WaitForSpecificEvent(gw, CtaQueueHd, expectedEvent, &event) != 0)
printf("\n\tERROR: mspSendCommand failed to send valid completion event\n");

The following example shows how to calculate the audio/video skew value after receiving MSPEVN_SKEW_OFFSET events from the audio data stream and the video data stream.

switch (pevent->id)
{
case MSPEVN_SKEW_OFFSET:
msp_RTP_SKEW_OFFSET *pSkewEvent;
pSkewEvent = (msp_RTP_SKEW_OFFSET*)(pevent->buffer);
skewOffset = (int)NMS2H_DWORD(pSkewEvent->offset);
if(VideoCtx[nGw].rtpEp.hd == pevent->objHd)
{
vidOffset = skewOffset;
bVid = TRUE;
}
else
{
audOffset = skewOffset;
bAud = TRUE;
}
if (bVid == TRUE && bAud == TRUE)
{
vidSkew = vidOffset – audOffset;
printf(“\nVideo lags audio by %d ms”, vidSkew);
bVid = bAud = FALSE;
}
Break;
}

## Enabling RTP video send endpoints to send video skew values to the IP destination

Note: This feature is for all video full-duplex and simplex send RTP endpoints. The example is shown for full-duplex endpoints.

### During endpoint creation

When creating a video send endpoint, configure the startRtcp bit field in the RTCP_ENDPOINT_PARMS (or RTCP_V6_ENDPOINT_PARMS) structure so that the endpoint sends video skew values to the IP destination in RTCP Sender Reports.

Use the following macros to configure the startRtcp bit field:

Use this macro... | To...
RTCP_ENABLE | Enable RTCP for the endpoint.
RTCP_SET_0_INTERVAL | Determine how quickly the RCTP Sender Reports begin after the RTP stream begins.
RTCP_VIDEO_LEADS_AUDIO | Indicate to the application that video leads audio (if true).
RTCP_VIDEO_SKEW | Set the actual video skew time, in ms.

For more information about creating and configuring RTP endpoints, see RTPRTCP_ENDPOINT_PARMS or RTPRTCP_V6_ENDPOINT_PARMS, the MSPP Developer's Reference Manual, and the Fusion Developer's Manual.

### After endpoint creation

After creating endpoints, send the MSP_CMD_RTPFDX_VIDEO_SKEW_TIME command to a video endpoint so that the endpoint sends video skew values to the IP destination in RTCP Sender Reports. The MSP_CMD_RTPFDX_VIDEO_SKEW_TIME command uses the msp_ENDPOINT_RTPFDX_SET_VID_SKEW structure to set the skew value.

The MSP_CMD_RTPFDX_VIDEO_SKEW_TIME command can return the following event:

Event | Description
MSPEVN_SENDCOMMAND_DONE | MSP_CMD_RTPFDX_VIDEO_SKEW_TIME command was successfully sent to the specified endpoint.

For more information, see Creating and sending MSPP commands.

#### Example

The following example shows how to send the MSP_CMD_RTPFDX_VIDEO_SKEW_TIME command to the video endpoint with the MSP handle ephd so that the endpoint signals video skew to the IP destination:

msp_ENDPOINT_RTPFDX_SET_VID_SKEW skewCmd;
skewCmd.vidSkew = 0;
if (skew < 0)
{
//Video leads audio
skewCmd.vidSkew = RTCP_VIDEO_LEADS_AUDIO(skewCmd.vidSkew);
skew *= -1; //Make skew a positive number
}
skewCmd.vidSkew = RTCP_VIDEO_SKEW(skewCmd.vidSkew, skew);
//Endian Adjust
skewCmd.vidSkew = H2NMS_DWORD(skewCmd.vidSkew);
command = mspBuildCommand(msp_ENDPOINT_RTPFDX_VIDEO_H263,
MSP_CMD_RTPFDX_VIDEO_SKEW_TIME);
ret = mspSendCommand(ephd, command, &skewCmd, sizeof(skewCmd));
expectedEvent = (MSPEVN_SENDCOMMAND_DONE |
MSP_CMD_RTPFDX_VIDEO_SKEW_TIME);
if (WaitForSpecificEvent(gw, CtaQueueHd, expectedEvent, &event) != 0)
printf("\n\tERROR: mspSendCommand failed to send valid completion event\n");