使用快速同步 h264_qsv 编码器时 ffmpeg avcodec_encode_video2 挂起

2024-05-01

当我使用 mpeg4 或 h264 编码器时,我能够使用 ffmpeg 3.1.0 的 API 成功编码图像以生成有效的 AVI 文件。但是,当我使用快速同步编码器(h264_qsv)时,avcodec_encode_video2 有时会挂起。我发现当使用 1920x1080 的图像时,avcodec_encode_video2 很少会挂起。当使用256x256图像时,该函数很可能会挂起。

我创建了下面的测试代码来演示 avcodec_encode_video2 的挂起。该代码将创建一个 1000 帧、256x256 AVI、比特率为 400000。这些帧只是简单分配的,因此输出视频应该只是绿色帧。

使用 Windows 7 和 Windows 10,使用 32 位或 64 位测试应用程序观察到该问题。

如果有人知道如何避免 avcodec_encode_video2 挂起,我将非常感激!预先感谢您的任何帮助。

extern "C"
{
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include "avcodec.h"
#include "avformat.h"
#include "swscale.h"
#include "avutil.h"
#include "imgutils.h"
#include "opt.h"
#include <rational.h>
}

#include <iostream>


// Globals
AVCodec* m_pCodec = NULL;
AVStream *m_pStream = NULL;
AVOutputFormat* m_pFormat = NULL;
AVFormatContext* m_pFormatContext = NULL;
AVCodecContext* m_pCodecContext = NULL;
AVFrame* m_pFrame = NULL;
int m_frameIndex;

// Output format
AVPixelFormat m_pixType = AV_PIX_FMT_NV12;
// Use for mpeg4
//AVPixelFormat m_pixType = AV_PIX_FMT_YUV420P;

// Output frame rate
int m_frameRate = 30;
// Output image dimensions
int m_imageWidth = 256;
int m_imageHeight = 256;
// Number of frames to export
int m_frameCount = 1000;
// Output file name
const char* m_fileName = "c:/test/test.avi";
// Output file type
const char* m_fileType = "AVI";
// Codec name used to encode
const char* m_encoderName = "h264_qsv";
// use for mpeg4
//const char* m_encoderName = "mpeg4";
// Target bit rate
int m_targetBitRate = 400000;

void addVideoStream()
{
    m_pStream = avformat_new_stream( m_pFormatContext, m_pCodec );
    m_pStream->id = m_pFormatContext->nb_streams - 1;
    m_pStream->time_base = m_pCodecContext->time_base;
    m_pStream->codec->pix_fmt = m_pixType;
    m_pStream->codec->flags = m_pCodecContext->flags;
    m_pStream->codec->width = m_pCodecContext->width;
    m_pStream->codec->height = m_pCodecContext->height;
    m_pStream->codec->time_base = m_pCodecContext->time_base;
    m_pStream->codec->bit_rate = m_pCodecContext->bit_rate;
}

AVFrame* allocatePicture( enum AVPixelFormat pix_fmt, int width, int height )
{
    AVFrame *frame;

    frame = av_frame_alloc();

    if ( !frame )
    {
        return NULL;
    }

    frame->format = pix_fmt;
    frame->width  = width;
    frame->height = height;

    int checkImage = av_image_alloc( frame->data, frame->linesize, width, height, pix_fmt, 32 );

    if ( checkImage < 0 )
    {
        return NULL;
    }

    return frame;
}

bool initialize()
{
    AVRational frameRate;
    frameRate.den = m_frameRate;
    frameRate.num = 1;

    av_register_all();

    m_pCodec = avcodec_find_encoder_by_name(m_encoderName);

    if( !m_pCodec )
    {
        return false;
    }

    m_pCodecContext = avcodec_alloc_context3( m_pCodec );
    m_pCodecContext->width = m_imageWidth;
    m_pCodecContext->height = m_imageHeight;
    m_pCodecContext->time_base = frameRate;
    m_pCodecContext->gop_size = 0;
    m_pCodecContext->pix_fmt = m_pixType;
    m_pCodecContext->codec_id = m_pCodec->id;
    m_pCodecContext->bit_rate = m_targetBitRate;

    av_opt_set( m_pCodecContext->priv_data, "+CBR", "", 0 );

    return true;
}

