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

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. Vivado_8位流水灯

    Design 代码中的计数器设置是因为我的开发板的时钟是100MHZ的,也就是1秒完成了100_000_000次时钟信号,所以我设置计数器为100_000_000次. 也就是说,我让流水灯的变化周期为 ...

  2. go mod常用命令 已经 常见问题

    最近接触到go mod,网上查了查资料,这里记录一下. 1 介绍 1.1.go mod是什么 go mod 是Golang 1.11 版本引入的官方包(package)依赖管理工具,用于解决之前没有地 ...

  3. 【经验分享】配置用户通过Console口登录设备示例

    组网需求 当用户无法进行远程登录设备时,可通过Console口进行本地登录.缺省情况下,使用Console用户界面登录设备时只需要密码认证.为了防止非法用户登录设备,修改Console用户界面的认证方 ...

  4. 如何安装Visual Studio Community2022

    如何安装Visual Studio Community2022 Visual Studio是一款强大的IDE(集成开发环境),对于初学者可以选择使用社区版,下面是Visual Studio Commu ...

  5. Java Web中requset,session,application 的作用域及区别

    三者概述 requset概述: request是表示一个请求,只要发出一个请求就会创建一个request 用处:常用于服务器间同一请求不同页面之间的参数传递,常应用于表单的控件值传递. session ...

  6. Day24.1:抽象类的详解

    抽象类 1.1抽象类概述 一个动物类中,我们创建对象时会去new一个动物:但是我们不应该直接创建动物这个对象,因为动物本身就是抽象的,没有动物这种实例,我们创建的应该是一个具体的动物类,比如猫.狗等动 ...

  7. 关于解决 inittramfs unpacking failed:Decoding failed 报错

    解决办法 vi /etc/initramfs-tools/initramfs.conf 更改COMPRESS=lz4以COMPRESS=gzip 保存更改 sudo update-initramfs ...

  8. 关于更改 lightdm 主题的方法

    lightdm 是一个显示管理器,它支持很多种 greeter lightdm 的主要配置文件都在 /etc/lightdm 目录下面 各个文件的作用: 配置文件名称 作用 图形化界面配置工具 lig ...

  9. 【每日一题】【优先队列、迭代器、lambda表达式】2022年1月15日-NC119 最小的K个数

    描述 给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数.例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可). 数据范围: ...

  10. 《HTTP权威指南》– 16.重定向与负载均衡

    重定向 重定向 的目标是尽快地将HTTP报文发送到可用的Web服务器上去.在穿过因特网的路径上,HTTP报文传输的方向会受到HTTP应用程序和报文经由的路由设备的影响: 配置创建客户端报文的浏览器应用 ...