ffmpeg 获取 rtsp 视频流 c++ 代码实现
时间: 2023-10-02 19:09:26 浏览: 189
opencv 获取rtsp流媒体视频的实现方法
3星 · 编辑精心推荐
以下是使用 ffmpeg 获取 rtsp 视频流的 C++ 代码示例:
```cpp
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
using namespace std;
int main(int argc, char* argv[]) {
AVFormatContext* pFormatCtx = NULL;
AVCodecContext* pCodecCtx = NULL;
AVCodec* pCodec = NULL;
AVFrame* pFrame = NULL;
AVPacket packet;
int videoStream = -1;
int i, numBytes;
uint8_t* buffer = NULL;
// 注册所有组件
av_register_all();
// 打开视频文件
if (avformat_open_input(&pFormatCtx, "rtsp://xxx.xxx.xxx.xxx:xxxx/stream", NULL, NULL) != 0) {
cout << "无法打开视频流" << endl;
return -1;
}
// 查找视频流信息
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
cout << "无法获取视频流信息" << endl;
return -1;
}
// 查找视频流
for (i = 0; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStream = i;
break;
}
}
if (videoStream == -1) {
cout << "无法找到视频流" << endl;
return -1;
}
// 获取视频流编解码上下文
pCodecCtx = avcodec_alloc_context3(NULL);
if (pCodecCtx == NULL) {
cout << "无法分配编解码上下文" << endl;
return -1;
}
avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStream]->codecpar);
// 查找视频流解码器
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
cout << "无法找到解码器" << endl;
return -1;
}
// 打开解码器
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
cout << "无法打开解码器" << endl;
return -1;
}
// 分配视频帧
pFrame = av_frame_alloc();
if (pFrame == NULL) {
cout << "无法分配视频帧" << endl;
return -1;
}
// 分配缓冲区
numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height, 1);
buffer = (uint8_t*)av_malloc(numBytes * sizeof(uint8_t));
av_image_fill_arrays(pFrame->data, pFrame->linesize, buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height, 1);
// 创建 SwsContext
struct SwsContext* sws_ctx = sws_getContext(
pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24,
SWS_BILINEAR, NULL, NULL, NULL);
// 读取视频流
while (av_read_frame(pFormatCtx, &packet) >= 0) {
if (packet.stream_index == videoStream) {
// 解码视频帧
int ret = avcodec_send_packet(pCodecCtx, &packet);
if (ret < 0) {
cout << "解码失败" << endl;
break;
}
while (ret >= 0) {
ret = avcodec_receive_frame(pCodecCtx, pFrame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
cout << "解码失败" << endl;
break;
}
// 转换像素格式
sws_scale(sws_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
// 处理视频帧
// TODO: 在这里处理 RGB24 格式的视频帧
}
}
av_packet_unref(&packet);
}
// 清理资源
av_free(buffer);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}
```
注意:该示例仅演示了如何获取 rtsp 视频流并解码成 RGB24 格式的视频帧,实际应用中还需要根据需要进行相应的处理。
阅读全文