bool startExport()
{
    m_frameIndex = 0;
    char fakeFileName[512]; 
    int checkAllocContext = avformat_alloc_output_context2( &m_pFormatContext, NULL, m_fileType, fakeFileName );

    if ( checkAllocContext < 0 )
    {
        return false;
    }

    if ( !m_pFormatContext ) 
    {
        return false;
    }

    m_pFormat = m_pFormatContext->oformat;

    if ( m_pFormat->video_codec != AV_CODEC_ID_NONE ) 
    {
        addVideoStream();

        int checkOpen = avcodec_open2( m_pCodecContext, m_pCodec, NULL );

        if ( checkOpen < 0 )
        {
            return false;
        }

        m_pFrame = allocatePicture( m_pCodecContext->pix_fmt, m_pCodecContext->width, m_pCodecContext->height );                
        if( !m_pFrame ) 
        {
            return false;
        }
        m_pFrame->pts = 0;
    }

    int checkOpen = avio_open( &m_pFormatContext->pb, m_fileName, AVIO_FLAG_WRITE );
    if ( checkOpen < 0 )
    {
        return false;
    }

    av_dict_set( &(m_pFormatContext->metadata), "title", "QS Test", 0 );

    int checkHeader = avformat_write_header( m_pFormatContext, NULL );
    if ( checkHeader < 0 )
    {
        return false;
    }

    return true;
}

int processFrame( AVPacket& avPacket )
{
    avPacket.stream_index = 0;
    avPacket.pts = av_rescale_q( m_pFrame->pts, m_pStream->codec->time_base, m_pStream->time_base );
    avPacket.dts = av_rescale_q( m_pFrame->pts, m_pStream->codec->time_base, m_pStream->time_base );
    m_pFrame->pts++;

    int retVal = av_interleaved_write_frame( m_pFormatContext, &avPacket );
    return retVal;
}

bool exportFrame()
{
    int success = 1;
    int result = 0;

    AVPacket avPacket;

    av_init_packet( &avPacket );
    avPacket.data = NULL;
    avPacket.size = 0;

    fflush(stdout);

    std::cout << "Before avcodec_encode_video2 for frame: " << m_frameIndex << std::endl;
    success = avcodec_encode_video2( m_pCodecContext, &avPacket, m_pFrame, &result );
    std::cout << "After avcodec_encode_video2 for frame: " << m_frameIndex << std::endl;

    if( result )
    { 
        success = processFrame( avPacket );
    }

    av_packet_unref( &avPacket );

    m_frameIndex++;
    return ( success == 0 );
}

void endExport()
{
    int result = 0;
    int success = 0;

    if (m_pFrame)
    {
        while ( success == 0 )
        {
            AVPacket avPacket;
            av_init_packet( &avPacket );
            avPacket.data = NULL;
            avPacket.size = 0;

            fflush(stdout);
            success = avcodec_encode_video2( m_pCodecContext, &avPacket, NULL, &result );

            if( result )
            { 
                success = processFrame( avPacket );
            }
            av_packet_unref( &avPacket );

            if (!result)
            {
                break;
            }
        }
    }

    if (m_pFormatContext)
    {
        av_write_trailer( m_pFormatContext );

        if( m_pFrame )
        {
            av_frame_free( &m_pFrame );
        }

        avio_closep( &m_pFormatContext->pb );
        avformat_free_context( m_pFormatContext );
        m_pFormatContext = NULL;
    }
}

void cleanup()
{
    if( m_pFrame || m_pCodecContext )
    {
        if( m_pFrame )
        {
            av_frame_free( &m_pFrame );
        }

        if( m_pCodecContext )
        {
            avcodec_close( m_pCodecContext );
            av_free( m_pCodecContext );
        }
    }
}

int main()
{
    bool success = true;
    if (initialize())
    {
        if (startExport())
        {
            for (int loop = 0; loop < m_frameCount; loop++)
            {
                if (!exportFrame())
                {
                    std::cout << "Failed to export frame\n";
                    success = false;
                    break;
                }
            }
            endExport();
        }
        else
        {
            std::cout << "Failed to start export\n";
            success = false;
        }

        cleanup();
    }
    else
    {
        std::cout << "Failed to initialize export\n";
        success = false;
    }

    if (success)
    {
        std::cout << "Successfully exported file\n";
    }
    return 1;
}

