跳到主要内容

AidStream SDK for C++

简介

AidStream 是用来构建流媒体应用的视频框架,其目标是要简化视频+AI应用程序的开发中需要插入算法的程序构建。 AidStream 以 pipeline 为基础,开发者需要为每条 pipeline 配置 输入流输出流 信息。 在一条完整的 pipeline 中,数据从 输入流 流出,开发者可以通过 AidStream 的 api 获取对应的 RGB 数据,并在处理后输入到 输出流 中。

功能说明

现有的pipeline有

0.拉流->显示(用于测试网路流)

1.获取RTSP流->解码->处理->显示

2.获取RTSP流->解码->处理->编码->推送RTSP流

3.获取RTSP流->解码->处理->编码->推送RTSP流&&保存MPEG-4

4.原生相机->处理->显示

5.原生相机->处理->推送RTSP流

6.UVC相机->处理->显示

7.MPEG-4->处理->推送RTSP流&&保存MPEG-4

8.仅解码

9.仅编码->推送RTSP流&&保存MPEG-4

备注: 原生相机、UVC相机只支持1路1920*1080,文件路径只能只能配置一路,且是sdcard路径。

上述pipeline中的处理环节需要自己去实现,即获取到解码转后后rgb数据后经过处理后送回到pipeline的编码入口。

现有的pipeline实现原理上基于不同的输入流和输出流的组合,如下方表格所示:

输入 \ 输出nullrtspfilescreanrtsp & file
null✔️
rtsp✔️✔️✔️✔️✔️
file✔️
mipi_camera✔️✔️
usb_camera✔️

快速上手

使用 Aidlite-SDK C++ 开发需要了解如下事项:

  • 编译时需要包含头文件,存放路径 /usr/local/include/aidlux/aidstream/aidstream.h
  • 链接时需要指定库文件,存放路径 /usr/local/lib/libaidstream.so

拉流加显示

访问远端RTSP链接,获取h265/h264的数据,通过解码和颜色空间转换后,获取rgb数据,处理后再发送到显示端。

#include "aidstream.h"


std::string config = "[{\"inputUrl\": \"rtsp://192.168.110.38:8554/a\"},{\"inputUrl\": \"rtsp://192.168.110.38:8554/b\"},{ \"inputUrl\": \"rtsp://192.168.110.38:8554/c\"},{\"inputUrl\": \"rtsp://192.168.110.38:8554/d\"}]";
// 此处使用的 inputUrl 仅供参考,请使用你的 rtsp 视频流地址替换它们

//创建Android对象
Android android;
void start(int index)
{
while (true)
{
char *buffer;
// 获取解码后的rgb数据,index对应配置文件中的顺序
int64_t size = android.getRGB(&buffer, index);
std::cout<<"size:"<<size<<std::endl;
//这里可以作rgb处理

// 塞入到显示的buffer中
int8_t result1 = android.pushBufferForDisplay(buffer, index);


}
}

int main()
{

//传入配置文件和pipeline的类型
nlohmann::json result = android.start(config, 1);

for (size_t i = 0; i < 4; i++)
{
std::thread worker(start, i); // 创建一个线程,运行start·函数
worker.detach();
}
std::cout << "Press ENTER to stop the program..." << std::endl;
std::cin.get(); // 等待开发者按下回车

// 可以在这里进行必要的资源清理和状态检查
std::cout << "Main thread stopping." << std::endl;
return 0;
}

示例详解

首先引入必要的头文件


#include "aidstream.h"


参数是配置和类型,不同的类型对应不同配置文件


nlohmann::json result = android.start(config, 1);

针对配置中的每一路获取相应的RGB buffer的指针,并返回size

char *buffer;
int64_t size = android.getRGB(&buffer, index);

将更改后的buffer、经算法后的buffer或者原buffer输入到显示buffer中


int8_t result1 = android.pushBufferForDisplay(buffer, index);

拉流加推流

访问远端RTSP链接,获取h265/h264的数据,通过解码和颜色空间转换后,获取rgb数据,处理后再发送到编码端,最后根据配置好的远端地址推送。

#include "aidstream.h"

std::string config ;
Android android;
void start(int index)
{
while (true)
{
char *buffer;
int64_t size = android.getRGB(&buffer, index);
std::cout<<"size:"<<size<<std::endl;
int8_t result = android.pushBuffer(buffer, index);



}
}

