You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于FFmpeg在ARMv7上实现H264无解码降帧率至10fps的可行性问询

问题背景

现有一款USB摄像头输出1920x1080分辨率、30fps的H264视频流,GOP大小为30或60(每秒1或2个I帧,其余为P帧),码率约6Mbps,需将码率降至2Mbps以下。运行设备为性能较弱的ARMv7平台(NanoPi Neo Core,搭载Mali GPU),转码方案资源消耗极高且未找到GPU转码方法。

已尝试的FFmpeg命令

# 查看H264编解码器支持情况
./ffmpeg -hide_banner -codecs | grep h264
 DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_v4l2m2m ) (encoders: libx264 libx264rgb h264_v4l2m2m )

# 尝试使用v4l2硬件解码测试
sudo ./ffmpeg -hide_banner -f v4l2 -input_format h264 -c:v h264_v4l2m2m -video_size 1920x1080 -threads 4 -i /dev/video0 -f null -
[h264 @ 0x149bb30] Increasing reorder buffer to 1
Input #0, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 269427.784703, bitrate: N/A
  Stream #0:0: Video: h264 (Baseline), yuvj420p(pc, bt709, progressive), 1920x1080, 30 fps, 30 tbr, 1000k tbn
[h264_v4l2m2m @ 0x160fd40] Could not find a valid device
[h264_v4l2m2m @ 0x160fd40] can't configure decoder
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (h264_v4l2m2m) -> wrapped_avframe (native))
Error while opening decoder for input stream #0:0 : Invalid argument

核心提问

基于FFmpeg框架,是否可在不解码、无画质损失的前提下将帧率降至10fps?

已做准备

  1. 已实现通过NALU识别关键帧相关结构的方法:
#include "libavcodec/h264.h"
...
(AVPacket.data[4] & 0x1F) == H264_NAL_SPS
  1. 了解到分层P帧编码中,并非所有P帧都依赖前一帧,或许可以通过跳过中间P帧实现降帧。

解答

完全可以通过无解码的帧过滤实现目标,核心思路是利用H264的GOP结构和帧依赖关系,只保留关键帧和合规的P帧,直接输出原始编码帧,全程不做解码编码操作,几乎不占用CPU资源。

具体实现方案

  1. 帧筛选逻辑

    • 若GOP=30(每秒1个I帧):每30帧里保留第1帧(I帧)和第11、21帧(间隔10帧的P帧),刚好对应10fps;
    • 若GOP=60(每秒2个I帧):每60帧里保留第1、31帧(I帧)和第11、21、41、51帧,同样得到10fps;
    • 注意:必须确保保留的P帧能正确依赖前面已保留的参考帧,避免画面断裂。如果是分层P结构,优先选择依赖I帧或最近保留帧的P帧。
  2. 基于FFmpeg的代码实现要点

    • 使用av_read_frame()读取原始H264数据包;
    • 通过NALU类型判断I帧(H264_NAL_IDR_SLICE)、SPS/PPS(必须保留,否则解码端无法初始化);
    • 维护帧计数器,按10fps的间隔筛选P帧;
    • 直接将筛选后的AVPacket写入输出文件/流,无需调用解码或编码接口。
  3. 替代方案:FFmpeg命令行快速验证
    若不想写代码,可尝试使用比特流滤镜结合帧选择逻辑,避免解码操作:

    ffmpeg -f v4l2 -input_format h264 -i /dev/video0 -c:v copy -bsf:v h264_mp4toannexb -vf "select='eq(pict_type,I)+eq(n,10*floor(n/10))',setpts=N/(10*TB)" -f h264 output.h264
    

    注:若发现命令触发了解码操作,建议改用代码实现原始数据包过滤。

关键注意事项

  • 必须保留所有SPS、PPS和IDR帧,否则接收端无法正常解码;
  • 筛选P帧时要确认其参考帧已被保留,避免解码错误;
  • 需修正输出流的帧率元数据(代码中可通过AVStream->r_frame_rate设置为10/1),否则播放端会出现速度异常。

内容的提问来源于stack exchange,提问作者Александр А

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:23:17