@TEMPLATE encoder_tmpl.c
VP8 Scalable Frame Patterns
===========================
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
This is an example demonstrating how to control the VP8 encoder's
reference frame selection and update mechanism for video applications
that benefit from a scalable bitstream.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION


Configuration
-------------
Scalable frame patterns are most useful in an error resilient context,
so error resiliency mode is enabled, as in the `error_resilient.c`
example. In addition, we want to disable automatic keyframe selection,
so we force an interval of 1000 frames.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  ENC_SET_CFG2

/* Enable error resilient mode */
cfg.g_error_resilient = 1;
cfg.g_lag_in_frames   = 0;
cfg.kf_mode           = VPX_KF_FIXED;

/* Disable automatic keyframe placement */
cfg.kf_min_dist = cfg.kf_max_dist = 1000;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_SET_CFG2

This example uses the following frame pattern (L->last_frame,
G->golden_frame, A->alt_ref_frame):

*  Frame  0  Intra, use none,  update L&G&A
*  Frame  1  Inter, use LGA,   update none
*  Frame  2  Inter, use LGA,   update L
*  Frame  3  Inter, use LGA,   update none
*  Frame  4  Inter, use GA,    update L&G
*  Frame  5  Inter, use LGA,   update none
*  Frame  6  Inter, use LGA,   update L
*  Frame  7  Inter, use LGA,   update none
*  Frame  8  Inter, use A,     update L&G&A
*  Frame  9  Inter, use LGA,   update none
*  Frame 10  Inter, use LGA,   update L
*  Frame 11  Inter, use LGA,   update none
*  Frame 12  Inter, use GA,    update L&G
*  Frame 13  Inter, use LGA,   update none
*  Frame 14  Inter, use LGA,   update L
*  Frame 15  Inter, use LGA,   update none
*  ...Repeats the pattern from frame 0

Change this variable to test the 3 decodable streams case.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS
int                  num_streams = 5;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PER_FRAME_CFG
flags = 0;
if(num_streams == 5)
{
    switch(frame_cnt % 16) {
        case 0:
            flags |= VPX_EFLAG_FORCE_KF;
            flags |= VP8_EFLAG_FORCE_GF;
            flags |= VP8_EFLAG_FORCE_ARF;
            break;
        case 1:
        case 3:
        case 5:
        case 7:
        case 9:
        case 11:
        case 13:
        case 15:
            flags |= VP8_EFLAG_NO_UPD_LAST;
            flags |= VP8_EFLAG_NO_UPD_GF;
            flags |= VP8_EFLAG_NO_UPD_ARF;
            break;
        case 2:
        case 6:
        case 10:
        case 14:
            break;
        case 4:
            flags |= VP8_EFLAG_NO_REF_LAST;
            flags |= VP8_EFLAG_FORCE_GF;
            break;
        case 8:
            flags |= VP8_EFLAG_NO_REF_LAST;
            flags |= VP8_EFLAG_NO_REF_GF;
            flags |= VP8_EFLAG_FORCE_GF;
            flags |= VP8_EFLAG_FORCE_ARF;
            break;
        case 12:
            flags |= VP8_EFLAG_NO_REF_LAST;
            flags |= VP8_EFLAG_FORCE_GF;
            break;
    }
}
else
{
    switch(frame_cnt % 9) {
        case 0:
            if(frame_cnt==0)
            {
                flags |= VPX_EFLAG_FORCE_KF;
            }
            else
            {
                cfg.rc_max_quantizer = 26;
                cfg.rc_min_quantizer = 0;
                cfg.rc_target_bitrate = 300;
                flags |= VP8_EFLAG_NO_REF_LAST;
                flags |= VP8_EFLAG_NO_REF_ARF;
            }
            flags |= VP8_EFLAG_FORCE_GF;
            flags |= VP8_EFLAG_FORCE_ARF;
            break;
        case 1:
        case 2:
        case 4:
        case 5:
        case 7:
        case 8:
            cfg.rc_max_quantizer = 45;
            cfg.rc_min_quantizer = 0;
            cfg.rc_target_bitrate = 230;
            break;
        case 3:
        case 6:
            cfg.rc_max_quantizer = 45;
            cfg.rc_min_quantizer = 0;
            cfg.rc_target_bitrate = 215;
            flags |= VP8_EFLAG_NO_REF_LAST;
            flags |= VP8_EFLAG_FORCE_ARF;
            break;
    }
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PER_FRAME_CFG

Observing The Effects
---------------------
Use the `decode_with_drops` example to decode with various dropped frame
patterns. Good patterns to start with are 1/2, 3/4, 7/8, and 15/16
drops.