原始视频数据

最近更新时间:2022-09-20 05:17:40

功能描述

音视频 SDK 提供了获取 原始视频数据 功能来实现对视频的 编码前处理 和 解码后处理,即在音视频处理过程中,对采集和接收到的视频、频帧进行修改,并发布到房间中供远端用户订阅,实现特殊的播放效果。

原始视频数据主要分为:本地摄像头采集的原始数据、本地预览数据(即经过裁剪或加水印处理后未编码的数据)、远端用户的原始视频数据。

  • 编码前处理:在编码前对SDK提供的原始视频数据(例如,本地摄像头采集的视频数据、本地预览数据)自行逐帧处理。
  • 解码后处理:在解码后对SDK提供的原始视频数据(例如,接收到的远端用户视频数据)自行逐帧处理。

Native SDK 通过提供 IVideoFrameObserver 类,实现获取或者修改原始视频数据功能。

实现方法

操作步骤

获取原始视频数据前,请确保已实现基本的音视频功能。

  1. 加入频道前调用 registerVideoFrameObserver 方法注册视频观测器,并在该方法中实现一个 IVideoFrameObserver 类。
  2. 成功注册后,SDK 会在捕捉到每个视频帧时通过 onCaptureVideoFrameonPreEncodeVideoFrameonRenderVideoFrame 回调发送获取到的原始视频数据。
  3. 用户拿到视频数据后,根据场景需要自行进行处理。然后将处理过的视频数据再通过上述回调发送给 SDK。

API 调用时序

下图展示使用原始视频数据的 API 调用时序:

通过回调获得VideoFrame对象,对该对象做修改并返回给 SDK。

示例代码

class ArVideoFrameObserver : public ar::media::IVideoFrameObserver
{
public:
    // 获取本地摄像头采集到的视频帧
    virtual bool onCaptureVideoFrame(VideoFrame& videoFrame) override
    {
        int width = videoFrame.width;
        int height = videoFrame.height;
 
        memset(videoFrame.uBuffer, 128, videoFrame.uStride * height / 2);
        memset(videoFrame.vBuffer, 128, videoFrame.vStride * height / 2);
 
        return true;
    }
     
    // 获取远端用户发送的视频帧
    virtual bool onRenderVideoFrame(unsigned int uid, VideoFrame& videoFrame) override
    {
        return true;
    }
        
    // 获取本地视频编码前的视频帧
    virtual bool onPreEncodeVideoFrame(VideoFrame& videoFrame) override
    {
        return true;
    }
};

class IVideoFrameObserver
{
     public:
         enum VIDEO_FRAME_TYPE {
         FRAME_TYPE_YUV420 = 0,  // 视频帧格式为 YUV 420
         };
     struct VideoFrame {
         VIDEO_FRAME_TYPE type;
         int width;  // 视频帧的宽
         int height;  // 视频帧的高
         int yStride;  // YUV 数据中的 Y 缓冲区的行跨度
         int uStride;  // YUV 数据中的 U 缓冲区的行跨度
         int vStride;  // YUV 数据中的 V 缓冲区的行跨度
         void* yBuffer;  // YUV 数据中的 Y 缓冲区的指针
         void* uBuffer;  // YUV 数据中 U 缓冲区的指针
         void* vBuffer;  // YUV 数据中 V 缓冲区的指针
         int rotation; // 该帧的旋转信息,可设为 0, 90, 180, 270
         int64_t renderTimeMs; // 该帧的时间戳
         };
     public:
         virtual bool onCaptureVideoFrame(VideoFrame& videoFrame) = 0;
         virtual bool onRenderVideoFrame(unsigned int uid, VideoFrame& videoFrame) = 0;
         virtual bool onPreEncodeVideoFrame(VideoFrame& videoFrame) { return true; }
};

API 参考

相关文档

如果你还想在项目中实现原始音频数据功能,请参考原始音频数据