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