[Libav-user] encoding bitrate wrong

mattes effemm at mykmk.com
Fri Mar 2 06:01:15 CET 2012


>> 2012/3/1 mattes <effemm at mykmk.com>:
>>> I ported an older mp4 encoder application (using ffmpeg 0.4.9 libs)  over to the ffmpeg 0.7.11 (on
> Fedora15).
>>> Encoding is working, but there is one minor glitch.
>>>   Bitrate is set via AVContext->bit_rate = bitrate.
>> Which video codec do you use?
>> Do you have audio tracks? Did you try encoding without audio tracks? How much bitrate differs from
> desired, without audio tracks?
>> 1. Ensure that frames you feed to encoder have timestamps in that AVCodecContext's time_base. 2. If
> that doesn't help, try setting also AVCodecContext.rc_max_rate to bitrate, and .rc_buffer_size (try
also bitrate value, as trial value). This possibly makes sense only if libx264 encoder is used. Andrey
Utkin
>
> The video codec used is CODEC_ID_MPEG4
> with one audio track and codec  AAC - FAAC
>
>   video bitrate   audio bitrate  resulting bitrate
>    500            128            12614
>   1500            128            237
>   2500            128            13355
>
> I did some test runs w/o audio and the results are similiar:
>
>   video bitrate  abr    resulting bitrate
>    500           -      16377
>   1500           -      105
>   2500           -      14895

I checked the code and it seems that the timebase is set as suggested
     AVCodecContext.timebase = (AVRational){1,30};
and timestamp are set for every single frame
     AVFrame.pts = srcFrameTimestamp;
>From what I noticed there are no AVsync issues noticable on playback
and it has 30 frames per second.

I then went on to add the following:
  AVCodecContext.rc_max_rate = m_avctx->bit_rate;
  AVCodecContext.rc_min_rate = m_avctx->bit_rate;
  AVCodecContext.rc_buffer_size = Profile()->m_videoMaxVopSize;

Test results show now an improved behaviour for the encoded bitrate. for 1500 and 2500kbits. Though I
think the cpu usage is rather high with the setting of rc_max_rate and rc_min_rate (compared to what i
measured with ffmpeg 0.4.9)

   video bitrate  abr    resulting bitrate  framerate
    500           -      233                13
   1500           -      1487               30
   2500           -      2513               30

At bitrate 500kbits the framerate start at 30fps and then slowly degresses. It seems the return of
avcodec_encode_video2() hangs after a while.

I attached the avcodec initialization and the encoder feed routine.
Is there anything obvious missing/or required for the later ffmpeg 0.7.x?

Does some one know what is required to properly intialize the mpeg4 encoder?

bool ffmVideoEncoder_Init()
{
  avcodec_init();
  avcodec_register_all();

  m_media_frame = MPEG4VIDEOFRAME;
  m_codec = avcodec_find_encoder(CODEC_ID_MPEG4);
  if (m_codec == NULL)    return false;

  m_avctx = avcodec_alloc_context3( m_codec );
  if (m_avctx == NULL)   return false;

  m_picture = avcodec_alloc_frame();
  m_avctx->width    = Profile()->m_videoWidth;
  m_avctx->height   = Profile()->m_videoHeight;
  m_avctx->bit_rate = Profile()->GetIntegerValue(CFG_VIDEO_BIT_RATE) * 1000;

  m_avctx->rc_max_rate = m_avctx->bit_rate;
  m_avctx->rc_min_rate = m_avctx->bit_rate;
  m_avctx->rc_buffer_size = Profile()->m_videoMaxVopSize;

  m_avctx->time_base = (AVRational){1, (int)(Profile()->GetFloatValue(CFG_VIDEO_FRAME_RATE) + .5)};
  m_avctx->pix_fmt = PIX_FMT_YUV420P;
  m_avctx->me_method = ME_EPZS;
  m_usingBFrames = false;
  m_BFrameCount = 0;
  m_count = 0;

  m_avctx->strict_std_compliance = -1;
  if (Profile()->GetBoolValue(CFG_VIDEO_USE_B_FRAMES)) {
        m_avctx->max_b_frames = Profile()->GetIntegerValue(CFG_VIDEO_NUM_OF_B_FRAMES);
        m_usingBFrames = true;
        m_BFrameCount = m_avctx->max_b_frames;
   }
   m_key_frame_count = m_avctx->gop_size = (int)
      ((Profile()->GetFloatValue(CFG_VIDEO_FRAME_RATE)+0.5)
       * Profile()->GetFloatValue(CFG_VIDEO_KEY_FRAME_INTERVAL));
   m_avctx->flags |= CODEC_FLAG_GLOBAL_HEADER;

  ffmpeg_interface_lock();
  if (avcodec_open2(m_avctx, m_codec, NULL ) < 0) {
    ffmpeg_interface_unlock();
    return false;
  }
  ffmpeg_interface_unlock();
  return true;
}

bool ffmpegVideoEncoder_EncodeImage(
        const u_int8_t* pY,
        const u_int8_t* pU,
        const u_int8_t* pV,
        u_int32_t yStride, u_int32_t uvStride,
        Timestamp srcFrameTimestamp)
{

  if (m_vopBuffer == NULL) {
    m_vopBuffer = (u_int8_t*)malloc(Profile()->m_videoMaxVopSize);
    if (m_vopBuffer == NULL)  return false;
  }

    m_picture->pict_type = (AVPictureType)0;

  m_picture->data[0] = (uint8_t *)pY;
  m_picture->data[1] = (uint8_t *)pU;
  m_picture->data[2] = (uint8_t *)pV;
  m_picture->linesize[0] = yStride;
  m_picture->linesize[1] = uvStride;
  m_picture->linesize[2] = uvStride;
  m_picture->pts = srcFrameTimestamp;
  m_count++;

  m_vopBufferLength = avcodec_encode_video(m_avctx,
                                           m_vopBuffer,
                                           Profile()->m_videoMaxVopSize,
                                           m_picture);
  //printf(" -%d "U64" ffmpeg len %d ", m_count, srcFrameTimestamp, m_vopBufferLength);
  return true;
}









More information about the Libav-user mailing list