int main()
{
std::ifstream file("encode_config.json");
if (!file.is_open()) {
std::cerr << "Failed to open file\n";
return 1;
}

std::stringstream buffer;
buffer << file.rdbuf(); // 读取文件到字符串流中

config= buffer.str(); // 将字符串流转换为std::string
std::cout<<"config:"<<config<<std::endl;

nlohmann::json result = android.start(config, 2);
std::cout << result.dump(4) << std::endl;
// android.run();

for (size_t i = 0; i < 4; i++)
{
std::thread worker(start, i); // 创建一个线程,运行keep函数
worker.detach();
}
std::cout << "Press ENTER to stop the program..." << std::endl;
std::cin.get(); // 等待开发者按下回车

// 可以在这里进行必要的资源清理和状态检查
std::cout << "Main thread stopping." << std::endl;
return 0;
}



配置文件:encode_config.json:
// 此处使用的 inputUrl,outUrl 仅供参考,请使用你的 rtsp 视频流地址 和 流媒体服务器地址 替换它们
[
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.234:554/h264/ch1/main/av_stream",
"inputFormat": "video/avc",
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.38:8554/stream1",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.234:554/h264/ch1/main/av_stream",
"inputFormat": "video/avc",
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.38:8554/stream2",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.234:554/h264/ch1/main/av_stream",
"inputFormat": "video/avc",
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.38:8554/stream3",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.234:554/h264/ch1/main/av_stream",
"inputFormat": "video/avc",
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.38:8554/stream4",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
}
]

示例详解

首先引入必要的头文件


#include "aidstream.h"


参数是配置和类型,不同的类型对应不同配置文件

//读取json文件
std::ifstream file("encode_config.json");
if (!file.is_open()) {
std::cerr << "Failed to open file\n";
return 1;
}

std::stringstream buffer;
buffer << file.rdbuf();
config= buffer.str();
//启动type为2的流水线,即 拉流->解码->算法->编码->推流
nlohmann::json result = android.start(config, 2);

针对配置中的每一路获取相应的RGB buffer的指针,并返回size

char *buffer;
int64_t size = android.getRGB(&buffer, index);

将更改后的buffer、经算法后的buffer或者原buffer输入到推流buffer中


int8_t result = android.pushBuffer(buffer, index);

API详细说明

启动函数

nlohmann::json Android::start(std::string config, int type)
成员变量名类型描述
configstd::string配置
typestd::stringpipeline类型

获取解码后的RGB数据

int8_t getRGB(char **buffer, int index);
成员变量名类型描述
bufferchar*获取最新解码的RGB数据
indexint标记(和config数据对应)

传入RGB数据接口--显示

int8_t pushBufferForDisplay(char *buffer, int index);
成员变量名类型描述
bufferchar*需要存储或者推流中此帧的指针
indexint标记(和config数据对应)

传入RGB数据接口--推流\存储

int8_t pushBuffer(char *buffer, int index);
成员变量名类型描述
bufferchar*需要存储或者推流中此帧的指针
indexint标记(和config数据对应)

pipeline详解及配置JSON样例

获取RTSP流->解码->处理->显示

从远端RTSP流获取h264/h265码流,解码且转RGB,RGB经开发者处理后放回pipeline,最后pipeline将回传的RGB显示到surface上。

// 此处使用的 inputUrl 仅供参考,请使用你的 rtsp 视频流地址替换它们
[
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.186:554/h264/ch1/main/av_stream"
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.186:554/h264/ch1/main/av_stream"
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.186:554/h264/ch1/main/av_stream"
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.186:554/h264/ch1/main/av_stream"
}
]

获取RTSP流->解码->处理->编码->推送RTSP流

从远端RTSP流获取h264/h265码流,解码且转RGB,RGB经开发者处理后放回pipeline,最后pipeline将回传的RGB推送到RTSP地址上。

// 此处使用的 inputUrl,outUrl 仅供参考,请使用你的 rtsp 视频流地址和 流媒体服务器地址 替换它们
[
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.234:554/h264/ch1/main/av_stream",
"inputFormat": "video/avc",
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.62:8554/stream-a",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.234:554/h264/ch1/main/av_stream",
"inputFormat": "video/avc",
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.62:8554/stream-b",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.234:554/h264/ch1/main/av_stream",
"inputFormat": "video/avc",
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.62:8554/stream-c",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.234:554/h264/ch1/main/av_stream",
"inputFormat": "video/avc",
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.62:8554/stream-d",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
}
]

获取RTSP流->解码->处理->编码->推送RTSP流&&保存MPEG-4

从远端RTSP流获取h264/h265码流,解码且转RGB,RGB经开发者处理后放回pipeline,最后pipeline将回传的RGB推送到RTSP地址且存到本地上,是否推送或保存根据字段outUrl和outPath是否存在确定。

备注: outPath只支持sdcard目录

