[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