avcodec_open only works with uncompressed format

时间:2015-05-24 20:29:03

标签: ffmpeg static-libraries codec avcodec

Context: I have a file called libffmpeg.so, that I took from the APK of an Android application that is using FFMPEG to encode and decode files between several Codecs. Thus, I take for grant that this is compiled with encoding options enable and that this .so file is containing all the codecs somewhere. This file is compiled for ARM (what we call ARMEABI profile on Android).

I also have a very complete class with interops to call API from ffmpeg. Whatever is the origin of this static library, all call responses are good and most endpoints exist. If not I add them or fix deprecated one.

When I want to create an ffmpeg Encoder, the returned encoder is correct.

var thisIsSuccessful = avcodec_find_encoder(myAVCodec.id);

Now, I have a problem with Codecs. The problem is that - let's say that out of curiosity - I iterate through the list of all the codecs to see which one I'm able to open with the avcodec_open call ...

        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);
            }
        }

... then only uncompressed codecs are working. (YUV, FFmpeg Video 1, etc)

My hypothesis are these one:

  • An option that was missing at the time of compiling to the .so file
  • The av_open_codec calls is acting depending on the properties of the AVCodecContext I've referenced in the call.

I'm really curious about why only a minimum set of uncompressed codecs are returned?

[EDIT]

@ronald-s-bultje answer led me to read AVCodecContext API description, and there are a lot of mendatory fileds with "MUST be set by user" when used on an encoder. Setting a value for these parameters on AVCodecContext made most of the nice codecs available:

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

1 个答案:

答案 0 :(得分:1)

  

av_open_codec调用的行为取决于的属性   我在电话中引用了AVCodecContext。

基本上就是这样。我的意思是,对于视频编码器,你甚至没有设置宽度/高度,所以大多数编码器实际上都不能做这样有用的事情,并且正确地出错。

您可以使用例如设置默认参数avcodec_get_context_defaults3(),它可以帮助您在AVCodecContext中获得一些有用的设置。之后,将宽度/高度/ pix_fmt等典型值设置为描述输入格式的那些(如果你想进行音频编码 - 实际上你的问题实际上不清楚,你需要设置一些不同的,如sample_fmt / sample_rate / channels,但同样的想法)。然后你应该相对好。