WebM Codec SDK

vpx_temporal_svc_encoder
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 VPx
12 // encoding scheme based on temporal scalability for video applications
13 // that benefit from a scalable bitstream.
14
15 #include <assert.h>
16 #include <math.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 #include "./vpx_config.h"
22 #include "../vpx_ports/vpx_timer.h"
23 #include "vpx/vp8cx.h"
24 #include "vpx/vpx_encoder.h"
25 #include "vpx_ports/bitops.h"
26
27 #include "../tools_common.h"
28 #include "../video_writer.h"
29
30 #define ROI_MAP 0
31
32 #define zero(Dest) memset(&Dest, 0, sizeof(Dest));
33
34 static const char *exec_name;
35
36 void usage_exit(void) { exit(EXIT_FAILURE); }
37
38 // Denoiser states for vp8, for temporal denoising.
39 enum denoiserStateVp8 {
40 kVp8DenoiserOff,
41 kVp8DenoiserOnYOnly,
42 kVp8DenoiserOnYUV,
43 kVp8DenoiserOnYUVAggressive,
44 kVp8DenoiserOnAdaptive
45 };
46
47 // Denoiser states for vp9, for temporal denoising.
48 enum denoiserStateVp9 {
49 kVp9DenoiserOff,
50 kVp9DenoiserOnYOnly,
51 // For SVC: denoise the top two spatial layers.
52 kVp9DenoiserOnYTwoSpatialLayers
53 };
54
55 static int mode_to_num_layers[13] = { 1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3 };
56
57 // For rate control encoding stats.
58 struct RateControlMetrics {
59 // Number of input frames per layer.
60 int layer_input_frames[VPX_TS_MAX_LAYERS];
61 // Total (cumulative) number of encoded frames per layer.
62 int layer_tot_enc_frames[VPX_TS_MAX_LAYERS];
63 // Number of encoded non-key frames per layer.
64 int layer_enc_frames[VPX_TS_MAX_LAYERS];
65 // Framerate per layer layer (cumulative).
66 double layer_framerate[VPX_TS_MAX_LAYERS];
67 // Target average frame size per layer (per-frame-bandwidth per layer).
68 double layer_pfb[VPX_TS_MAX_LAYERS];
69 // Actual average frame size per layer.
70 double layer_avg_frame_size[VPX_TS_MAX_LAYERS];
71 // Average rate mismatch per layer (|target - actual| / target).
72 double layer_avg_rate_mismatch[VPX_TS_MAX_LAYERS];
73 // Actual encoding bitrate per layer (cumulative).
74 double layer_encoding_bitrate[VPX_TS_MAX_LAYERS];
75 // Average of the short-time encoder actual bitrate.
76 // TODO(marpan): Should we add these short-time stats for each layer?
77 double avg_st_encoding_bitrate;
78 // Variance of the short-time encoder actual bitrate.
79 double variance_st_encoding_bitrate;
80 // Window (number of frames) for computing short-timee encoding bitrate.
81 int window_size;
82 // Number of window measurements.
83 int window_count;
84 int layer_target_bitrate[VPX_MAX_LAYERS];
85 };
86
87 // Note: these rate control metrics assume only 1 key frame in the
88 // sequence (i.e., first frame only). So for temporal pattern# 7
89 // (which has key frame for every frame on base layer), the metrics
90 // computation will be off/wrong.
91 // TODO(marpan): Update these metrics to account for multiple key frames
92 // in the stream.
93 static void set_rate_control_metrics(struct RateControlMetrics *rc,
94 vpx_codec_enc_cfg_t *cfg) {
95 unsigned int i = 0;
96 // Set the layer (cumulative) framerate and the target layer (non-cumulative)
97 // per-frame-bandwidth, for the rate control encoding stats below.
98 const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
99 rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
100 rc->layer_pfb[0] =
101 1000.0 * rc->layer_target_bitrate[0] / rc->layer_framerate[0];
102 for (i = 0; i < cfg->ts_number_layers; ++i) {
103 if (i > 0) {
104 rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
105 rc->layer_pfb[i] =
106 1000.0 *
107 (rc->layer_target_bitrate[i] - rc->layer_target_bitrate[i - 1]) /
108 (rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
109 }
110 rc->layer_input_frames[i] = 0;
111 rc->layer_enc_frames[i] = 0;
112 rc->layer_tot_enc_frames[i] = 0;
113 rc->layer_encoding_bitrate[i] = 0.0;
114 rc->layer_avg_frame_size[i] = 0.0;
115 rc->layer_avg_rate_mismatch[i] = 0.0;
116 }
117 rc->window_count = 0;
118 rc->window_size = 15;
119 rc->avg_st_encoding_bitrate = 0.0;
120 rc->variance_st_encoding_bitrate = 0.0;
121 }
122
123 static void printout_rate_control_summary(struct RateControlMetrics *rc,
124 vpx_codec_enc_cfg_t *cfg,
125 int frame_cnt) {
126 unsigned int i = 0;
127 int tot_num_frames = 0;
128 double perc_fluctuation = 0.0;
129 printf("Total number of processed frames: %d\n\n", frame_cnt - 1);
130 printf("Rate control layer stats for %d layer(s):\n\n",
131 cfg->ts_number_layers);
132 for (i = 0; i < cfg->ts_number_layers; ++i) {
133 const int num_dropped =
134 (i > 0) ? (rc->layer_input_frames[i] - rc->layer_enc_frames[i])
135 : (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1);
136 tot_num_frames += rc->layer_input_frames[i];
137 rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] *
138 rc->layer_encoding_bitrate[i] /
139 tot_num_frames;
140 rc->layer_avg_frame_size[i] =
141 rc->layer_avg_frame_size[i] / rc->layer_enc_frames[i];
142 rc->layer_avg_rate_mismatch[i] =
143 100.0 * rc->layer_avg_rate_mismatch[i] / rc->layer_enc_frames[i];
144 printf("For layer#: %d \n", i);
145 printf("Bitrate (target vs actual): %d %f \n", rc->layer_target_bitrate[i],
146 rc->layer_encoding_bitrate[i]);
147 printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i],
148 rc->layer_avg_frame_size[i]);
149 printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]);
150 printf(
151 "Number of input frames, encoded (non-key) frames, "
152 "and perc dropped frames: %d %d %f \n",
153 rc->layer_input_frames[i], rc->layer_enc_frames[i],
154 100.0 * num_dropped / rc->layer_input_frames[i]);
155 printf("\n");
156 }
157 rc->avg_st_encoding_bitrate = rc->avg_st_encoding_bitrate / rc->window_count;
158 rc->variance_st_encoding_bitrate =
159 rc->variance_st_encoding_bitrate / rc->window_count -
160 (rc->avg_st_encoding_bitrate * rc->avg_st_encoding_bitrate);
161 perc_fluctuation = 100.0 * sqrt(rc->variance_st_encoding_bitrate) /
162 rc->avg_st_encoding_bitrate;
163 printf("Short-time stats, for window of %d frames: \n", rc->window_size);
164 printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
165 rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate),
166 perc_fluctuation);
167 if ((frame_cnt - 1) != tot_num_frames)
168 die("Error: Number of input frames not equal to output! \n");
169 }
170
171 #if ROI_MAP
172 static void set_roi_map(const char *enc_name, vpx_codec_enc_cfg_t *cfg,
173 vpx_roi_map_t *roi) {
174 unsigned int i, j;
175 int block_size = 0;
176 uint8_t is_vp8 = strncmp(enc_name, "vp8", 3) == 0 ? 1 : 0;
177 uint8_t is_vp9 = strncmp(enc_name, "vp9", 3) == 0 ? 1 : 0;
178 if (!is_vp8 && !is_vp9) {
179 die("unsupported codec.");
180 }
181 zero(*roi);
182
183 block_size = is_vp9 && !is_vp8 ? 8 : 16;
184
185 // ROI is based on the segments (4 for vp8, 8 for vp9), smallest unit for
186 // segment is 16x16 for vp8, 8x8 for vp9.
187 roi->rows = (cfg->g_h + block_size - 1) / block_size;
188 roi->cols = (cfg->g_w + block_size - 1) / block_size;
189
190 // Applies delta QP on the segment blocks, varies from -63 to 63.
191 // Setting to negative means lower QP (better quality).
192 // Below we set delta_q to the extreme (-63) to show strong effect.
193 // VP8 uses the first 4 segments. VP9 uses all 8 segments.
194 zero(roi->delta_q);
195 roi->delta_q[1] = -63;
196
197 // Applies delta loopfilter strength on the segment blocks, varies from -63 to
198 // 63. Setting to positive means stronger loopfilter. VP8 uses the first 4
199 // segments. VP9 uses all 8 segments.
200 zero(roi->delta_lf);
201
202 if (is_vp8) {
203 // Applies skip encoding threshold on the segment blocks, varies from 0 to
204 // UINT_MAX. Larger value means more skipping of encoding is possible.
205 // This skip threshold only applies on delta frames.
206 zero(roi->static_threshold);
207 }
208
209 if (is_vp9) {
210 // Apply skip segment. Setting to 1 means this block will be copied from
211 // previous frame.
212 zero(roi->skip);
213 }
214
215 if (is_vp9) {
216 // Apply ref frame segment.
217 // -1 : Do not apply this segment.
218 // 0 : Froce using intra.
219 // 1 : Force using last.
220 // 2 : Force using golden.
221 // 3 : Force using alfref but not used in non-rd pickmode for 0 lag.
222 memset(roi->ref_frame, -1, sizeof(roi->ref_frame));
223 roi->ref_frame[1] = 1;
224 }
225
226 // Use 2 states: 1 is center square, 0 is the rest.
227 roi->roi_map =
228 (uint8_t *)calloc(roi->rows * roi->cols, sizeof(*roi->roi_map));
229 for (i = 0; i < roi->rows; ++i) {
230 for (j = 0; j < roi->cols; ++j) {
231 if (i > (roi->rows >> 2) && i < ((roi->rows * 3) >> 2) &&
232 j > (roi->cols >> 2) && j < ((roi->cols * 3) >> 2)) {
233 roi->roi_map[i * roi->cols + j] = 1;
234 }
235 }
236 }
237 }
238 #endif
239
240 // Temporal scaling parameters:
241 // NOTE: The 3 prediction frames cannot be used interchangeably due to
242 // differences in the way they are handled throughout the code. The
243 // frames should be allocated to layers in the order LAST, GF, ARF.
244 // Other combinations work, but may produce slightly inferior results.
245 static void set_temporal_layer_pattern(int layering_mode,
246 vpx_codec_enc_cfg_t *cfg,
247 int *layer_flags,
248 int *flag_periodicity) {
249 switch (layering_mode) {
250 case 0: {
251 // 1-layer.
252 int ids[1] = { 0 };
253 cfg->ts_periodicity = 1;
254 *flag_periodicity = 1;
255 cfg->ts_number_layers = 1;
256 cfg->ts_rate_decimator[0] = 1;
257 memcpy(cfg->ts_layer_id, ids, sizeof(ids));
258 // Update L only.
259 layer_flags[0] =
260 VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
261 break;
262 }
263 case 1: {
264 // 2-layers, 2-frame period.
265 int ids[2] = { 0, 1 };
266 cfg->ts_periodicity = 2;
267 *flag_periodicity = 2;
268 cfg->ts_number_layers = 2;
269 cfg->ts_rate_decimator[0] = 2;
270 cfg->ts_rate_decimator[1] = 1;
271 memcpy(cfg->ts_layer_id, ids, sizeof(ids));
272 #if 1
273 // 0=L, 1=GF, Intra-layer prediction enabled.
274 layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
275 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF |
276 VP8_EFLAG_NO_REF_ARF;
277 layer_flags[1] =
278 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF;
279 #else
280 // 0=L, 1=GF, Intra-layer prediction disabled.
281 layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
282 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF |
283 VP8_EFLAG_NO_REF_ARF;
284 layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
285 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_LAST;
286 #endif
287 break;
288 }
289 case 2: {
290 // 2-layers, 3-frame period.
291 int ids[3] = { 0, 1, 1 };
292 cfg->ts_periodicity = 3;
293 *flag_periodicity = 3;
294 cfg->ts_number_layers = 2;
295 cfg->ts_rate_decimator[0] = 3;
296 cfg->ts_rate_decimator[1] = 1;
297 memcpy(cfg->ts_layer_id, ids, sizeof(ids));
298 // 0=L, 1=GF, Intra-layer prediction enabled.
299 layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
300 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
301 VP8_EFLAG_NO_UPD_ARF;
302 layer_flags[1] = layer_flags[2] =
303 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
304 VP8_EFLAG_NO_UPD_LAST;
305 break;
306 }
307 case 3: {
308 // 3-layers, 6-frame period.
309 int ids[6] = { 0, 2, 2, 1, 2, 2 };
310 cfg->ts_periodicity = 6;
311 *flag_periodicity = 6;
312 cfg->ts_number_layers = 3;
313 cfg->ts_rate_decimator[0] = 6;
314 cfg->ts_rate_decimator[1] = 3;
315 cfg->ts_rate_decimator[2] = 1;
316 memcpy(cfg->ts_layer_id, ids, sizeof(ids));
317 // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
318 layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
319 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
320 VP8_EFLAG_NO_UPD_ARF;
321 layer_flags[3] =
322 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
323 layer_flags[1] = layer_flags[2] = layer_flags[4] = layer_flags[5] =
324 VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
325 break;
326 }
327 case 4: {
328 // 3-layers, 4-frame period.
329 int ids[4] = { 0, 2, 1, 2 };
330 cfg->ts_periodicity = 4;
331 *flag_periodicity = 4;
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, Intra-layer prediction disabled.
338 layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
339 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
340 VP8_EFLAG_NO_UPD_ARF;
341 layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
342 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
343 layer_flags[1] = layer_flags[3] =
344 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
345 VP8_EFLAG_NO_UPD_ARF;
346 break;
347 }
348 case 5: {
349 // 3-layers, 4-frame period.
350 int ids[4] = { 0, 2, 1, 2 };
351 cfg->ts_periodicity = 4;
352 *flag_periodicity = 4;
353 cfg->ts_number_layers = 3;
354 cfg->ts_rate_decimator[0] = 4;
355 cfg->ts_rate_decimator[1] = 2;
356 cfg->ts_rate_decimator[2] = 1;
357 memcpy(cfg->ts_layer_id, ids, sizeof(ids));
358 // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled in layer 1, disabled
359 // in layer 2.
360 layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
361 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
362 VP8_EFLAG_NO_UPD_ARF;
363 layer_flags[2] =
364 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
365 layer_flags[1] = layer_flags[3] =
366 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
367 VP8_EFLAG_NO_UPD_ARF;
368 break;
369 }
370 case 6: {
371 // 3-layers, 4-frame period.
372 int ids[4] = { 0, 2, 1, 2 };
373 cfg->ts_periodicity = 4;
374 *flag_periodicity = 4;
375 cfg->ts_number_layers = 3;
376 cfg->ts_rate_decimator[0] = 4;
377 cfg->ts_rate_decimator[1] = 2;
378 cfg->ts_rate_decimator[2] = 1;
379 memcpy(cfg->ts_layer_id, ids, sizeof(ids));
380 // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
381 layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
382 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
383 VP8_EFLAG_NO_UPD_ARF;
384 layer_flags[2] =
385 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
386 layer_flags[1] = layer_flags[3] =
387 VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
388 break;
389 }
390 case 7: {
391 // NOTE: Probably of academic interest only.
392 // 5-layers, 16-frame period.
393 int ids[16] = { 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4 };
394 cfg->ts_periodicity = 16;
395 *flag_periodicity = 16;
396 cfg->ts_number_layers = 5;
397 cfg->ts_rate_decimator[0] = 16;
398 cfg->ts_rate_decimator[1] = 8;
399 cfg->ts_rate_decimator[2] = 4;
400 cfg->ts_rate_decimator[3] = 2;
401 cfg->ts_rate_decimator[4] = 1;
402 memcpy(cfg->ts_layer_id, ids, sizeof(ids));
403 layer_flags[0] = VPX_EFLAG_FORCE_KF;
404 layer_flags[1] = layer_flags[3] = layer_flags[5] = layer_flags[7] =
405 layer_flags[9] = layer_flags[11] = layer_flags[13] = layer_flags[15] =
406 VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
407 VP8_EFLAG_NO_UPD_ARF;
408 layer_flags[2] = layer_flags[6] = layer_flags[10] = layer_flags[14] =
409 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF;
410 layer_flags[4] = layer_flags[12] =
411 VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_ARF;
412 layer_flags[8] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF;
413 break;
414 }
415 case 8: {
416 // 2-layers, with sync point at first frame of layer 1.
417 int ids[2] = { 0, 1 };
418 cfg->ts_periodicity = 2;
419 *flag_periodicity = 8;
420 cfg->ts_number_layers = 2;
421 cfg->ts_rate_decimator[0] = 2;
422 cfg->ts_rate_decimator[1] = 1;
423 memcpy(cfg->ts_layer_id, ids, sizeof(ids));
424 // 0=L, 1=GF.
425 // ARF is used as predictor for all frames, and is only updated on
426 // key frame. Sync point every 8 frames.
427
428 // Layer 0: predict from L and ARF, update L and G.
429 layer_flags[0] =
430 VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF;
431 // Layer 1: sync point: predict from L and ARF, and update G.
432 layer_flags[1] =
433 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
434 // Layer 0, predict from L and ARF, update L.
435 layer_flags[2] =
436 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
437 // Layer 1: predict from L, G and ARF, and update G.
438 layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
439 VP8_EFLAG_NO_UPD_ENTROPY;
440 // Layer 0.
441 layer_flags[4] = layer_flags[2];
442 // Layer 1.
443 layer_flags[5] = layer_flags[3];
444 // Layer 0.
445 layer_flags[6] = layer_flags[4];
446 // Layer 1.
447 layer_flags[7] = layer_flags[5];
448 break;
449 }
450 case 9: {
451 // 3-layers: Sync points for layer 1 and 2 every 8 frames.
452 int ids[4] = { 0, 2, 1, 2 };
453 cfg->ts_periodicity = 4;
454 *flag_periodicity = 8;
455 cfg->ts_number_layers = 3;
456 cfg->ts_rate_decimator[0] = 4;
457 cfg->ts_rate_decimator[1] = 2;
458 cfg->ts_rate_decimator[2] = 1;
459 memcpy(cfg->ts_layer_id, ids, sizeof(ids));
460 // 0=L, 1=GF, 2=ARF.
461 layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
462 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
463 VP8_EFLAG_NO_UPD_ARF;
464 layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
465 VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
466 layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
467 VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
468 layer_flags[3] = layer_flags[5] =
469 VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
470 layer_flags[4] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
471 VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
472 layer_flags[6] =
473 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
474 layer_flags[7] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
475 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_ENTROPY;
476 break;
477 }
478 case 10: {
479 // 3-layers structure where ARF is used as predictor for all frames,
480 // and is only updated on key frame.
481 // Sync points for layer 1 and 2 every 8 frames.
482
483 int ids[4] = { 0, 2, 1, 2 };
484 cfg->ts_periodicity = 4;
485 *flag_periodicity = 8;
486 cfg->ts_number_layers = 3;
487 cfg->ts_rate_decimator[0] = 4;
488 cfg->ts_rate_decimator[1] = 2;
489 cfg->ts_rate_decimator[2] = 1;
490 memcpy(cfg->ts_layer_id, ids, sizeof(ids));
491 // 0=L, 1=GF, 2=ARF.
492 // Layer 0: predict from L and ARF; update L and G.
493 layer_flags[0] =
494 VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
495 // Layer 2: sync point: predict from L and ARF; update none.
496 layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
497 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
498 VP8_EFLAG_NO_UPD_ENTROPY;
499 // Layer 1: sync point: predict from L and ARF; update G.
500 layer_flags[2] =
501 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
502 // Layer 2: predict from L, G, ARF; update none.
503 layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
504 VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
505 // Layer 0: predict from L and ARF; update L.
506 layer_flags[4] =
507 VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
508 // Layer 2: predict from L, G, ARF; update none.
509 layer_flags[5] = layer_flags[3];
510 // Layer 1: predict from L, G, ARF; update G.
511 layer_flags[6] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
512 // Layer 2: predict from L, G, ARF; update none.
513 layer_flags[7] = layer_flags[3];
514 break;
515 }
516 case 11: {
517 // 3-layers structure with one reference frame.
518 // This works same as temporal_layering_mode 3.
519 // This was added to compare with vp9_spatial_svc_encoder.
520
521 // 3-layers, 4-frame period.
522 int ids[4] = { 0, 2, 1, 2 };
523 cfg->ts_periodicity = 4;
524 *flag_periodicity = 4;
525 cfg->ts_number_layers = 3;
526 cfg->ts_rate_decimator[0] = 4;
527 cfg->ts_rate_decimator[1] = 2;
528 cfg->ts_rate_decimator[2] = 1;
529 memcpy(cfg->ts_layer_id, ids, sizeof(ids));
530 // 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled.
531 layer_flags[0] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
532 VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
533 layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
534 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
535 layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
536 VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
537 layer_flags[3] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_ARF |
538 VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
539 break;
540 }
541 case 12:
542 default: {
543 // 3-layers structure as in case 10, but no sync/refresh points for
544 // layer 1 and 2.
545 int ids[4] = { 0, 2, 1, 2 };
546 cfg->ts_periodicity = 4;
547 *flag_periodicity = 8;
548 cfg->ts_number_layers = 3;
549 cfg->ts_rate_decimator[0] = 4;
550 cfg->ts_rate_decimator[1] = 2;
551 cfg->ts_rate_decimator[2] = 1;
552 memcpy(cfg->ts_layer_id, ids, sizeof(ids));
553 // 0=L, 1=GF, 2=ARF.
554 // Layer 0: predict from L and ARF; update L.
555 layer_flags[0] =
556 VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
557 layer_flags[4] = layer_flags[0];
558 // Layer 1: predict from L, G, ARF; update G.
559 layer_flags[2] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
560 layer_flags[6] = layer_flags[2];
561 // Layer 2: predict from L, G, ARF; update none.
562 layer_flags[1] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
563 VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
564 layer_flags[3] = layer_flags[1];
565 layer_flags[5] = layer_flags[1];
566 layer_flags[7] = layer_flags[1];
567 break;
568 }
569 }
570 }
571
572 int main(int argc, char **argv) {
573 VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = { NULL };
574 vpx_codec_ctx_t codec;
575 vpx_codec_enc_cfg_t cfg;
576 int frame_cnt = 0;
577 vpx_image_t raw;
578 vpx_codec_err_t res;
579 unsigned int width;
580 unsigned int height;
581 uint32_t error_resilient = 0;
582 int speed;
583 int frame_avail;
584 int got_data;
585 int flags = 0;
586 unsigned int i;
587 int pts = 0; // PTS starts at 0.
588 int frame_duration = 1; // 1 timebase tick per frame.
589 int layering_mode = 0;
590 int layer_flags[VPX_TS_MAX_PERIODICITY] = { 0 };
591 int flag_periodicity = 1;
592 #if ROI_MAP
593 vpx_roi_map_t roi;
594 #endif
595 vpx_svc_layer_id_t layer_id;
596 const VpxInterface *encoder = NULL;
597 FILE *infile = NULL;
598 struct RateControlMetrics rc;
599 int64_t cx_time = 0;
600 const int min_args_base = 13;
601 #if CONFIG_VP9_HIGHBITDEPTH
602 vpx_bit_depth_t bit_depth = VPX_BITS_8;
603 int input_bit_depth = 8;
604 const int min_args = min_args_base + 1;
605 #else
606 const int min_args = min_args_base;
607 #endif // CONFIG_VP9_HIGHBITDEPTH
608 double sum_bitrate = 0.0;
609 double sum_bitrate2 = 0.0;
610 double framerate = 30.0;
611
612 zero(rc.layer_target_bitrate);
613 memset(&layer_id, 0, sizeof(vpx_svc_layer_id_t));
614 exec_name = argv[0];
615 // Check usage and arguments.
616 if (argc < min_args) {
617 #if CONFIG_VP9_HIGHBITDEPTH
618 die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
619 "<rate_num> <rate_den> <speed> <frame_drop_threshold> "
620 "<error_resilient> <threads> <mode> "
621 "<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n",
622 argv[0]);
623 #else
624 die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
625 "<rate_num> <rate_den> <speed> <frame_drop_threshold> "
626 "<error_resilient> <threads> <mode> "
627 "<Rate_0> ... <Rate_nlayers-1> \n",
628 argv[0]);
629 #endif // CONFIG_VP9_HIGHBITDEPTH
630 }
631
632 encoder = get_vpx_encoder_by_name(argv[3]);
633 if (!encoder) die("Unsupported codec.");
634
635 printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
636
637 width = (unsigned int)strtoul(argv[4], NULL, 0);
638 height = (unsigned int)strtoul(argv[5], NULL, 0);
639 if (width < 16 || width % 2 || height < 16 || height % 2) {
640 die("Invalid resolution: %d x %d", width, height);
641 }
642
643 layering_mode = (int)strtol(argv[12], NULL, 0);
644 if (layering_mode < 0 || layering_mode > 13) {
645 die("Invalid layering mode (0..12) %s", argv[12]);
646 }
647
648 if (argc != min_args + mode_to_num_layers[layering_mode]) {
649 die("Invalid number of arguments");
650 }
651
652 #if CONFIG_VP9_HIGHBITDEPTH
653 switch (strtol(argv[argc - 1], NULL, 0)) {
654 case 8:
655 bit_depth = VPX_BITS_8;
656 input_bit_depth = 8;
657 break;
658 case 10:
659 bit_depth = VPX_BITS_10;
660 input_bit_depth = 10;
661 break;
662 case 12:
663 bit_depth = VPX_BITS_12;
664 input_bit_depth = 12;
665 break;
666 default: die("Invalid bit depth (8, 10, 12) %s", argv[argc - 1]);
667 }
668 if (!vpx_img_alloc(
669 &raw, bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016,
670 width, height, 32)) {
671 die("Failed to allocate image", width, height);
672 }
673 #else
674 if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
675 die("Failed to allocate image", width, height);
676 }
677 #endif // CONFIG_VP9_HIGHBITDEPTH
678
679 // Populate encoder configuration.
680 res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
681 if (res) {
682 printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
683 return EXIT_FAILURE;
684 }
685
686 // Update the default configuration with our settings.
687 cfg.g_w = width;
688 cfg.g_h = height;
689
690 #if CONFIG_VP9_HIGHBITDEPTH
691 if (bit_depth != VPX_BITS_8) {
692 cfg.g_bit_depth = bit_depth;
693 cfg.g_input_bit_depth = input_bit_depth;
694 cfg.g_profile = 2;
695 }
696 #endif // CONFIG_VP9_HIGHBITDEPTH
697
698 // Timebase format e.g. 30fps: numerator=1, demoninator = 30.
699 cfg.g_timebase.num = (int)strtol(argv[6], NULL, 0);
700 cfg.g_timebase.den = (int)strtol(argv[7], NULL, 0);
701
702 speed = (int)strtol(argv[8], NULL, 0);
703 if (speed < 0) {
704 die("Invalid speed setting: must be positive");
705 }
706
707 for (i = min_args_base;
708 (int)i < min_args_base + mode_to_num_layers[layering_mode]; ++i) {
709 rc.layer_target_bitrate[i - 13] = (int)strtol(argv[i], NULL, 0);
710 if (strncmp(encoder->name, "vp8", 3) == 0)
711 cfg.ts_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
712 else if (strncmp(encoder->name, "vp9", 3) == 0)
713 cfg.layer_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
714 }
715
716 // Real time parameters.
717 cfg.rc_dropframe_thresh = (unsigned int)strtoul(argv[9], NULL, 0);
718 cfg.rc_end_usage = VPX_CBR;
719 cfg.rc_min_quantizer = 2;
720 cfg.rc_max_quantizer = 56;
721 if (strncmp(encoder->name, "vp9", 3) == 0) cfg.rc_max_quantizer = 52;
722 cfg.rc_undershoot_pct = 50;
723 cfg.rc_overshoot_pct = 50;
724 cfg.rc_buf_initial_sz = 600;
725 cfg.rc_buf_optimal_sz = 600;
726 cfg.rc_buf_sz = 1000;
727
728 // Disable dynamic resizing by default.
729 cfg.rc_resize_allowed = 0;
730
731 // Use 1 thread as default.
732 cfg.g_threads = (unsigned int)strtoul(argv[11], NULL, 0);
733
734 error_resilient = (uint32_t)strtoul(argv[10], NULL, 0);
735 if (error_resilient != 0 && error_resilient != 1) {
736 die("Invalid value for error resilient (0, 1): %d.", error_resilient);
737 }
738 // Enable error resilient mode.
739 cfg.g_error_resilient = error_resilient;
740 cfg.g_lag_in_frames = 0;
741 cfg.kf_mode = VPX_KF_AUTO;
742
743 // Disable automatic keyframe placement.
744 cfg.kf_min_dist = cfg.kf_max_dist = 3000;
745
746 cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
747
748 set_temporal_layer_pattern(layering_mode, &cfg, layer_flags,
749 &flag_periodicity);
750
751 set_rate_control_metrics(&rc, &cfg);
752
753 // Target bandwidth for the whole stream.
754 // Set to layer_target_bitrate for highest layer (total bitrate).
755 cfg.rc_target_bitrate = rc.layer_target_bitrate[cfg.ts_number_layers - 1];
756
757 // Open input file.
758 if (!(infile = fopen(argv[1], "rb"))) {
759 die("Failed to open %s for reading", argv[1]);
760 }
761
762 framerate = cfg.g_timebase.den / cfg.g_timebase.num;
763 // Open an output file for each stream.
764 for (i = 0; i < cfg.ts_number_layers; ++i) {
765 char file_name[PATH_MAX];
766 VpxVideoInfo info;
767 info.codec_fourcc = encoder->fourcc;
768 info.frame_width = cfg.g_w;
769 info.frame_height = cfg.g_h;
770 info.time_base.numerator = cfg.g_timebase.num;
771 info.time_base.denominator = cfg.g_timebase.den;
772
773 snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i);
774 outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info);
775 if (!outfile[i]) die("Failed to open %s for writing", file_name);
776
777 assert(outfile[i] != NULL);
778 }
779 // No spatial layers in this encoder.
780 cfg.ss_number_layers = 1;
781
782 // Initialize codec.
783 #if CONFIG_VP9_HIGHBITDEPTH
784 if (vpx_codec_enc_init(
785 &codec, encoder->codec_interface(), &cfg,
786 bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH))
787 #else
788 if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
789 #endif // CONFIG_VP9_HIGHBITDEPTH
790 die_codec(&codec, "Failed to initialize encoder");
791
792 if (strncmp(encoder->name, "vp8", 3) == 0) {
793 vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
794 vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kVp8DenoiserOff);
795 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
796 vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);
797 #if ROI_MAP
798 set_roi_map(encoder->name, &cfg, &roi);
799 if (vpx_codec_control(&codec, VP8E_SET_ROI_MAP, &roi))
800 die_codec(&codec, "Failed to set ROI map");
801 #endif
802
803 } else if (strncmp(encoder->name, "vp9", 3) == 0) {
804 vpx_svc_extra_cfg_t svc_params;
805 memset(&svc_params, 0, sizeof(svc_params));
806 vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
807 vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
808 vpx_codec_control(&codec, VP9E_SET_GF_CBR_BOOST_PCT, 0);
809 vpx_codec_control(&codec, VP9E_SET_FRAME_PARALLEL_DECODING, 0);
810 vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
811 vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kVp9DenoiserOff);
812 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
813 vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
814 vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, get_msb(cfg.g_threads));
815 #if ROI_MAP
816 set_roi_map(encoder->name, &cfg, &roi);
817 if (vpx_codec_control(&codec, VP9E_SET_ROI_MAP, &roi))
818 die_codec(&codec, "Failed to set ROI map");
819 vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 0);
820 #endif
821 // TODO(marpan/jianj): There is an issue with row-mt for low resolutons at
822 // high speed settings, disable its use for those cases for now.
823 if (cfg.g_threads > 1 && ((cfg.g_w > 320 && cfg.g_h > 240) || speed < 7))
824 vpx_codec_control(&codec, VP9E_SET_ROW_MT, 1);
825 else
826 vpx_codec_control(&codec, VP9E_SET_ROW_MT, 0);
827 if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1 : 0))
828 die_codec(&codec, "Failed to set SVC");
829 for (i = 0; i < cfg.ts_number_layers; ++i) {
830 svc_params.max_quantizers[i] = cfg.rc_max_quantizer;
831 svc_params.min_quantizers[i] = cfg.rc_min_quantizer;
832 }
833 svc_params.scaling_factor_num[0] = cfg.g_h;
834 svc_params.scaling_factor_den[0] = cfg.g_h;
835 vpx_codec_control(&codec, VP9E_SET_SVC_PARAMETERS, &svc_params);
836 }
837 if (strncmp(encoder->name, "vp8", 3) == 0) {
838 vpx_codec_control(&codec, VP8E_SET_SCREEN_CONTENT_MODE, 0);
839 }
840 vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1);
841 // This controls the maximum target size of the key frame.
842 // For generating smaller key frames, use a smaller max_intra_size_pct
843 // value, like 100 or 200.
844 {
845 const int max_intra_size_pct = 1000;
846 vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT,
847 max_intra_size_pct);
848 }
849
850 frame_avail = 1;
851 while (frame_avail || got_data) {
852 struct vpx_usec_timer timer;
853 vpx_codec_iter_t iter = NULL;
854 const vpx_codec_cx_pkt_t *pkt;
855 // Update the temporal layer_id. No spatial layers in this test.
856 layer_id.spatial_layer_id = 0;
857 layer_id.temporal_layer_id =
858 cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
859 layer_id.temporal_layer_id_per_spatial[0] = layer_id.temporal_layer_id;
860 if (strncmp(encoder->name, "vp9", 3) == 0) {
861 vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
862 } else if (strncmp(encoder->name, "vp8", 3) == 0) {
863 vpx_codec_control(&codec, VP8E_SET_TEMPORAL_LAYER_ID,
864 layer_id.temporal_layer_id);
865 }
866 flags = layer_flags[frame_cnt % flag_periodicity];
867 if (layering_mode == 0) flags = 0;
868 frame_avail = vpx_img_read(&raw, infile);
869 if (frame_avail) ++rc.layer_input_frames[layer_id.temporal_layer_id];
870 vpx_usec_timer_start(&timer);
871 if (vpx_codec_encode(&codec, frame_avail ? &raw : NULL, pts, 1, flags,
872 VPX_DL_REALTIME)) {
873 die_codec(&codec, "Failed to encode frame");
874 }
875 vpx_usec_timer_mark(&timer);
876 cx_time += vpx_usec_timer_elapsed(&timer);
877 // Reset KF flag.
878 if (layering_mode != 7) {
879 layer_flags[0] &= ~VPX_EFLAG_FORCE_KF;
880 }
881 got_data = 0;
882 while ((pkt = vpx_codec_get_cx_data(&codec, &iter))) {
883 got_data = 1;
884 switch (pkt->kind) {
885 case VPX_CODEC_CX_FRAME_PKT:
886 for (i = cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
887 i < cfg.ts_number_layers; ++i) {
888 vpx_video_writer_write_frame(outfile[i], pkt->data.frame.buf,
889 pkt->data.frame.sz, pts);
890 ++rc.layer_tot_enc_frames[i];
891 rc.layer_encoding_bitrate[i] += 8.0 * pkt->data.frame.sz;
892 // Keep count of rate control stats per layer (for non-key frames).
893 if (i == cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity] &&
894 !(pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
895 rc.layer_avg_frame_size[i] += 8.0 * pkt->data.frame.sz;
896 rc.layer_avg_rate_mismatch[i] +=
897 fabs(8.0 * pkt->data.frame.sz - rc.layer_pfb[i]) /
898 rc.layer_pfb[i];
899 ++rc.layer_enc_frames[i];
900 }
901 }
902 // Update for short-time encoding bitrate states, for moving window
903 // of size rc->window, shifted by rc->window / 2.
904 // Ignore first window segment, due to key frame.
905 if (frame_cnt > rc.window_size) {
906 sum_bitrate += 0.001 * 8.0 * pkt->data.frame.sz * framerate;
907 if (frame_cnt % rc.window_size == 0) {
908 rc.window_count += 1;
909 rc.avg_st_encoding_bitrate += sum_bitrate / rc.window_size;
910 rc.variance_st_encoding_bitrate +=
911 (sum_bitrate / rc.window_size) *
912 (sum_bitrate / rc.window_size);
913 sum_bitrate = 0.0;
914 }
915 }
916 // Second shifted window.
917 if (frame_cnt > rc.window_size + rc.window_size / 2) {
918 sum_bitrate2 += 0.001 * 8.0 * pkt->data.frame.sz * framerate;
919 if (frame_cnt > 2 * rc.window_size &&
920 frame_cnt % rc.window_size == 0) {
921 rc.window_count += 1;
922 rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
923 rc.variance_st_encoding_bitrate +=
924 (sum_bitrate2 / rc.window_size) *
925 (sum_bitrate2 / rc.window_size);
926 sum_bitrate2 = 0.0;
927 }
928 }
929 break;
930 default: break;
931 }
932 }
933 ++frame_cnt;
934 pts += frame_duration;
935 }
936 fclose(infile);
937 printout_rate_control_summary(&rc, &cfg, frame_cnt);
938 printf("\n");
939 printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
940 frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
941 1000000 * (double)frame_cnt / (double)cx_time);
942
943 if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
944
945 // Try to rewrite the output file headers with the actual frame count.
946 for (i = 0; i < cfg.ts_number_layers; ++i) vpx_video_writer_close(outfile[i]);
947
948 vpx_img_free(&raw);
949 #if ROI_MAP
950 free(roi.roi_map);
951 #endif
952 return EXIT_SUCCESS;
953 }
vpx_codec_enc_cfg::rc_buf_initial_sz
unsigned int rc_buf_initial_sz
Decoder Buffer Initial Size.
Definition: vpx_encoder.h:540
vpx_svc_parameters::min_quantizers
int min_quantizers[12]
Definition: vpx_encoder.h:703
vpx_roi_map::roi_map
unsigned char * roi_map
Definition: vp8cx.h:727
vpx_codec_enc_cfg::ts_number_layers
unsigned int ts_number_layers
Number of temporal coding layers.
Definition: vpx_encoder.h:644
VP8E_SET_CPUUSED
Codec control function to set encoder internal speed settings.
Definition: vp8cx.h:155
VPX_MAX_LAYERS
#define VPX_MAX_LAYERS
Definition: vpx_encoder.h:43
VP8_EFLAG_NO_REF_LAST
#define VP8_EFLAG_NO_REF_LAST
Don&#39;t reference the last frame.
Definition: vp8cx.h:58
VP8_EFLAG_NO_UPD_GF
#define VP8_EFLAG_NO_UPD_GF
Don&#39;t update the golden frame.
Definition: vp8cx.h:88
vpx_image
Image Descriptor.
Definition: vpx_image.h:71
vpx_encoder.h
Describes the encoder algorithm interface to applications.
vpx_codec_iface_name
const char * vpx_codec_iface_name(vpx_codec_iface_t *iface)
Return the name for a given interface.
vpx_codec_err_to_string
const char * vpx_codec_err_to_string(vpx_codec_err_t err)
Convert error number to printable string.
vpx_roi_map::delta_q
int delta_q[8]
Definition: vp8cx.h:731
VPX_TS_MAX_LAYERS
#define VPX_TS_MAX_LAYERS
Definition: vpx_encoder.h:40
VP9E_SET_TUNE_CONTENT
Codec control function to set content type.
Definition: vp8cx.h:460
vpx_codec_enc_cfg::g_timebase
struct vpx_rational g_timebase
Stream timebase units.
Definition: vpx_encoder.h:343
VPX_CBR
Definition: vpx_encoder.h:233
VP9E_SET_NOISE_SENSITIVITY
Codec control function to set noise sensitivity.
Definition: vp8cx.h:418
vpx_codec_enc_cfg::layer_target_bitrate
unsigned int layer_target_bitrate[12]
Target bitrate for each spatial/temporal layer.
Definition: vpx_encoder.h:684
vpx_roi_map::cols
unsigned int cols
Definition: vp8cx.h:729
vpx_codec_enc_cfg::rc_buf_sz
unsigned int rc_buf_sz
Decoder Buffer Size.
Definition: vpx_encoder.h:531
VP8_EFLAG_NO_REF_GF
#define VP8_EFLAG_NO_REF_GF
Don&#39;t reference the golden frame.
Definition: vp8cx.h:66
vpx_codec_enc_cfg::g_input_bit_depth
unsigned int g_input_bit_depth
Bit-depth of the input frames.
Definition: vpx_encoder.h:329
vpx_codec_enc_cfg::kf_mode
enum vpx_kf_mode kf_mode
Keyframe placement mode.
Definition: vpx_encoder.h:596
vpx_rational::den
int den
Definition: vpx_encoder.h:220
vpx_codec_encode
vpx_codec_err_t vpx_codec_encode(vpx_codec_ctx_t *ctx, const vpx_image_t *img, vpx_codec_pts_t pts, unsigned long duration, vpx_enc_frame_flags_t flags, unsigned long deadline)
Encode a frame.
vpx_codec_enc_cfg::rc_max_quantizer
unsigned int rc_max_quantizer
Maximum (Worst Quality) Quantizer.
Definition: vpx_encoder.h:482
VP8E_SET_ROI_MAP
Codec control function to pass an ROI map to encoder.
Definition: vp8cx.h:130
vpx_codec_enc_cfg::rc_min_quantizer
unsigned int rc_min_quantizer
Minimum (Best Quality) Quantizer.
Definition: vpx_encoder.h:473
vpx_codec_enc_cfg::kf_max_dist
unsigned int kf_max_dist
Keyframe maximum interval.
Definition: vpx_encoder.h:614
vpx_codec_enc_cfg::g_lag_in_frames
unsigned int g_lag_in_frames
Allow lagged encoding.
Definition: vpx_encoder.h:372
vpx_codec_enc_cfg
Encoder configuration structure.
Definition: vpx_encoder.h:268
VPX_KF_AUTO
Definition: vpx_encoder.h:248
VP9E_SET_ROW_MT
Codec control function to set row level multi-threading.
Definition: vp8cx.h:567
vpx_svc_layer_id::spatial_layer_id
int spatial_layer_id
Definition: vp8cx.h:800
VP8E_SET_MAX_INTRA_BITRATE_PCT
Codec control function to set Max data rate for Intra frames.
Definition: vp8cx.h:254
VPX_CODEC_USE_HIGHBITDEPTH
#define VPX_CODEC_USE_HIGHBITDEPTH
Definition: vpx_encoder.h:90
vpx_codec_cx_pkt
Encoder output packet.
Definition: vpx_encoder.h:159
vpx_codec_enc_cfg::rc_overshoot_pct
unsigned int rc_overshoot_pct
Rate control adaptation overshoot control.
Definition: vpx_encoder.h:516
VP9E_SET_SVC_PARAMETERS
Codec control function to set parameters for SVC.
Definition: vp8cx.h:441
vpx_codec_enc_cfg::ts_rate_decimator
unsigned int ts_rate_decimator[5]
Frame rate decimation factor for each temporal layer.
Definition: vpx_encoder.h:658
vpx_codec_enc_cfg::rc_buf_optimal_sz
unsigned int rc_buf_optimal_sz
Decoder Buffer Optimal Size.
Definition: vpx_encoder.h:549
vpx_codec_enc_cfg::kf_min_dist
unsigned int kf_min_dist
Keyframe minimum interval.
Definition: vpx_encoder.h:605
vpx_svc_layer_id::temporal_layer_id_per_spatial
int temporal_layer_id_per_spatial[5]
Definition: vp8cx.h:803
vpx_codec_enc_cfg::g_profile
unsigned int g_profile
Bitstream profile to use.
Definition: vpx_encoder.h:295
VP9E_SET_TILE_COLUMNS
Codec control function to set number of tile columns.
Definition: vp8cx.h:348
vpx_codec_enc_cfg::ts_layer_id
unsigned int ts_layer_id[16]
Template defining the membership of frames to temporal layers.
Definition: vpx_encoder.h:676
vpx_codec_cx_pkt::frame
struct vpx_codec_cx_pkt::@1::@2 frame
vpx_img_alloc
vpx_image_t * vpx_img_alloc(vpx_image_t *img, vpx_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int align)
Open a descriptor, allocating storage for the underlying image.
VPX_IMG_FMT_I420
Definition: vpx_image.h:42
vpx_svc_parameters::scaling_factor_num
int scaling_factor_num[12]
Definition: vpx_encoder.h:704
vpx_codec_enc_cfg::g_w
unsigned int g_w
Width of the frame.
Definition: vpx_encoder.h:304
vpx_roi_map::static_threshold
unsigned int static_threshold[4]
Definition: vp8cx.h:737
vpx_codec_enc_cfg::ts_target_bitrate
unsigned int ts_target_bitrate[5]
Target bitrate for each temporal layer.
Definition: vpx_encoder.h:651
vpx_bit_depth_t
enum vpx_bit_depth vpx_bit_depth_t
Bit depth for codecThis enumeration determines the bit depth of the codec.
vpx_codec_enc_cfg::rc_undershoot_pct
unsigned int rc_undershoot_pct
Rate control adaptation undershoot control.
Definition: vpx_encoder.h:501
VP9E_SET_AQ_MODE
Codec control function to set adaptive quantization mode.
Definition: vp8cx.h:395
vpx_roi_map::skip
int skip[8]
Definition: vp8cx.h:734
vpx_codec_enc_cfg::g_h
unsigned int g_h
Height of the frame.
Definition: vpx_encoder.h:313
vpx_roi_map::delta_lf
int delta_lf[8]
Definition: vp8cx.h:732
vpx_codec_cx_pkt::kind
enum vpx_codec_cx_pkt_kind kind
Definition: vpx_encoder.h:160
vpx_codec_enc_cfg::rc_dropframe_thresh
unsigned int rc_dropframe_thresh
Temporal resampling configuration, if supported by the codec.
Definition: vpx_encoder.h:391
VP8E_SET_GF_CBR_BOOST_PCT
Boost percentage for Golden Frame in CBR mode.
Definition: vp8cx.h:598
vpx_svc_layer_id
vp9 svc layer parameters
Definition: vp8cx.h:799
VP8E_SET_TEMPORAL_LAYER_ID
Codec control function to set the temporal layer id.
Definition: vp8cx.h:301
VP8_EFLAG_NO_UPD_LAST
#define VP8_EFLAG_NO_UPD_LAST
Don&#39;t update the last frame.
Definition: vp8cx.h:81
vpx_img_free
void vpx_img_free(vpx_image_t *img)
Close an image descriptor.
VP8E_SET_TOKEN_PARTITIONS
Codec control function to set the number of token partitions.
Definition: vp8cx.h:191
vpx_codec_enc_cfg::rc_target_bitrate
unsigned int rc_target_bitrate
Target data rate.
Definition: vpx_encoder.h:460
VPX_DL_REALTIME
#define VPX_DL_REALTIME
deadline parameter analogous to VPx REALTIME mode.
Definition: vpx_encoder.h:830
vpx_rational::num
int num
Definition: vpx_encoder.h:219
VP8E_SET_NOISE_SENSITIVITY
control function to set noise sensitivity
Definition: vp8cx.h:170
VPX_BITS_12
Definition: vpx_codec.h:220
vpx_roi_map::ref_frame
int ref_frame[8]
Definition: vp8cx.h:735
VP9E_SET_GF_CBR_BOOST_PCT
Boost percentage for Golden Frame in CBR mode.
Definition: vp8cx.h:290
vpx_codec_enc_config_default
vpx_codec_err_t vpx_codec_enc_config_default(vpx_codec_iface_t *iface, vpx_codec_enc_cfg_t *cfg, unsigned int usage)
Get a default configuration.
vpx_codec_enc_cfg::g_threads
unsigned int g_threads
Maximum number of threads to use.
Definition: vpx_encoder.h:285
vpx_codec_enc_cfg::ss_number_layers
unsigned int ss_number_layers
Number of spatial coding layers.
Definition: vpx_encoder.h:624
VP9E_SET_ROI_MAP
Codec control function to pass an ROI map to encoder.
Definition: vp8cx.h:433
vpx_codec_enc_cfg::g_bit_depth
vpx_bit_depth_t g_bit_depth
Bit-depth of the codec.
Definition: vpx_encoder.h:321
vp8cx.h
Provides definitions for using VP8 or VP9 encoder algorithm within the vpx Codec Interface.
vpx_codec_enc_init
#define vpx_codec_enc_init(ctx, iface, cfg, flags)
Convenience macro for vpx_codec_enc_init_ver()
Definition: vpx_encoder.h:741
VP8E_SET_SCREEN_CONTENT_MODE
Codec control function to set encoder screen content mode.
Definition: vp8cx.h:309
vpx_codec_enc_cfg::rc_resize_allowed
unsigned int rc_resize_allowed
Enable/disable spatial resampling, if supported by the codec.
Definition: vpx_encoder.h:400
VP9E_TEMPORAL_LAYERING_MODE_BYPASS
Bypass mode. Used when application needs to control temporal layering. This will only work when the n...
Definition: vp8cx.h:705
vpx_codec_err_t
vpx_codec_err_t
Algorithm return codes.
Definition: vpx_codec.h:90
vpx_codec_get_cx_data
const vpx_codec_cx_pkt_t * vpx_codec_get_cx_data(vpx_codec_ctx_t *ctx, vpx_codec_iter_t *iter)
Encoded data iterator.
vpx_codec_cx_pkt::data
union vpx_codec_cx_pkt::@1 data
vpx_codec_enc_cfg::temporal_layering_mode
int temporal_layering_mode
Temporal layering mode indicating which temporal layering scheme to use.
Definition: vpx_encoder.h:693
vpx_svc_layer_id::temporal_layer_id
int temporal_layer_id
Definition: vp8cx.h:802
VPX_IMG_FMT_I42016
Definition: vpx_image.h:46
VP9E_SET_FRAME_PERIODIC_BOOST
Codec control function to enable/disable periodic Q boost.
Definition: vp8cx.h:410
VPX_TS_MAX_PERIODICITY
#define VPX_TS_MAX_PERIODICITY
Definition: vpx_encoder.h:37
VP9E_SET_SVC
Codec control function to turn on/off SVC in encoder.
Definition: vp8cx.h:427
vpx_codec_control
#define vpx_codec_control(ctx, id, data)
vpx_codec_control wrapper macro
Definition: vpx_codec.h:404
vpx_codec_enc_cfg::ts_periodicity
unsigned int ts_periodicity
Length of the sequence defining frame temporal layer membership.
Definition: vpx_encoder.h:667
VP8_EFLAG_NO_REF_ARF
#define VP8_EFLAG_NO_REF_ARF
Don&#39;t reference the alternate reference frame.
Definition: vp8cx.h:74
vpx_codec_destroy
vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx)
Destroy a codec instance.
vpx_roi_map::rows
unsigned int rows
Definition: vp8cx.h:728
VP9E_SET_FRAME_PARALLEL_DECODING
Codec control function to enable frame parallel decoding feature.
Definition: vp8cx.h:382
VPX_BITS_8
Definition: vpx_codec.h:218
vpx_svc_parameters::scaling_factor_den
int scaling_factor_den[12]
Definition: vpx_encoder.h:705
VP8E_SET_STATIC_THRESHOLD
Codec control function to set the threshold for MBs treated static.
Definition: vp8cx.h:185
VPX_FRAME_IS_KEY
#define VPX_FRAME_IS_KEY
Definition: vpx_encoder.h:116
VPX_BITS_10
Definition: vpx_codec.h:219
VPX_EFLAG_FORCE_KF
#define VPX_EFLAG_FORCE_KF
Definition: vpx_encoder.h:260
vpx_codec_iter_t
const void * vpx_codec_iter_t
Iterator.
Definition: vpx_codec.h:187
vpx_roi_map
vpx region of interest map
Definition: vp8cx.h:722
VPX_CODEC_CX_FRAME_PKT
Definition: vpx_encoder.h:147
vpx_svc_parameters::max_quantizers
int max_quantizers[12]
Definition: vpx_encoder.h:702
vpx_svc_parameters
vp9 svc extra configure parameters
Definition: vpx_encoder.h:701
vpx_codec_enc_cfg::g_error_resilient
vpx_codec_er_flags_t g_error_resilient
Enable error resilient modes.
Definition: vpx_encoder.h:351
VP8_EFLAG_NO_UPD_ARF
#define VP8_EFLAG_NO_UPD_ARF
Don&#39;t update the alternate reference frame.
Definition: vp8cx.h:95
VP8_EFLAG_NO_UPD_ENTROPY
#define VP8_EFLAG_NO_UPD_ENTROPY
Disable entropy update.
Definition: vp8cx.h:116
VP9E_SET_SVC_LAYER_ID
Codec control function to set svc layer for spatial and temporal.
Definition: vp8cx.h:450
vpx_codec_enc_cfg::rc_end_usage
enum vpx_rc_mode rc_end_usage
Rate control algorithm to use.
Definition: vpx_encoder.h:440
vpx_codec_ctx
Codec context structure.
Definition: vpx_codec.h:197