一、实验目的
掌握基于算能平台的JPEG压缩编码方法以及开发环境,包括开发主机环境搭建,硬件嵌入式开发板的连接,云平台的配置,编码程序的编译、运行等。
二、实验内容
搭建实验开发环境,并编写静止图像jpeg格式编解码程序,输入端读取原始图像数据,选择编解码模式,输出压缩编码结果。在目标开发机运行测试,验证开发环境。如果是基于云平台虚拟环境,则需要将编译好的程序代码上传云平台进行测试运行。
三、开发环境
开发主机:Ubuntu 20.04.6 LTS
硬件:算能SE5
四、实验器材
开发主机 + 云平台(或SE5硬件)
五、实验过程与结果
参考例程
本实验可以参考git上的ocv_video_xcode.cpp例程完成。
实验内容与步骤
图1 连接部署图
如上图所示,本实验利用OpenCV接口,在SE5上实现通过RTSP拉流,然后通过RTMP将码流推送给PC/服务器。在实现过程中,RTSP拉流和RTMP推流分别在不同的线程中实现。并且,RTSP拉流的过程中会进行解码,在RTMP推流的过程中会进行编码操作。
本实验中的摄像头也可以直接通过PC机一起完成,可以在PC机上安装并启动RTSP Server。
推荐使用EasyDarwin安装RTSP Server:https://www.easydarwin.org/
也可以直接在SE5上安装,则需要下载源码并进行编译后在SE5上进行安装。PC上可以安装Nginx作为RTMP服务器。
Windows下Nginx服务器的安装和RTMP服务器开启方法见附件描述。
本实验两个线程的操作流程如下图:
在上述处理流程中,在主线程中只需要将open的文件名设置为RTSP地址即可实现对视频流的拉取,然后将读取后的视频帧(解码后的视频帧)存入视频缓存队列,在写线程中将write的文件名设置为RTMP即可实现将视频流推送到指定地址。
在OpenCV中分别提供了VideoCapture类和VideoWriter类用于视频文件的读和写操作。下面介绍具体的编程实现过程。
主线程函数
OpenCV获取视频流
如前所述,OpenCV通过VideoCapture类实现对URL地址进行读取,并进行解码。这部分相关的代码也可以参考实例11来实现,其关键代码如下:
//初始化VideoCapture类
VideoCapture cap;
//打开文件或者摄像头或者某个RTSP连接
cap.open(threadPara->inputUrl, CAP_FFMPEG, threadPara->deviceId);
...
//读取视频帧存入image中
Mat image;
cap.read(image);
代码中的threadPara->inputUrl即为输入的RTSP视频流地址。threadPara->deviceId为板卡ID,如果是SOC模式,则为0,如果是PCIE模式需要指定具体的板卡ID。
视频帧存入视频缓存队列
主线程通过cap.read(image)获取到image后,存入视频缓存队列。本实验中涉及两个不同的线程对缓存队列进行读写操作,为保障线程同步,需要通过上锁和解锁对缓存队列进行保护:
g_video_lock.lock();
//存入缓存队列
threadPara->imageQueue->push(image);
g_video_lock.unlock();
上述代码中获取到的MAT格式的image就是解码后的视频帧数据。
写线程函数
OpenCV推送视频流
OpenCV提供了写入视频的接口类VideoWriter,VideoWriter是向文件中以指定的编码格式将每一帧图片写入到视频中。可以直接通过VideoWriter类对URL地址进行推流:
VideoWriter writer; //创建VideoWriter类
//outfile输出视频文件的路径名称
//fourcc: 字符类型的编码,表示用于编码视频文件的编码器,比如采用HEVC编码
writer.open(outfile, VideoWriter::fourcc('h', 'v', 'c', '1'),
threadPara->fps, //帧率
Size(threadPara->imageCols, threadPara->imageRows),
encodeparms,
true,
threadPara->deviceId);
writer.write(*toEncImage); //通过write接口推送
fourcc接口还可以设置不同的编码方式比如:
VideoWriter::fourcc('P','I','M','1') //表示MPEG-1 编码文件扩展名为avi; VideoWriter::fourcc('X','V','I','D') //表示MPEG-4编码文件扩展名为avi; VideoWriter::fourcc('X','2','6','4') //表示MPEG-4编码文件扩展名为mp4;
VideoWriter::fourcc('I','4','2','0') //表示YUV编码,文件扩展名为avi;
VideoWriter::fourcc('M','P','4','V') //表示旧的MPEG-4编码,文件扩展名为avi;
VideoWriter::fourcc('T','H','E','O') //表示使用ogg vorbis,文件扩展名为ogv;
VideoWriter::fourcc('F','L','V','1') //表示flash video,文件扩展名为flv;
本实验中的RTSP服务器端可以直接通过摄像头进行拉流,也可以通过在PC机上安装RTSP服务器来完成。本实验中的RTMP服务器可以通过安装Nginx服务器来完成。安装Nginx的流程如下:
Windows下Nginx服务器的安装与RTMP使用
Nginx官网:nginx news ,然后点击“download”
选择最新版本或稳定版本
解压Nginx,进入CMD,进到目录后并运行start nginx或者ngnix.exe。
进入conf文件夹,打开nginx.conf文件,增加配置如下:
worker_processes 1;
events {
worker_connections 1024;
}
rtmp {
server {
listen 1935;
chunk_size 4000;
application live {
live on;
allow publish 127.0.0.1;
allow play all;
}
}
}
配置HTTP
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
#location / {
# root html;
# index index.html index.htm;
#}
# Serve HLS fragments
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
add_header Cache-Control no-cache;
}
# Serve DASH fragments
location /dash {
root /tmp;
add_header Cache-Control no-cache;
}
location /live_hls {
types{
#m3u8 type设置
application/vnd.apple.mpegurl m3u8;
#ts分片文件设置
video/mp2t ts;
}
#指向访问m3u8文件目录
alias ./m3u8File;
add_header Cache-Control no-cache; #禁止缓存
}
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl{
root ./nginx-rtmp-module;
}
location /control {
rtmp_control all;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
验证nginx配置文件
cd nginx所在目录
nginx -t
启动nginx
cd nginx所在目录
start nginx
验证nginx
在浏览器输入:http://localhost/,查看nginx是否启动
在浏览器输入:http://localhost/stat,查看媒体流服务的情况
VLC拉流
安装VLC播放器,并打开软件。
左上角媒体→打开网络串流→网络,配置URL(格式形如:rtmp://ip:port/live)
rtmp://127.0.0.1:1935/live
点击播放,验证是否成功拉到了流。
Wireshark安装与使用
Wireshark下载安装
下载地址:Wireshark · Go Deep
根据自己的操作系统选择对应的版本:
打开Wireshark,并选择监听的网卡
也可以选择:
然后选择自己对应的网卡:
进入抓包
设置过滤
ip.addr == 192.0.2.1 //设置仅捕获IP地址为192.0.2.1的报文