1 @TEMPLATE encoder_tmpl.c 2 VP8 Scalable Frame Patterns 3 =========================== 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION 5 This is an example demonstrating how to control the VP8 encoder's 6 reference frame selection and update mechanism for video applications 7 that benefit from a scalable bitstream. 8 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION 9 10 11 Configuration 12 ------------- 13 Scalable frame patterns are most useful in an error resilient context, 14 so error resiliency mode is enabled, as in the `error_resilient.c` 15 example. In addition, we want to disable automatic keyframe selection, 16 so we force an interval of 1000 frames. 17 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_SET_CFG2 18 19 /* Enable error resilient mode */ 20 cfg.g_error_resilient = 1; 21 cfg.g_lag_in_frames = 0; 22 cfg.kf_mode = VPX_KF_FIXED; 23 24 /* Disable automatic keyframe placement */ 25 cfg.kf_min_dist = cfg.kf_max_dist = 1000; 26 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_SET_CFG2 27 28 This example uses the following frame pattern (L->last_frame, 29 G->golden_frame, A->alt_ref_frame): 30 31 * Frame 0 Intra, use none, update L&G&A 32 * Frame 1 Inter, use LGA, update none 33 * Frame 2 Inter, use LGA, update L 34 * Frame 3 Inter, use LGA, update none 35 * Frame 4 Inter, use GA, update L&G 36 * Frame 5 Inter, use LGA, update none 37 * Frame 6 Inter, use LGA, update L 38 * Frame 7 Inter, use LGA, update none 39 * Frame 8 Inter, use A, update L&G&A 40 * Frame 9 Inter, use LGA, update none 41 * Frame 10 Inter, use LGA, update L 42 * Frame 11 Inter, use LGA, update none 43 * Frame 12 Inter, use GA, update L&G 44 * Frame 13 Inter, use LGA, update none 45 * Frame 14 Inter, use LGA, update L 46 * Frame 15 Inter, use LGA, update none 47 * ...Repeats the pattern from frame 0 48 49 Change this variable to test the 3 decodable streams case. 50 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS 51 int num_streams = 5; 52 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS 53 54 55 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PER_FRAME_CFG 56 flags = 0; 57 if(num_streams == 5) 58 { 59 switch(frame_cnt % 16) { 60 case 0: 61 flags |= VPX_EFLAG_FORCE_KF; 62 flags |= VP8_EFLAG_FORCE_GF; 63 flags |= VP8_EFLAG_FORCE_ARF; 64 break; 65 case 1: 66 case 3: 67 case 5: 68 case 7: 69 case 9: 70 case 11: 71 case 13: 72 case 15: 73 flags |= VP8_EFLAG_NO_UPD_LAST; 74 flags |= VP8_EFLAG_NO_UPD_GF; 75 flags |= VP8_EFLAG_NO_UPD_ARF; 76 break; 77 case 2: 78 case 6: 79 case 10: 80 case 14: 81 break; 82 case 4: 83 flags |= VP8_EFLAG_NO_REF_LAST; 84 flags |= VP8_EFLAG_FORCE_GF; 85 break; 86 case 8: 87 flags |= VP8_EFLAG_NO_REF_LAST; 88 flags |= VP8_EFLAG_NO_REF_GF; 89 flags |= VP8_EFLAG_FORCE_GF; 90 flags |= VP8_EFLAG_FORCE_ARF; 91 break; 92 case 12: 93 flags |= VP8_EFLAG_NO_REF_LAST; 94 flags |= VP8_EFLAG_FORCE_GF; 95 break; 96 } 97 } 98 else 99 { 100 switch(frame_cnt % 9) { 101 case 0: 102 if(frame_cnt==0) 103 { 104 flags |= VPX_EFLAG_FORCE_KF; 105 } 106 else 107 { 108 cfg.rc_max_quantizer = 26; 109 cfg.rc_min_quantizer = 0; 110 cfg.rc_target_bitrate = 300; 111 flags |= VP8_EFLAG_NO_REF_LAST; 112 flags |= VP8_EFLAG_NO_REF_ARF; 113 } 114 flags |= VP8_EFLAG_FORCE_GF; 115 flags |= VP8_EFLAG_FORCE_ARF; 116 break; 117 case 1: 118 case 2: 119 case 4: 120 case 5: 121 case 7: 122 case 8: 123 cfg.rc_max_quantizer = 45; 124 cfg.rc_min_quantizer = 0; 125 cfg.rc_target_bitrate = 230; 126 break; 127 case 3: 128 case 6: 129 cfg.rc_max_quantizer = 45; 130 cfg.rc_min_quantizer = 0; 131 cfg.rc_target_bitrate = 215; 132 flags |= VP8_EFLAG_NO_REF_LAST; 133 flags |= VP8_EFLAG_FORCE_ARF; 134 break; 135 } 136 } 137 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PER_FRAME_CFG 138 139 Observing The Effects 140 --------------------- 141 Use the `decode_with_drops` example to decode with various dropped frame 142 patterns. Good patterns to start with are 1/2, 3/4, 7/8, and 15/16 143 drops. 144