公司项目需要提供实时显示网络摄像头实时视频.

void RTSPFFmpeg::rtsp_open(const char *url) {
AVFormatContext* format_ctx = avformat_alloc_context();
AVCodecContext *pAVCodecContext_video = nullptr;
AVCodec *pAVCodec_video = nullptr;
AVCodecParameters *pAVCodePar_video = avcodec_parameters_alloc();
AVPacket *pAVPacket = av_packet_alloc(); ; // ffmpeg单帧数据包
AVFrame *pAVFrame_video = av_frame_alloc(); // ffmpeg单帧缓存
AVFrame *pAVFrameRGB32_video = av_frame_alloc(); // ffmpeg单帧缓存转换颜色空间后的缓存
AVCodecParserContext *pAVCodeParseContext_video = nullptr;
struct SwsContext *pSwsContext_video = nullptr; // ffmpeg编码数据格式转换
AVDictionary * opts = nullptr; int ret = -1;
int numBytes = 0; // 解码后的数据长度
u_char *outBuffer = nullptr; // 解码后的数据存放缓存区
// open rtsp: Open an input stream and read the header. The codecs are not opened
//const char* url = "rtsp://admin:genepoint2020@192.168.100.14:554/cam/realmonitor?channel=1&subtype=0";
av_dict_set(&opts, "rtsp_transport", "tcp", 0);
av_dict_set(&opts, "stimeout", "2000000", 0);
// audio/video stream index
int video_stream_index = -1;
   ret = avformat_open_input(&format_ctx, url, nullptr, &opts);
if (ret != 0) {
fprintf(stderr, "fail to open url: %s, return value: %d\n", url, ret);
continue;
}
// Read packets of a media file to get stream information
ret = avformat_find_stream_info(format_ctx, nullptr);
if (ret < 0) {
fprintf(stderr, "fail to get stream information: %d\n", ret);
continue;
} fprintf(stdout, "Number of elements in AVFormatContext.streams: %d\n", format_ctx->nb_streams);
for (int i = 0; i < format_ctx->nb_streams; ++i) {
const AVStream *stream = format_ctx->streams[i];
fprintf(stdout, "type of the encoded data: %d\n", stream->codecpar->codec_id);
if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
video_stream_index = i;
// 对找到的视频流寻解码器
pAVCodePar_video = stream->codecpar;
pAVCodec_video = avcodec_find_decoder(stream->codecpar->codec_id);
if (!pAVCodec_video) {
video_stream_index = -1;
break;
}
pAVCodeParseContext_video = av_parser_init(pAVCodec_video->id);
if (!pAVCodeParseContext_video) {
video_stream_index = -1;
break;
}
pAVCodecContext_video = avcodec_alloc_context3(pAVCodec_video);
if (!pAVCodecContext_video) {
}
if (avcodec_open2(pAVCodecContext_video, pAVCodec_video, NULL) < 0) {
video_stream_index = -1;
break;
}
fprintf(stdout, "dimensions of the video frame in pixels: width: %d, height: %d, pixel format: %d\n",
stream->codecpar->width, stream->codecpar->height, stream->codecpar->format);
}
}
if (video_stream_index == -1) {
fprintf(stderr, "no video stream\n");
continue;
}
// 对拿到的原始数据格式进行缩放转换为指定的格式高宽大小
pSwsContext_video = sws_getContext(
pAVCodePar_video->width,
pAVCodePar_video->height,
static_cast<AVPixelFormat>(pAVCodePar_video->format),
pAVCodePar_video->width,
pAVCodePar_video->height,
AV_PIX_FMT_RGBA,
SWS_FAST_BILINEAR,
nullptr,
nullptr,
nullptr
);
numBytes = av_image_get_buffer_size(
AV_PIX_FMT_RGBA,
pAVCodePar_video->width,
pAVCodePar_video->height,
1
);
outBuffer = (u_char *) av_malloc(numBytes);
// pAVFrame32的data指针指向了outBuffer
av_image_fill_arrays(
pAVFrameRGB32_video->data,
pAVFrameRGB32_video->linesize,
outBuffer,
AV_PIX_FMT_RGBA,
pAVCodePar_video->width,
pAVCodePar_video->height,
1
);
while (1) {
ret = av_read_frame(format_ctx, pAVPacket);
if (ret < 0) {
fprintf(stderr, "error or end of file: %d\n", ret);
continue;
}
if (pAVPacket->stream_index == video_stream_index) {
// fprintf(stdout, "video stream, packet size: %d\n", pAVPacket->size);
ret = avcodec_send_packet(pAVCodecContext_video,pAVPacket);
if( 0 != ret){
continue;
}
while (avcodec_receive_frame(pAVCodecContext_video,pAVFrame_video) == 0){
sws_scale(pSwsContext_video,
(const uint8_t * const *)pAVFrame_video->data,
pAVFrame_video->linesize,
0,
pAVCodePar_video->height,
pAVFrameRGB32_video->data,
pAVFrameRGB32_video->linesize);
QImage image((u_char*)outBuffer,pAVCodePar_video->width,pAVCodePar_video->height,QImage::Format_RGBA8888);
emit rtsp_image_sig(image);
}
}
av_packet_unref(pAVPacket);
}
av_parser_close(pAVCodeParseContext_video);
av_frame_free(&pAVFrame_video);
av_frame_free(&pAVFrameRGB32_video);
av_free(outBuffer);
av_free(pSwsContext_video);
avcodec_free_context(&pAVCodecContext_video);
avformat_close_input(&format_ctx);
}

