【深度学习】使用ffmpg及gstreamer进行视频拉流及编解码(一):ffmpg

这篇具有很好参考价值的文章主要介绍了【深度学习】使用ffmpg及gstreamer进行视频拉流及编解码(一):ffmpg。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

为什么要进行视频编解码

视频流需要编解码的主要原因是视频文件的数据量很大,直接传输视频文件会占用大量网络带宽和存储空间。而通过对视频进行编码和解码,可以将视频数据压缩到较小的体积,从而实现更高效的传输和存储。
具体来说,编码就是将原始的视频数据转换为压缩后的视频数据,而解码则是将压缩后的视频数据还原为原始的视频数据。编码和解码过程都需要采用一定的算法和规则,以便能够在压缩和解压缩过程中实现最小的数据损失和最高的数据压缩比。常用的视频编解码器包括H.264、H.265、VP8、VP9等。

视频编解码的主要优点是:

节省存储空间:通过视频编码可以将视频文件的大小压缩到原始大小的10%~50%左右,从而节省存储空间。

减少网络带宽:通过视频编码可以将视频流的数据量减小,从而减少传输数据所需要的网络带宽。

提高视频传输质量:通过视频编码可以减少数据传输时的延迟和抖动,从而提高视频的传输质量和稳定性。

加密视频流:通过对视频进行编码,可以加密视频流,保护数据的安全性和隐私性。
总之,视频编解码是实现高效传输和存储视频的重要手段,广泛应用于视频监控、视频直播、视频通话等领域。

网络带宽

视频拉流中的网络带宽指的是在视频流传输过程中所占用的网络传输带宽。在视频拉流过程中,视频流需要通过网络传输到客户端,因此需要一定的网络带宽来支持数据的传输。
网络带宽是指在单位时间内可以传输的数据量,通常用Mbps(兆比特每秒)或Gbps(千兆比特每秒)来表示。网络带宽越大,传输的数据量就越大,传输速度也就越快。因此,在视频拉流过程中,需要保证网络带宽足够大,以便能够快速、稳定地传输视频数据。
视频拉流中的网络带宽大小会受到多种因素的影响,例如网络带宽的限制、网络拥塞、数据传输的距离等。如果网络带宽不足,就会出现视频卡顿、画面模糊、声音不同步等问题,影响用户的观看体验。因此,在进行视频拉流时,需要对网络带宽进行充分考虑,选择合适的传输协议、码率和分辨率,以便实现更好的视频传输效果。

常见的视频编码格式

H.264/AVC:H.264/AVC是一种广泛应用的视频编码格式,具有高压缩比、高画质和低延迟等优点。它通常采用的是CBR(固定码率)或者VBR(可变码率)的编码方式,消耗的带宽大小取决于视频分辨率、帧率和码率等因素。

H.265/HEVC:H.265/HEVC是H.264/AVC的后继版本,具有更高的压缩比和更低的码率,可以在相同的画质下降低带宽消耗。然而,H.265/HEVC相对于H.264/AVC而言,更加计算复杂,需要更高的计算性能和更好的网络环境。

视频分辨率及其占用的经验带宽

1080p、CIF、D1和720p是视频分辨率的标准表示方式,具体解释如下:

1080p:也称为全高清,是指视频分辨率为1920×1080像素的格式,其中“p”表示逐行扫描方式。

CIF:是指视频分辨率为352×288像素的格式,其中“CIF”代表“Common Intermediate Format”,是一种标准格式。

D1:是指视频分辨率为720×576像素的格式,其中“D1”代表“Digital 1”,是一种标准格式。

720p:也称为高清,是指视频分辨率为1280×720像素的格式,其中“p”表示逐行扫描方式。
不同的视频分辨率对带宽的消耗大小不同,一般而言,分辨率越高,需要的带宽就越大。根据经验值,1080p视频流需要的带宽一般在5-10Mbps之间,CIF视频流需要的带宽一般在0.2-0.5Mbps之间,D1视频流需要的带宽一般在1-2Mbps之间,720p视频流需要的带宽一般在2-4Mbps之间。但是需要注意的是,实际消耗的带宽大小还受到视频编码方式、帧率、码率、压缩比以及网络环境和设备性能等因素的影响,因此具体的带宽消耗还需要根据实际情况进行评估。

