EasyCVR做为视频融合平台,可以支持除RTMP之外的大部分协议,包括海康SDK及Ehome私有协议,视频云网关不须要对现有监控架构作调整,支持CDN推流,灵活适应原有架构。算法
在 EasyCVR 视频处理中,对于部分视频数据须要转换成 BGR 数据才可以使用。浏览器
I 帧数据为采用视频压缩算法已经压缩后的数据。数据量小,便于存储和传输。在正式使用时,如播放视频等功能,都须要从新将压缩后的数据还原成YUV 或者 RGB 等模型的程序才能够显示使用。网络
BGR 数据为和 RGB 相同的数据,仅是顺序不一样,RGB 数据时红色、绿色和蓝色的顺序,BGR 是蓝色、绿色和红色的顺序模型。架构
使用 ffmpeg 代码将 H.264 一帧数据转换成 BGR 数据的功能代码以下。由于 ffmpeg 的代码在 3.x 后,部分接口进行了修改,如下代码在 ffmpeg4.2 中可正常运行。函数
#include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavutil/avutil.h> #include <libavutil/imgutils.h> #include <libswscale/swscale.h> // 将 H.264 帧转换为 BGR 数据 void H264ToBGR(char* data, int dataSize, char* outBuffer) { // 1. 将元数据装填到packet AVPacket* avPkt = av_packet_alloc(); avPkt->size = dataSize; avPkt->data = (unsigned char*)data; static AVCodecContext* codecCtx = nullptr; // 2. 建立并配置codecContext if (codecCtx == nullptr) { AVCodec* h264Codec = avcodec_find_decoder(AV_CODEC_ID_H264); codecCtx = avcodec_alloc_context3(h264Codec); avcodec_get_context_defaults3(codecCtx, h264Codec); avcodec_open2(codecCtx, h264Codec, nullptr); } // 3. 解码 auto ret = avcodec_send_packet(codecCtx, avPkt); if (ret >= 0) { AVFrame* YUVFrame = av_frame_alloc(); ret = avcodec_receive_frame(codecCtx, YUVFrame); if (ret >= 0) { // 4.YUV转BGR24 AVFrame* RGB24Frame = av_frame_alloc(); AVPixelFormat yuvFmt = convertDeprecatedFormat(codecCtx->pix_fmt); struct SwsContext* convertCxt = sws_getContext( YUVFrame->width, YUVFrame->height, yuvFmt, YUVFrame->width, YUVFrame->height, AV_PIX_FMT_BGR24, SWS_POINT, NULL, NULL, NULL); printf("yuv 数据的编码格式为 %d\n", yuvFmt); // outBuffer将会分配给RGB24Frame->data,AV_PIX_FMT_RGB24格式只分配到RGB24Frame->data[0] av_image_fill_arrays(RGB24Frame->data, RGB24Frame->linesize, (unsigned char*)outBuffer, AV_PIX_FMT_BGR24, YUVFrame->width, YUVFrame->height, 1); sws_scale(convertCxt, YUVFrame->data, YUVFrame->linesize, 0, YUVFrame->height, RGB24Frame->data, RGB24Frame->linesize); // 5.清除各对象/context -> 释放内存 // free context and avFrame sws_freeContext(convertCxt); av_frame_free(&RGB24Frame); // RGB24Frame. } // free context and avFrame av_frame_free(&YUVFrame); } // free context and avFrame av_packet_unref(avPkt); av_packet_free(&avPkt); avcodec_free_context(&codecCtx); } // 把已经废除的格式转换成新的格式,防止报 "deprecated pixel format used, make sure you did set range correctly" 错误 AVPixelFormat convertDeprecatedFormat(enum AVPixelFormat format) { switch (format) { case AV_PIX_FMT_YUVJ420P: return AV_PIX_FMT_YUV420P; break; case AV_PIX_FMT_YUVJ422P: return AV_PIX_FMT_YUV422P; break; case AV_PIX_FMT_YUVJ444P: return AV_PIX_FMT_YUV444P; break; case AV_PIX_FMT_YUVJ440P: return AV_PIX_FMT_YUV440P; break; default: return format; break; } }
在上述代码中convertDeprecatedFormat主要是转换格式的函数。随着 ffmpeg 程序的升级,不少原有的代码再也不建议使用,若是想兼容原有的程序须要作一些处理,不然程序中就会报 warning 警告,虽然不影响使用,可是消除 warning 代码结构会更清晰。阿里云
关于EasyCVR视频上云网关
- 多终端兼容
支持传统网络摄像机、NVR、编码器、SDK等设备,最大程度的提升了硬件设备的兼容性; - 灵活扩展
按需灵活扩展、收缩资源,免去了插件安装、浏览器限定等条件,实现了无插件、多平台自由观看回放; - 快速接入云端
支持阿里云、腾讯云、华为云、七牛云等,支持S3和Swift接口的对象存储服务,简单配置,部署更高效。
若是你们还想了解更多关于EasyCVR相关内容,或有视频相关需求,欢迎在博客下方留言,联系咱们。编码