ffmpeg拉取rtsp视频流的更多相关文章

  1. ffmpeg API录制rtsp视频流

    原文出自http://blog.csdn.net/zxwangyun/article/details/8190638#reply   作者 Sloan 这里在录制时,并没有进行转码,只是相当于把rts ...

  2. Web下无插件播放rtsp视频流的方案及各家优秀内容资源整理

    Web下无插件播放rtsp视频流的方案及各家优秀内容资源整理 方案一:服务器端用 websocket 接受 rtsp ,然后,推送至客户端 实现步骤: 方案二:使用 ffmpeg + nginx 把 ...

  3. 使用FFmpeg如何转发一个RTSP视频流

    版权声明:转载请说明出处:http://www.cnblogs.com/renhui/p/6930221.html   转发RTSP流,这类需求一般出现于转发一些摄像头采集视频,并在摄像头上做RTSP ...

  4. Ffmpeg 获取USB Camera 视频流

    本文讲述的案例是如何通过Ffmpeg实现从USB Camera中获取视频流并将视频流保存到MP4文件. 本文亦适用于从USB Camera 获取视频流并将视频流转发到rtmp服务的案例,二者基本的原理 ...

  5. OpenCV读取RTSP视频流

    用opencv的VideoCapture读取RTSP视频流,只有opencv3.1版本可以,之前的版本都无法读取视频流.可能的原因是云平台的RTSP视频流太差,经常错码.项目最后使用的是opencv2 ...

  6. 基于阿里云直播实现视频推流(ffmpeg)/拉流(Django2.0)以及在线视频直播播放(支持http/https)功能

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_146 由于5g网络的光速推广,视频业务又被推上了风口浪尖,在2019年初我们还在谈论照片,短视频等关键字,而进入2020年,我们津 ...

  7. github拉取和推送

    登入github 创建一个开源项目 然后打开安装好的git 首先进入一个指定的文件夹 例如: 1)E:\>cd miaov/testGit 回车 进入E盘的testGit文件夹 2)E:\mia ...

  8. 流媒体测试笔记记录之————阿里云监控、OBS、FFmpeg拉流和推流变化比较记录

    OBS设置视频(512kbps)和音频(128kbps)比特率 阿里云监控结果: 使用FFmpeg拉流到Nginx 服务器测试比特率 第二次测试,修改视频和音频比特率 OBS设置 阿里云监控 Ngin ...

  9. git&sourcetree安装及在IntelliIJ下拉取项目基础使用

    be careful: 1)git版本与Sourcetree版本最好一致 ,不能git为2.5,sourcetree为1.8 2)先安装git再安装Sourcetree 3)拥有git和sourcet ...

随机推荐

  1. 论文笔记 - Fantastically Ordered Prompts and Where to Find Them: Overcoming Few-Shot Prompt Order Sensitivity

    prompt 的影响因素 Motivation Prompt 中 Example 的排列顺序对模型性能有较大影响(即使已经校准参见好的情况下,选取不同的排列顺序依然会有很大的方差): 校准可以大幅度提 ...

  2. Oracle数据库的导出和导入

    本次数据库的导入导出操作是导出公司环境的Oracle数据库,再导入本地数据库,采用impdp和expdp命令进行导入导出操作. 一.导出52数据库 1.用system用户登录到数据库,查看是否有创建d ...

  3. 【题解】CF1659E AND-MEX Walk

    题目传送门 位运算 设题目中序列 \(w_1,w_1 \& w_2,w_1 \& w_2 \& w_3,\dots,w_1 \& w_2 \& \dots \& ...

  4. 篇(18)-Asp.Net Core入门实战-文章管理之文章内容管理(下拉框二级结构递归)

    篇(18)-Asp.Net Core入门实战-文章管理之文章内容管理(下拉框二级结构递归实现) 文章管理是CMS系统的核心表之一,存储文章内容,特点就是字段端,属性多,比如是否标识为热点.推荐等属性, ...

  5. <一>继承的基本意义

    1:继承的本质和原理 2:派生类的构造过程 3:重载,覆盖,隐藏 4:静态绑定和动态绑定 5:多态,vfptr,vftable 6:抽象类的设计原理 7:多重继承以及问题 8:虚基类 vbptr 和v ...

  6. 第2-4-8章 规则引擎Drools实战(1)-个人所得税计算器

    目录 9. Drools实战 9.1 个人所得税计算器 9.1.1 名词解释 9.1.2 计算规则 9.1.2.1 新税制主要有哪些变化? 9.1.2.2 资较高人员本次个税较少,可能到年底扣税增加? ...

  7. 【每日一题】【map存值】2022年2月25日-NC112 进制转换

    描述给定一个十进制数 M ,以及需要转换的进制数 N .将十进制数 M 转化为 N 进制数. 当 N 大于 10 以后, 应在结果中使用大写字母表示大于 10 的一位,如 'A' 表示此位为 10 , ...

  8. 进击的K8S:Kubernetes基础概念

    Kubernetes简介 Kubernetes简称K8S(因为k和s中间有8个字母),是一个开源的容器集群管理平台,基于Go语言编写. 使用K8S,将简化分布式系统上的容器应用部署,使得开发人员可以专 ...

  9. 伙伴福利,100个项目彻底精通Java!【开源】

    为了帮助更多的小伙伴,快速成长进步,冲进大厂中厂,我分享了很多的项目哟,例如: java项目精品实战案例 | JavaSwing实战项目 但很多小伙伴,还觉得不够,好吧!今天就拿出压箱底的项目,给支持 ...

  10. 「笔记」某移动SRE运维体系交流

    痛点 传统竖井式IT架构(封闭.隔离.非标.难运维) X86 服务器硬件稳定性不足 开源软件可靠性不足,且不可控 出了故障,被动救火救不完 转型 由此催生了转型升级的需求: 运维智能(SRE)的转型 ...