千兆网口及百兆网口

千兆网口和百兆网口的区别主要在于传输速率和支持的最大带宽不同。具体而言,千兆网口支持的传输速率为1Gbps(即1000Mbps),而百兆网口支持的传输速率为100Mbps,因此千兆网口的传输速率是百兆网口的10倍。同时,千兆网口支持的最大带宽也比百兆网口更大,可以达到1Gbps。
至于为什么网线4根线也能运行,这是因为千兆以太网技术采用了全双工通信方式,并且采用了自适应速率和双工模式,可以在不同的传输环境下自动调整传输速率和双工模式。因此,即使网线只有4根线,也可以通过自适应技术实现千兆网口的运行。不过,为了保证千兆以太网的正常运行,建议使用符合千兆以太网标准的8根网线,以避免出现传输速率降低或者网络不稳定等问题。

硬件编解码和软件编解码的区别

硬件编解码和软件编解码的主要区别在于编解码的实现方式不同。
软件编解码是在CPU上实现的,需要使用软件算法对视频数据进行编解码。这种方式的优点是灵活性高,可以在不同的平台和系统上运行,同时支持多种编解码格式和算法,兼容性好。缺点是速度较慢,尤其是对于高清视频和高帧率视频,需要消耗大量的CPU资源,容易造成系统卡顿。
硬件编解码是通过GPU或专用的硬件模块实现的,可以快速地对视频数据进行编解码。这种方式的优点是速度快,对于高清视频和高帧率视频可以实现实时处理,同时可以减少CPU的负担和功耗。缺点是硬件编解码器通常只支持有限的编解码格式和算法,不够灵活,而且不同平台和系统之间的兼容性也有所差异。
总的来说,硬件编解码和软件编解码各有优缺点,需要根据具体的应用场景和需求进行选择。对于需要实现高速编解码和实时处理的场景,硬件编解码是更好的选择;对于对兼容性和灵活性有更高要求的场景,软件编解码则更适合。

拉流工具简介

GStreamer:一款功能强大的多媒体框架,可以用于音视频的采集、编码、解码、处理和传输。

FFmpeg:一个开源的音视频处理工具,可以用于音视频的采集、编码、解码、转码、处理等。

FFmpeg和GStreamer都是流媒体处理框架,它们在音视频编解码、转码、过滤、采集等方面都有广泛的应用。
FFmpeg是一个开源的音视频处理库,支持多种音视频格式的编解码、转码、过滤等操作。它可以在多个平台上运行,包括Windows、Linux、macOS等,被广泛应用于多媒体软件开发、流媒体服务器、视频编辑、转码等领域。FFmpeg提供了一系列的命令行工具,可以方便地进行各种音视频处理操作,如播放、录制、转码等。同时,FFmpeg也提供了一系列的API接口,允许开发者在自己的应用程序中集成音视频处理功能。
GStreamer是一个基于插件的开源多媒体框架,可以进行音视频的采集、编解码、处理和播放等操作。它提供了一套组件和插件体系结构,可以通过组合不同的插件来实现不同的功能。GStreamer可以运行在多个平台上,包括Linux、macOS、Windows等,被广泛应用于数字电视、音视频编辑、流媒体服务器等领域。GStreamer提供了一套完整的API接口,可以通过编写C/C++、Python等语言的代码来实现音视频处理功能。
区别方面,FFmpeg更加注重音视频编解码方面的处理,被广泛应用于媒体格式转换、编码解码等方面;而GStreamer则更加注重音视频处理的整体框架,在音视频采集、流媒体传输、播放等方面有着广泛应用。同时,GStreamer的应用范围更加广泛,可以用于多媒体软件开发、数字电视、流媒体服务器等领域。

安装ffmpg库

安装必要的依赖库

在编译FFmpeg之前,需要安装一些必要的依赖库,包括:
h264解码库
nasm

