[FFmpeg-devel] Live streaming of VP8

James Zern jzern at google.com
Sun Jun 10 23:20:20 CEST 2012


On Sun, Jun 10, 2012 at 1:56 AM, Andy Bell <allbabel at gmail.com> wrote:
> On 9 Jun 2012 22:50, "James Zern" <jzern at google.com> wrote:
>>
>> On Sat, Jun 9, 2012 at 8:14 AM, Michael Niedermayer <michaelni at gmx.at>
> wrote:
>> > On Sat, Jun 09, 2012 at 04:51:23PM +0200, Andy Bell wrote:
>> >> Hi All,
>> >>
>> >> I am streaming a VP8 stream over network and using the following code
> to
>> >> encode:
>> >>
>> >> _bitRate = 500 * 1000;
>> >> _codecContext->bit_rate = _bitRate; // --target-bitrate=500
>> >> _codecContext->rc_min_rate = _codecContext->rc_max_rate =
>> >> _codecContext->bit_rate; // --end-usage=cbr
>>
>> Pairing vbr with realtime (quality=realtime/deadline=1) is probably a
>> better choice for live encoding.
>
> How do I set the above to reflect this?
>

VBR is the default if you avoid setting min=max=bitrate.
Quality and deadline are codec options, '-deadline 1' has the same
meaning as '-quality realtime'.
>From code the easiest way to set these is probably av_set_opt [1].
    av_opt_set_double(_codecContext->priv_data, "max-intra-rate", 90, 0);
    av_opt_set(_codecContext->priv_data, "quality", "realtime", 0);

>>
>> >>
>> >> _codecContext->thread_count = 4;
>> >> _codecContext->qmin = 4;
>> >> _codecContext->qmax = 56;
>> >> _codecContext->width = 800;
>> >> _codecContext->height = 600;
>> >> _codecContext->rc_buffer_aggressivity = 0.95;  // --undershoot-pct=95
>> >> _codecContext->rc_buffer_size = _bitRate * 6; // --buz-sz=6000 ms
>> >> _codecContext->rc_initial_buffer_occupancy = _bitRate * 4; //
>> >> --buf-initial-sz=4000 ms
>> >> _codecContext->profile = 3;
>>
>> You probably don't want to set this. It impacts decode complexity at
>> the cost of encode quality.
>
> I was hoping that this would reduce the decode times for low powered
> devices.
>
This is probably a bit much, if you're concerned you could start with
1. Also setting slices=2/4 may help if the decoder is not doing
frame-based multithreaded decoding.

>>
>> >> _codecContext->time_base.num = 1;
>> >> _codecContext->time_base.den = 25;
>> >> _codecContext->gop_size = 999999; // --kf-max-dist
>> >>
>> >> This works fine but when there is a huge scene change the codec
> generates a
>> >> key frame which I am having trouble transmitting in realtime over the
>> >> network due to the sudden jump in bitrate.
>> >
>> > rc_buffer_size indicates a wanted max latency of 6 seconds
>> > if you want it to be less you can use a smaller value
>> >
>>
>> This will help overall bitrate spikes and as I mentioned on
>> webm-discuss you might be looking for the max-intra-rate option. I've
>> attached a patch to add this option.
>
> Where can I find the patch?
>

It was attached to the mail thread, but has been pulled into the main
repository, so a git pull will include it.

> Is there support in FFMPEG to force a key frame as there is in libvpx?
>

There's support generally yes via -force_key_frames. The attached adds
support to libvpxenc. If you get into forcing other frames like
golden, etc. you might be better served by using libvpx directly.

[1] http://ffmpeg.org/doxygen/trunk/group__opt__set__funcs.html#g5fd4b92bdf4f392a2847f711676a7537
-------------- next part --------------
From ec958a6a41fdf38751e4fedbdbe0c975ef16a75a Mon Sep 17 00:00:00 2001
From: James Zern <jzern at google.com>
Date: Sun, 10 Jun 2012 14:15:20 -0700
Subject: [PATCH] libvpxenc: add support for forced key frames

---
 libavcodec/libvpxenc.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index b3ec17d..f9180f0 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -503,6 +503,7 @@ static int vp8_encode(AVCodecContext *avctx, AVPacket *pkt,
     VP8Context *ctx = avctx->priv_data;
     struct vpx_image *rawimg = NULL;
     int64_t timestamp = 0;
+    long flags = 0;
     int res, coded_size;
 
     if (frame) {
@@ -514,10 +515,11 @@ static int vp8_encode(AVCodecContext *avctx, AVPacket *pkt,
         rawimg->stride[VPX_PLANE_U] = frame->linesize[1];
         rawimg->stride[VPX_PLANE_V] = frame->linesize[2];
         timestamp                   = frame->pts;
+        flags                       = frame->pict_type == AV_PICTURE_TYPE_I ? VPX_EFLAG_FORCE_KF : 0;
     }
 
     res = vpx_codec_encode(&ctx->encoder, rawimg, timestamp,
-                           avctx->ticks_per_frame, 0, ctx->deadline);
+                           avctx->ticks_per_frame, flags, ctx->deadline);
     if (res != VPX_CODEC_OK) {
         log_encoder_error(avctx, "Error encoding frame");
         return AVERROR_INVALIDDATA;
-- 
1.7.7.3


More information about the ffmpeg-devel mailing list