Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / libvpx / source / libvpx / examples / vpx_temporal_scalable_patterns.c
1 /*
2  *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 //  This is an example demonstrating how to implement a multi-layer VP9
12 //  encoding scheme based on temporal scalability for video applications
13 //  that benefit from a scalable bitstream.
14
15 #include <math.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #define VPX_CODEC_DISABLE_COMPAT 1
21 #include "vpx/vp8cx.h"
22 #include "vpx/vpx_encoder.h"
23
24 #include "./tools_common.h"
25 #include "./video_writer.h"
26
27 static const char *exec_name;
28
29 void usage_exit() {
30   exit(EXIT_FAILURE);
31 }
32
33 static int mode_to_num_layers[12] = {1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3};
34
35 // For rate control encoding stats.
36 struct RateControlMetrics {
37   // Number of input frames per layer.
38   int layer_input_frames[VPX_TS_MAX_LAYERS];
39   // Total (cumulative) number of encoded frames per layer.
40   int layer_tot_enc_frames[VPX_TS_MAX_LAYERS];
41   // Number of encoded non-key frames per layer.
42   int layer_enc_frames[VPX_TS_MAX_LAYERS];
43   // Framerate per layer layer (cumulative).
44   float layer_framerate[VPX_TS_MAX_LAYERS];
45   // Target average frame size per layer (per-frame-bandwidth per layer).
46   float layer_pfb[VPX_TS_MAX_LAYERS];
47   // Actual average frame size per layer.
48   float layer_avg_frame_size[VPX_TS_MAX_LAYERS];
49   // Average rate mismatch per layer (|target - actual| / target).
50   float layer_avg_rate_mismatch[VPX_TS_MAX_LAYERS];
51   // Actual encoding bitrate per layer (cumulative).
52   float layer_encoding_bitrate[VPX_TS_MAX_LAYERS];
53 };
54
55 static void set_rate_control_metrics(struct RateControlMetrics *rc,
56                                      vpx_codec_enc_cfg_t *cfg) {
57   int i = 0;
58   // Set the layer (cumulative) framerate and the target layer (non-cumulative)
59   // per-frame-bandwidth, for the rate control encoding stats below.
60   float framerate = cfg->g_timebase.den / cfg->g_timebase.num;
61   rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
62   rc->layer_pfb[0] = 1000.0 * cfg->ts_target_bitrate[0] /
63       rc->layer_framerate[0];
64   for (i = 0; i < cfg->ts_number_layers; ++i) {
65     if (i > 0) {
66       rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
67       rc->layer_pfb[i] = 1000.0 *
68           (cfg->ts_target_bitrate[i] - cfg->ts_target_bitrate[i - 1]) /
69           (rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
70     }
71     rc->layer_input_frames[i] = 0;
72     rc->layer_enc_frames[i] = 0;
73     rc->layer_tot_enc_frames[i] = 0;
74     rc->layer_encoding_bitrate[i] = 0.0;
75     rc->layer_avg_frame_size[i] = 0.0;
76     rc->layer_avg_rate_mismatch[i] = 0.0;
77   }
78 }
79
80 static void printout_rate_control_summary(struct RateControlMetrics *rc,
81                                           vpx_codec_enc_cfg_t *cfg,
82                                           int frame_cnt) {
83   int i = 0;
84   int check_num_frames = 0;
85   printf("Total number of processed frames: %d\n\n", frame_cnt -1);
86   printf("Rate control layer stats for %d layer(s):\n\n",
87       cfg->ts_number_layers);
88   for (i = 0; i < cfg->ts_number_layers; ++i) {
89     const int num_dropped = (i > 0) ?
90         (rc->layer_input_frames[i] - rc->layer_enc_frames[i]) :
91         (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1);
92     rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] *
93         rc->layer_encoding_bitrate[i] / rc->layer_tot_enc_frames[i];
94     rc->layer_avg_frame_size[i] = rc->layer_avg_frame_size[i] /
95         rc->layer_enc_frames[i];
96     rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] /
97         rc->layer_enc_frames[i];
98     printf("For layer#: %d \n", i);
99     printf("Bitrate (target vs actual): %d %f \n", cfg->ts_target_bitrate[i],
100            rc->layer_encoding_bitrate[i]);
101     printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i],
102            rc->layer_avg_frame_size[i]);
103     printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]);
104     printf("Number of input frames, encoded (non-key) frames, "
105         "and perc dropped frames: %d %d %f \n", rc->layer_input_frames[i],
106         rc->layer_enc_frames[i],
107         100.0 * num_dropped / rc->layer_input_frames[i]);
108     check_num_frames += rc->layer_input_frames[i];
109     printf("\n");
110   }
111   if ((frame_cnt - 1) != check_num_frames)
112     die("Error: Number of input frames not equal to output! \n");
113 }
114
115 // Temporal scaling parameters:
116 // NOTE: The 3 prediction frames cannot be used interchangeably due to
117 // differences in the way they are handled throughout the code. The
118 // frames should be allocated to layers in the order LAST, GF, ARF.
119 // Other combinations work, but may produce slightly inferior results.
120 static void set_temporal_layer_pattern(int layering_mode,
121                                        vpx_codec_enc_cfg_t *cfg,
122                                        int *layer_flags,
123                                        int *flag_periodicity) {
124   switch (layering_mode) {
125     case 0: {
126       // 1-layer.
127       int ids[1] = {0};
128       cfg->ts_periodicity = 1;
129       *flag_periodicity = 1;
130       cfg->ts_number_layers = 1;
131       cfg->ts_rate_decimator[0] = 1;
132       memcpy(cfg->ts_layer_id, ids, sizeof(ids));
133       // Update L only.
134       layer_flags[0] = VPX_EFLAG_FORCE_KF  | VP8_EFLAG_NO_UPD_GF |
135           VP8_EFLAG_NO_UPD_ARF;
136       break;
137     }
138     case 1: {
139       // 2-layers, 2-frame period.
140       int ids[2] = {0, 1};
141       cfg->ts_periodicity = 2;
142       *flag_periodicity = 2;
143       cfg->ts_number_layers = 2;
144       cfg->ts_rate_decimator[0] = 2;
145       cfg->ts_rate_decimator[1] = 1;
146       memcpy(cfg->ts_layer_id, ids, sizeof(ids));
147 #if 1
148       // 0=L, 1=GF, Intra-layer prediction enabled.
149       layer_flags[0] = VPX_EFLAG_FORCE_KF  | VP8_EFLAG_NO_UPD_GF |
150           VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
151       layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
152           VP8_EFLAG_NO_REF_ARF;
153 #else
154        // 0=L, 1=GF, Intra-layer prediction disabled.
155       layer_flags[0] = VPX_EFLAG_FORCE_KF  | VP8_EFLAG_NO_UPD_GF |
156           VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
157       layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
158           VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_LAST;
159 #endif
160       break;
161     }
162     case 2: {
163       // 2-layers, 3-frame period.
164       int ids[3] = {0, 1, 1};
165       cfg->ts_periodicity = 3;
166       *flag_periodicity = 3;
167       cfg->ts_number_layers = 2;
168       cfg->ts_rate_decimator[0] = 3;
169       cfg->ts_rate_decimator[1] = 1;
170       memcpy(cfg->ts_layer_id, ids, sizeof(ids));
171       // 0=L, 1=GF, Intra-layer prediction enabled.
172       layer_flags[0] = VPX_EFLAG_FORCE_KF  | VP8_EFLAG_NO_REF_GF |
173           VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
174       layer_flags[1] =
175       layer_flags[2] = VP8_EFLAG_NO_REF_GF  | VP8_EFLAG_NO_REF_ARF |
176           VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
177       break;
178     }
179     case 3: {
180       // 3-layers, 6-frame period.
181       int ids[6] = {0, 2, 2, 1, 2, 2};
182       cfg->ts_periodicity = 6;
183       *flag_periodicity = 6;
184       cfg->ts_number_layers = 3;
185       cfg->ts_rate_decimator[0] = 6;
186       cfg->ts_rate_decimator[1] = 3;
187       cfg->ts_rate_decimator[2] = 1;
188       memcpy(cfg->ts_layer_id, ids, sizeof(ids));
189       // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
190       layer_flags[0] = VPX_EFLAG_FORCE_KF  | VP8_EFLAG_NO_REF_GF |
191           VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
192       layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
193           VP8_EFLAG_NO_UPD_LAST;
194       layer_flags[1] =
195       layer_flags[2] =
196       layer_flags[4] =
197       layer_flags[5] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
198       break;
199     }
200     case 4: {
201       // 3-layers, 4-frame period.
202       int ids[4] = {0, 2, 1, 2};
203       cfg->ts_periodicity = 4;
204       *flag_periodicity = 4;
205       cfg->ts_number_layers = 3;
206       cfg->ts_rate_decimator[0] = 4;
207       cfg->ts_rate_decimator[1] = 2;
208       cfg->ts_rate_decimator[2] = 1;
209       memcpy(cfg->ts_layer_id, ids, sizeof(ids));
210       // 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled.
211       layer_flags[0] = VPX_EFLAG_FORCE_KF  | VP8_EFLAG_NO_REF_GF |
212           VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
213       layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
214           VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
215       layer_flags[1] =
216       layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
217           VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
218       break;
219     }
220     case 5: {
221       // 3-layers, 4-frame period.
222       int ids[4] = {0, 2, 1, 2};
223       cfg->ts_periodicity = 4;
224       *flag_periodicity = 4;
225       cfg->ts_number_layers     = 3;
226       cfg->ts_rate_decimator[0] = 4;
227       cfg->ts_rate_decimator[1] = 2;
228       cfg->ts_rate_decimator[2] = 1;
229       memcpy(cfg->ts_layer_id, ids, sizeof(ids));
230       // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled in layer 1, disabled
231       // in layer 2.
232       layer_flags[0] = VPX_EFLAG_FORCE_KF  | VP8_EFLAG_NO_REF_GF |
233           VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
234       layer_flags[2] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
235           VP8_EFLAG_NO_UPD_ARF;
236       layer_flags[1] =
237       layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
238           VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
239       break;
240     }
241     case 6: {
242       // 3-layers, 4-frame period.
243       int ids[4] = {0, 2, 1, 2};
244       cfg->ts_periodicity = 4;
245       *flag_periodicity = 4;
246       cfg->ts_number_layers = 3;
247       cfg->ts_rate_decimator[0] = 4;
248       cfg->ts_rate_decimator[1] = 2;
249       cfg->ts_rate_decimator[2] = 1;
250       memcpy(cfg->ts_layer_id, ids, sizeof(ids));
251       // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
252       layer_flags[0] = VPX_EFLAG_FORCE_KF  | VP8_EFLAG_NO_REF_GF |
253           VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
254       layer_flags[2] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
255           VP8_EFLAG_NO_UPD_ARF;
256       layer_flags[1] =
257       layer_flags[3] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
258       break;
259     }
260     case 7: {
261       // NOTE: Probably of academic interest only.
262       // 5-layers, 16-frame period.
263       int ids[16] = {0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4};
264       cfg->ts_periodicity = 16;
265       *flag_periodicity = 16;
266       cfg->ts_number_layers = 5;
267       cfg->ts_rate_decimator[0] = 16;
268       cfg->ts_rate_decimator[1] = 8;
269       cfg->ts_rate_decimator[2] = 4;
270       cfg->ts_rate_decimator[3] = 2;
271       cfg->ts_rate_decimator[4] = 1;
272       memcpy(cfg->ts_layer_id, ids, sizeof(ids));
273       layer_flags[0]  = VPX_EFLAG_FORCE_KF;
274       layer_flags[1]  =
275       layer_flags[3]  =
276       layer_flags[5]  =
277       layer_flags[7]  =
278       layer_flags[9]  =
279       layer_flags[11] =
280       layer_flags[13] =
281       layer_flags[15] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
282           VP8_EFLAG_NO_UPD_ARF;
283       layer_flags[2]  =
284       layer_flags[6]  =
285       layer_flags[10] =
286       layer_flags[14] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF;
287       layer_flags[4] =
288       layer_flags[12] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_ARF;
289       layer_flags[8]  = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF;
290       break;
291     }
292     case 8: {
293       // 2-layers, with sync point at first frame of layer 1.
294       int ids[2] = {0, 1};
295       cfg->ts_periodicity = 2;
296       *flag_periodicity = 8;
297       cfg->ts_number_layers = 2;
298       cfg->ts_rate_decimator[0] = 2;
299       cfg->ts_rate_decimator[1] = 1;
300       memcpy(cfg->ts_layer_id, ids, sizeof(ids));
301       // 0=L, 1=GF.
302       // ARF is used as predictor for all frames, and is only updated on
303       // key frame. Sync point every 8 frames.
304
305       // Layer 0: predict from L and ARF, update L and G.
306       layer_flags[0] = VPX_EFLAG_FORCE_KF  | VP8_EFLAG_NO_REF_GF |
307           VP8_EFLAG_NO_UPD_ARF;
308       // Layer 1: sync point: predict from L and ARF, and update G.
309       layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST |
310           VP8_EFLAG_NO_UPD_ARF;
311       // Layer 0, predict from L and ARF, update L.
312       layer_flags[2] = VP8_EFLAG_NO_REF_GF  | VP8_EFLAG_NO_UPD_GF |
313           VP8_EFLAG_NO_UPD_ARF;
314       // Layer 1: predict from L, G and ARF, and update G.
315       layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
316           VP8_EFLAG_NO_UPD_ENTROPY;
317       // Layer 0.
318       layer_flags[4] = layer_flags[2];
319       // Layer 1.
320       layer_flags[5] = layer_flags[3];
321       // Layer 0.
322       layer_flags[6] = layer_flags[4];
323       // Layer 1.
324       layer_flags[7] = layer_flags[5];
325      break;
326     }
327     case 9: {
328       // 3-layers: Sync points for layer 1 and 2 every 8 frames.
329       int ids[4] = {0, 2, 1, 2};
330       cfg->ts_periodicity = 4;
331       *flag_periodicity = 8;
332       cfg->ts_number_layers = 3;
333       cfg->ts_rate_decimator[0] = 4;
334       cfg->ts_rate_decimator[1] = 2;
335       cfg->ts_rate_decimator[2] = 1;
336       memcpy(cfg->ts_layer_id, ids, sizeof(ids));
337       // 0=L, 1=GF, 2=ARF.
338       layer_flags[0] = VPX_EFLAG_FORCE_KF  | VP8_EFLAG_NO_REF_GF |
339           VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
340       layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
341           VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
342       layer_flags[2] = VP8_EFLAG_NO_REF_GF   | VP8_EFLAG_NO_REF_ARF |
343           VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
344       layer_flags[3] =
345       layer_flags[5] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
346       layer_flags[4] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
347           VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
348       layer_flags[6] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
349           VP8_EFLAG_NO_UPD_ARF;
350       layer_flags[7] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
351           VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_ENTROPY;
352       break;
353     }
354     case 10: {
355       // 3-layers structure where ARF is used as predictor for all frames,
356       // and is only updated on key frame.
357       // Sync points for layer 1 and 2 every 8 frames.
358
359       int ids[4] = {0, 2, 1, 2};
360       cfg->ts_periodicity = 4;
361       *flag_periodicity = 8;
362       cfg->ts_number_layers = 3;
363       cfg->ts_rate_decimator[0] = 4;
364       cfg->ts_rate_decimator[1] = 2;
365       cfg->ts_rate_decimator[2] = 1;
366       memcpy(cfg->ts_layer_id, ids, sizeof(ids));
367       // 0=L, 1=GF, 2=ARF.
368       // Layer 0: predict from L and ARF; update L and G.
369       layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_ARF |
370           VP8_EFLAG_NO_REF_GF;
371       // Layer 2: sync point: predict from L and ARF; update none.
372       layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
373           VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
374           VP8_EFLAG_NO_UPD_ENTROPY;
375       // Layer 1: sync point: predict from L and ARF; update G.
376       layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF |
377           VP8_EFLAG_NO_UPD_LAST;
378       // Layer 2: predict from L, G, ARF; update none.
379       layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
380           VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
381       // Layer 0: predict from L and ARF; update L.
382       layer_flags[4] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
383           VP8_EFLAG_NO_REF_GF;
384       // Layer 2: predict from L, G, ARF; update none.
385       layer_flags[5] = layer_flags[3];
386       // Layer 1: predict from L, G, ARF; update G.
387       layer_flags[6] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
388       // Layer 2: predict from L, G, ARF; update none.
389       layer_flags[7] = layer_flags[3];
390       break;
391     }
392     case 11:
393     default: {
394       // 3-layers structure as in case 10, but no sync/refresh points for
395       // layer 1 and 2.
396       int ids[4] = {0, 2, 1, 2};
397       cfg->ts_periodicity = 4;
398       *flag_periodicity = 8;
399       cfg->ts_number_layers = 3;
400       cfg->ts_rate_decimator[0] = 4;
401       cfg->ts_rate_decimator[1] = 2;
402       cfg->ts_rate_decimator[2] = 1;
403       memcpy(cfg->ts_layer_id, ids, sizeof(ids));
404       // 0=L, 1=GF, 2=ARF.
405       // Layer 0: predict from L and ARF; update L.
406       layer_flags[0] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
407           VP8_EFLAG_NO_REF_GF;
408       layer_flags[4] = layer_flags[0];
409       // Layer 1: predict from L, G, ARF; update G.
410       layer_flags[2] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
411       layer_flags[6] = layer_flags[2];
412       // Layer 2: predict from L, G, ARF; update none.
413       layer_flags[1] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
414           VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
415       layer_flags[3] = layer_flags[1];
416       layer_flags[5] = layer_flags[1];
417       layer_flags[7] = layer_flags[1];
418       break;
419     }
420   }
421 }
422
423 int main(int argc, char **argv) {
424   VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS];
425   vpx_codec_ctx_t codec;
426   vpx_codec_enc_cfg_t cfg;
427   int frame_cnt = 0;
428   vpx_image_t raw;
429   vpx_codec_err_t res;
430   unsigned int width;
431   unsigned int height;
432   int frame_avail;
433   int got_data;
434   int flags = 0;
435   int i;
436   int pts = 0;  // PTS starts at 0.
437   int frame_duration = 1;  // 1 timebase tick per frame.
438   int layering_mode = 0;
439   int layer_flags[VPX_TS_MAX_PERIODICITY] = {0};
440   int flag_periodicity = 1;
441   int max_intra_size_pct;
442   vpx_svc_layer_id_t layer_id = {0, 0};
443   const VpxInterface *encoder = NULL;
444   FILE *infile = NULL;
445   struct RateControlMetrics rc;
446
447   exec_name = argv[0];
448   // Check usage and arguments.
449   if (argc < 11) {
450     die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
451         "<rate_num> <rate_den>  <frame_drop_threshold> <mode> "
452         "<Rate_0> ... <Rate_nlayers-1> \n", argv[0]);
453   }
454
455   encoder = get_vpx_encoder_by_name(argv[3]);
456   if (!encoder)
457     die("Unsupported codec.");
458
459   printf("Using %s\n", vpx_codec_iface_name(encoder->interface()));
460
461   width = strtol(argv[4], NULL, 0);
462   height = strtol(argv[5], NULL, 0);
463   if (width < 16 || width % 2 || height < 16 || height % 2) {
464     die("Invalid resolution: %d x %d", width, height);
465   }
466
467   layering_mode = strtol(argv[9], NULL, 0);
468   if (layering_mode < 0 || layering_mode > 12) {
469     die("Invalid mode (0..12) %s", argv[9]);
470   }
471
472   if (argc != 10 + mode_to_num_layers[layering_mode]) {
473     die("Invalid number of arguments");
474   }
475
476   if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
477     die("Failed to allocate image", width, height);
478   }
479
480   // Populate encoder configuration.
481   res = vpx_codec_enc_config_default(encoder->interface(), &cfg, 0);
482   if (res) {
483     printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
484     return EXIT_FAILURE;
485   }
486
487   // Update the default configuration with our settings.
488   cfg.g_w = width;
489   cfg.g_h = height;
490
491   // Timebase format e.g. 30fps: numerator=1, demoninator = 30.
492   cfg.g_timebase.num = strtol(argv[6], NULL, 0);
493   cfg.g_timebase.den = strtol(argv[7], NULL, 0);
494
495   for (i = 10; i < 10 + mode_to_num_layers[layering_mode]; ++i) {
496     cfg.ts_target_bitrate[i - 10] = strtol(argv[i], NULL, 0);
497   }
498
499   // Real time parameters.
500   cfg.rc_dropframe_thresh = strtol(argv[8], NULL, 0);
501   cfg.rc_end_usage = VPX_CBR;
502   cfg.rc_resize_allowed = 0;
503   cfg.rc_min_quantizer = 2;
504   cfg.rc_max_quantizer = 56;
505   cfg.rc_undershoot_pct = 50;
506   cfg.rc_overshoot_pct = 50;
507   cfg.rc_buf_initial_sz = 500;
508   cfg.rc_buf_optimal_sz = 600;
509   cfg.rc_buf_sz = 1000;
510
511   // Enable error resilient mode.
512   cfg.g_error_resilient = 1;
513   cfg.g_lag_in_frames   = 0;
514   cfg.kf_mode = VPX_KF_DISABLED;
515
516   // Disable automatic keyframe placement.
517   cfg.kf_min_dist = cfg.kf_max_dist = 3000;
518
519   // Default setting for bitrate: used in special case of 1 layer (case 0).
520   cfg.rc_target_bitrate = cfg.ts_target_bitrate[0];
521
522   set_temporal_layer_pattern(layering_mode,
523                              &cfg,
524                              layer_flags,
525                              &flag_periodicity);
526
527   set_rate_control_metrics(&rc, &cfg);
528
529   // Open input file.
530   if (!(infile = fopen(argv[1], "rb"))) {
531     die("Failed to open %s for reading", argv[1]);
532   }
533
534   // Open an output file for each stream.
535   for (i = 0; i < cfg.ts_number_layers; ++i) {
536     char file_name[PATH_MAX];
537     VpxVideoInfo info;
538     info.codec_fourcc = encoder->fourcc;
539     info.frame_width = cfg.g_w;
540     info.frame_height = cfg.g_h;
541     info.time_base.numerator = cfg.g_timebase.num;
542     info.time_base.denominator = cfg.g_timebase.den;
543
544     snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i);
545     outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info);
546     if (!outfile[i])
547       die("Failed to open %s for writing", file_name);
548   }
549   // No spatial layers in this encoder.
550   cfg.ss_number_layers = 1;
551
552   // Initialize codec.
553   if (vpx_codec_enc_init(&codec, encoder->interface(), &cfg, 0))
554     die_codec(&codec, "Failed to initialize encoder");
555
556   vpx_codec_control(&codec, VP8E_SET_CPUUSED, -6);
557   vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, 1);
558   if (strncmp(encoder->name, "vp9", 3) == 0) {
559     vpx_codec_control(&codec, VP8E_SET_CPUUSED, 3);
560     vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, 0);
561     if (vpx_codec_control(&codec, VP9E_SET_SVC, 1)) {
562       die_codec(&codec, "Failed to set SVC");
563     }
564   }
565   vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
566   vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1);
567   max_intra_size_pct = (int) (((double)cfg.rc_buf_optimal_sz * 0.5)
568       * ((double) cfg.g_timebase.den / cfg.g_timebase.num) / 10.0);
569   vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, max_intra_size_pct);
570
571   frame_avail = 1;
572   while (frame_avail || got_data) {
573     vpx_codec_iter_t iter = NULL;
574     const vpx_codec_cx_pkt_t *pkt;
575     // Update the temporal layer_id. No spatial layers in this test.
576     layer_id.spatial_layer_id = 0;
577     layer_id.temporal_layer_id =
578         cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
579     if (strncmp(encoder->name, "vp9", 3) == 0) {
580       vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
581     }
582     flags = layer_flags[frame_cnt % flag_periodicity];
583     frame_avail = vpx_img_read(&raw, infile);
584     if (frame_avail)
585       ++rc.layer_input_frames[layer_id.temporal_layer_id];
586     if (vpx_codec_encode(&codec, frame_avail? &raw : NULL, pts, 1, flags,
587         VPX_DL_REALTIME)) {
588       die_codec(&codec, "Failed to encode frame");
589     }
590     // Reset KF flag.
591     if (layering_mode != 7) {
592       layer_flags[0] &= ~VPX_EFLAG_FORCE_KF;
593     }
594     got_data = 0;
595     while ( (pkt = vpx_codec_get_cx_data(&codec, &iter)) ) {
596       got_data = 1;
597       switch (pkt->kind) {
598         case VPX_CODEC_CX_FRAME_PKT:
599           for (i = cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
600               i < cfg.ts_number_layers; ++i) {
601             vpx_video_writer_write_frame(outfile[i], pkt->data.frame.buf,
602                                          pkt->data.frame.sz, pts);
603             ++rc.layer_tot_enc_frames[i];
604             rc.layer_encoding_bitrate[i] += 8.0 * pkt->data.frame.sz;
605             // Keep count of rate control stats per layer (for non-key frames).
606             if (i == cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity] &&
607                 !(pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
608               rc.layer_avg_frame_size[i] += 8.0 * pkt->data.frame.sz;
609               rc.layer_avg_rate_mismatch[i] +=
610                   fabs(8.0 * pkt->data.frame.sz - rc.layer_pfb[i]) /
611                   rc.layer_pfb[i];
612               ++rc.layer_enc_frames[i];
613             }
614           }
615           break;
616           default:
617             break;
618       }
619     }
620     ++frame_cnt;
621     pts += frame_duration;
622   }
623   fclose(infile);
624   printout_rate_control_summary(&rc, &cfg, frame_cnt);
625
626   if (vpx_codec_destroy(&codec))
627     die_codec(&codec, "Failed to destroy codec");
628
629   // Try to rewrite the output file headers with the actual frame count.
630   for (i = 0; i < cfg.ts_number_layers; ++i)
631     vpx_video_writer_close(outfile[i]);
632
633   return EXIT_SUCCESS;
634 }