现在我已更新到最新的英特尔®显卡驱动程序(版本 15.45.10.4542),该问题不再出现

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用快速同步 h264_qsv 编码器时 ffmpeg avcodec_encode_video2 挂起 的相关文章

  • 在 macOS 上为 MoviePy 安装 ffmpeg 失败并出现 SSL 错误

    我正在尝试编写一个 Python 程序 在 Mac OS 10 11 16 上使用 MoviePy 将 MP4 文件转换为 GIF 我用 import moviepy editor as mp 我收到一条错误消息 说我需要打电话imagei
  • Windows 上的 ffmpeg-android ndk

    我正在尝试编译 bash 文件 带有 android ndk 的 ffmpeg 我收到如下错误 arm linux androideabi gcc 无法创建可执行文件 C 编译器测试失败 Makefile 2 config mak 没有这样
  • ffmpeg concat:“不安全的文件名”

    尝试将一堆 mts 文件转换为一个大 mp4 文件 stephan rechenmonster mnt backupsystem archive2 Videos 20151222 PRIVATE AVCHD BDMV bin ffmpeg
  • 为什么处理时间随着修剪位置的增加而增加?

    我最近一直在使用ffmpeg修剪一些视频 我注意到随着修剪位置的增加 修剪视频所花费的时间也会增加 即使持续时间相同 5 seconds 下面给出了修剪视频的命令0 to 5秒 处理仅需1秒 ffmpeg y i input mp4 fil
  • Ffmpeg 无法正确转换为 ogg [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我正在使用 ffmpeg 在我的网站上转换音频和视频 Ffmpeg 可以正确转换为其他格式 如 mp3 mp4 等 但无法正确转换为 ogg 虽然 f
  • FFMPEG波形透明,背景纯色

    我正在尝试使用 ffmpeg 生成波形 我希望背景为纯色 实际波形为透明 以下部分实现了我想要的 除了有黑色背景 我希望能够将其更改为任何颜色 但波形是透明的 我怎样才能用 ffmepg 实现这个目标 ffmpeg i input mp3
  • Android 中的 FFMpeg jni?

    我已经构建了 Bambuser http bambuser com opensource 提供的 FFMPEG 可执行文件和库 所以我设法构建了 Android 可执行文件和库 如何在 Eclipse 项目中链接这些库并从 Java 调用
  • FFMPEG:将 YUV 数据转储到 AVFrame 结构中

    我正在尝试转储YUV420数据进入AVFrameFFMPEG 的结构 从下面的链接 http ffmpeg org doxygen trunk structAVFrame html http ffmpeg org doxygen trunk
  • 为 Android 编译时显示 FFMPEG 错误

    我正在尝试将 ffmpeg 添加到我的 android 项目中 我使用的是 ubuntu 14 04 操作系统 我正在关注此链接 Link https software intel com en us android blogs 2013
  • 以 Gif 形式在 Android 上以编程方式共享 WhatsApp 视频

    我如何将 mp4 视频文件转换为 WhatsApp gif 文件 在应用程序 UI 中简单显示为 gif 但内部是特定的 mp4 格式 以在 android 共享意图中使用 并被 Whatsapp 聊天应用程序识别为此类媒体 我搜索了很多
  • 使用 ffmpeg 将 mp4 转换为 gif 时帧率较低

    我正在使用 ffmpeg 将高质量视频转换为 gif 大多数视频都是 60fps 及以上720p 但是当我使用下面的代码将视频转换为 gif 时 我得到的 gif 输出的 fps 非常低 usr bin env palette tmp pa
  • 将循环视频添加到声音 ffmpeg

    我开始使用 ffmpeg 这是我的第一个疑问 我有一个声音文件 example mp3 持续时间 1 分钟 我想添加一个循环视频 example mp4 x 秒持续时间 在这种情况下 我想生成 1 分钟的 mp4 视频并循环该视频 3 次
  • 有没有更有效的方法通过ffmpeg批量添加水印和加入视频?

    我有这个批处理文件 使用 ffmpeg 在我的视频中添加徽标 然后添加简介 但需要 10 小时到一天的时间 具体取决于我需要添加水印的数量 是否有更有效的方法来实现此目的 视频有时具有不同的分辨率 因此我无法删除到 1280 720 尺寸的
  • 视频文件转换/转码 Google App Engine

    我想启动一个云计算项目 其简单任务是 接收上传的视频文件 对它们进行一些转码 转换 允许用户下载 流式传输生成的文件 我刚在想ffmpeg作为集成在的外部命令行工具Java Google App engine Application 由于很
  • 使用 mp4box 直播破折号内容

    我正在尝试直播H 264内容到HTML5使用媒体源扩展 API 下面的方法效果很好 ffmpeg i rtsp 10 50 1 29 media video1 vcodec copy f mp4 reset timestamps 1 mov
  • 如何使用 FFmpeg 连接 MTS 视频并应用过滤器而不重新编码?

    我有一个包含许多 MTS 视频文件的 txt 文件 我想使用将它们全部合并在一起FFmpeg并获取一个大的 MTS 文件 但我想申请fade in and fade out到最后的视频 我可以在不重新编码的情况下做到这一点吗 因为重新编码需
  • 用于 Windows Phone 开发的 FFmpeg

    我在 ASP Net 基于 Web 的应用程序中使用了 FFmpeg 现在我想用它来进行Windows Phone开发 可以使用吗 如果是 那么如何 Windows Phone 7 根本不支持 FFmpeg 而且据我在网上找到的信息 Win
  • ffmpeg视频已压缩但无法在浏览器中播放

    我已经集成了ffmpeg4android lib 视频压缩工作正常 但视频无法在除 safari 浏览器之外的浏览器中播放 上传到服务器后 我使用了以下命令 ffmpeg y i
  • 在 Mac 操作系统上使用 ffmpeg 录制视频

    我想在 mac OS 上使用 ffmpeg 以任何格式录制实时网络摄像头视频 我尝试了很多 但无法找到用于重新编码视频的命令 所以请任何人都可以告诉我 ffmpeg 命令用于使用 Mac 操作系统的网络摄像头捕获视频 提前致谢 对于 Mac
  • 使用 libavcodec 提取音频样本

    我对如何从 AVFrame 中的数据提取双值感到困惑 我正在尝试提取帧 我尝试检查用 CPython 编写的 av 模块背后的源代码 尤其是 AudioFrame 来尝试了解它从何处解码样本 https github com PyAV Or

随机推荐

  • CloudFormation - 永久删除堆栈

    在 CloudFormation 中删除堆栈后 堆栈保留在 已删除 下的 cloudformation 中 有没有一种方法可以完全删除所有已删除的堆栈并在我的项目上获得干净的云信息 我认为你在 90 天的时间里只能在历史中看到它们 此命令讨
  • 从具有重复元素的向量生成所有独特的组合

    这个问题之前曾被问过 但仅适用于具有非重复元素的向量 我无法找到一个简单的解决方案来从具有重复元素的向量中获取所有组合 为了说明这一点 我在下面列出了一个例子 x lt c red blue green red green red 向量 x
  • 删除编译时的 LESS // 注释

    是否可以配置LESS在通过JS编译时删除 注释 我想从输出的 less 文件中删除它们 Less的单行注释 根据文档所述 应该保持沉默 单行注释在 LESS 中也有效 但它们是 沉默的 它们不会出现在编译后的 CSS 输出中 Hi I m
  • AutoFixture,创建电子邮件地址列表

    我正在编写一些单元测试并有一个名为Account其中有 public Guid AccountId get set public IEnumerable
  • jQuery:检查字段的值是否为 null(空)

    这是检查字段值是否为的好方法null if person data document type value NULL 或者 还有更好的方法 字段的值不能为空 它始终是字符串值 该代码将检查字符串值是否为字符串 NULL 您想检查它是否是空字
  • 将 showModalDialog() 的内容添加到剪贴板 Google 脚本

    当我单击按钮时 我已将格式化数据添加到模态对话框中 我想要的内容showModalDialog 当我单击按钮时也会自动添加到剪贴板 模态是用下面的代码生成的 并且temp是我想要添加到剪贴板的输出 Output to Html var ht
  • 在 C# 汇编版本中使用前导零是否合适?

    我正在为我的 dot net dll 设置程序集版本 汇编版本具有以下格式 主要版本 次要版本 内部版本号 修订版 我将 Verison 设置如下 200 1 1 0 现在我的问题是我是否需要在次要版本 内部版本号和修订号中保留前导零 20
  • 覆盖菜单按钮标签文本颜色 (MacOS SwiftUI)

    我可以覆盖菜单按钮标签的 设置后变暗 颜色吗 下面的 GIF 显示了一个清晰明亮的菜单项 在新选择后会变暗 此系统样式的默认行为 例如 在触控板首选项中 但它不符合可访问性标准 例如 WCAG 要求活动控件中该字体大小的亮度对比度 gt 4
  • 删除ID最小的记录

    当我在 MySQL 中输入此查询时 DELETE FROM myTable WHERE ID SELECT Min ID FROM myTable 我收到以下错误消息 1093 You can t specify target table
  • 枚举本质上不是 IEnumerable 的集合?

    当您想要递归枚举一个分层对象 根据某些条件选择一些元素时 有许多技术示例 例如 扁平化 然后使用 Linq 进行过滤 就像在这里找到的那 些 链接文本 https stackoverflow com questions 141467 rec
  • Razor:为什么我的变量不在范围内

    inherits umbraco MacroEngines DynamicNodeContext using System Collections List
  • 如何测试视图是否用“login_required”装饰(Django)

    我正在对用 login required 装饰的视图进行一些 独立的 单元测试 例子 login required def my view request return HttpResponse test 是否可以测试 my view 函数
  • 使用 Python 和 Boto3 列出 S3 存储桶的目录内容?

    我正在尝试使用 Python 和 Boto3 列出 S3 存储桶中的所有目录 我正在使用以下代码 s3 session resource s3 I already have a boto3 Session object bucket nam
  • 重用 Jest 单元测试

    我正在尝试使用 Jest 测试几个数据库实现 为了帮助测试这些实现 我首先针对两个实现都预期实现的 API 提出了一组单元测试 我目前正在努力将这两个实现传递给测试套件 下面是最简单形式的 虚拟 MongoDB 实现 class Mongo
  • 使用 Ant 运行 JUnit 测试

    我正在尝试运行我的 JUnit 测试用例 但我不断收到错误 Test com capscan accentsWorld FAILED 报告已创建 但测试未运行 这是我的蚂蚁代码
  • backbone.js - 如何在视图之间进行通信?

    我有一个带有多个backbone js 视图的单页Web 应用程序 观点有时必须相互沟通 两个例子 当有两种方式视图同时以不同方式呈现集合时 并且对一个视图中的项目的点击必须转发到另一个视图 当用户转换到流程的下一个阶段时 第一个视图将数据
  • Java发送邮件出错

    我的代码是 File Name SendEmail java import java util import javax mail import javax mail internet import javax activation pub
  • 使用虚拟列表视图调用 BeginUpdate/EndUpdate 是否有用

    我有一个虚拟列表视图 其中有数百个项目 我必须定期更新文件列表视图 方法是清除它 然后向其中添加新的 更新的项目 执行此操作时调用 BeingUpdate 和 EndUpdate 有用吗 我没有注意到任何视觉差异 Thanks 使用可能有一
  • 优化数组压缩

    假设我有一个数组k 1 2 0 0 5 4 0 我可以按如下方式计算掩码m k gt 0 1 1 0 0 1 1 0 仅使用掩码 m 和以下操作 左移 右移 And Or 加 减 乘 我可以将 k 压缩为以下形式 1 2 5 4 以下是我目
  • 使用快速同步 h264_qsv 编码器时 ffmpeg avcodec_encode_video2 挂起

    当我使用 mpeg4 或 h264 编码器时 我能够使用 ffmpeg 3 1 0 的 API 成功编码图像以生成有效的 AVI 文件 但是 当我使用快速同步编码器 h264 qsv 时 avcodec encode video2 有时会挂