【问题标题】:avcodec_open only works with uncompressed formatavcodec_open 仅适用于未压缩格式
【发布时间】:2015-08-06 07:47:44
【问题描述】:

上下文:我有一个名为 libffmpeg.so 的文件,我从 Android 应用程序的 APK 获取,该应用程序使用 FFMPEG 在多个 Codecs 之间编码和解码文件。因此,我认为这是使用编码选项启用编译的,并且这个 .so 文件在某处包含所有编解码器。该文件是为ARM 编译的(我们在Android 上称为ARMEABI 配置文件)。

我还有一个非常完整的类,可以从ffmpeg 调用API。无论这个static library 的来源是什么,所有呼叫响应都很好,并且大多数端点都存在。如果没有,我添加它们或修复已弃用的。

当我要创建ffmpegEncoder时,返回的编码器是正确的。

var thisIsSuccessful = avcodec_find_encoder(myAVCodec.id);

现在,我遇到了Codecs 的问题。问题是——假设是出于好奇——我遍历所有编解码器的列表,看看我可以使用 avcodec_open 调用打开哪一个 ...

        AVCodec codec;

        var res = FFmpeg.av_codec_next(&codec);
        while((res = FFmpeg.av_codec_next(res)) != null)
        {
            var name = res->longname;


            AVCodec* encoder = FFmpeg.avcodec_find_encoder(res->id);
            if (encoder != null) {
                AVCodecContext c = new AVCodecContext ();       

                /* put sample parameters */
                c.bit_rate = 64000;
                c.sample_rate = 22050;
                c.channels = 1;

                if (FFmpeg.avcodec_open (ref c, encoder) >= 0) {
                    System.Diagnostics.Debug.WriteLine ("[YES] - " + name);
                }
            } else {
                System.Diagnostics.Debug.WriteLine ("[NO ] - " + name);
            }
        }

...那么只有未压缩的编解码器在工作。 (YUV、FFmpeg 视频 1 等)

我的假设是:

  • 编译为 .so 文件时缺少的选项
  • av_open_codec 调用的作用取决于我在调用中引用的 AVCodecContext 的属性。

我真的很好奇为什么只返回最少的未压缩编解码器集?

[编辑]

@ronald-s-bultje 的回答让我阅读了 AVCodecContext API 描述,当在编码器上使用时,有很多带有“必须由用户设置”的补充文件。在AVCodecContext 上为这些参数设置一个值可以使大多数漂亮的编解码器可用:

c.time_base = new AVRational (); // Output framerate. Here, 30fps
c.time_base.num = 1;
c.time_base.den = 30;
c.me_method = 1; // Motion-estimation mode on compression -> 1 is none
c.width = 640; // Source width
c.height = 480; // Source height
c.gop_size = 30; // Used by h264. Just here for test purposes.
c.bit_rate = c.width * c.height * 4; // Randomly set to that...
c.pix_fmt = FFmpegSharp.Interop.Util.PixelFormat.PIX_FMT_YUV420P; // Source pixel format

【问题讨论】:

  • 也许他们省略了各种编解码器以获得更小的二进制文件或避免许可问题。
  • 在 Google Play 上查看应用程序 screenshot 时,似乎至少有 3GP 作为输出格式,而我列出编解码器时并非如此。
  • @RhythmicFistman 我会将其添加为假设。我需要看看从 avcodec 中包含/删除编解码器的过程是什么样的。

标签: ffmpeg static-libraries codec avcodec


【解决方案1】:

av_open_codec 调用的作用取决于 我在调用中引用了 AVCodecContext。

基本上就是这样。我的意思是,对于视频编码器,你甚至没有设置宽度/高度,所以大多数编码器真的不能指望做任何像这样有用的事情,而且直接出错是正确的。

您可以使用例如设置默认参数avcodec_get_context_defaults3(),它应该可以帮助您在 AVCodecContext 中获得一些有用的设置。之后,将诸如 width/height/pix_fmt 之类的典型设置设置为描述您的输入格式的那些(如果您想进行音频编码 - 这实际上从您的问题中令人惊讶地不清楚,您需要设置一些不同的设置,例如 sample_fmt/sample_rate /channels,但同样的想法)。然后你应该比较好去。

【讨论】:

  • 作为该领域的专家,如果目标只是将 YUV 内容和 PCM 声音编码为包含在 .MP4 文件中的工作 H264 电影,您是否知道是否可以单独使用 libx264?很抱歉这个问题,接受一个简短的回答。 :)
  • 你的意思是直接使用libx264而不是通过ffmpeg?我认为对于仅视频,您会发现它可以完成所有这些,但是当您想开始混合音频时,我个人已经使用 ffmpeg。您需要学习使用私有选项 API (av_opt_set_*()) 为“preset”和“x264_params”等选项设置值,然后它的工作方式与原始 x264 API 非常相似(请参阅trac.ffmpeg.org/wiki/Encode/H.264) .
  • 最后一个小问题,我保证。 (这太具体了,无法在其他地方问。)我注意到我需要编写很多代码才能使用 ffmpeg API。 ffmpeg.c 是 ffmpeg.exe 用于帮助程序和“自动检测”/预设处理的唯一代码吗?如果是这样,我将只使用 ffmpeg.c 中的现有函数,而不是从头开始编写我的编码/解码函数。
  • 没关系。这里的确切问题:stackoverflow.com/questions/2401764/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多