惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
K
Kaspersky official blog
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
Recorded Future
Recorded Future
Engineering at Meta
Engineering at Meta
U
Unit 42
D
Docker
I
InfoQ
D
DataBreaches.Net
Google DeepMind News
Google DeepMind News
N
Netflix TechBlog - Medium
C
Check Point Blog
The Cloudflare Blog
美团技术团队
V
Vulnerabilities – Threatpost
博客园_首页
T
Threat Research - Cisco Blogs
Google DeepMind News
Google DeepMind News
Attack and Defense Labs
Attack and Defense Labs
A
Arctic Wolf
IT之家
IT之家
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
Troy Hunt's Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
人人都是产品经理
人人都是产品经理
C
Cyber Attacks, Cyber Crime and Cyber Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Security Archives - TechRepublic
Security Archives - TechRepublic
S
Schneier on Security
Apple Machine Learning Research
Apple Machine Learning Research
MyScale Blog
MyScale Blog
P
Privacy International News Feed
云风的 BLOG
云风的 BLOG
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
The Blog of Author Tim Ferriss
GbyAI
GbyAI
The Last Watchdog
The Last Watchdog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
aimingoo的专栏
aimingoo的专栏
P
Proofpoint News Feed
The Register - Security
The Register - Security
博客园 - 三生石上(FineUI控件)
Forbes - Security
Forbes - Security
NISL@THU
NISL@THU
Y
Y Combinator Blog
T
Threatpost
Microsoft Azure Blog
Microsoft Azure Blog
L
Lohrmann on Cybersecurity

FFmpeg

[FFmpeg 的实时性太糟糕了] 后续 - V2EX FFmpeg 的实时性太糟糕了 - V2EX 早就听说过 ffmpeg,但是一直不知道有多牛 - V2EX 使用 FFmpeg 和 GPU 实现最简“图片+无损音频=视频”的方法 - V2EX FFmpegKit has been officially retired. There will be no further ffmpeg-kit releases. - V2EX 有没有精通 ffmpeg 的大佬帮我看下这个视频是怎么制作的 - V2EX 使用 FFmpeg 试图做个人用的转码点播服务端, 但 mpegts 多个切片间音频偶尔不连续? - V2EX 求助大佬们, FFmpeg 指令拉实时流转推的正确姿势到底是什么? - V2EX 在几乎不损失画质的前提下,怎么用 ffmpeg 把 h.264 格式的视频转换成 h.265 格式的? - V2EX 我又来询问 ffmpeg 问题了!这次是硬件加速! - V2EX 大佬们, nodejs 和 Python 做类似 jellyfin 实时转码是不是只能用 ffmpeg 实现了 - V2EX 有大佬开发过 ffmpeg 吗?用 c++调用 ffmpeg API 解码视频流 CPU 占用率高,求解决办法 - V2EX ffmpeg 视频录制切分问题请教 - V2EX 通过 ffmpeg 压缩视频很慢 时间敏感的需求该怎么设置参数呢? - V2EX ffmpeg 处理后视频时长问题 - V2EX 请教一个关于 ffmpeg 的问题 - V2EX 如何下载官方的 ffmpeg 二进制发布 - V2EX 视频模板替换图片,有偿 - V2EX ffmpeg 过滤器 xfade 自定义动画的研究 - V2EX 关于我在 fcp 导入视频时出现的无法解决的问题,请求各位 ffmpeg 大佬的帮忙 - V2EX go + ffmpeg pipe 怎么确定当前转码操作已经结束,可以停了 - V2EX 给人声视频加入背景声音,如何做到自动调整背景的音量 - V2EX 使用 ffmpeg 用 aes 加密 m3u8 文件的疑惑 - V2EX 把歌曲压缩至 7 kbps, FFmpeg 之父发布音频压缩工具 TSAC - V2EX 求助使用 ffmpeg 压缩.mov 视频输出后丢失元数据问题如何解决 - V2EX homebrew 安装的 fmpeg 转码速度比较慢?直接编译可以提高速度吗? - V2EX 使用 nodejs 调用和在 macos 终端里直接调用 ffmpeg 转 m3u8,两者花费时间相差巨大 - V2EX FFmpeg 如何录屏时排除录制指定的某个窗口 - V2EX ffmpeg 最近大版本发布为啥这么快 - V2EX ffmpeg 如何加快解码速度?算力不变的情况下,不在乎解码质量 - V2EX FFmpeg 怎么支持 segment_size 选项? - V2EX 为什么 ffmpeg 的体积会这么大?多复杂的算法编译后也不会有几十 MB 吧? - V2EX FFmpeg 使用 debug_ts 打印全过程的 pts - V2EX ffmpeg 如何更快速的查询视频的"缺帧" - V2EX 如何将 AVS3 8KHDR 视频转码为 HEVC 8KHDR 视频? - V2EX 请教大佬们,在线网站抓到 m3u8 能播放,但是用 ffmpeg 下载的时候 “403 forbidden” 或者 “Output file #0 does not contain any stream” 应该怎么解决 - V2EX FFmpeg 使用 qsv 加速失败 - V2EX 使用 ffmepg 把图片和长音频转换为视频的时候,视频和音频的时间对不上,声音也减少了一半 - V2EX FFmpeg 解码器如何识别码流格式变了? - V2EX ffmpeg 提取音频中有声部分并单独生成文件 - V2EX ffplay 如何并行下载 m3u8 - V2EX 如何用 ffmpeg 找到损坏的视频 50 块钱悬赏答案 - V2EX ffmpeg 如何压缩 h.265 的视频不丢帧? - V2EX 有没有 win 下已编译好的 FLV 标准支持 H265 的 ffmpeg? - V2EX 为什么有些视频体积这么大但是画质这么差? - V2EX lalserver 流媒体(直播音视频网络传输)服务器 v0.30.1 2022.6.15 - V2EX [求助] mp4 录制,怎么才能不缓冲在内存中 - V2EX ffmpeg 怎么处理 h265 切 h264 的直播流? - V2EX 为什么 ffmpeg 加不上 rotate 旋转参数 - V2EX
intel qsv ffmpeg 编码问题 - V2EX
yoyoluck · 2025-12-17 · via FFmpeg

