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

av_write_header()调用失败,报Invalid data found错误(错误码-1094995529)

问题描述

编写了一段基础代码尝试将样本帧编码到文件,但还未进入编码步骤就无法写入文件头;若忽略该错误或跳过写头操作,av_write_frame()会触发段错误,推测这两个问题均与I/O相关。

原代码
#include <stdlib.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <stdio.h>

int main() {
   AVFormatContext* formatContext = NULL;
   avformat_alloc_output_context2(&formatContext, NULL, NULL, "output.mkv");
   if (!formatContext) {
      return 1;
   }

   const AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264);
   if (!codec) {
      return 1;
   }

   AVStream* stream = avformat_new_stream(formatContext, codec);
   if (!stream) {
      return 1;
   }

   AVCodecContext* codecContext = avcodec_alloc_context3(codec);
   if (!codecContext) {
      return 1;
   }

   codecContext->codec_id = AV_CODEC_ID_H264;
   codecContext->codec_type = AVMEDIA_TYPE_VIDEO;
   codecContext->pix_fmt = AV_PIX_FMT_YUV420P;
   codecContext->width = 640;
   codecContext->height = 480;
   codecContext->time_base.den = 30;
   codecContext->time_base.num = 1;
   codecContext->gop_size = 30;

   if (avcodec_open2(codecContext, codec, NULL) < 0) {
      return 1;
   }

   avcodec_parameters_from_context(stream->codecpar, codecContext);

   if (avio_open(&formatContext->pb, "output.mkv", AVIO_FLAG_WRITE) < 0) {
      return 1;
   }

   int h = avformat_write_header(formatContext, NULL);
   if (h < 0) {
      printf("failed to write header: %s (%d)\n",av_err2str(h),h);
      return 1;
   }

   avformat_free_context(formatContext);
   avcodec_free_context(&codecContext);
}
程序输出
$ ./a.out
[libx264 @ 0x6468176c52c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x6468176c52c0] profile High, level 3.0, 4:2:0, 8-bit
failed to write header: Invalid data found when processing input (-1094995529)
问题分析与修正

核心问题

手动调用avio_open重复初始化了formatContext->pb,而avformat_alloc_output_context2已经根据指定的输出文件名自动创建并初始化了IO上下文,重复打开会导致资源冲突,引发写头失败。

修正步骤

  1. 移除手动avio_open调用:删除重复打开文件的代码块,依赖avformat_alloc_output_context2自动创建的IO上下文即可
  2. 修正avformat_new_stream参数:新版本FFmpeg中该函数的codec参数已废弃,传入NULL即可
  3. 同步流的时间基:添加stream->time_base = codecContext->time_base;,确保流参数与编码上下文一致
  4. 补全收尾操作:写完头后调用av_write_trailer完成文件写入,避免文件损坏
  5. 完善错误打印:添加更清晰的错误信息输出,方便调试

修正后的代码

#include <stdlib.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <stdio.h>

int main() {
    AVFormatContext* formatContext = NULL;
    int ret = avformat_alloc_output_context2(&formatContext, NULL, NULL, "output.mkv");
    if (ret < 0 || !formatContext) {
        fprintf(stderr, "Failed to allocate output context: %s\n", av_err2str(ret));
        return 1;
    }

    const AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264);
    if (!codec) {
        fprintf(stderr, "H264 encoder not found\n");
        return 1;
    }

    AVStream* stream = avformat_new_stream(formatContext, NULL);
    if (!stream) {
        fprintf(stderr, "Failed to create new stream\n");
        return 1;
    }

    AVCodecContext* codecContext = avcodec_alloc_context3(codec);
    if (!codecContext) {
        fprintf(stderr, "Failed to allocate codec context\n");
        return 1;
    }

    codecContext->codec_id = AV_CODEC_ID_H264;
    codecContext->codec_type = AVMEDIA_TYPE_VIDEO;
    codecContext->pix_fmt = AV_PIX_FMT_YUV420P;
    codecContext->width = 640;
    codecContext->height = 480;
    codecContext->time_base.den = 30;
    codecContext->time_base.num = 1;
    codecContext->gop_size = 30;
    codecContext->bit_rate = 500000; // 显式设置码率,避免编码器自动计算异常

    ret = avcodec_open2(codecContext, codec, NULL);
    if (ret < 0) {
        fprintf(stderr, "Failed to open codec: %s\n", av_err2str(ret));
        return 1;
    }

    ret = avcodec_parameters_from_context(stream->codecpar, codecContext);
    if (ret < 0) {
        fprintf(stderr, "Failed to copy codec parameters: %s\n", av_err2str(ret));
        return 1;
    }

    stream->time_base = codecContext->time_base;

    ret = avformat_write_header(formatContext, NULL);
    if (ret < 0) {
        fprintf(stderr, "Failed to write header: %s (%d)\n", av_err2str(ret), ret);
        return 1;
    }

    // 此处可添加帧编码与写入逻辑

    av_write_trailer(formatContext);

    avformat_free_context(formatContext);
    avcodec_free_context(&codecContext);

    return 0;
}

说明

修正后的代码解决了IO上下文冲突问题,同时完善了错误处理和资源管理逻辑,能够正常写入文件头。后续只需添加帧编码和写入的逻辑即可完成完整的视频编码流程。

内容的提问来源于stack exchange,提问作者Dan Rafone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 02:45:28