# Raw video processing (/en/realtime-media/rtc/build/capture-and-render-video/raw-video-processing/unity)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

In certain use-cases, it is necessary to process raw video captured through the camera to achieve desired functionality or enhance the user experience. RTC SDK provides the capability to pre-process and post-process the captured video data, allowing you to implement custom playback effects.

      
  
      
  
      
  
      
  
      
## Understand the tech

RTC SDK enables you to pre-process the captured video frames before sending the data to the encoder or perform post-processing on the received video frames after sending the data to the decoder.

The following figure shows the video data processing flow in the SDK video module.

**Process raw video**

![image](https://assets-docs.agora.io/images/video-sdk/video-module-data-processing.svg)

* Position (2) corresponds to the `onCaptureVideoFrame` callback.
* Position (3) corresponds to the `onPreEncodeVideoFrame` callback.
* Position (4) corresponds to the`onRenderVideoFrame` callback.

## Prerequisites

Ensure that you have implemented the [SDK quickstart](/en/realtime-media/rtc/get-started-sdk) in your project.

## Implement raw video processing

To implement raw video data functionality in your project, refer to the following steps:

1. Before joining the channel, create an `IVideoFrameObserver` object and register the video observer by calling the `RegisterVideoFrameObserver` method. To apply pre-processed video data, set the `formatPreference` to `FRAME_TYPE_YUV420` and the `mode` to `INTPTR`.

   ```csharp
   // Register the video observer
   RtcEngine.RegisterVideoFrameObserver(
     new VideoFrameObserver(this),
     VIDEO_OBSERVER_FRAME_TYPE.FRAME_TYPE_YUV420,
     VIDEO_MODULE_POSITION.POSITION_POST_CAPTURER |
     VIDEO_MODULE_POSITION.POSITION_PRE_RENDERER |
     VIDEO_MODULE_POSITION.POSITION_PRE_ENCODER,
     OBSERVER_MODE.INTPTR
   );
   ```

2. After obtaining video data via the `OnCaptureVideoFrame` and `OnRenderVideoFrame` callbacks, process it according to your requirements.

   ```csharp
   class VideoFrr : IVideoFrameObserver {
     // Get the original video data captured by the local camera
     public override bool OnCaptureVideoFrame(VIDEO_SOURCE_TYPE sourceType, VideoFrame videoFrame) {
       ProcessVideoFrame(videoFrame);
       return true;
     }

     // Get the video data sent by the remote user
     public override bool OnRenderVideoFrame(string channelId, uint remoteUid, VideoFrame videoFrame) {
       ProcessVideoFrame(videoFrame);
       return true;
     }

     public void ProcessVideoFrame(VideoFrame videoFrame) {
       int yBufferLength = videoFrame.yStride * videoFrame.height;
       int uBufferLength = videoFrame.uStride * videoFrame.height / 2;
       int vBufferLength = videoFrame.vStride * videoFrame.height / 2;

       byte[] bytes = new byte[uBufferLength];
       for (int i = 0; i < uBufferLength; i++) {
         bytes[i] = 128;
       }

       System.Runtime.InteropServices.Marshal.Copy(bytes, 0, videoFrame.uBufferPtr, uBufferLength);
       System.Runtime.InteropServices.Marshal.Copy(bytes, 0, videoFrame.vBufferPtr, vBufferLength);
     }
   }
   ```

<CalloutContainer type="warning">
  <CalloutDescription>
    When modifying parameters in `videoFrame`, ensure that the updated values are consistent with the actual video frames in the buffer. Mismatches may cause issues like unexpected rotation, distortion, or other visual problems in the local preview and the remote video.
  </CalloutDescription>
</CalloutContainer>

## Reference

This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.

### Sample project

Agora provides an open source sample project [ProcessRawData](https://github.com/AgoraIO-Extensions/Agora-Unity-Quickstart/blob/main/API-Example-Unity/Assets/API-Example/Examples/Advanced/ProcessVideoRawData/ProcessVideoRawData.cs) on GitHub. Download it or view the source code for a more detailed example.

### API reference

* [`RegisterVideoFrameObserver`](https://api-ref.agora.io/en/video-sdk/unity/4.x/API/class_irtcengine.html#api_imediaengine_registervideoframeobserver)
* [`RegisterVideoEncodedFrameObserver`](https://api-ref.agora.io/en/video-sdk/unity/4.x/API/class_irtcengine.html#api_imediaengine_registervideoencodedframeobserver)
* [`OnCaptureVideoFrame`](https://api-ref.agora.io/en/video-sdk/unity/4.x/API/class_ivideoframeobserver.html#callback_ivideoframeobserver_oncapturevideoframe)
* [`OnRenderVideoFrame`](https://api-ref.agora.io/en/video-sdk/unity/4.x/API/class_ivideoframeobserver.html#callback_ivideoframeobserver_onrendervideoframe)

    
  
      
  
      
  
