[Libav-user] Filesize difference between using ffmpeg command line and C API

Alexandre Bizeau abizeau at 36pix.com
Tue Mar 30 17:36:41 EEST 2021


While using following ffmpeg command :

*ffmpeg -framerate 12 -pattern_type glob -i 'FRAMES/frame_*.tif' -map 0:v
test_binffmpeg.mp4*

It uses the default *H.264* parameters which are *preset=medium and crf=23*.
This generates a file size with *bit_rate = 1358 kb/s* and *size = 1659kb*.

But by using my own code to encode an mp4 video (using the exact same
images), I then have a video around *bit_rate = 3929 kb/s* and *size =
4757kb*.

In my code, I leave the codec options to default, and even if I try to
overwrite with preset=medium + crf=23, I still have the same size of
4757kb. I'm wondering what I am missing?

See attached file for the code of my muxer

Regards,
Alexandre
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20210330/5f7fabfa/attachment.html>
-------------- next part --------------
    // Search for the output format based on the file name.
    AVOutputFormat* oformat = av_guess_format(nullptr, m_filename.c_str(), nullptr);
    if ( !oformat ) return false;

    // Allocate the context based on that format
    _ret = avformat_alloc_output_context2(&m_ofmt_ctx, oformat, nullptr, m_filename.c_str());
    if ( _ret ) return false;

    // Get the codec appropriate to that format
    // and be able to set some parameter to that codec.
    AVCodec* codec = avcodec_find_encoder(oformat->video_codec);
    if ( !codec ) return false;

#if _DEBUG
    printf("Codec name: %s\n", avcodec_get_name(codec->id));
    const AVPixelFormat* p = codec->pix_fmts;
    while ( p != NULL && *p != AV_PIX_FMT_NONE )
    {
        printf("supported pix fmt: %s\n", av_get_pix_fmt_name(*p));
        ++p;
    }
#endif

    // Prepare stream/context according to above variable (codec/format).
    AVStream* stream = avformat_new_stream(m_ofmt_ctx, codec);
    if ( !stream ) return false;

    // Allocate the context for that codec.
    m_o_codec_ctx = avcodec_alloc_context3(codec);
    if ( !m_o_codec_ctx ) return false;        

    // Setup the 'global' parameter for the codec (Size, color format, etc)
    stream->codecpar->codec_id = codec->id;
    stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
    stream->codecpar->width = m_width;
    stream->codecpar->height = m_height;
    stream->codecpar->format = AV_PIX_FMT_YUV444P;

    // Assign the global parameter to the context.
    avcodec_parameters_to_context(m_o_codec_ctx, stream->codecpar);

    // Set the framerate.
    m_o_codec_ctx->time_base = { 1, m_framerate };

#if 0 // We can enable this, but it still the default parameters anyway.
    if ( (_ret = av_dict_set(&m_options_dict, "preset", "medium", 0)) < 0 )
        return false;

    if ( (_ret = av_dict_set(&m_options_dict, "crf", "23.0", 0)) < 0 )
        return false;
#endif
    
    avcodec_parameters_from_context(stream->codecpar, m_o_codec_ctx);

    // Open the file and write the header.
    if ( (_ret = avcodec_open2(m_o_codec_ctx, codec, &m_options_dict)) < 0 )
        return false;

    if ( (_ret = avio_open(&m_ofmt_ctx->pb, m_filename.c_str(), AVIO_FLAG_WRITE)) < 0 )
        return false;

    if ( (_ret = avformat_write_header(m_ofmt_ctx, &options_dict)) < 0 )
        return false;

#if _DEBUG
    // This print the stream/output format.
    av_dump_format(m_ofmt_ctx, 0, m_filename.c_str(), 1);
#endif

    // Define the pts increment (the time to the next frame).
    if ( m_ofmt_ctx && m_ofmt_ctx->nb_streams > 0 )
        m_pts_increment = av_rescale_q(1, m_o_codec_ctx->time_base, m_ofmt_ctx->streams[0]->time_base);
    else
       return false;
       
   return true;


More information about the Libav-user mailing list