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