// 此处使用的 inputUrl,outUrl 仅供参考,请使用你的 rtsp 视频流地址和 流媒体服务器地址 替换它们
[
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.199:554/h265/ch1/main/av_stream",
"inputFormat": "video/hevc",
"outPath":"/sdcard/Download/rtsp-h265-a.mp4",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.199:554/h265/ch1/main/av_stream",
"inputFormat": "video/hevc",
"outFormat":"video/hevc",
"outPath":"/sdcard/Download/rtsp-h265-b.mp4",
"outUrl": "rtsp://127.0.0.1:8554/rtsp-h265-b",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.199:554/h265/ch1/main/av_stream",
"inputFormat": "video/hevc",
"outPath":"/sdcard/Download/rtsp-h264-c.mp4",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.199:554/h265/ch1/main/av_stream",
"inputFormat": "video/hevc",
"outPath":"/sdcard/Download/rtmp-d.mp4",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
}
]

原生相机->处理->显示

获取前置或后置摄像头的图像,解码且转RGB,RGB经开发者处理后放回pipeline,最后pipeline将回传的RGB显示到surface上。

[
{
"camera_id": 0
}
]

原生相机->处理->推送RTSP流

获取前置或后置摄像头的图像,解码且转RGB,RGB经开发者处理后放回pipeline,最后pipeline将回传的RGB推送到RTSP地址上。

// 此处使用的 outUrl 仅供参考,请使用你的 流媒体服务器地址 替换它们
[
{
"camera_id":0,
"outUrl": "rtsp://127.0.0.1:8554/a",
"outFrameRate": 25,
"inputResizeWidth": 1920,
"inputResizeHeight": 1080,
"outWidth": 1920,
"outHeight": 1080
}
]

UVC相机->处理->显示

获取UVC相机图像,转化为RGB,RGB经开发者处理后放回pipeline,最后pipeline将回传的RGB显示到surface上。

备注: usbDeviceId需要python3脚本查询,见附录;仅支持单路。

[
{
"usbDeviceId":3004
}
]

MPEG-4->处理->推送RTSP流&&保存MPEG-4

获取MPEG-4文件,解码且转RGB,RGB经开发者处理后放回pipeline,最后pipeline将回传的RGB显示到surface上。

备注: file_path只支持sdcard目录,仅支持单路。

// 此处使用的 outUrl 仅供参考,请使用你的 流媒体服务器地址 替换它们
[{
"file_path"="/sdcard/test_kobe.mp4",
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.38:8554/stream2",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
}]

仅解码

从远端RTSP流获取h264/h265码流,解码且转RGB,不放回pipeline,

// 此处使用的 inputUrl 仅供参考,请使用你的 rtsp 视频流地址 替换它们
[
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.186:554/h264/ch1/main/av_stream"
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.186:554/h264/ch1/main/av_stream"
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.186:554/h264/ch1/main/av_stream"
},
{
"inputUrl": "rtsp://admin:aidlux123@192.168.110.186:554/h264/ch1/main/av_stream"
}
]

仅编码->推送RTSP流&&保存MPEG-4

传入RGB图像,将回传的RGB推送到RTSP地址且存到本地上,是否推送或保存根据字段outUrl和outPath是否存在确定。

// 此处使用的 outUrl 仅供参考,请使用你的 流媒体服务器地址 替换它们
[
{
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.62:8554/stream-a",
"outPath":"/sdcard/Download/rtsp-d.mp4",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
},
{
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.62:8554/stream-b",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
},
{
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.62:8554/stream-c",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
},
{
"outFormat":"video/hevc",
"outUrl": "rtsp://192.168.110.62:8554/stream-d",
"outFrameRate": 25,
"inputResizeWidth": 960,
"inputResizeHeight": 540,
"outWidth": 960,
"outHeight": 540
}
]

附录

配置文件字段详解

字段名描述取值
inputUrlRTSP源RTSP有效地址
inputFormatRTSP源格式1.video/avc:格式h264 2.video/hevc:格式h265
inputResizeWidth缩放源数据的图像的宽度,不输入就不缩放不大于源数据图像的宽
inputResizeHeight是否缩放源数据的图像大小,不输入就不缩放不大于源数据图像的高
outUrlRTSP推送地址RTSP有效地址
outFormatRTSP推送格式1.video/avc:格式h264 2.video/hevc:格式h265
outWidth输出RGB宽度与放回RGB宽度相同
outHeight输出RGB高度与放回RGB宽度相同
camera_id前后置摄像头0:前置 1:后置
usbDeviceIdusb摄像头id
file_path文件地址仅sdcard
outPath输出文件地址仅sdcard

查询usb相机信息

import android
droid = android.Android()
usb=droid.searchUSB()
print(usb)

请求usb相机权限

import android
droid = android.Android()
hasPermission=droid.requestPermission(id)//id由查询usb相机信息中可得
print(hasPermission)

查询usb相机权限

import android
droid = android.Android()
hasPermission=droid.hasPermission(id)//id由查询usb相机信息中可得
print(hasPermission)