Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extremely high bit rate when encoding video with libavcodec

I am trying to capture the camera output and make a video using libavcodec. As an example on how to accomplish this i have used ffmpeg muxing example.

The problem is that a 4 seconds video has a size of ~15mb and a bitrate of ~30000 kb/s, although I have set the bitrate on AVCodecContext to 400000 (I consider this value is in bits / sec, not kb/s).

I have also tried to record the video using ffmpeg from command line and it has a bitrate of ~700 kb/s.

Does anybody have an idea why the bitrate is not preserved and thus the resulting file is very large? The code I have used to initialize the codec context is below:

initialization part:

avformat_alloc_output_context2(&m_formatContext, NULL, NULL, filename);
outputFormat = m_formatContext->oformat;

codec = avcodec_find_encoder(outputFormat->video_codec);

m_videoStream = avformat_new_stream(m_formatContext, codec);

m_videoStream->id = m_formatContext->nb_streams - 1;

codecContext = m_videoStream->codec;

codecContext->codec_id = outputFormat->video_codec;

codecContext->width = m_videoResolution.width();
codecContext->height = m_videoResolution.height();

int m_bitRate = 400000;
codecContext->bit_rate = m_bitRate;
codecContext->rc_min_rate = m_bitRate;
codecContext->rc_max_rate = m_bitRate;
codecContext->bit_rate_tolerance = 0;

codecContext->time_base.den = 20;
codecContext->time_base.num = 1;

codecContext->pix_fmt = AV_PIX_FMT_YUV422P;

if (m_formatContext->oformat->flags & AVFMT_GLOBALHEADER)
    codecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
/* open it */
ret = avcodec_open2(codecContext, codec, NULL);

avFrame = avcodec_alloc_frame();

ret = avpicture_alloc(&avPicture, codecContext->pix_fmt, codecContext->width, codecContext->height);

*((AVPicture *)avFrame) = avPicture;

av_dump_format(m_formatContext, 0, filename, 1);

if (!(outputFormat->flags & AVFMT_NOFILE)) {
    ret = avio_open(&m_formatContext->pb, filename, AVIO_FLAG_WRITE);
}

ret = avformat_write_header(m_formatContext, NULL);

if (avFrame)
    avFrame->pts = 0;
like image 952
niculare Avatar asked Oct 18 '13 12:10

niculare


People also ask

What is an encoder bitrate?

Bitrate is the amount of data encoded for a unit of time, and for streaming is usually referenced in megabits per second (Mbps) for video, and in kilobits per second (kbps) for audio. From a streaming perspective, a higher video bitrate means a higher quality video that requires more bandwidth.


1 Answers

Because each encoder has its own profile and the bitrate you provide is a hint. If your bitrate is a valid value (not too small and not too big), the codec will just select a supported bitrate in his profile list.

Codec "capabilities" may also influence the bitrate, but that's as far I know.

Codec profiles define a correlation between at least :

  • Frame size (width, heigth)
  • bitrate
  • pixel format
  • frame rate

I still struggle to find a way to get bitrates from the codec using the api, but you can find out its profiles by giving a bitrate really low before opening the codec.

with the code

codecContext->bit_rate = 1;
avcodec_open2(codecContext, codec, NULL);

FFmpeg codec will log a complaint and a list of acceptable tuples listed above.

Note: Only tried with codecs which don't required external libraries

like image 99
UmNyobe Avatar answered Nov 15 '22 18:11

UmNyobe