有朋友搞过 ffmpeg qsv 硬件编码吗? 最近有一个任务,需要将音视频经过 ffmpeg 库编码成 h264/h265 之后送到海康的硬盘录像机 目前遇到问题是 使用 libx264 软编码的数据通过 rtsp 送到海康录像机能正常显示 通过 intel 的 qsv 硬件编码的 h264/h265 等送到海康录像机只能显示出关键帧,其他 P 帧无法显示(没有 B 帧),通过英伟达显卡硬件编码的 h264/h265 送到海康能正常显示。 以上所有编码后的数据都是通过 rtsp 服务推送的,所有的在 vlc 等播放器上都能正常显示。 目前大部分都是核显,所以想解决 qsv 硬件编码问题 下面是部分初始化代码,有偿协助

    // 查找编码器(支持硬件编码)
    video_codec_ = FindBestEncoder(config_.use_hardware_encoding);
    // 检查是否使用了硬件编码器
    video_using_hardware_ = (strcmp(video_codec_->name, "libx264") != 0 && strcmp(video_codec_->name, "libx265") != 0);
    // 创建编码器上下文
    video_codec_ctx_ = avcodec_alloc_context3(video_codec_);
    // 设置编码参数
    video_codec_ctx_->width = config_.width;
    video_codec_ctx_->height = config_.height;
    video_codec_ctx_->time_base.num = 1;
    video_codec_ctx_->time_base.den = config_.fps;
    video_codec_ctx_->framerate.num = config_.fps;
    video_codec_ctx_->framerate.den = 1;
    video_codec_ctx_->bit_rate = config_.bitrate;
    video_codec_ctx_->gop_size = config_.fps * 3; // 每 3 秒一个关键帧
    video_codec_ctx_->has_b_frames = 0;
    video_codec_ctx_->max_b_frames = 0;
    video_codec_ctx_->refs = 1;

    // 根据编码器类型设置像素格式
    if (video_using_hardware_)
    {
        // 硬件编码器使用 NV12 格式( QSV 、NVENC 、AMF 都支持)
        video_codec_ctx_->pix_fmt = AV_PIX_FMT_NV12;
    }
    else
    {
        // 软件编码器使用 YUV420P
        video_codec_ctx_->pix_fmt = AV_PIX_FMT_YUV420P;
    }

    video_codec_ctx_->flags = AV_CODEC_FLAG_LOW_DELAY | AV_CODEC_FLAG_GLOBAL_HEADER;
    video_codec_ctx_->rc_buffer_size = config_.bitrate; // 缓冲区大小等于码率
    video_codec_ctx_->rc_max_rate = config_.bitrate; // 最大码率
    video_codec_ctx_->rc_min_rate = config_.bitrate/5; // 最小码率

    if (!video_using_hardware_)
    {
        // 软件编码器特定参数
        video_codec_ctx_->thread_count = 4;
        if (strcmp(video_codec_->name, "libx264") == 0)
        {
            // libx264 特定选项
            if (!config_.preset.isEmpty())
            {
                av_opt_set(video_codec_ctx_->priv_data, "preset", config_.preset.toStdString().c_str(), 0);
            }

            if (!config_.tune.isEmpty())
            {
                av_opt_set(video_codec_ctx_->priv_data, "tune", config_.tune.toStdString().c_str(), 0);
            }

            if (!config_.profile.isEmpty())
            {
                av_opt_set(video_codec_ctx_->priv_data, "profile", config_.profile.toStdString().c_str(), 0);
            }

            av_opt_set(video_codec_ctx_->priv_data, "x264opts", "bframes=0:rc-lookahead=0:scenecut=0", 0);
        }
        else if (strcmp(video_codec_->name, "libx265") == 0)
        {
            // libx265 特定选项
            if (!config_.preset.isEmpty())
            {
                av_opt_set(video_codec_ctx_->priv_data, "preset", config_.preset.toStdString().c_str(), 0);
            }

            if (!config_.tune.isEmpty())
            {
                av_opt_set(video_codec_ctx_->priv_data, "tune", config_.tune.toStdString().c_str(), 0);
            }

            // H.265 的 profile: main, main10, main-intra 等
            if (!config_.profile.isEmpty())
            {
                QString profile_to_use = config_.profile;

                // 检查 profile 是否与 H.265 兼容
                // H.264 的 profile (baseline, high) 不能用于 H.265
                if (profile_to_use == "baseline" || profile_to_use == "high")
                {
                    profile_to_use = "main";  // H.265 的默认 profile
                    LOG(WARNING) << "H.265 不支持 profile \"" << config_.profile.toStdString()
                                 << "\", 已自动调整为 \"main\"";
                }

                av_opt_set(video_codec_ctx_->priv_data, "profile", profile_to_use.toStdString().c_str(), 0);
            }

            // H.265 低延迟参数
            av_opt_set(video_codec_ctx_->priv_data, "x265-params",
                       "bframes=0:rc-lookahead=0:scenecut=0:aq-mode=0", 0);
        }
    }
    else
    {
        // 硬件编码器特定参数
        const char* codec_name = video_codec_->name;

        if (strcmp(codec_name, "h264_qsv") == 0 || strcmp(codec_name, "hevc_qsv") == 0)
        {
            // Intel QSV 编码器参数
            // QSV 的 preset 值: veryfast, faster, fast, medium, slow, slower, veryslow
            av_opt_set(video_codec_ctx_->priv_data, "preset", "veryfast", 0);
            av_opt_set(video_codec_ctx_->priv_data, "async_depth", "1", 0); // 低延迟
            av_opt_set(video_codec_ctx_->priv_data, "look_ahead", "0", 0);  // 关闭前瞻

            // H.264 专用:添加严格的兼容性参数以解决海康录像机播放问题
            if (strcmp(codec_name, "h264_qsv") == 0)
            {
                // 强制使用 baseline profile (如果配置中指定了)
                if (!config_.profile.isEmpty())
                {
                    av_opt_set(video_codec_ctx_->priv_data, "profile", config_.profile.toStdString().c_str(), 0);
                }

                // 强制 CAVLC 熵编码( baseline profile 必需,H.264 标准)
                // QSV 默认可能使用 CABAC ,这会导致不兼容 baseline profile
                av_opt_set(video_codec_ctx_->priv_data, "cavlc", "1", 0);

                // 设置 H.264 level ( 40 = level 4.0 ,支持 1080p@30fps )
                // 与 NVENC 保持一致,提高兼容性
                av_opt_set(video_codec_ctx_->priv_data, "level", "40", 0);

                // 禁用 B 帧策略(确保真正不使用 B 帧)
                av_opt_set(video_codec_ctx_->priv_data, "b_strategy", "0", 0);

                // 禁用自适应 I 帧和 B 帧(提高 GOP 结构的一致性)
                av_opt_set(video_codec_ctx_->priv_data, "adaptive_i", "0", 0);
                av_opt_set(video_codec_ctx_->priv_data, "adaptive_b", "0", 0);

                // 严格的 GOP 结构(不允许动态调整关键帧位置)
                av_opt_set(video_codec_ctx_->priv_data, "strict_gop", "1", 0);

                // 低延迟模式(类似 NVENC 的 zerolatency )
                av_opt_set(video_codec_ctx_->priv_data, "low_delay_brc", "1", 0);

                LOG(INFO) << "Intel QSV H.264 编码器:已启用海康录像机兼容模式( baseline+CAVLC+level4.0 )";
            }
        }
        else if (strcmp(codec_name, "h264_nvenc") == 0 || strcmp(codec_name, "hevc_nvenc") == 0)
        {
            // NVIDIA NVENC 编码器参数
            // NVENC 的 preset: default, slow, medium, fast, hp, hq, bd, ll, llhq, llhp, lossless, losslesshp
            av_opt_set(video_codec_ctx_->priv_data, "preset", "llhp", 0);  // 低延迟高性能
            av_opt_set(video_codec_ctx_->priv_data, "zerolatency", "1", 0);
            av_opt_set(video_codec_ctx_->priv_data, "delay", "0", 0);
        }
        else if (strcmp(codec_name, "h264_amf") == 0 || strcmp(codec_name, "hevc_amf") == 0)
        {
            // AMD AMF 编码器参数
            av_opt_set(video_codec_ctx_->priv_data, "usage", "lowlatency", 0);
            av_opt_set(video_codec_ctx_->priv_data, "quality", "speed", 0);
        }
        else if (strcmp(codec_name, "h264_mf") == 0)
        {
            // Windows Media Foundation 编码器参数
            av_opt_set(video_codec_ctx_->priv_data, "rate_control", "cbr", 0);
        }

        // NVENC 的 profile 设置( QSV 已在上面单独设置)
        if (!config_.profile.isEmpty() && strcmp(codec_name, "h264_nvenc") == 0)
        {
            // NVENC 支持标准 H.264 profiles: baseline, main, high
            av_opt_set(video_codec_ctx_->priv_data, "profile", config_.profile.toStdString().c_str(), 0);
        }
    }

    // 初始化硬件加速上下文(如果使用硬件编码)
    if (!InitializeHardwareContext())
    {
        LOG(ERROR) << "硬件加速上下文初始化失败";
        return false;
    }

    // 打开编码器
    int ret = avcodec_open2(video_codec_ctx_, video_codec_, nullptr);
    if (ret < 0)
    {
        char errbuf[AV_ERROR_MAX_STRING_SIZE];
        av_strerror(ret, errbuf, sizeof(errbuf));
        LOG(ERROR) << "无法打开编码器: " << errbuf;
        return false;
    }