如果你想在 FFmpeg 4.2.1 中使用 C++ 解码 H.264 摄像头数据,可以参考以下的示例代码。这个示例展示了如何打开摄像头流,读取视频帧并解码。
确保你已安装 FFmpeg,并且在编译时正确链接相关库 (libavformat
, libavcodec
, libavutil
, libswscale
)。
示例代码
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}
#include <iostream>
int main() {
// 注册所有组件
av_register_all();
// 打开摄像头设备(根据你的系统可能需要更改)
const char* deviceName = "/dev/video0"; // Linux 的设备名
AVFormatContext* pFormatCtx = nullptr;
if (avformat_open_input(&pFormatCtx, deviceName, nullptr, nullptr) != 0) {
std::cerr << "Couldn't open input stream." << std::endl;
return -1;
}
// 查找流信息
if (avformat_find_stream_info(pFormatCtx, nullptr) < 0) {
std::cerr << "Couldn't find stream info." << std::endl;
avformat_close_input(&pFormatCtx);
return -1;
}
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;
break;
}
}
if (videoStreamIndex == -1) {
std::cerr << "Couldn't find a video stream." << std::endl;
avformat_close_input(&pFormatCtx);
return -1;
}
AVCodecParameters* pCodecParameters = pFormatCtx->streams[videoStreamIndex]->codecpar;
// 查找解码器
AVCodec* pCodec = avcodec_find_decoder(pCodecParameters->codec_id);
if (!pCodec) {
std::cerr << "Unsupported codec!" << std::endl;
avformat_close_input(&pFormatCtx);
return -1;
}
// 创建解码上下文
AVCodecContext* pCodecCtx = avcodec_alloc_context3(pCodec);
if (!pCodecCtx) {
std::cerr << "Could not allocate codec context." << std::endl;
avformat_close_input(&pFormatCtx);
return -1;
}
// 初始化解码上下文参数
if (avcodec_parameters_to_context(pCodecCtx, pCodecParameters) < 0) {
std::cerr << "Failed to copy codec parameters to decoder context." << std::endl;
avcodec_free_context(&pCodecCtx);
avformat_close_input(&pFormatCtx);
return -1;
}
if (avcodec_open2(pCodecCtx, pCodec, nullptr) < 0){
std::cerr<<"Could not open codec!"<<std::endl;
av_codec_free_context (&p_codec_ctx);
av_format_close_input (&fmt_ctx);
return-1;
}
AVPacket packet;
AVFrame *frame= av_frame_alloc();
while(av_read_frame(pFormatCtx,&packet)>=0){
if(packet.stream_index==videoStreamIndex){
int response= av_codec_send_packet(pCodecCtx,&packet);
if(response<0){
std :: cerr<<"Error while sending a packet"<<std :: endl;
break ;
}
while(response==0){
response= av_codec_receive_frame(pCodecCtx, frame);
if(response==AVERROR(EAGAIN)||response==AVERROR_EOF){
break ;
} else if(response<0){
std :: cerr<<"Error while receiving a frame"<<std :: endl;
break ;
}
// 在这里处理每一帧,例如保存、显示等
std :: cout<<"Frame received!"<<std :: endl;
}
}
av_packet_unref(&packet);
}
// 清理资源
av_frame_free(&frame);
av_packet_unref(&packet);
avcodec_free_context(&pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}
编译指令
将上述代码保存为 camera_capture.cpp
文件,然后使用以下命令进行编译:
g++ camera_capture.cpp -o camera_capture -lavformat -lavcodec -lavutil -lswscale
注意事项
- 设备路径:确保修改设备名称
/dev/video0
为适合你系统的值。 - 权限问题:运行此程序时,确保具有对摄像头设备的访问权限。
- 错误处理:实际应用中建议增加更多错误检查与处理逻辑以避免崩溃。
- FFmpeg版本兼容性:该代码应兼容于 FFmpeg 4.2.1,但某些 API 调用和结构可能会随着版本变化而有所不同。请参考官方文档了解具体细节。
内容由零声教学AI助手提供,问题来源于学员提问