# Send raw data

<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

You can feed your own video, audio, and share frames into a session, which is useful for headless apps with no camera or microphone, or to send processed media.

## Send raw video data

To send raw or processed video as the local user's camera:

1. Implement an instance of `IZoomVideoSDKVideoSource`.
2. Assign it to `externalVideoSource` on the `ZoomVideoSDKSessionContext` before joining a session.
3. Obtain the `IZoomVideoSDKVideoSender` from the `onInitialize` callback.
4. Call `sendVideoFrame` from `onStartSend` to send frames.

```cpp
ZoomVideoSDKVideoSource* pVirtualVideoSource = new ZoomVideoSDKVideoSource();
session_context.externalVideoSource = pVirtualVideoSource;

void ZoomVideoSDKVideoSource::onInitialize(IZoomVideoSDKVideoSender* sender, IVideoSDKVector<VideoSourceCapability>* support_cap_list, VideoSourceCapability& suggest_cap)
{
    m_pSender = sender;
}

void ZoomVideoSDKVideoSource::onPropertyChange(IVideoSDKVector<VideoSourceCapability>* support_cap_list, VideoSourceCapability suggest_cap) {}

void ZoomVideoSDKVideoSource::onStartSend()
{
    // Send a frame buffer of raw video data.
    m_pSender->sendVideoFrame(frameBuffer, width, height, frameLength, rotation);
}

void ZoomVideoSDKVideoSource::onStopSend() {}

void ZoomVideoSDKVideoSource::onUninitialized() {}
```

In the `onInitialize` callback:

-   The `support_cap_list` parameter is the supported capability list. It combines the supported resolution of the session and the device into a list of supported capabilities.
-   The `suggest_cap` parameter is the suggested capability. It combines the maximum capability of the session and the device to get the real maximum as the suggested capability.

`sendVideoFrame` accepts an optional `FrameDataFormat` argument that defaults to `FrameDataFormat_I420_FULL`.

## Pre-process raw video data

To modify the local camera frames before they are sent, rather than supplying frames from scratch, implement `IZoomVideoSDKVideoSourcePreProcessor` and assign it to `preProcessor` on the `ZoomVideoSDKSessionContext`. The SDK passes each frame to `onPreProcessRawData`.

```cpp
void CExampleVideoSourcePreProcessor::onPreProcessRawData(YUVProcessDataI420* rawData)
{
    unsigned int width = rawData->GetWidth();
    unsigned int height = rawData->GetHeight();
    char* yBuffer = rawData->GetYBuffer();
    char* uBuffer = rawData->GetUBuffer();
    char* vBuffer = rawData->GetVBuffer();
    // Modify the buffers in place.
}
```

## Send raw audio data

To send raw or processed audio as the local user's microphone:

1. Implement an instance of `IZoomVideoSDKVirtualAudioMic`.
2. Assign it to `virtualAudioMic` on the `ZoomVideoSDKSessionContext` before joining a session. Set `audioOption.connect = true` and `audioOption.mute = false`.
3. Obtain the `IZoomVideoSDKAudioSender` from the `onMicInitialize` callback.
4. Call `Send` from `onMicStartSend` to send frames.

```cpp
ZoomVideoSDKVirtualAudioMic* pVirtualMic = new ZoomVideoSDKVirtualAudioMic();
session_context.virtualAudioMic = pVirtualMic;
session_context.audioOption.connect = true;
session_context.audioOption.mute = false;

void ZoomVideoSDKVirtualAudioMic::onMicInitialize(IZoomVideoSDKAudioSender* rawdata_sender)
{
    // Store rawdata_sender for later use.
    m_pSender = rawdata_sender;
}

void ZoomVideoSDKVirtualAudioMic::onMicStartSend()
{
    // You can now send audio.
    m_pSender->Send(rawData, lengthInBytes, sampleRate);
}

void ZoomVideoSDKVirtualAudioMic::onMicStopSend() {}

void ZoomVideoSDKVirtualAudioMic::onMicUninitialized() {}
```

`Send` takes 16-bit PCM audio. The `data_length` must be even, and `sample_rate` accepts an optional `ZoomVideoSDKAudioChannel` argument that defaults to `ZoomVideoSDKAudioChannel_Mono`.

## Send raw share data

To send raw screen share frames:

1. Implement an instance of `IZoomVideoSDKShareSource`.
2. Pass it to `startSharingExternalSource` on `IZoomVideoSDKShareHelper` while in a session.
3. Call `sendShareFrame` from `onShareSendStarted` to send frames.

```cpp
ZoomVideoSDKShareSource* pVirtualShareSource = new ZoomVideoSDKShareSource();
m_pVideoSDK->getShareHelper()->startSharingExternalSource(pVirtualShareSource);

void ZoomVideoSDKShareSource::onShareSendStarted(IZoomVideoSDKShareSender* pSender)
{
    pSender->sendShareFrame(frameBuffer, width, height, frameLength);
}

void ZoomVideoSDKShareSource::onShareSendStopped() {}
```
