avcodec_open 仅适用于未压缩格式

avcodec_open only works with uncompressed format

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

我还有一个非常完整的 class,带有从 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 等)

我的假设是:

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

[编辑]

@ronald-s-bultje 的回答让我阅读了 AVCodecContext API 描述,并且在编码器上使用时有很多带有 "MUST be set by user" 的强制字段。在 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

The av_open_codec calls is acting depending on the properties of the AVCodecContext I've referenced in the call.

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

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