FFmpeg中拉取rtsp视频流并缩放显示测试代码
之前在https://blog.csdn.net/fengbingchun/article/details/92198857中给出过仅拉取rtsp视频流的测试代码,这里在此代码的基础上进行扩充,包括设置使用多线程进行解码,使用sws_scale函数进行图像格式转换和缩放,并通过OpenCV进行显示,测试代码如下:
#include "funset.hpp"
#include <iostream>#ifdef __cplusplus
extern "C" {
#endif#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>#ifdef __cplusplus
}
#endif#include <opencv2/opencv.hpp>
#include "common.hpp"int test_ffmpeg_rtsp_client_decode_show()
{const char* url = "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_115k.mov";AVFormatContext* format_ctx = avformat_alloc_context();int ret = avformat_open_input(&format_ctx, url, nullptr, nullptr);if (ret != 0) {fprintf(stderr, "fail to open url: %s, return value: %d\n", url, ret);return -1;}ret = avformat_find_stream_info(format_ctx, nullptr);if (ret < 0) {fprintf(stderr, "fail to get stream information: %d\n", ret);return -1;}int video_stream_index = -1, audio_stream_index = -1;for (unsigned int i = 0; i < format_ctx->nb_streams; ++i) {const AVStream* stream = format_ctx->streams[i];if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {video_stream_index = i;fprintf(stdout, "type of the encoded data: %d, dimensions of the video frame in pixels: width: %d, height: %d, pixel format: %d\n",stream->codecpar->codec_id, stream->codecpar->width, stream->codecpar->height, stream->codecpar->format);} else if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {audio_stream_index = i;fprintf(stdout, "audio sample format: %d\n", stream->codecpar->format);}}if (video_stream_index == -1) {fprintf(stderr, "no video stream\n");return -1;}if (audio_stream_index == -1) {fprintf(stderr, "no audio stream\n");}AVCodecParameters* codecpar = format_ctx->streams[video_stream_index]->codecpar;const AVCodec* codec = avcodec_find_decoder(codecpar->codec_id);if (!codec) {fprintf(stderr, "fail to avcodec_find_decoder\n");return -1;}AVCodecContext* codec_ctx = avcodec_alloc_context3(codec);if (!codec_ctx) {fprintf(stderr, "fail to avcodec_alloc_context3\n");return -1;}codec_ctx->pix_fmt = AVPixelFormat(codecpar->format);codec_ctx->height = codecpar->height;codec_ctx->width = codecpar->width;codec_ctx->thread_count = 16;ret = avcodec_open2(codec_ctx, codec, nullptr);if (ret != 0) {fprintf(stderr, "fail to avcodec_open2: %d\n", ret);return -1;}const int width_new = 640, height_new = 480;AVFrame* frame = av_frame_alloc();AVPacket* packet = (AVPacket*)av_malloc(sizeof(AVPacket));SwsContext* sws_ctx = sws_getContext(codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt, width_new, height_new, AV_PIX_FMT_BGR24, SWS_BICUBIC, nullptr, nullptr, nullptr);if (!frame || !packet || !sws_ctx) {fprintf(stderr, "fail to alloc\n");return -1;}uint8_t* bgr_data[4];int bgr_linesize[4];av_image_alloc(bgr_data, bgr_linesize, width_new, height_new, AV_PIX_FMT_BGR24, 1);cv::Mat mat(height_new, width_new, CV_8UC3);const char* winname = "rtst video";cv::namedWindow(winname);long long time_begin, time_end;while (1) {//time_begin = Timer::getNowTime();ret = av_read_frame(format_ctx, packet);//time_end = Timer::getNowTime();//fprintf(stdout, "av_read_frame cost time: %lldms\n", time_end - time_begin);if (ret >= 0 && packet->stream_index == video_stream_index && packet->size > 0) {//time_begin = Timer::getNowTime();ret = avcodec_send_packet(codec_ctx, packet);//time_end = Timer::getNowTime();//fprintf(stdout, "avcodec_send_packet cost time: %lldms\n", time_end - time_begin);if (ret < 0) {fprintf(stderr, "##### fail to avcodec_send_packet: %d\n", ret);av_packet_unref(packet);continue;}//time_begin = Timer::getNowTime();ret = avcodec_receive_frame(codec_ctx, frame);//time_end = Timer::getNowTime();//fprintf(stdout, "avcodec_receive_frame cost time: %lldms\n", time_end - time_begin);if (ret < 0) {fprintf(stderr, "##### fail to avcodec_receive_frame: %d\n", ret);av_packet_unref(packet);continue;}//time_begin = Timer::getNowTime();sws_scale(sws_ctx, frame->data, frame->linesize, 0, codec_ctx->height, bgr_data, bgr_linesize);//time_end = Timer::getNowTime();//fprintf(stdout, "sws_scale cost time: %lldms\n", time_end - time_begin);mat.data = bgr_data[0];cv::imshow(winname, mat);} else if (ret < 0 || packet->size <= 0) {fprintf(stderr, "##### fail to av_read_frame: %d, packet size: %d\n", ret, packet->size);continue;}av_packet_unref(packet);int key = cv::waitKey(10);if (key == 27) break;}cv::destroyWindow(winname);av_frame_free(&frame);sws_freeContext(sws_ctx);avformat_close_input(&format_ctx);av_freep(packet);av_freep(&bgr_data[0]);fprintf(stdout, "test finish\n");return 0;
}
执行结果如下:拉取到的rtsp视频流,编码类型为H264,像素格式为YUV420P,原始大小为240x160,通过sws_scale将像素格式转换为bgr24并缩放到640x480显示。
GitHub:https://github.com/fengbingchun/OpenCV_Test
相关文章:

全面分析阿里数据中台,小白也能看懂 | CSDN原力计划
扫码参与CSDN“原力计划”作者 | yuanziok来源 | CSDN原力计划获奖作品数据中台被誉为大数据的下一站,由阿里兴起,核心思想是数据共享,2015年阿里提出“大中台,小前台”的策略。2018 年因为“腾讯数据中台论”,中台再度…

【Stage3D学习笔记续】山寨Starling(八):核心优化(批处理)的实现
批处理是使GPU进行高效绘制的一种技术手段,也是整个渲染流程中最核心的技术,到目前为止我们并没有使用到这种技术手段,下面我们看看我们现在的渲染机制。 先想一想我们最开始是怎么向GPU绘制一幅图像的,可以回头查看Stage3D学习笔…

MBProgressHUD 使用详解
MBProgressHUD是一个显示HUD窗口的第三方类库,用于在执行一些后台任务时,在程序中显示一个表示进度的loading视图和两个可选的文本提示的HUD窗口。我想最多是应用在加载网络数据的时候。其实苹果官方自己有一个带有此功能的类UIProgressHUD,只…

V4L2获取usb视频流测试代码
Video4Linux2(Video for Linux Two, 简称V4L2)是Linux中关于视频设备的驱动框架,为上层访问底层的视频设备提供统一接口。V4L2主要支持三类设备:视频输入输出设备、VBI设备和Radio设备,分别会在/dev目录下产生videoX、vbiX和radioX设备节点&a…

深度学习渐趋冷静,为何图形计算却逆势反涨?
不知不觉,2019 年的进度条已经快撑不住了 ▓▓▓▓▓▓▓▓▓▓▓▓▓░░ 88%。就像这个进度条一样,人工智能的发展也绝不是一蹴而就的事,而是一步一个脚印逐渐发展,最后达成某个目标。近年来,深度学习领域的技术发展…

数字图像处理课设
2019独角兽企业重金招聘Python工程师标准>>> 对于整个窗体的设计,菜单组件(MenuStrip)和工具条(ToolStrip)来添加相应的功能事件当然还有右击鼠标就能弹出相应的属性框,也是使用了叫contextMenuStrip的组件…

Swift3.0带来的变化汇总
var string "Hello-Swift" //获取某个下标后一个下标对应的字符 char"e" //swift2.2 //var char string[startIndex.successor()] //swift3.0 var char string[string.index(after: startIndex)] //获取某个下标前一个下标对应的字符 char2 "t&qu…

通过配置NFS使Ubuntu和海思3559A板子共享目录
之前在Ubuntu和海思3559A板子之间来回拷贝文件都是用的scp命令,不是很方便,这里通过配置NFS来实现它们之间共享目录,操作步骤如下: 1. 在Ubuntu上安装NFS,执行以下命令,执行结果如下: sudo ap…

22w+的人选择了这款蓝牙耳机
01现在有两个电子产品,应该是你们现在必有的,手机和电脑。但还有一样不可缺少的电子产品,那就是耳机。不管喜不喜欢带,反正你手里肯定有一个,应该没人不认可我说的这个话吧。反正我去哪都会带着耳机,听不听…

自定义数字格式字符串输出示例
自定义数字格式字符串输出示例 MSDN 下表阐释了通过给特定数据类型和值应用某些自定义数字格式字符串来创建的输出。输出是通过使用 ToString 方法和美国英语 (en-US) 区域性生成的。 “格式字符串”列指示格式字符串,“数据类型”列指示所用的数据类型,…

海思3559A上编译LIVE555源码操作步骤
1. 从http://www.live555.com/liveMedia/public/ 下载live.2019.06.28.tar.gz,并解压缩; 2. 生成静态库,拷贝一份config.armlinux,取名为config.hi3559a,修改后的内容如下: CROSS_COMPILE? /opt/hisi-linux/x86-ar…

基于海康机器视觉算法平台的对位贴合项目个人理解 | CSDN原力计划
扫码参与CSDN“原力计划”作者 | 果汁分你一半哈哈来源 | CSDN原力计划获奖作品都说“纸上得来终觉浅,绝知此事要躬行”,可惜咱没这条件呀,没项目咱也不能干坐着呀,那咱发挥主观能动性,咱不是学机械的么,还…

解决Swift中present(uiImagePickerController,animated: true,completion: nil)闪退的问题
swift中开发选择图片上传,会使用到Tap Gesture Recognizer控件,对应 UITapGestureRecognizer API,以下是代码示例(取自IOS developer library): IBAction func selectImageFromPhotoLibrary(_ sender: UIT…

测试发现equals和hashCode与书上描述的不一样
2019独角兽企业重金招聘Python工程师标准>>> 如果两个对象根据equals()方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生同样的整数结果。但是现实情况,两者产生的hashCode值却不相等求解? 转载于:htt…

海思3559A上编译OpenCV4.1.0源码操作步骤
1. 从https://github.com/opencv/opencv/releases 下载opencv源码opencv-4.1.0.zip并解压缩; 2. 修改最顶层的CMakeLists.txt,在第658行加入一条语句如下,fix error: pngstruct.h:30:18: fatal error: zlib.h: No such file or directory #i…

如何从零开始设计与开发一款通用模型预测调度系统 | 干货分享
机器学习模型从训练导出到生成环境部署,这个过程中涉及大量工作,会面临着各种问题与挑战,比如不断丰富的业务场景,系统需要负载种类繁多的神经网络,预测任务不均匀等,然而企业拥有的计算资源(如…

闲来无事,总结 Xcode常用快捷键
IOS模拟器home键:Command Shift H 构建应用程序:Command + B 运行app:Command + R 清理工程:Command + Shift + K 打开Xcode首选项:Command + ÿ…

openNebulafrontEnd ComputeNode 配置记录
openNebulafrontEnd ComputeNode 配置记录 1,OpenNebula nfs(file system shared) for image datastore; openNebula computeNode挂载,如果frontend与compute在同一台服务器则不用做NFS shared; 3,make raw image 4,配置过程中配置服务器网桥报错 报错信息 bringing up interfa…

武汉大学提出ARGAN:注意力循环生成对抗模型用于检测、去除图像阴影 | ICCV 2019...
作者 | 王红成出品|AI科技大本营(ID:rgznai100)【导读】如何去除一张图像中的阴影部分?在ICCV 2019会上,武汉大学的一篇论文针对这一问题提出了一种用于阴影检测和去除的注意循环生成对抗网络——ARGAN。论…

海思3559A上编译libyuv源码操作步骤
1. 下载libyuv源代码,执行: git clone https://chromium.googlesource.com/libyuv/libyuv 2. 通过CMakeLists.txt编译生成库,build.sh脚本内容如下: cmake \-DCMAKE_BUILD_TYPERELEASE \-DCMAKE_C_COMPILER/opt/hisi-linux/x86…

Cocoapods的安装以及使用(2)
Cocoapods 在网上看博客,看了好多次,都没有学会cocoapods,今天上午浪费了一上午的时间,终于算是学会了。其实也是很简单的。 iOS 新版 CocoaPods 安装流程 1.换掉现有Ruby默认源(由于好多人都没有翻墙,所…
MyEclipse10中导入的jquery文件报错(出现红叉叉,提示语法错误)
为了做一个页面特效,导入了一个jquery文件,怎想,myeclipse竟然报错说是语法错误,但是这个js文件我是从官网上下载的,不应该出错才对,百度谷歌之后终于找到了解决办法: 选中报错的js文件…

海思3559A上编译libjpeg-turbo源码操作步骤
1. 从https://github.com/libjpeg-turbo/libjpeg-turbo/releases/tag/2.0.2 下载libjpeg-turbo 2.0.2版本; 2. 脚本build.sh内容如下: cmake \-DCMAKE_BUILD_TYPERELEASE \-DCMAKE_C_COMPILER/opt/hisi-linux/x86-arm/aarch64-himix100-linux/bin/aarc…

免费!这里有一份开发者进阶“宝典”求带走
作为开发者,无论是前端还是后端,做机器学习还是云计算、架构,保持对技术的敏感性都是非常重要的事。新技术一般发源于人力、财力等各方面资源都很雄厚的大厂,经过时间的沉淀逐渐成为技术主流。因此,从 BAT、Google、Fa…

使用终端建立自己需要工程
cocoapods应该是时下类库比较全面的三方管理工具,使用也特别方便,你只需将别人的类库在你的 podfile中 pod "SomeoneNameLibrary" 就可以在你的工程中使用这个库,作为一个开发者,你是否也想让别人在他的项目中 pod &quo…

1.0 封装后的布局成本
2019独角兽企业重金招聘Python工程师标准>>> 1.0.1 C语言中(.c) 1. 数据和函数是分开声明的,语言本身没有支持“数据和函数”之间的关联性。 2. 这种程序方法为程序性的,由一组“分布在各个以功能为导向的函数…

通过gdb core dump方法查看程序异常时的堆栈信息
在Linux下可通过core文件来获取当程序异常退出(如异常信号SIGSEGV, SIGABRT等)时的堆栈信息。core dump叫做核心转储,当程序运行过程中发生异常的那一刻的一个内存快照,操作系统在程序发生异常而异常在进程内部又没有被捕获的情况下,会把进程…

日均350000亿接入量,腾讯TubeMQ性能超过Kafka
整理 | 夕颜出品 | AI科技大本营(ID:rgznai100)【导读】近日,腾讯开源动作不断,相继开源了分布式消息中间件TubeMQ,基于最主流的 OpenJDK8开发的Tencent Kona JDK,分布式HTAP数据库 TBase,企业级…

iOS应用版本更新(自动提醒用户)
在#import "AppDelegate.h" 文件中的application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions 方法中调用检测结果 获得发布版本的Version 比较当前版本与新上线版本做比较 UIAlertView代理方法

Bash Shell脚本编程-变量知识
Shell:GUI CLI提供交互式接口:提高效率命令行展开:~ ,{}命令别名:alias命令历史:historyGlobbing:*,?,[],[^]命令补全:$PATH指定的目录下路径补全…