ffmpeg打开摄像头 c++
时间: 2023-09-21 18:05:05 浏览: 154
要在 C++ 中使用 FFmpeg 打开摄像头,你可以使用 FFmpeg 的 libavformat 库和 libavcodec 库。
以下是一个简单的示例程序,它使用 FFmpeg 打开摄像头并将视频流保存为 AVI 文件:
```c++
#include <iostream>
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
}
using namespace std;
int main(int argc, char** argv) {
av_register_all();
avformat_network_init();
AVFormatContext* pFormatCtx = avformat_alloc_context();
AVDictionary* options = NULL;
av_dict_set(&options, "video_size", "640x480", 0);
av_dict_set(&options, "framerate", "30", 0);
AVInputFormat* pInputFmt = av_find_input_format("v4l2");
if (avformat_open_input(&pFormatCtx, "/dev/video0", pInputFmt, &options) != 0) {
cerr << "Could not open input stream" << endl;
return -1;
}
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
cerr << "Could not find stream information" << endl;
return -1;
}
AVCodec* pCodec = NULL;
AVCodecParameters* pCodecParameters = NULL;
int videoStreamIndex = -1;
for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStreamIndex = i;
pCodecParameters = pFormatCtx->streams[i]->codecpar;
pCodec = avcodec_find_decoder(pCodecParameters->codec_id);
break;
}
}
if (videoStreamIndex == -1 || pCodec == NULL) {
cerr << "Could not find video stream or codec" << endl;
return -1;
}
AVCodecContext* pCodecCtx = avcodec_alloc_context3(pCodec);
if (avcodec_parameters_to_context(pCodecCtx, pCodecParameters) < 0) {
cerr << "Failed to copy codec parameters to decoder context" << endl;
return -1;
}
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
cerr << "Failed to open codec" << endl;
return -1;
}
AVFrame* pFrame = av_frame_alloc();
AVPacket packet;
av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;
AVFormatContext* pOutputFormatCtx = NULL;
avformat_alloc_output_context2(&pOutputFormatCtx, NULL, NULL, "output.avi");
if (!pOutputFormatCtx) {
cerr << "Could not create output context" << endl;
return -1;
}
AVOutputFormat* pOutputFmt = pOutputFormatCtx->oformat;
AVStream* pOutputStream = avformat_new_stream(pOutputFormatCtx, NULL);
if (!pOutputStream) {
cerr << "Could not create output stream" << endl;
return -1;
}
if (avcodec_parameters_copy(pOutputStream->codecpar, pCodecParameters) < 0) {
cerr << "Failed to copy codec parameters to output stream" << endl;
return -1;
}
pOutputStream->codecpar->codec_tag = 0;
if (!(pOutputFmt->flags & AVFMT_NOFILE)) {
if (avio_open(&pOutputFormatCtx->pb, "output.avi", AVIO_FLAG_WRITE) < 0) {
cerr << "Could not open output file" << endl;
return -1;
}
}
if (avformat_write_header(pOutputFormatCtx, NULL) < 0) {
cerr << "Error occurred when opening output file" << endl;
return -1;
}
while (av_read_frame(pFormatCtx, &packet) >= 0) {
if (packet.stream_index == videoStreamIndex) {
int ret = avcodec_send_packet(pCodecCtx, &packet);
if (ret < 0) {
cerr << "Error sending packet to decoder" << endl;
break;
}
while (ret >= 0) {
ret = avcodec_receive_frame(pCodecCtx, pFrame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
cerr << "Error during decoding" << endl;
return -1;
}
if (ret >= 0) {
AVPacket newPacket;
av_init_packet(&newPacket);
newPacket.data = NULL;
newPacket.size = 0;
if (avcodec_send_frame(pOutputStream->codec, pFrame) >= 0) {
while (avcodec_receive_packet(pOutputStream->codec, &newPacket) >= 0) {
av_interleaved_write_frame(pOutputFormatCtx, &newPacket);
av_packet_unref(&newPacket);
}
}
}
}
}
av_packet_unref(&packet);
}
av_write_trailer(pOutputFormatCtx);
avcodec_free_context(&pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}
```
在这个例子中,我们首先初始化 FFmpeg 库并打开摄像头。然后,我们查找视频流的索引和解码器,并初始化解码器上下文。接下来,我们循环读取视频帧并将它们解码到 AVFrame 中。最后,我们将解码后的帧编码为 AVPacket 并写入 AVI 文件中。
请注意,这只是一个简单的示例程序,可能需要进行修改以适应不同的使用情况。
阅读全文