Merge "Cleaning up vp9_dec_build_inter_predictors_sb function."
[platform/upstream/libvpx.git] / vpx / src / svc_encodeframe.c
1 /*
2  *  Copyright (c) 2013 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 /**
12  * @file
13  * VP9 SVC encoding support via libvpx
14  */
15
16 #include <stdarg.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #define VPX_DISABLE_CTRL_TYPECHECKS 1
21 #define VPX_CODEC_DISABLE_COMPAT 1
22 #include "vpx/svc_context.h"
23 #include "vpx/vp8cx.h"
24 #include "vpx/vpx_encoder.h"
25
26 #if defined(__MINGW32__) && !defined(MINGW_HAS_SECURE_API)
27 #define strtok_r strtok_s
28 // proto from /usr/x86_64-w64-mingw32/include/sec_api/string_s.h
29 _CRTIMP char *__cdecl strtok_s(char *str, const char *delim, char **context);
30 #endif
31
32 #ifdef _MSC_VER
33 #define strdup _strdup
34 #define strtok_r strtok_s
35 #endif
36
37 #define SVC_REFERENCE_FRAMES 8
38 #define SUPERFRAME_SLOTS (8)
39 #define SUPERFRAME_BUFFER_SIZE (SUPERFRAME_SLOTS * sizeof(uint32_t) + 2)
40 #define OPTION_BUFFER_SIZE 256
41
42 static const char *DEFAULT_QUANTIZER_VALUES = "60,53,39,33,27";
43 static const char *DEFAULT_SCALE_FACTORS = "4/16,5/16,7/16,11/16,16/16";
44
45 typedef struct SvcInternal {
46   char options[OPTION_BUFFER_SIZE];        // set by vpx_svc_set_options
47   char quantizers[OPTION_BUFFER_SIZE];     // set by vpx_svc_set_quantizers
48   char scale_factors[OPTION_BUFFER_SIZE];  // set by vpx_svc_set_scale_factors
49
50   // values extracted from option, quantizers
51   int scaling_factor_num[VPX_SS_MAX_LAYERS];
52   int scaling_factor_den[VPX_SS_MAX_LAYERS];
53   int quantizer[VPX_SS_MAX_LAYERS];
54
55   // accumulated statistics
56   double psnr_in_layer[VPX_SS_MAX_LAYERS];
57   uint32_t bytes_in_layer[VPX_SS_MAX_LAYERS];
58
59   // codec encoding values
60   int width;    // width of highest layer
61   int height;   // height of highest layer
62   int kf_dist;  // distance between keyframes
63
64   // state variables
65   int encode_frame_count;
66   int frame_within_gop;
67   vpx_enc_frame_flags_t enc_frame_flags;
68   int layers;
69   int layer;
70   int is_keyframe;
71
72   size_t frame_size;
73   size_t buffer_size;
74   void *buffer;
75
76   char message_buffer[2048];
77   vpx_codec_ctx_t *codec_ctx;
78 } SvcInternal;
79
80 // Superframe is used to generate an index of individual frames (i.e., layers)
81 struct Superframe {
82   int count;
83   uint32_t sizes[SUPERFRAME_SLOTS];
84   uint32_t magnitude;
85   uint8_t buffer[SUPERFRAME_BUFFER_SIZE];
86   size_t index_size;
87 };
88
89 // One encoded frame layer
90 struct LayerData {
91   void *buf;    // compressed data buffer
92   size_t size;  // length of compressed data
93   struct LayerData *next;
94 };
95
96 // create LayerData from encoder output
97 static struct LayerData *ld_create(void *buf, size_t size) {
98   struct LayerData *const layer_data = malloc(sizeof(*layer_data));
99   if (layer_data == NULL) {
100     return NULL;
101   }
102   layer_data->buf = malloc(size);
103   if (layer_data->buf == NULL) {
104     free(layer_data);
105     return NULL;
106   }
107   memcpy(layer_data->buf, buf, size);
108   layer_data->size = size;
109   return layer_data;
110 }
111
112 // free LayerData
113 static void ld_free(struct LayerData *layer_data) {
114   if (layer_data) {
115     if (layer_data->buf) {
116       free(layer_data->buf);
117       layer_data->buf = NULL;
118     }
119     free(layer_data);
120   }
121 }
122
123 // add layer data to list
124 static void ld_list_add(struct LayerData **list, struct LayerData *layer_data) {
125   struct LayerData **p = list;
126
127   while (*p != NULL) p = &(*p)->next;
128   *p = layer_data;
129   layer_data->next = NULL;
130 }
131
132 // get accumulated size of layer data
133 static size_t ld_list_get_buffer_size(struct LayerData *list) {
134   struct LayerData *p;
135   size_t size = 0;
136
137   for (p = list; p != NULL; p = p->next) {
138     size += p->size;
139   }
140   return size;
141 }
142
143 // copy layer data to buffer
144 static void ld_list_copy_to_buffer(struct LayerData *list, uint8_t *buffer) {
145   struct LayerData *p;
146
147   for (p = list; p != NULL; p = p->next) {
148     buffer[0] = 1;
149     memcpy(buffer, p->buf, p->size);
150     buffer += p->size;
151   }
152 }
153
154 // free layer data list
155 static void ld_list_free(struct LayerData *list) {
156   struct LayerData *p = list;
157
158   while (p) {
159     list = list->next;
160     ld_free(p);
161     p = list;
162   }
163 }
164
165 static void sf_create_index(struct Superframe *sf) {
166   uint8_t marker = 0xc0;
167   int i;
168   uint32_t mag, mask;
169   uint8_t *bufp;
170
171   if (sf->count == 0 || sf->count >= 8) return;
172
173   // Add the number of frames to the marker byte
174   marker |= sf->count - 1;
175
176   // Choose the magnitude
177   for (mag = 0, mask = 0xff; mag < 4; ++mag) {
178     if (sf->magnitude < mask) break;
179     mask <<= 8;
180     mask |= 0xff;
181   }
182   marker |= mag << 3;
183
184   // Write the index
185   sf->index_size = 2 + (mag + 1) * sf->count;
186   bufp = sf->buffer;
187
188   *bufp++ = marker;
189   for (i = 0; i < sf->count; ++i) {
190     int this_sz = sf->sizes[i];
191     uint32_t j;
192
193     for (j = 0; j <= mag; ++j) {
194       *bufp++ = this_sz & 0xff;
195       this_sz >>= 8;
196     }
197   }
198   *bufp++ = marker;
199 }
200
201 static SvcInternal *get_svc_internal(SvcContext *svc_ctx) {
202   if (svc_ctx == NULL) return NULL;
203   if (svc_ctx->internal == NULL) {
204     SvcInternal *const si = malloc(sizeof(*si));
205     if (si != NULL) {
206       memset(si, 0, sizeof(*si));
207     }
208     svc_ctx->internal = si;
209   }
210   return svc_ctx->internal;
211 }
212
213 static const SvcInternal *get_const_svc_internal(const SvcContext *svc_ctx) {
214   if (svc_ctx == NULL) return NULL;
215   return svc_ctx->internal;
216 }
217
218 static void svc_log_reset(SvcContext *svc_ctx) {
219   SvcInternal *const si = (SvcInternal *)svc_ctx->internal;
220   si->message_buffer[0] = '\0';
221 }
222
223 static int svc_log(SvcContext *svc_ctx, int level, const char *fmt, ...) {
224   char buf[512];
225   int retval = 0;
226   va_list ap;
227   SvcInternal *const si = get_svc_internal(svc_ctx);
228
229   if (level > svc_ctx->log_level) {
230     return retval;
231   }
232
233   va_start(ap, fmt);
234   retval = vsnprintf(buf, sizeof(buf), fmt, ap);
235   va_end(ap);
236
237   if (svc_ctx->log_print) {
238     printf("%s", buf);
239   } else {
240     strncat(si->message_buffer, buf,
241             sizeof(si->message_buffer) - strlen(si->message_buffer) - 1);
242   }
243
244   if (level == SVC_LOG_ERROR) {
245     si->codec_ctx->err_detail = si->message_buffer;
246   }
247   return retval;
248 }
249
250 static vpx_codec_err_t set_option_encoding_mode(SvcContext *svc_ctx,
251                                                 const char *value_str) {
252   if (strcmp(value_str, "i") == 0) {
253     svc_ctx->encoding_mode = INTER_LAYER_PREDICTION_I;
254   } else if (strcmp(value_str, "alt-ip") == 0) {
255     svc_ctx->encoding_mode = ALT_INTER_LAYER_PREDICTION_IP;
256   } else if (strcmp(value_str, "ip") == 0) {
257     svc_ctx->encoding_mode = INTER_LAYER_PREDICTION_IP;
258   } else if (strcmp(value_str, "gf") == 0) {
259     svc_ctx->encoding_mode = USE_GOLDEN_FRAME;
260   } else {
261     svc_log(svc_ctx, SVC_LOG_ERROR, "invalid encoding mode: %s", value_str);
262     return VPX_CODEC_INVALID_PARAM;
263   }
264   return VPX_CODEC_OK;
265 }
266
267 static vpx_codec_err_t parse_quantizer_values(SvcContext *svc_ctx,
268                                               const char *quantizer_values) {
269   char *input_string;
270   char *token;
271   const char *delim = ",";
272   char *save_ptr;
273   int found = 0;
274   int i, q;
275   int res = VPX_CODEC_OK;
276   SvcInternal *const si = get_svc_internal(svc_ctx);
277
278   if (quantizer_values == NULL || strlen(quantizer_values) == 0) {
279     input_string = strdup(DEFAULT_QUANTIZER_VALUES);
280   } else {
281     input_string = strdup(quantizer_values);
282   }
283
284   token = strtok_r(input_string, delim, &save_ptr);
285   for (i = 0; i < svc_ctx->spatial_layers; ++i) {
286     if (token != NULL) {
287       q = atoi(token);
288       if (q <= 0 || q > 100) {
289         svc_log(svc_ctx, SVC_LOG_ERROR,
290                 "svc-quantizer-values: invalid value %s\n", token);
291         res = VPX_CODEC_INVALID_PARAM;
292         break;
293       }
294       token = strtok_r(NULL, delim, &save_ptr);
295       found = i + 1;
296     } else {
297       q = 0;
298     }
299     si->quantizer[i + VPX_SS_MAX_LAYERS - svc_ctx->spatial_layers] = q;
300   }
301   if (res == VPX_CODEC_OK && found != svc_ctx->spatial_layers) {
302     svc_log(svc_ctx, SVC_LOG_ERROR,
303             "svc: quantizers: %d values required, but only %d specified\n",
304             svc_ctx->spatial_layers, found);
305     res = VPX_CODEC_INVALID_PARAM;
306   }
307   free(input_string);
308   return res;
309 }
310
311 static void log_invalid_scale_factor(SvcContext *svc_ctx, const char *value) {
312   svc_log(svc_ctx, SVC_LOG_ERROR, "svc scale-factors: invalid value %s\n",
313           value);
314 }
315
316 static vpx_codec_err_t parse_scale_factors(SvcContext *svc_ctx,
317                                            const char *scale_factors) {
318   char *input_string;
319   char *token;
320   const char *delim = ",";
321   char *save_ptr;
322   int found = 0;
323   int i;
324   int64_t num, den;
325   int res = VPX_CODEC_OK;
326   SvcInternal *const si = get_svc_internal(svc_ctx);
327
328   if (scale_factors == NULL || strlen(scale_factors) == 0) {
329     input_string = strdup(DEFAULT_SCALE_FACTORS);
330   } else {
331     input_string = strdup(scale_factors);
332   }
333   token = strtok_r(input_string, delim, &save_ptr);
334   for (i = 0; i < svc_ctx->spatial_layers; ++i) {
335     num = den = 0;
336     if (token != NULL) {
337       num = strtol(token, &token, 10);
338       if (num <= 0) {
339         log_invalid_scale_factor(svc_ctx, token);
340         res = VPX_CODEC_INVALID_PARAM;
341         break;
342       }
343       if (*token++ != '/') {
344         log_invalid_scale_factor(svc_ctx, token);
345         res = VPX_CODEC_INVALID_PARAM;
346         break;
347       }
348       den = strtol(token, &token, 10);
349       if (den <= 0) {
350         log_invalid_scale_factor(svc_ctx, token);
351         res = VPX_CODEC_INVALID_PARAM;
352         break;
353       }
354       token = strtok_r(NULL, delim, &save_ptr);
355       found = i + 1;
356     }
357     si->scaling_factor_num[i + VPX_SS_MAX_LAYERS - svc_ctx->spatial_layers] =
358         (int)num;
359     si->scaling_factor_den[i + VPX_SS_MAX_LAYERS - svc_ctx->spatial_layers] =
360         (int)den;
361   }
362   if (res == VPX_CODEC_OK && found != svc_ctx->spatial_layers) {
363     svc_log(svc_ctx, SVC_LOG_ERROR,
364             "svc: scale-factors: %d values required, but only %d specified\n",
365             svc_ctx->spatial_layers, found);
366     res = VPX_CODEC_INVALID_PARAM;
367   }
368   free(input_string);
369   return res;
370 }
371
372 /**
373  * Parse SVC encoding options
374  * Format: encoding-mode=<svc_mode>,layers=<layer_count>
375  *         scale-factors=<n1>/<d1>,<n2>/<d2>,...
376  *         quantizers=<q1>,<q2>,...
377  * svc_mode = [i|ip|alt_ip|gf]
378  */
379 static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) {
380   char *input_string;
381   char *option_name;
382   char *option_value;
383   char *input_ptr;
384   int res = VPX_CODEC_OK;
385
386   if (options == NULL) return VPX_CODEC_OK;
387   input_string = strdup(options);
388
389   // parse option name
390   option_name = strtok_r(input_string, "=", &input_ptr);
391   while (option_name != NULL) {
392     // parse option value
393     option_value = strtok_r(NULL, " ", &input_ptr);
394     if (option_value == NULL) {
395       svc_log(svc_ctx, SVC_LOG_ERROR, "option missing value: %s\n",
396               option_name);
397       res = VPX_CODEC_INVALID_PARAM;
398       break;
399     }
400     if (strcmp("encoding-mode", option_name) == 0) {
401       res = set_option_encoding_mode(svc_ctx, option_value);
402       if (res != VPX_CODEC_OK) break;
403     } else if (strcmp("layers", option_name) == 0) {
404       svc_ctx->spatial_layers = atoi(option_value);
405     } else if (strcmp("scale-factors", option_name) == 0) {
406       res = parse_scale_factors(svc_ctx, option_value);
407       if (res != VPX_CODEC_OK) break;
408     } else if (strcmp("quantizers", option_name) == 0) {
409       res = parse_quantizer_values(svc_ctx, option_value);
410       if (res != VPX_CODEC_OK) break;
411     } else {
412       svc_log(svc_ctx, SVC_LOG_ERROR, "invalid option: %s\n", option_name);
413       res = VPX_CODEC_INVALID_PARAM;
414       break;
415     }
416     option_name = strtok_r(NULL, "=", &input_ptr);
417   }
418   free(input_string);
419   return res;
420 }
421
422 vpx_codec_err_t vpx_svc_set_options(SvcContext *svc_ctx, const char *options) {
423   SvcInternal *const si = get_svc_internal(svc_ctx);
424   if (svc_ctx == NULL || options == NULL || si == NULL) {
425     return VPX_CODEC_INVALID_PARAM;
426   }
427   strncpy(si->options, options, sizeof(si->options));
428   si->options[sizeof(si->options) - 1] = '\0';
429   return VPX_CODEC_OK;
430 }
431
432 vpx_codec_err_t vpx_svc_set_quantizers(SvcContext *svc_ctx,
433                                        const char *quantizers) {
434   SvcInternal *const si = get_svc_internal(svc_ctx);
435   if (svc_ctx == NULL || quantizers == NULL || si == NULL) {
436     return VPX_CODEC_INVALID_PARAM;
437   }
438   strncpy(si->quantizers, quantizers, sizeof(si->quantizers));
439   si->quantizers[sizeof(si->quantizers) - 1] = '\0';
440   return VPX_CODEC_OK;
441 }
442
443 vpx_codec_err_t vpx_svc_set_scale_factors(SvcContext *svc_ctx,
444                                           const char *scale_factors) {
445   SvcInternal *const si = get_svc_internal(svc_ctx);
446   if (svc_ctx == NULL || scale_factors == NULL || si == NULL) {
447     return VPX_CODEC_INVALID_PARAM;
448   }
449   strncpy(si->scale_factors, scale_factors, sizeof(si->scale_factors));
450   si->scale_factors[sizeof(si->scale_factors) - 1] = '\0';
451   return VPX_CODEC_OK;
452 }
453
454 vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
455                              vpx_codec_iface_t *iface,
456                              vpx_codec_enc_cfg_t *enc_cfg) {
457   int max_intra_size_pct;
458   vpx_codec_err_t res;
459   SvcInternal *const si = get_svc_internal(svc_ctx);
460   if (svc_ctx == NULL || codec_ctx == NULL || iface == NULL ||
461       enc_cfg == NULL) {
462     return VPX_CODEC_INVALID_PARAM;
463   }
464   if (si == NULL) return VPX_CODEC_MEM_ERROR;
465
466   si->codec_ctx = codec_ctx;
467
468   si->width = enc_cfg->g_w;
469   si->height = enc_cfg->g_h;
470
471   if (enc_cfg->kf_max_dist < 2) {
472     svc_log(svc_ctx, SVC_LOG_ERROR, "key frame distance too small: %d\n",
473             enc_cfg->kf_max_dist);
474     return VPX_CODEC_INVALID_PARAM;
475   }
476   si->kf_dist = enc_cfg->kf_max_dist;
477
478   if (svc_ctx->spatial_layers == 0)
479     svc_ctx->spatial_layers = VPX_SS_DEFAULT_LAYERS;
480   if (svc_ctx->spatial_layers < 1 ||
481       svc_ctx->spatial_layers > VPX_SS_MAX_LAYERS) {
482     svc_log(svc_ctx, SVC_LOG_ERROR, "spatial layers: invalid value: %d\n",
483             svc_ctx->spatial_layers);
484     return VPX_CODEC_INVALID_PARAM;
485   }
486   // use SvcInternal value for number of layers to enable forcing single layer
487   // for first frame
488   si->layers = svc_ctx->spatial_layers;
489
490   res = parse_quantizer_values(svc_ctx, si->quantizers);
491   if (res != VPX_CODEC_OK) return res;
492
493   res = parse_scale_factors(svc_ctx, si->scale_factors);
494   if (res != VPX_CODEC_OK) return res;
495
496   // parse aggregate command line options
497   res = parse_options(svc_ctx, si->options);
498   if (res != VPX_CODEC_OK) return res;
499
500   // modify encoder configuration
501   enc_cfg->ss_number_layers = si->layers;
502   enc_cfg->kf_mode = VPX_KF_DISABLED;
503   enc_cfg->g_pass = VPX_RC_ONE_PASS;
504   // Lag in frames not currently supported
505   enc_cfg->g_lag_in_frames = 0;
506
507   // TODO(ivanmaltz): determine if these values need to be set explicitly for
508   // svc, or if the normal default/override mechanism can be used
509   enc_cfg->rc_dropframe_thresh = 0;
510   enc_cfg->rc_end_usage = VPX_CBR;
511   enc_cfg->rc_resize_allowed = 0;
512   enc_cfg->rc_min_quantizer = 33;
513   enc_cfg->rc_max_quantizer = 33;
514   enc_cfg->rc_undershoot_pct = 100;
515   enc_cfg->rc_overshoot_pct = 15;
516   enc_cfg->rc_buf_initial_sz = 500;
517   enc_cfg->rc_buf_optimal_sz = 600;
518   enc_cfg->rc_buf_sz = 1000;
519   enc_cfg->g_error_resilient = 1;
520
521   // Initialize codec
522   res = vpx_codec_enc_init(codec_ctx, iface, enc_cfg, VPX_CODEC_USE_PSNR);
523   if (res != VPX_CODEC_OK) {
524     svc_log(svc_ctx, SVC_LOG_ERROR, "svc_enc_init error\n");
525     return res;
526   }
527
528   vpx_codec_control(codec_ctx, VP9E_SET_SVC, 1);
529   vpx_codec_control(codec_ctx, VP8E_SET_CPUUSED, 1);
530   vpx_codec_control(codec_ctx, VP8E_SET_STATIC_THRESHOLD, 1);
531   vpx_codec_control(codec_ctx, VP8E_SET_NOISE_SENSITIVITY, 1);
532   vpx_codec_control(codec_ctx, VP8E_SET_TOKEN_PARTITIONS, 1);
533
534   max_intra_size_pct =
535       (int)(((double)enc_cfg->rc_buf_optimal_sz * 0.5) *
536             ((double)enc_cfg->g_timebase.den / enc_cfg->g_timebase.num) / 10.0);
537   vpx_codec_control(codec_ctx, VP8E_SET_MAX_INTRA_BITRATE_PCT,
538                     max_intra_size_pct);
539   return VPX_CODEC_OK;
540 }
541
542 // SVC Algorithm flags - these get mapped to VP8_EFLAG_* defined in vp8cx.h
543
544 // encoder should reference the last frame
545 #define USE_LAST (1 << 0)
546
547 // encoder should reference the alt ref frame
548 #define USE_ARF (1 << 1)
549
550 // encoder should reference the golden frame
551 #define USE_GF (1 << 2)
552
553 // encoder should copy current frame to the last frame buffer
554 #define UPDATE_LAST (1 << 3)
555
556 // encoder should copy current frame to the alt ref frame buffer
557 #define UPDATE_ARF (1 << 4)
558
559 // encoder should copy current frame to the golden frame
560 #define UPDATE_GF (1 << 5)
561
562 static int map_vp8_flags(int svc_flags) {
563   int flags = 0;
564
565   if (!(svc_flags & USE_LAST)) flags |= VP8_EFLAG_NO_REF_LAST;
566   if (!(svc_flags & USE_ARF)) flags |= VP8_EFLAG_NO_REF_ARF;
567   if (!(svc_flags & USE_GF)) flags |= VP8_EFLAG_NO_REF_GF;
568
569   if (svc_flags & UPDATE_LAST) {
570     // last is updated automatically
571   } else {
572     flags |= VP8_EFLAG_NO_UPD_LAST;
573   }
574   if (svc_flags & UPDATE_ARF) {
575     flags |= VP8_EFLAG_FORCE_ARF;
576   } else {
577     flags |= VP8_EFLAG_NO_UPD_ARF;
578   }
579   if (svc_flags & UPDATE_GF) {
580     flags |= VP8_EFLAG_FORCE_GF;
581   } else {
582     flags |= VP8_EFLAG_NO_UPD_GF;
583   }
584   return flags;
585 }
586
587 static void calculate_enc_frame_flags(SvcContext *svc_ctx) {
588   vpx_enc_frame_flags_t flags = VPX_EFLAG_FORCE_KF;
589   SvcInternal *const si = get_svc_internal(svc_ctx);
590   const int is_keyframe = (si->frame_within_gop == 0);
591
592   // keyframe layer zero is identical for all modes
593   if (is_keyframe && si->layer == 0) {
594     si->enc_frame_flags = VPX_EFLAG_FORCE_KF;
595     return;
596   }
597
598   switch (svc_ctx->encoding_mode) {
599     case ALT_INTER_LAYER_PREDICTION_IP:
600       if (si->layer == 0) {
601         flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
602       } else if (is_keyframe) {
603         if (si->layer == si->layers - 1) {
604           flags = map_vp8_flags(USE_ARF | UPDATE_LAST);
605         } else {
606           flags = map_vp8_flags(USE_ARF | UPDATE_LAST | UPDATE_GF);
607         }
608       } else {
609         flags = map_vp8_flags(USE_LAST | USE_ARF | UPDATE_LAST);
610       }
611       break;
612     case INTER_LAYER_PREDICTION_I:
613       if (si->layer == 0) {
614         flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
615       } else if (is_keyframe) {
616         flags = map_vp8_flags(USE_ARF | UPDATE_LAST);
617       } else {
618         flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
619       }
620       break;
621     case INTER_LAYER_PREDICTION_IP:
622       if (si->layer == 0) {
623         flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
624       } else if (is_keyframe) {
625         flags = map_vp8_flags(USE_ARF | UPDATE_LAST);
626       } else {
627         flags = map_vp8_flags(USE_LAST | USE_ARF | UPDATE_LAST);
628       }
629       break;
630     case USE_GOLDEN_FRAME:
631       if (2 * si->layers - SVC_REFERENCE_FRAMES <= si->layer) {
632         if (si->layer == 0) {
633           flags = map_vp8_flags(USE_LAST | USE_GF | UPDATE_LAST);
634         } else if (is_keyframe) {
635           flags = map_vp8_flags(USE_ARF | UPDATE_LAST | UPDATE_GF);
636         } else {
637           flags = map_vp8_flags(USE_LAST | USE_ARF | USE_GF | UPDATE_LAST);
638         }
639       } else {
640         if (si->layer == 0) {
641           flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
642         } else if (is_keyframe) {
643           flags = map_vp8_flags(USE_ARF | UPDATE_LAST);
644         } else {
645           flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
646         }
647       }
648       break;
649     default:
650       svc_log(svc_ctx, SVC_LOG_ERROR, "unexpected encoding mode: %d\n",
651               svc_ctx->encoding_mode);
652       break;
653   }
654   si->enc_frame_flags = flags;
655 }
656
657 vpx_codec_err_t vpx_svc_get_layer_resolution(const SvcContext *svc_ctx,
658                                              int layer,
659                                              unsigned int *width,
660                                              unsigned int *height) {
661   int w, h, index, num, den;
662   const SvcInternal *const si = get_const_svc_internal(svc_ctx);
663
664   if (svc_ctx == NULL || si == NULL || width == NULL || height == NULL) {
665     return VPX_CODEC_INVALID_PARAM;
666   }
667   if (layer < 0 || layer >= si->layers) return VPX_CODEC_INVALID_PARAM;
668
669   index = layer + VPX_SS_MAX_LAYERS - si->layers;
670   num = si->scaling_factor_num[index];
671   den = si->scaling_factor_den[index];
672   if (num == 0 || den == 0) return VPX_CODEC_INVALID_PARAM;
673
674   w = si->width * num / den;
675   h = si->height * num / den;
676
677   // make height and width even to make chrome player happy
678   w += w % 2;
679   h += h % 2;
680
681   *width = w;
682   *height = h;
683
684   return VPX_CODEC_OK;
685 }
686
687 static void set_svc_parameters(SvcContext *svc_ctx,
688                                vpx_codec_ctx_t *codec_ctx) {
689   int layer, layer_index;
690   vpx_svc_parameters_t svc_params;
691   SvcInternal *const si = get_svc_internal(svc_ctx);
692
693   memset(&svc_params, 0, sizeof(svc_params));
694   svc_params.layer = si->layer;
695   svc_params.flags = si->enc_frame_flags;
696
697   layer = si->layer;
698   if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP &&
699       si->frame_within_gop == 0) {
700     // layers 1 & 3 don't exist in this mode, use the higher one
701     if (layer == 0 || layer == 2) {
702       layer += 1;
703     }
704   }
705   if (VPX_CODEC_OK != vpx_svc_get_layer_resolution(svc_ctx, layer,
706                                                    &svc_params.width,
707                                                    &svc_params.height)) {
708     svc_log(svc_ctx, SVC_LOG_ERROR, "vpx_svc_get_layer_resolution failed\n");
709   }
710   layer_index = layer + VPX_SS_MAX_LAYERS - si->layers;
711   svc_params.min_quantizer = si->quantizer[layer_index];
712   svc_params.max_quantizer = si->quantizer[layer_index];
713   svc_params.distance_from_i_frame = si->frame_within_gop;
714
715   // Use buffer i for layer i LST
716   svc_params.lst_fb_idx = si->layer;
717
718   // Use buffer i-1 for layer i Alt (Inter-layer prediction)
719   if (si->layer != 0) {
720     const int use_higher_layer =
721         svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP &&
722         si->frame_within_gop == 0;
723     svc_params.alt_fb_idx = use_higher_layer ? si->layer - 2 : si->layer - 1;
724   }
725
726   if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP) {
727     svc_params.gld_fb_idx = si->layer + 1;
728   } else {
729     if (si->layer < 2 * si->layers - SVC_REFERENCE_FRAMES)
730       svc_params.gld_fb_idx = svc_params.lst_fb_idx;
731     else
732       svc_params.gld_fb_idx = 2 * si->layers - 1 - si->layer;
733   }
734
735   svc_log(svc_ctx, SVC_LOG_DEBUG, "SVC frame: %d, layer: %d, %dx%d, q: %d\n",
736           si->encode_frame_count, si->layer, svc_params.width,
737           svc_params.height, svc_params.min_quantizer);
738
739   if (svc_params.flags == VPX_EFLAG_FORCE_KF) {
740     svc_log(svc_ctx, SVC_LOG_DEBUG, "flags == VPX_EFLAG_FORCE_KF\n");
741   } else {
742     svc_log(
743         svc_ctx, SVC_LOG_DEBUG, "Using:    LST/GLD/ALT [%2d|%2d|%2d]\n",
744         svc_params.flags & VP8_EFLAG_NO_REF_LAST ? -1 : svc_params.lst_fb_idx,
745         svc_params.flags & VP8_EFLAG_NO_REF_GF ? -1 : svc_params.gld_fb_idx,
746         svc_params.flags & VP8_EFLAG_NO_REF_ARF ? -1 : svc_params.alt_fb_idx);
747     svc_log(
748         svc_ctx, SVC_LOG_DEBUG, "Updating: LST/GLD/ALT [%2d|%2d|%2d]\n",
749         svc_params.flags & VP8_EFLAG_NO_UPD_LAST ? -1 : svc_params.lst_fb_idx,
750         svc_params.flags & VP8_EFLAG_NO_UPD_GF ? -1 : svc_params.gld_fb_idx,
751         svc_params.flags & VP8_EFLAG_NO_UPD_ARF ? -1 : svc_params.alt_fb_idx);
752   }
753
754   vpx_codec_control(codec_ctx, VP9E_SET_SVC_PARAMETERS, &svc_params);
755 }
756
757 /**
758  * Encode a frame into multiple layers
759  * Create a superframe containing the individual layers
760  */
761 vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
762                                struct vpx_image *rawimg, vpx_codec_pts_t pts,
763                                int64_t duration, int deadline) {
764   vpx_codec_err_t res;
765   vpx_codec_iter_t iter;
766   const vpx_codec_cx_pkt_t *cx_pkt;
767   struct LayerData *cx_layer_list = NULL;
768   struct LayerData *layer_data;
769   struct Superframe superframe;
770   SvcInternal *const si = get_svc_internal(svc_ctx);
771   if (svc_ctx == NULL || codec_ctx == NULL || rawimg == NULL || si == NULL) {
772     return VPX_CODEC_INVALID_PARAM;
773   }
774
775   memset(&superframe, 0, sizeof(superframe));
776   svc_log_reset(svc_ctx);
777
778   si->layers = svc_ctx->spatial_layers;
779   if (si->frame_within_gop >= si->kf_dist ||
780       si->encode_frame_count == 0) {
781     si->frame_within_gop = 0;
782   }
783   si->is_keyframe = (si->frame_within_gop == 0);
784   si->frame_size = 0;
785
786   svc_log(svc_ctx, SVC_LOG_DEBUG,
787           "vpx_svc_encode  layers: %d, frame_count: %d, frame_within_gop: %d\n",
788           si->layers, si->encode_frame_count, si->frame_within_gop);
789
790   // encode each layer
791   for (si->layer = 0; si->layer < si->layers; ++si->layer) {
792     if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP &&
793         si->is_keyframe && (si->layer == 1 || si->layer == 3)) {
794       svc_log(svc_ctx, SVC_LOG_DEBUG, "Skip encoding layer %d\n", si->layer);
795       continue;
796     }
797     calculate_enc_frame_flags(svc_ctx);
798
799     set_svc_parameters(svc_ctx, codec_ctx);
800
801     res = vpx_codec_encode(codec_ctx, rawimg, pts, (uint32_t)duration,
802                            si->enc_frame_flags, deadline);
803     if (res != VPX_CODEC_OK) {
804       return res;
805     }
806     // save compressed data
807     iter = NULL;
808     while ((cx_pkt = vpx_codec_get_cx_data(codec_ctx, &iter))) {
809       switch (cx_pkt->kind) {
810         case VPX_CODEC_CX_FRAME_PKT: {
811           const uint32_t frame_pkt_size = (uint32_t)(cx_pkt->data.frame.sz);
812           si->bytes_in_layer[si->layer] += frame_pkt_size;
813           svc_log(svc_ctx, SVC_LOG_DEBUG,
814                   "SVC frame: %d, layer: %d, size: %u\n",
815                   si->encode_frame_count, si->layer, frame_pkt_size);
816           layer_data =
817               ld_create(cx_pkt->data.frame.buf, (size_t)frame_pkt_size);
818           if (layer_data == NULL) {
819             svc_log(svc_ctx, SVC_LOG_ERROR, "Error allocating LayerData\n");
820             return 0;
821           }
822           ld_list_add(&cx_layer_list, layer_data);
823
824           // save layer size in superframe index
825           superframe.sizes[superframe.count++] = frame_pkt_size;
826           superframe.magnitude |= frame_pkt_size;
827           break;
828         }
829         case VPX_CODEC_PSNR_PKT: {
830           svc_log(svc_ctx, SVC_LOG_DEBUG,
831                   "SVC frame: %d, layer: %d, PSNR(Total/Y/U/V): "
832                   "%2.3f  %2.3f  %2.3f  %2.3f \n",
833                   si->encode_frame_count, si->layer,
834                   cx_pkt->data.psnr.psnr[0], cx_pkt->data.psnr.psnr[1],
835                   cx_pkt->data.psnr.psnr[2], cx_pkt->data.psnr.psnr[3]);
836           si->psnr_in_layer[si->layer] += cx_pkt->data.psnr.psnr[0];
837           break;
838         }
839         default: {
840           break;
841         }
842       }
843     }
844   }
845   // add superframe index to layer data list
846   sf_create_index(&superframe);
847   layer_data = ld_create(superframe.buffer, superframe.index_size);
848   ld_list_add(&cx_layer_list, layer_data);
849
850   // get accumulated size of layer data
851   si->frame_size = ld_list_get_buffer_size(cx_layer_list);
852   if (si->frame_size == 0) return VPX_CODEC_ERROR;
853
854   // all layers encoded, create single buffer with concatenated layers
855   if (si->frame_size > si->buffer_size) {
856     free(si->buffer);
857     si->buffer = malloc(si->frame_size);
858     if (si->buffer == NULL) {
859       ld_list_free(cx_layer_list);
860       return VPX_CODEC_MEM_ERROR;
861     }
862     si->buffer_size = si->frame_size;
863   }
864   // copy layer data into packet
865   ld_list_copy_to_buffer(cx_layer_list, si->buffer);
866
867   ld_list_free(cx_layer_list);
868
869   svc_log(svc_ctx, SVC_LOG_DEBUG, "SVC frame: %d, kf: %d, size: %d, pts: %d\n",
870           si->encode_frame_count, si->is_keyframe, (int)si->frame_size,
871           (int)pts);
872   ++si->frame_within_gop;
873   ++si->encode_frame_count;
874
875   return VPX_CODEC_OK;
876 }
877
878 const char *vpx_svc_get_message(const SvcContext *svc_ctx) {
879   const SvcInternal *const si = get_const_svc_internal(svc_ctx);
880   if (svc_ctx == NULL || si == NULL) return NULL;
881   return si->message_buffer;
882 }
883
884 void *vpx_svc_get_buffer(const SvcContext *svc_ctx) {
885   const SvcInternal *const si = get_const_svc_internal(svc_ctx);
886   if (svc_ctx == NULL || si == NULL) return NULL;
887   return si->buffer;
888 }
889
890 size_t vpx_svc_get_frame_size(const SvcContext *svc_ctx) {
891   const SvcInternal *const si = get_const_svc_internal(svc_ctx);
892   if (svc_ctx == NULL || si == NULL) return 0;
893   return si->frame_size;
894 }
895
896 int vpx_svc_get_encode_frame_count(const SvcContext *svc_ctx) {
897   const SvcInternal *const si = get_const_svc_internal(svc_ctx);
898   if (svc_ctx == NULL || si == NULL) return 0;
899   return si->encode_frame_count;
900 }
901
902 int vpx_svc_is_keyframe(const SvcContext *svc_ctx) {
903   const SvcInternal *const si = get_const_svc_internal(svc_ctx);
904   if (svc_ctx == NULL || si == NULL) return 0;
905   return si->is_keyframe;
906 }
907
908 void vpx_svc_set_keyframe(SvcContext *svc_ctx) {
909   SvcInternal *const si = get_svc_internal(svc_ctx);
910   if (svc_ctx == NULL || si == NULL) return;
911   si->frame_within_gop = 0;
912 }
913
914 // dump accumulated statistics and reset accumulated values
915 const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) {
916   int number_of_frames, number_of_keyframes, encode_frame_count;
917   int i;
918   uint32_t bytes_total = 0;
919   SvcInternal *const si = get_svc_internal(svc_ctx);
920   if (svc_ctx == NULL || si == NULL) return NULL;
921
922   svc_log_reset(svc_ctx);
923
924   encode_frame_count = si->encode_frame_count;
925   if (si->encode_frame_count <= 0) return vpx_svc_get_message(svc_ctx);
926
927   svc_log(svc_ctx, SVC_LOG_INFO, "\n");
928   number_of_keyframes = encode_frame_count / si->kf_dist + 1;
929   for (i = 0; i < si->layers; ++i) {
930     number_of_frames = encode_frame_count;
931
932     if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP &&
933         (i == 1 || i == 3)) {
934       number_of_frames -= number_of_keyframes;
935     }
936     svc_log(svc_ctx, SVC_LOG_INFO, "Layer %d PSNR=[%2.3f], Bytes=[%u]\n", i,
937             (double)si->psnr_in_layer[i] / number_of_frames,
938             si->bytes_in_layer[i]);
939     bytes_total += si->bytes_in_layer[i];
940     si->psnr_in_layer[i] = 0;
941     si->bytes_in_layer[i] = 0;
942   }
943
944   // only display statistics once
945   si->encode_frame_count = 0;
946
947   svc_log(svc_ctx, SVC_LOG_INFO, "Total Bytes=[%u]\n", bytes_total);
948   return vpx_svc_get_message(svc_ctx);
949 }
950
951 void vpx_svc_release(SvcContext *svc_ctx) {
952   SvcInternal *si;
953   if (svc_ctx == NULL) return;
954   // do not use get_svc_internal as it will unnecessarily allocate an
955   // SvcInternal if it was not already allocated
956   si = (SvcInternal *)svc_ctx->internal;
957   if (si != NULL) {
958     free(si->buffer);
959     free(si);
960     svc_ctx->internal = NULL;
961   }
962 }