ffmpeg之ff_filter_graph_run_once功能

ff_filter_graph_run_once() 是 FFmpeg 滤镜系统内部用于驱动 单次滤镜链路调度 的核心函数。它负责查找当前最需要执行的滤镜,并激活它处理数据。

下面的表格整理了它的核心功能与工作原理和关键作用:

特性维度 功能描述 在项目中的关键意义
主要功能 驱动单步执行:每调用一次,就推动整个滤镜链路向前执行"一步"。 在"等待并排空 "场景中,必须反复循环调用此函数 ,才能将队列中的帧逐一处理并最终输出到编码器。
工作原理 1. 查找就绪滤镜 :遍历图中所有滤镜 (AVFilterContext),基于其ready字段等状态,找出当前优先级最高且准备就绪 的滤镜。 2. 激活处理 :调用 ff_filter_activate() 激活该滤镜。这会触发滤镜从输入链路的 FIFO 队列中取出帧进行处理,或通过 request_frame 向上游请求新帧。 保证了所有滤镜(包括异步滤镜 )都能按正确的调度顺序被触发,从而让已入队的帧能流转起来。
调度机制 基于优先级调度 。当一个滤镜通过 ff_filter_frame() 向下游发送帧时,会同时设置下游滤镜的 ready 优先级。run_once 就依据此优先级决定激活顺序。 理解此机制,能帮助分析在等待异步帧时,为何需要循环调用它来"驱动"整个链路,而不是仅仅等待。
返回值 - 0 :成功执行了一个滤镜。 - AVERROR(EAGAIN) :本次调用没有找到可以立即执行的滤镜(例如所有输入队列为空或滤镜在等待)。这是一个关键信号 当返回 EAGAIN 时,意味着当前队列中所有能立即处理的帧都已处理完 。需要结合async_frame_count判断:如果还有异步帧未完成,就应稍作等待。
与异步的关系 它是同步、主动的驱动者 。它本身不管理异步任务,但负责执行那些已由异步回调将帧放入队列后的滤镜。 需要在异步回调函数中,在调用 ff_filter_frame() 将处理完的帧送回滤镜链路后,主动调用 (或安排其他线程调用)run_once 或其外层驱动函数(如 push_frame),才能让帧继续流动。

思路:如何与异步插件结合

分辨率变化的时候,所有滤镜会直接uninit,此时异步处理帧会丢失,如何解决该问题,核心思路如下:

  1. 异步处理完成时 :在filter异步处理回调 async_process_complete_callback 中,在调用 ff_filter_frame() 之后,需要设法触发一次 ff_filter_graph_run_once() 。如果整个滤镜图运行在独立线程或 push_frame 这样的循环中,这可能意味着要设置一个状态标志或发送信号来通知主驱动循环。

  2. wait_and_drain_graph 函数中 :这里需要循环调用 ff_filter_graph_run_once() ,直到它返回 AVERROR(EAGAIN) 并且 async_frame_count 降为 0。

    复制代码
    while (1) {
        ret = ff_filter_graph_run_once(graph);
        if (ret == AVERROR(EAGAIN)) {
            if (atomic_load(&graph->async_frame_count) == 0) {
                break; // 所有帧都处理完毕
            }
            // 还有异步帧在途中,等待一小段时间或等待条件变量
            av_usleep(1000);
            continue;
        }
        if (ret < 0) {
            // 处理错误
            break;
        }
        // 成功处理了一帧,继续循环
    }

总结来说,ff_filter_graph_run_once() 是确保滤镜链路动起来的"发动机"。在异步插件场景中,必须确保在所有合适的时机(异步回调后、等待排空时)主动"踩油门"(调用它),才能让数据走完整个流程。

相关推荐
胖_大海_12 小时前
【FFmpeg+Surface 底层渲染,实现超低延迟100ms】
ffmpeg
冷冷的菜哥12 小时前
springboot调用ffmpeg实现对视频的截图,截取与水印
java·spring boot·ffmpeg·音视频·水印·截图·截取
进击的CJR1 天前
redis哨兵实现主从自动切换
mysql·ffmpeg·dba
huahualaly1 天前
重建oracle测试库步骤
数据库·oracle·ffmpeg
aqi001 天前
FFmpeg开发笔记(九十九)基于Kotlin的国产开源播放器DKVideoPlayer
android·ffmpeg·kotlin·音视频·直播·流媒体
lizongyao2 天前
FFMPEG命令行典型案例
ffmpeg
冷冷的菜哥2 天前
ASP.NET Core调用ffmpeg对视频进行截图,截取,增加水印
开发语言·后端·ffmpeg·asp.net·音视频·asp.net core
冷冷的菜哥2 天前
go(golang)调用ffmpeg对视频进行截图、截取、增加水印
后端·golang·ffmpeg·go·音视频·水印截取截图
小尧嵌入式2 天前
【基础学习七十】ffmpeg命令
c++·stm32·嵌入式硬件·ffmpeg
烧饼Fighting2 天前
统信UOS操作系统离线安装ffmpeg
开发语言·javascript·ffmpeg