Search code examples
ffmpegh.264

How to reduce the latency of FFmpeg h264_qsv encoder?


I use FFmpeg(3.4) h264_qsv encoder in my camera-live software, I found that the encoded data recieved after sending 40 frames! There is about 1.5 seconds latency, it is not sutiable for realtime situation.How to config the encoder? Thanks a lot.

my code:

AVCodecContext* OpenH264Codec(int width, int height, int bitrate, int framerate)
{
    AVCodecContext* ctx = 0;
    AVCodec* c = 0;
    c = avcodec_find_encoder_by_name("h264_qsv");
    if (c == NULL) return NULL;
    ctx = avcodec_alloc_context3(c);
    if (ctx == NULL) return NULL;
    ctx->width = width;
    ctx->height = height;
    ctx->pix_fmt = c->pix_fmts[0];
    ctx->bit_rate = bitrate;
    ctx->bit_rate_tolerance = ctx->bit_rate / 2;
    ctx->rc_min_rate = 32000;
    ctx->rc_max_rate = ctx->bit_rate*1.5;
    ctx->time_base.den = framerate;
    ctx->time_base.num = 1;
    ctx->framerate.den = 1;
    ctx->framerate.num = framerate;
    ctx->gop_size = framerate*5;
    ctx->max_b_frames = 0;

    av_opt_set(ctx->priv_data, "preset", "veryfast", 0);
    av_opt_set(ctx->priv_data, "avbr_accuracy", "1", 0);
    av_opt_set(ctx->priv_data, "async_depth", "1", 0);
    av_opt_set(ctx->priv_data, "profile", "main", 0);
    ctx->flags |= AV_CODEC_FLAG_QSCALE;
    if (avcodec_open2(ctx, c, 0) < 0)
    {
        avcodec_free_context(&ctx);
        return NULL;
    }
    return ctx;
}

Solution

  • Thanks for Mulvya's tip. There is only 5 frames latency now.

    AVCodecContext* OpenH264Codec(int width, int height, int bitrate, int framerate)
    {
        AVCodecContext* ctx = 0;
        AVCodec* c = 0;
        c = avcodec_find_encoder_by_name("h264_qsv");
        if (c == NULL) return NULL;
        ctx = avcodec_alloc_context3(c);
        if (ctx == NULL) return NULL;
        ctx->width = width;
        ctx->height = height;
        ctx->pix_fmt = c->pix_fmts[0];
        ctx->bit_rate = bitrate;
        ctx->bit_rate_tolerance = ctx->bit_rate / 2;
        ctx->time_base.den = framerate;
        ctx->time_base.num = 1;
        ctx->framerate.den = 1;
        ctx->framerate.num = framerate;
        ctx->gop_size = framerate*5;
        ctx->max_b_frames = 0;
        av_opt_set(ctx->priv_data, "preset", "medium", 0);
        av_opt_set(ctx->priv_data, "look_ahead", "0", 0);
        //av_opt_set(ctx->priv_data, "look_ahead_depth", "8", 0);
        if (avcodec_open2(ctx, c, 0) < 0)
        {
            avcodec_free_context(&ctx);
            return NULL;
        }
        return ctx;
    }