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相關內容,或有視頻相關需求,歡迎在博客下方留言,聯繫咱們。編碼