先安装nasm依赖,安装完成后,将帮助安装h264.

wget https://www.nasm.us/pub/nasm/releasebuilds/2.14/nasm-2.14.tar.gz
/home/imagedepth/streamWork/nasm-2.14.tar.gz
 tar zxvf /home/imagedepth/streamWork/nasm-2.14.tar.gz -C ./
 cd nasm-2.14
 ./configure
 make
 make install

下面安装x264:

使用:

git clone https://code.videolan.org/videolan/x264.git
cd x264
./configure --prefix=/usr/x264/ --includedir=/usr/local/include --libdir=/usr/local/lib --enable-shared
make
make install

如果出现:ERROR: x264 not found using pkg-config

vim /etc/profile
末尾加入内容export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig,具体看各位自己x264的安装路径
source /etc/profile
然后再./configure ...就没问题了

安装ffmpg库

git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
cd ffmpeg
./configure --enable-gpl --enable-libx264 --enable-shared
make
make install
#添加动态库搜索路径,解决找不到libx264.so.164的问题
sudo sh -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/local.conf'
sudo ldconfig

安装后可执行文件默认放在/usr /local/bin,库文件默认放在/usr/local/lib,配置文件默认放在/usr/local/etc,其它的资源文件放在/usr /local/share,头文件在/usr/local/include

代码

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
}
int main(int argc, char* argv[]) {
    // 输入流地址,对应大华摄像头
    const char* input_url = "rtsp://admin:admin123@192.168.25.253:554/cam/realmonitor?channel=1&subtype=0";
    // 输出视频宽度
    const int output_width = 640;
    // 输出视频高度
    const int output_height = 480;
    // 初始化FFmpeg
    // av_register_all();
    avformat_network_init();
    // 打开输入流
    AVFormatContext* input_format_context = avformat_alloc_context();
    if (avformat_open_input(&input_format_context, input_url, nullptr, nullptr) != 0) {
        std::cerr << "Could not open input stream: " << input_url << std::endl;
        return EXIT_FAILURE;
    }
    // 获取输入流信息
    if (avformat_find_stream_info(input_format_context, nullptr) < 0) {
        std::cerr << "Could not find stream information." << std::endl;
        return EXIT_FAILURE;
    }
    // 获取视频流索引
    int video_stream_index = -1;
    for (unsigned int i = 0; i < input_format_context->nb_streams; i++) {
        if (input_format_context->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            video_stream_index = i;
            break;
        }
    }
    if (video_stream_index == -1) {
        std::cerr << "Could not find video stream." << std::endl;
        return EXIT_FAILURE;
    }
    // 获取视频流解码器
    AVCodecParameters* codec_parameters = input_format_context->streams[video_stream_index]->codecpar;
    AVCodec* codec = const_cast<AVCodec*>(avcodec_find_decoder(codec_parameters->codec_id));
    if (!codec) {
        std::cerr << "Could not find decoder." << std::endl;
        return EXIT_FAILURE;
    }
    // 打开视频流解码器
    AVCodecContext* codec_context = avcodec_alloc_context3(codec);
    if (avcodec_parameters_to_context(codec_context, codec_parameters) < 0) {
        std::cerr << "Could not create codec context." << std::endl;
        return EXIT_FAILURE;
    }
    if (avcodec_open2(codec_context, codec, nullptr) < 0) {
        std::cerr << "Could not open codec." << std::endl;
        return EXIT_FAILURE;
    }
    // 初始化视频帧
    AVFrame* frame = av_frame_alloc();
    if (!frame) {
        std::cerr << "Could not allocate frame." << std::endl;
        return EXIT_FAILURE;
    }
    // 初始化视频帧RGB格式
    AVFrame* frame_rgb = av_frame_alloc();
    if (!frame_rgb) {
        std::cerr << "Could not allocate frame." << std::endl;
        return EXIT_FAILURE;
    }
    int num_bytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, output_width, output_height, 1);
    uint8_t* buffer = (uint8_t*)av_malloc(num_bytes * sizeof(uint8_t));
    av_image_fill_arrays(frame_rgb->data, frame_rgb->linesize, buffer, AV_PIX_FMT_RGB24, output_width, output_height, 1);
    // 初始化图像转换器
    SwsContext* sws_context = sws_getContext(codec_context->width, codec_context->height, codec_context->pix_fmt, output_width, output_height, AV_PIX_FMT_RGB24, SWS_BILINEAR, nullptr, nullptr, nullptr);
    // 读取视频帧
    AVPacket packet;
    av_init_packet(&packet);
    while (av_read_frame(input_format_context, &packet) >= 0) {
        if (packet.stream_index == video_stream_index) {
            // 解码视频帧
            int ret = avcodec_send_packet(codec_context, &packet);
            if (ret < 0) {
                std::cerr << "Error sending a packet for decoding." << std::endl;
                av_packet_unref(&packet);
                continue;
            }
            while (ret >= 0) {
                ret = avcodec_receive_frame(codec_context, frame);
                if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
                    break;
                }
                else if (ret < 0) {
                    std::cerr << "Error during decoding." << std::endl;
                    return EXIT_FAILURE;
                }
                // 转换图像格式
                sws_scale(sws_context, (const uint8_t* const*)frame->data, frame->linesize, 0, codec_context->height, frame_rgb->data, frame_rgb->linesize);
                // 将图像数据复制到OpenCV的Mat中
                cv::Mat mat(output_height, output_width, CV_8UC3, frame_rgb->data[0]);
                // 显示图像
                cv::imwrite("output.jpg", mat, {cv::IMWRITE_JPEG_QUALITY, 80});
                // cv::imshow("Video", mat);
                // cv::waitKey(1);
            }
            av_packet_unref(&packet);
        }
    }
    // 释放资源
    av_free(buffer);
    av_frame_free(&frame_rgb);
    av_frame_free(&frame);
    avcodec_close(codec_context);
    avformat_close_input(&input_format_context);
    avformat_network_deinit();
    return EXIT_SUCCESS;
}

