头文件:
#define __STDC_CONSTANT_MACROS
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
}
AVInputFormat类型表示一种输入文件/输入设备的数据格式
AVFormatContext类型表示音视频的格式内容
AVDictionary类型表示相关的配置项,如摄像头设备有图像大小的配置
AVPacket类型用于装载一帧数据
1. av_register_all(); //注册能用的编解码器及文件格式
2. avdevice_register_all(); //注册能操作的输入输出设备
3. 准备参数
AVInputFormat *ifmt = av_find_input_format("x11grab"); ///指定要获取x11桌面系统的设备
AVFormatContext *fmtContxt = avformat_alloc_context();
AVDictionary *options = NULL;
av_dict_set(&options, "video_size", "1024x768", 0); //指定分辨率
av_dict_set(&options, "draw_mouse", "1", 0); //获取的图像中有鼠标
//桌面可配置的选项,可参考ffmpeg源码/libavdevice/x11grab.c
4. 使用指定的参数, 打开指定的设备
if (avformat_open_input(&fmtContxt, ":0", ifmt, &options) < 0)
{
perror("avformat open");
return 1;
}
5. 打开设备后, 可检查摄像头的图像格式及分辨率.
AVCodecID id = fmtContxt->streams[0]->codec->codec_id; //获取数据的格式ID
qDebug() << id << " " << avcodec_get_name(id);
// 显示是:rawvideo, 实际上是 ARGB8888(可通过输出的数据大小与分辨率反推算)
int w = fmtContxt->streams[0]->codec->width;
int h = fmtContxt->streams[0]->codec->height;
6. 准备一帧数据的空间,及读取数据:
AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket));
av_read_frame(fmtContxt, packet); //读取一帧数据
// packet->data指针指向图像数据缓冲区的首地址
// packet->size是图像数据的真实大小
7. 保存为pnm图像
FILE *fl = fopen("/my.pnm", "w");
fprintf(fl, "P6\n%d %d\n255\n", w, h); // 加入pnm文件头
unsigned char *p = (unsigned char *)packet->data;
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{ // ARGB8888 --> 存为RGB888
fputc(p[(i*w+j)*4+2], fl);
fputc(p[(i*w+j)*4+1], fl);
fputc(p[(i*w+j)*4+0], fl);
}
}
fclose(fl);
02 ffmpeg获取桌面图像的编程
最新推荐文章于 2024-01-04 23:16:57 发布