上下文:我有一个名为libffmpeg的文件。因此,我从Android
应用程序的APK
中提取,该应用程序使用FFMPEG
对几个Codecs
之间的文件进行编码和解码。因此,我认为这是在启用编码选项的情况下编译的,并且这个。so文件在某个地方包含所有编解码器。这个文件是为ARM
编译的(我们在Android
上称之为ARMEABI
配置文件)。
我也有一个非常完整的类与互操作从ffmpeg
调用API
。无论这个static library
的起源是什么,所有的呼叫响应都是好的,大多数端点都存在。如果没有,我将添加它们或修复已弃用的。
当我想创建ffmpeg
Encoder
时,返回的编码器是正确的。
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 Video 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
av_open_codec调用的行为取决于AVCodecContext我已经在调用中引用。
基本上就是这样。我的意思是,对于视频编码器,你甚至没有设置宽度/高度,所以大多数编码器真的不能像这样做任何有用的东西,并且是正确的错误。
你可以使用例如avcodec_get_context_defaults3()来设置默认参数,这将帮助你在AVCodecContext中获得一些有用的设置。之后,将width/height/pix_fmt等典型参数设置为描述输入格式的参数(如果您想进行音频编码-实际上从您的问题中令人惊讶地不清楚,则需要设置一些不同的参数,如sample_fmt/sample_rate/channels,但想法相同)。然后你就可以开始了