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