使用FFmpeg 打开摄像头 C++示例
时间: 2024-09-11 13:07:40 浏览: 96
在C++中,可以使用FFmpeg库来处理视频流,包括打开摄像头。FFmpeg是一个跨平台的多媒体框架,它支持多种音频和视频编码。以下是一个简单的FFmpeg 示例,展示如何打开本地摄像头并捕获实时视频:
```cpp
#include <iostream>
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/frame.h"
#include "libswscale/swscale.h"
// 创建一个用于存储视频帧的回调函数
static int write_frame_callback(void* user_data, AVFrame* frame) {
AVCodecContext* codec = (AVCodecContext*)user_data;
AVFrame* coded_frame = av_frame_alloc();
avcodec_send_frame(codec, coded_frame);
while (avcodec_receive_frame(codec, coded_frame) == AVERROR(EAGAIN))
continue;
// 这里你可以进一步处理或显示编码后的视频帧
// 例如,使用Swscaler进行缩放或者渲染到屏幕
SwsContext* sws_ctx = sws_getContext(
codec->width, codec->height,
codec->pix_fmt, codec->width, codec->height,
PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
uint8_t* out_buffer;
int out_buffer_size;
avpicture_fill((AVPicture*)frame, frame->data[0], frame->linesize[0], codec->width, codec->height);
if (sws_scale(sws_ctx, frame->data, frame->linesize, 0, frame->height, coded_frame->data, coded_frame->linesize)) {
std::cerr << "Error scaling the frame" << std::endl;
return -1;
}
// 将编码后的帧写入文件或其他目的地
// 注意这里只是一个示例,实际应用中你需要连接到显示器或者其他设备
// 假设我们有一个AVWriter对象writer
writer.write(coded_frame->data[0], coded_frame->linesize[0] * frame->height);
av_free(frame);
av_frame_unref(coded_frame);
return 0;
}
int main() {
// 初始化FFmpeg库
av_register_all();
// 获取默认摄像头设备索引
int camera_index = 0; // 根据实际情况修改
// 打开摄像头
AVFormatContext* format_ctx = avformat_open_input(&input_context, "video", NULL, NULL);
if (!format_ctx) {
std::cerr << "Failed to open input context" << std::endl;
return -1;
}
if (avformat_find_stream_info(format_ctx, NULL) < 0) {
std::cerr << "Failed to find stream information" << std::endl;
avformat_close_input(&format_ctx);
return -1;
}
// 选择视频流
AVStream* video_stream = avformat_find_stream_by_index(format_ctx, 0);
if (!video_stream) {
std::cerr << "Failed to find video stream" << std::endl;
avformat_close_input(&format_ctx);
return -1;
}
// 解码器上下文
AVCodecContext* codec_ctx = video_stream->codec;
AVCodec* codec = avcodec_find_decoder(codec_ctx->codec_id);
if (!codec) {
std::cerr << "Failed to find decoder for video stream" << std::endl;
avformat_close_input(&format_ctx);
return -1;
}
if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
std::cerr << "Failed to open codec" << std::endl;
avcodec_close(codec);
avformat_close_input(&format_ctx);
return -1;
}
// 创建一个解码缓冲区
AVPacket packet;
av_init_packet(&packet);
// 开始读取摄像头数据
while (av_read_frame(format_ctx, &packet) >= 0) {
if (packet.stream_index == video_stream->index && packet.data) {
int ret = write_frame_callback(codec_ctx, packet.data);
if (ret < 0)
break;
av_packet_unref(&packet);
} else {
av_packet_unref(&packet);
}
}
// 关闭资源
avformat_close_input(&format_ctx);
avcodec_close(codec_ctx);
sws_freeContext(sws_ctx);
return 0;
}
```
这个示例假设你已经包含了必要的FFmpeg头文件,并且有一个`writer`对象可以接收和处理编码后的帧。请注意,这只是一个基本框架,实际应用中可能需要添加错误处理和其他功能。
阅读全文