对应cmakelist:

cmake_minimum_required(VERSION 3.0)
project(pro)
add_definitions(-std=c++11)
option(CUDA_USE_STATIC_CUDA_RUNTIME OFF)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE Release)
#set(CMAKE_BUILD_TYPE Debug)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/workspace)
set(ffmpeg_libs_DIR /usr/local/lib)
set(ffmpeg_headers_DIR /usr/local/include)
set(OpenCV_DIR   "/usr/local/opencv/lib64/cmake/opencv4")

find_package(OpenCV)
include_directories(
    ${PROJECT_SOURCE_DIR}/src
    ${OpenCV_INCLUDE_DIRS}
    ${ffmpeg_headers_DIR} 
)
link_directories(${OpenCV_LIBRARY_DIRS} ${ffmpeg_libs_DIR} )
set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -O0 -Wfatal-errors -pthread -w -g")
#递归地添加的相关文件
file(GLOB_RECURSE cpp_srcs ${PROJECT_SOURCE_DIR}/src/*.cpp)
file(GLOB_RECURSE c_srcs ${PROJECT_SOURCE_DIR}/src/*.c)
add_executable(pro ${cpp_srcs} ${c_srcs})


target_link_libraries( pro ${OpenCV_LIBS} ${ffmpeg_libs_DIR} avcodec.a avformat.a avutil.a swscale.a avfilter.a swresample.a z bz2 x264)

拉流效果:
ffmpeg mpp,c++,计算机视觉,深度学习,深度学习,音视频,人工智能文章来源地址https://www.toymoban.com/news/detail-616652.html

到了这里,关于【深度学习】使用ffmpg及gstreamer进行视频拉流及编解码(一):ffmpg的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于开源的Micro-RTSP,使用VLC和ffmpeg拉流播放RTSP视频流,本例使用安信可ESP32 CAM进行推流。

    基于开源的Micro-RTSP,使用VLC和ffmpeg拉流播放RTSP视频流,本例使用安信可ESP32 CAM进行推流。 vlc播放命令为:rtsp://192.168.43.128:8554/mjpeg/1。 ffmpeg播放命令为:ffplay rtsp://192.168.43.128:8554/mjpeg/1。 使用ESP-IDF5.0编译成功。esp-idf-v4.4.2编译不成功,有成功的小伙伴可以分享一下。 git cl

    2024年02月01日
    浏览(47)
  • FFmpeg/opencv + C++ 实现直播拉流和直播推流(对视频帧进行处理)

    本文主要使用C++ ffmpeg库实现对除去webrtc的视频流进行拉流,而后经过自身的处理,而后通过将处理后的视频帧进行编码,最后进行推流处理。详情请看代码 参考链接: https://blog.csdn.net/weixin_45807901/article/details/129086344 https://blog.csdn.net/T__zxt/article/details/126827167

    2024年02月16日
    浏览(56)
  • gstreamer中使用webrtc实现音视频对讲

    gstreamer官方源代码中有一个基于webrtc插件实现音视频通话的开源项目,下面介绍在Ubuntu系统中如何搭建环境并使用。 这里省略gstreamer安装,直接安装使用webrtcbin插件使用的相关库,参考官网。系统版本建议高于ubuntu18.04。 首先安装如下相关依赖库。 gstreamer项目编译官方建议

    2024年04月11日
    浏览(45)
  • LiveNVR Onvif/RTSP流媒体软件接入监控摄像头后如何获取直播流地址进行大屏展示、播放端拉流、网页播放监控视频等...

    LiveNVR的安防监控的视频直播,可以按标准的Onvif/RTSP协议接入监控设备,也可以通过海康、大华、天地伟业等厂家私有SDK接入监控,实现web页面的播放和录像回放。 可以分发HTTP-FLV、WS-FLV、WebRTC、RTMP、HLS(M3U8)、RTSP等多中视频流 2.1.1、接口说明 http://192.168.2.135:10800 是示例的i

    2024年02月16日
    浏览(53)
  • Python基于深度学习的人脸识别项目源码+演示视频,利用OpenCV进行人脸检测与识别 preview

    ​ 该人脸识别实例是一个基于深度学习和计算机视觉技术的应用,主要利用OpenCV和Python作为开发工具。系统采用了一系列算法和技术,其中包括以下几个关键步骤: 图像预处理 :首先,对输入图像进行预处理,包括读取图片、将图片灰度转换、修改图片的尺寸、绘制矩形

    2024年04月13日
    浏览(70)
  • 深度学习与图像识别:如何使用深度学习进行图像识别

    深度学习与图像识别:如何使用深度学习进行图像识别 深度学习是一种基于多层神经网络的机器学习方法,能够从大量的数据中自动提取特征和规律,从而实现复杂的任务,如图像识别。图像识别是指让计算机能够理解和分析图像中的内容,如物体、人脸、场景等。使用深度

    2024年02月05日
    浏览(45)
  • 使用 Python 进行深度学习以进行裂纹检测

    虽然新技术已经改变了我们生活的方方面面,在建筑领域似乎牛逼Ø正在努力追赶。目前,建筑物的结构状况仍然主要是人工检查。简单来说,即使现在需要检查结构是否有任何损坏,工程师也会手动检查所有表面并拍下一堆照片,同时记录任何裂缝的位置。然后需要在办公

    2024年02月04日
    浏览(41)
  • 使用深度学习模型进行情感分析

    在本篇文章中,我们将介绍如何使用深度学习模型进行情感分析。具体来说,我们将使用卷积神经网络(Convolutional Neural Network,CNN)对 IMDB 数据集进行情感分类。 1. 数据集介绍 IMDB 数据集是一个常用的自然语言处理数据集,包含了 50000 条电影评论。其中,25000 条评论用于训

    2023年04月15日
    浏览(48)
  • 深度学习使用Keras进行多分类

    之前的文章介绍了使用Keras解决二分类问题。那么对于多分类问题该怎么解决?本文介绍利用深度学习----Keras进行多分类。 为了演示,本次选用了博文keras系列︱图像多分类训练与利用bottleneck features进行微调(三)中提到的数据集,原始的数据集将所有类别的train照片放到t

    2024年02月07日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包