# Service quality You can use service quality callbacks to notify users about video, audio, and sharing quality during a session and unstable network conditions. You can also use these to measure or show latency, FPS, and resolution. Zoom Video SDK optimizes the FPS and resolution to the current device and network capabilities to optimize a good, smooth experience. Additionally, you can build network strength indicators for your users or a real-time statistics dashboard of video, audio, and share quality. This is similar to [how Zoom Meetings shares diagnostic information](https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0070504). If you want near real time analytics to quickly diagnose and resolve network disruptions, consider purchasing a [Quality of Service Subscription (QSS) plan](https://www.zoom.com/en/services/qss/) to use our [QSS API](/docs/api/qss/#tag/video-sdk-sessions/get/videosdk/sessions/{sessionId}/users/qos_summary) and [webhooks](/docs/api/qss/events/#tag/session) for Video SDK. ## Network status The [`ZoomVideoSDKNetworkStatus`](https://marketplacefront.zoom.us/sdk/custom/windows/zoom__video__sdk__user__helper__interface_8h.html#aef71ee4668bf0f030240ac22dfc67826) enum includes literals representing the network status. ```cpp ZoomVideoSDKNetwork_None, ZoomVideoSDKNetwork_Bad, ZoomVideoSDKNetwork_Normal, ZoomVideoSDKNetwork_Good; ``` To get a network status change callback, there must be at least two users in the session with their video on. You can use the network status returned from the callback to create an icon to show the current network quality. ```cpp void onUserVideoNetworkStatusChanged(ZoomVideoSDKNetworkStatus status, IZoomVideoSDKUser* pUser) { pUser->getUserID(); pUser->getUserName(); if (status == ZoomVideoSDKNetwork_None) {} else if (status == ZoomVideoSDKNetwork_Bad) {} else if (status == ZoomVideoSDKNetwork_Normal) {} else if (status == ZoomVideoSDKNetwork_Good) {} } ``` ## QOS statistics The [`onQOSStatisticsReceived`](https://marketplacefront.zoom.us/sdk/custom/windows/class_i_zoom_video_s_d_k_delegate.html#a992e9976e5c1931978730dc939190de3) callback provides real-time quality-of-service metrics for audio, video, and sharing streams. It fires for both send and receive directions, identified by the `direction` field on the statistics object. The base [`ZoomVideoSDKQOSStatistics`](https://marketplacefront.zoom.us/sdk/custom/windows/struct_zoom_video_s_d_k_q_o_s_statistics.html) reference contains fields common to all stream types and directions. Check `statistics.direction` and `static_cast` to [`ZoomVideoSDKQOSSendStatistics`](https://marketplacefront.zoom.us/sdk/custom/windows/struct_zoom_video_s_d_k_q_o_s_send_statistics.html) or [`ZoomVideoSDKQOSRecvStatistics`](https://marketplacefront.zoom.us/sdk/custom/windows/struct_zoom_video_s_d_k_q_o_s_recv_statistics.html) to access direction-specific fields. ```cpp void onQOSStatisticsReceived(const ZoomVideoSDKQOSStatistics& statistics, IZoomVideoSDKUser* pUser) { // Common fields available on all statistics statistics.direction; // ZoomVideoSDKStatisticsDirection_Send or _Receive statistics.statisticsType; // Audio, Video, or Share statistics.codecName; // e.g. "h264", "av1", "opus" — valid only during this callback statistics.timestamp; statistics.rtt; statistics.jitter; statistics.width; statistics.height; statistics.fps; statistics.bps; statistics.packetsLost; statistics.packetsSent; statistics.networkLevel; statistics.avg_Loss; // per-thousand, e.g. 100 = 10% statistics.max_Loss; // per-thousand statistics.bandwidth; if (statistics.direction == ZoomVideoSDKStatisticsDirection_Send) { const ZoomVideoSDKQOSSendStatistics& sendStats = static_cast(statistics); sendStats.frameWidthInput; sendStats.frameHeightInput; sendStats.frameRateInput; sendStats.bytesSent; sendStats.packetsSent; sendStats.totalPacketSendDelay; sendStats.totalEncodeTime; sendStats.framesEncoded; } else if (statistics.direction == ZoomVideoSDKStatisticsDirection_Receive) { const ZoomVideoSDKQOSRecvStatistics& recvStats = static_cast(statistics); recvStats.bytesReceived; recvStats.packetsReceived; recvStats.estimatedPlayoutTimestamp; recvStats.totalDecodeTime; recvStats.framesDecoded; recvStats.jitterBufferDelay; recvStats.jitterBufferEmittedCount; } } ``` ### Video quality When `statisticsType` is `ZoomVideoSDKDataType_Video`, the callback provides video-specific metrics such as frame dimensions, frame rate, and bitrate. To receive video statistics, there must be at least two users in the session with their video on. ### Audio quality When `statisticsType` is `ZoomVideoSDKDataType_Audio`, the callback provides audio-specific metrics such as codec, jitter, and packet loss. The `width`, `height`, and `fps` fields are not applicable for audio. To receive audio statistics, there must be at least two users actively sending audio to the session. ### Sharing quality When `statisticsType` is `ZoomVideoSDKDataType_Share`, the callback provides sharing metrics such as frame dimensions, frame rate, and bitrate. To receive share statistics, there must be at least two users in the session with at least one sharing.