FFmpeg:‘UINT64_C‘ was not declared in ths scope

FFmpeg 编译错误:UINT64_C 未声明解决方案
在使用FFmpeg时遇到'UINT64_C'未声明的错误,同时提示缺少-D__STDC_CONSTANT_MACROS宏定义。解决方法是在libavutilcommon.h文件开头添加#define __STDC_CONSTANT_MACROS,以确保编译通过。

这个错误的出现还会伴随着下面这个错误:

error: #error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS
 #error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS解决的办法是在libavuti\common.h开头处加入

#ifndef UINT64_C
#define UINT64_C(c) (c ## ULL)
#endif

<think> 我们正在解决 `avpicture_fill was not declared in this scope` 错误。这个错误同样是因为使用了FFmpeg废弃的API。在较新的FFmpeg版本中(大约从3.0开始),`avpicture_fill`已经被标记为废弃,并在4.0以上版本中移除。替代函数是`av_image_fill_arrays`。 ### 解决步骤: #### 1. **理解API变更** `avpicture_fill` 用于将图像数据填充到AVPicture结构(旧结构)中,而新版本中,我们直接使用AVFrame,并且使用`av_image_fill_arrays`来填充图像数据。 #### 2. **代码替换** 原代码可能类似于: ```c AVPicture pict; avpicture_fill(&pict, buffer, AV_PIX_FMT_RGB24, width, height); ``` 应替换为: ```c // 确保buffer足够大,可以使用av_image_get_buffer_size来获取所需大小 int num_bytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, width, height, 1); uint8_t *buffer = (uint8_t *)av_malloc(num_bytes * sizeof(uint8_t)); AVFrame *frame = av_frame_alloc(); frame->format = AV_PIX_FMT_RGB24; frame->width = width; frame->height = height; // 将buffer与frame关联 av_image_fill_arrays(frame->data, frame->linesize, buffer, AV_PIX_FMT_RGB24, width, height, 1); ``` #### 3. **参数解释** `av_image_fill_arrays` 函数原型: ```c int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], const uint8_t *src, enum AVPixelFormat pix_fmt, int width, int height, int align); ``` - `dst_data`: 输出的数据指针数组(对应AVFrame的data成员) - `dst_linesize`: 输出的行大小数组(对应AVFrame的linesize成员) - `src`: 源缓冲区(即我们分配的内存块) - `pix_fmt`: 像素格式 - `width`, `height`: 图像的宽高 - `align`: 内存对齐(通常设为1,表示不进行对齐,或者使用默认对齐) #### 4. **内存管理** - 使用`av_malloc`分配内存,使用`av_free`释放。 - 在释放时,先释放AVFrame(`av_frame_free`),再释放buffer(`av_free`)。 #### 5. **完整示例** ```c #include <libavutil/imgutils.h> #include <libavformat/avformat.h> // 分配图像内存并设置AVFrame AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height) { AVFrame *frame = av_frame_alloc(); if (!frame) return NULL; frame->format = pix_fmt; frame->width = width; frame->height = height; // 分配图像内存 int ret = av_frame_get_buffer(frame, 0); // 0表示自动对齐 if (ret < 0) { av_frame_free(&frame); return NULL; } return frame; } // 或者手动分配内存的方式: AVFrame *alloc_picture_2(enum AVPixelFormat pix_fmt, int width, int height) { AVFrame *frame = av_frame_alloc(); if (!frame) return NULL; // 计算所需缓冲区大小 int num_bytes = av_image_get_buffer_size(pix_fmt, width, height, 1); uint8_t *buffer = (uint8_t *)av_malloc(num_bytes); if (!buffer) { av_frame_free(&frame); return NULL; } frame->format = pix_fmt; frame->width = width; frame->height = height; // 填充数组 av_image_fill_arrays(frame->data, frame->linesize, buffer, pix_fmt, width, height, 1); return frame; } ``` #### 6. **注意事项** - 新方法中,我们通常使用`av_frame_get_buffer`来为AVFrame分配内存,这样更简单且安全。 - 如果使用手动分配(`av_malloc`)并调用`av_image_fill_arrays`,要确保在释放时先释放AVFrame,然后释放buffer。但是注意,在第二种方法中,buffer是独立分配的,所以需要单独释放。而使用`av_frame_get_buffer`分配的内存会在释放frame时自动释放。 - 推荐使用`av_frame_get_buffer`,因为它会自动处理内存分配和填充。 #### 7. **错误处理** 检查函数的返回值: ```c int ret = av_image_fill_arrays(...); if (ret < 0) { // 错误处理 } ``` ### 总结 | 旧API | 新API | 说明 | |------------------------|--------------------------------|----------------------------------------------------------------------| | `avpicture_fill` | `av_image_fill_arrays` | 填充图像数据到AVFrame中 | | `avpicture_get_size` | `av_image_get_buffer_size` | 获取给定像素格式和尺寸的图像所需缓冲区大小 | | `avpicture_free` | 不再需要,使用`av_frame_free` | 释放AVFrame时会自动释放其内部缓冲区(如果是通过`av_frame_get_buffer`分配的)| ### 相关问题 1. 如何检测FFmpeg版本以决定使用旧API还是新API? 2. 使用`av_image_fill_arrays`时出现内存对齐问题如何处理? 3. 如何将FFmpeg解码后的帧转换为RGB格式并显示? 4. 使用新API时,如何正确释放内存避免泄漏? 5. 在跨平台开发中,如何处理不同FFmpeg版本带来的API差异? [^1]: `avpicture_fill`已被废弃,推荐使用`av_image_fill_arrays`替代 [^2]: 使用`av_image_get_buffer_size`获取图像缓冲区大小 [^3]: 内存分配和释放要匹配,避免内存泄漏 </think> ### 解决 `avpicture_fill was not declared in this scope` 错误的方法 这个错误表明你使用了 FFmpeg 废弃的旧 API。自 FFmpeg 3.x 版本起,`avpicture_fill()` 已被新 API 取代。以下是系统解决方案: #### 1. **理解 API 变更原因** `avpicture_fill()` 属于旧版图像处理 API,其替代方案是 `av_image_fill_arrays()`。主要变更点: - 废弃时间:FFmpeg 3.0+ 开始标记为 deprecated,4.0+ 完全移除[^1] - 核心差异: ```c // 旧 API (已废弃) avpicture_fill((AVPicture*)frame, buffer, pix_fmt, width, height); // 新 API ✅ av_image_fill_arrays(frame->data, frame->linesize, buffer, pix_fmt, width, height, alignment); ``` - 参数变化:新增 `alignment` 参数(通常设为 1 或 32) #### 2. **完整代码迁移方案** ```c #include <libavutil/imgutils.h> // 必须包含此头文件[^3] // 步骤1: 获取缓冲区大小 int buf_size = av_image_get_buffer_size(AV_PIX_FMT_RGB24, width, height, 1); uint8_t *buffer = (uint8_t*)av_malloc(buf_size); // 步骤2: 分配AVFrame AVFrame *frame = av_frame_alloc(); frame->width = width; frame->height = height; frame->format = AV_PIX_FMT_RGB24; // 步骤3: 替换avpicture_fill av_image_fill_arrays( frame->data, // 输出:数据指针数组 frame->linesize, // 输出:行宽数组 buffer, // 输入缓冲区 frame->format, // 像素格式 frame->width, // 图像宽度 frame->height, // 图像高度 1 // 内存对齐(字节) ); ``` #### 3. **关键注意事项** 1. **内存管理**: ```c // 释放资源时 av_freep(&buffer); // 释放缓冲区 av_frame_free(&frame); // 释放帧 ``` 2. **图像尺寸计算**: 使用 `av_image_get_buffer_size()` 替代 `avpicture_get_size()` ```c // 错误:int size = avpicture_get_size(...); // 正确: int size = av_image_get_buffer_size(pix_fmt, width, height, 1); ``` 3. **对齐参数**: - `alignment=1` 表示无特殊对齐 - 视频处理通常用 `32`(SIMD 指令要求) #### 4. **版本兼容方案** 支持新旧 FFmpeg 版本的跨平台代码: ```c #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 92, 100) // 旧版 (< 52.92.100) avpicture_fill((AVPicture*)frame, buffer, pix_fmt, width, height); #else // 新版 (FFmpeg 4.0+) av_image_fill_arrays(frame->data, frame->linesize, buffer, pix_fmt, width, height, 1); #endif ``` 检测版本号: ```c #include <libavutil/version.h> printf("FFmpeg libavutil version: %d\n", avutil_version()); ``` #### 5. **典型错误修复案例 原始错误代码: ```c AVFrame *frame = av_frame_alloc(); uint8_t *buffer = (uint8_t*)av_malloc(avpicture_get_size(...)); avpicture_fill((AVPicture*)frame, buffer, ...); // 触发错误 ``` 修正后: ```c int buf_size = av_image_get_buffer_size(...); uint8_t *buffer = (uint8_t*)av_malloc(buf_size); av_image_fill_arrays(frame->data, frame->linesize, buffer, ...); // 正确[^2] ``` ### API 替代对照表 | 旧 API (已废弃) | 新 API (FFmpeg 4.0+) | 作用域 | |--------------------------|-----------------------------------|----------------------| | `avpicture_fill()` | `av_image_fill_arrays()` | 图像缓冲区填充 | | `avpicture_get_size()` | `av_image_get_buffer_size()` | 计算图像缓冲区大小 | | `avpicture_free()` | `av_freep()` + `av_frame_free()` | 资源释放 | | `avcodec_decode_video2()`| `avcodec_send/receive_packet()` | 视频解码 (相关替换)[^4] | > **关键提示**:当同时使用视频解码和图像处理时,需同步更新 `avcodec_decode_video2()` 到新解码 API[^4],否则会出现兼容性问题。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吉特哈布

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值