Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(734)

Side by Side Diff: source/libvpx/vpx/src/svc_encodeframe.c

Issue 375983002: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « source/libvpx/vp9/vp9cx.mk ('k') | source/libvpx/vpx/src/vpx_image.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 /** 11 /**
12 * @file 12 * @file
13 * VP9 SVC encoding support via libvpx 13 * VP9 SVC encoding support via libvpx
14 */ 14 */
15 15
16 #include <assert.h> 16 #include <assert.h>
17 #include <math.h> 17 #include <math.h>
18 #include <stdarg.h> 18 #include <stdarg.h>
19 #include <stdio.h> 19 #include <stdio.h>
20 #include <stdlib.h> 20 #include <stdlib.h>
21 #include <string.h> 21 #include <string.h>
22 #define VPX_DISABLE_CTRL_TYPECHECKS 1 22 #define VPX_DISABLE_CTRL_TYPECHECKS 1
23 #define VPX_CODEC_DISABLE_COMPAT 1 23 #define VPX_CODEC_DISABLE_COMPAT 1
24 #include "vpx/svc_context.h" 24 #include "vpx/svc_context.h"
25 #include "vpx/vp8cx.h" 25 #include "vpx/vp8cx.h"
26 #include "vpx/vpx_encoder.h" 26 #include "vpx/vpx_encoder.h"
27 #include "vpx_mem/vpx_mem.h"
27 28
28 #ifdef __MINGW32__ 29 #ifdef __MINGW32__
29 #define strtok_r strtok_s 30 #define strtok_r strtok_s
30 #ifndef MINGW_HAS_SECURE_API 31 #ifndef MINGW_HAS_SECURE_API
31 // proto from /usr/x86_64-w64-mingw32/include/sec_api/string_s.h 32 // proto from /usr/x86_64-w64-mingw32/include/sec_api/string_s.h
32 _CRTIMP char *__cdecl strtok_s(char *str, const char *delim, char **context); 33 _CRTIMP char *__cdecl strtok_s(char *str, const char *delim, char **context);
33 #endif /* MINGW_HAS_SECURE_API */ 34 #endif /* MINGW_HAS_SECURE_API */
34 #endif /* __MINGW32__ */ 35 #endif /* __MINGW32__ */
35 36
36 #ifdef _MSC_VER 37 #ifdef _MSC_VER
37 #define strdup _strdup 38 #define strdup _strdup
38 #define strtok_r strtok_s 39 #define strtok_r strtok_s
39 #endif 40 #endif
40 41
41 #define SVC_REFERENCE_FRAMES 8 42 #define SVC_REFERENCE_FRAMES 8
42 #define SUPERFRAME_SLOTS (8) 43 #define SUPERFRAME_SLOTS (8)
43 #define SUPERFRAME_BUFFER_SIZE (SUPERFRAME_SLOTS * sizeof(uint32_t) + 2) 44 #define SUPERFRAME_BUFFER_SIZE (SUPERFRAME_SLOTS * sizeof(uint32_t) + 2)
44 #define OPTION_BUFFER_SIZE 256 45 #define OPTION_BUFFER_SIZE 256
45 #define COMPONENTS 4 // psnr & sse statistics maintained for total, y, u, v 46 #define COMPONENTS 4 // psnr & sse statistics maintained for total, y, u, v
46 47
47 static const char *DEFAULT_QUANTIZER_VALUES = "60,53,39,33,27"; 48 static const char *DEFAULT_QUANTIZER_VALUES = "60,53,39,33,27";
48 static const char *DEFAULT_SCALE_FACTORS = "4/16,5/16,7/16,11/16,16/16"; 49 static const char *DEFAULT_SCALE_FACTORS = "4/16,5/16,7/16,11/16,16/16";
49 50
51 // One encoded frame
52 typedef struct FrameData {
53 void *buf; // compressed data buffer
54 size_t size; // length of compressed data
55 vpx_codec_frame_flags_t flags; /**< flags for this frame */
56 struct FrameData *next;
57 } FrameData;
58
50 typedef struct SvcInternal { 59 typedef struct SvcInternal {
51 char options[OPTION_BUFFER_SIZE]; // set by vpx_svc_set_options 60 char options[OPTION_BUFFER_SIZE]; // set by vpx_svc_set_options
52 char quantizers[OPTION_BUFFER_SIZE]; // set by vpx_svc_set_quantizers 61 char quantizers[OPTION_BUFFER_SIZE]; // set by vpx_svc_set_quantizers
53 char quantizers_keyframe[OPTION_BUFFER_SIZE]; // set by
54 // vpx_svc_set_quantizers
55 char scale_factors[OPTION_BUFFER_SIZE]; // set by vpx_svc_set_scale_factors 62 char scale_factors[OPTION_BUFFER_SIZE]; // set by vpx_svc_set_scale_factors
56 63
57 // values extracted from option, quantizers 64 // values extracted from option, quantizers
58 int scaling_factor_num[VPX_SS_MAX_LAYERS]; 65 int scaling_factor_num[VPX_SS_MAX_LAYERS];
59 int scaling_factor_den[VPX_SS_MAX_LAYERS]; 66 int scaling_factor_den[VPX_SS_MAX_LAYERS];
60 int quantizer_keyframe[VPX_SS_MAX_LAYERS];
61 int quantizer[VPX_SS_MAX_LAYERS]; 67 int quantizer[VPX_SS_MAX_LAYERS];
62 68
63 // accumulated statistics 69 // accumulated statistics
64 double psnr_sum[VPX_SS_MAX_LAYERS][COMPONENTS]; // total/Y/U/V 70 double psnr_sum[VPX_SS_MAX_LAYERS][COMPONENTS]; // total/Y/U/V
65 uint64_t sse_sum[VPX_SS_MAX_LAYERS][COMPONENTS]; 71 uint64_t sse_sum[VPX_SS_MAX_LAYERS][COMPONENTS];
66 uint32_t bytes_sum[VPX_SS_MAX_LAYERS]; 72 uint32_t bytes_sum[VPX_SS_MAX_LAYERS];
67 73
68 // codec encoding values 74 // codec encoding values
69 int width; // width of highest layer 75 int width; // width of highest layer
70 int height; // height of highest layer 76 int height; // height of highest layer
71 int kf_dist; // distance between keyframes 77 int kf_dist; // distance between keyframes
72 78
73 // state variables 79 // state variables
74 int encode_frame_count; 80 int encode_frame_count;
81 int frame_received;
75 int frame_within_gop; 82 int frame_within_gop;
76 vpx_enc_frame_flags_t enc_frame_flags; 83 vpx_enc_frame_flags_t enc_frame_flags;
77 int layers; 84 int layers;
78 int layer; 85 int layer;
79 int is_keyframe; 86 int is_keyframe;
80 87
81 size_t frame_size; 88 FrameData *frame_list;
82 size_t buffer_size; 89 FrameData *frame_temp;
83 void *buffer;
84 90
85 char *rc_stats_buf; 91 char *rc_stats_buf;
86 size_t rc_stats_buf_size; 92 size_t rc_stats_buf_size;
87 size_t rc_stats_buf_used; 93 size_t rc_stats_buf_used;
88 94
89 char message_buffer[2048]; 95 char message_buffer[2048];
90 vpx_codec_ctx_t *codec_ctx; 96 vpx_codec_ctx_t *codec_ctx;
91 } SvcInternal; 97 } SvcInternal;
92 98
93 // Superframe is used to generate an index of individual frames (i.e., layers) 99 // create FrameData from encoder output
94 struct Superframe { 100 static struct FrameData *fd_create(void *buf, size_t size,
95 int count; 101 vpx_codec_frame_flags_t flags) {
96 uint32_t sizes[SUPERFRAME_SLOTS]; 102 struct FrameData *const frame_data =
97 uint32_t magnitude; 103 (struct FrameData *)vpx_malloc(sizeof(*frame_data));
98 uint8_t buffer[SUPERFRAME_BUFFER_SIZE]; 104 if (frame_data == NULL) {
99 size_t index_size;
100 };
101
102 // One encoded frame layer
103 struct LayerData {
104 void *buf; // compressed data buffer
105 size_t size; // length of compressed data
106 struct LayerData *next;
107 };
108
109 // create LayerData from encoder output
110 static struct LayerData *ld_create(void *buf, size_t size) {
111 struct LayerData *const layer_data =
112 (struct LayerData *)malloc(sizeof(*layer_data));
113 if (layer_data == NULL) {
114 return NULL; 105 return NULL;
115 } 106 }
116 layer_data->buf = malloc(size); 107 frame_data->buf = vpx_malloc(size);
117 if (layer_data->buf == NULL) { 108 if (frame_data->buf == NULL) {
118 free(layer_data); 109 vpx_free(frame_data);
119 return NULL; 110 return NULL;
120 } 111 }
121 memcpy(layer_data->buf, buf, size); 112 vpx_memcpy(frame_data->buf, buf, size);
122 layer_data->size = size; 113 frame_data->size = size;
123 return layer_data; 114 frame_data->flags = flags;
115 return frame_data;
124 } 116 }
125 117
126 // free LayerData 118 // free FrameData
127 static void ld_free(struct LayerData *layer_data) { 119 static void fd_free(struct FrameData *p) {
128 if (layer_data) { 120 if (p) {
129 if (layer_data->buf) { 121 if (p->buf)
130 free(layer_data->buf); 122 vpx_free(p->buf);
131 layer_data->buf = NULL; 123 vpx_free(p);
132 }
133 free(layer_data);
134 } 124 }
135 } 125 }
136 126
137 // add layer data to list 127 // add FrameData to list
138 static void ld_list_add(struct LayerData **list, struct LayerData *layer_data) { 128 static void fd_list_add(struct FrameData **list, struct FrameData *layer_data) {
139 struct LayerData **p = list; 129 struct FrameData **p = list;
140 130
141 while (*p != NULL) p = &(*p)->next; 131 while (*p != NULL) p = &(*p)->next;
142 *p = layer_data; 132 *p = layer_data;
143 layer_data->next = NULL; 133 layer_data->next = NULL;
144 } 134 }
145 135
146 // get accumulated size of layer data 136 // free FrameData list
147 static size_t ld_list_get_buffer_size(struct LayerData *list) { 137 static void fd_free_list(struct FrameData *list) {
148 struct LayerData *p; 138 struct FrameData *p = list;
149 size_t size = 0;
150
151 for (p = list; p != NULL; p = p->next) {
152 size += p->size;
153 }
154 return size;
155 }
156
157 // copy layer data to buffer
158 static void ld_list_copy_to_buffer(struct LayerData *list, uint8_t *buffer) {
159 struct LayerData *p;
160
161 for (p = list; p != NULL; p = p->next) {
162 buffer[0] = 1;
163 memcpy(buffer, p->buf, p->size);
164 buffer += p->size;
165 }
166 }
167
168 // free layer data list
169 static void ld_list_free(struct LayerData *list) {
170 struct LayerData *p = list;
171 139
172 while (p) { 140 while (p) {
173 list = list->next; 141 list = list->next;
174 ld_free(p); 142 fd_free(p);
175 p = list; 143 p = list;
176 } 144 }
177 } 145 }
178 146
179 static void sf_create_index(struct Superframe *sf) {
180 uint8_t marker = 0xc0;
181 int i;
182 uint32_t mag, mask;
183 uint8_t *bufp;
184
185 if (sf->count == 0 || sf->count >= 8) return;
186
187 // Add the number of frames to the marker byte
188 marker |= sf->count - 1;
189
190 // Choose the magnitude
191 for (mag = 0, mask = 0xff; mag < 4; ++mag) {
192 if (sf->magnitude < mask) break;
193 mask <<= 8;
194 mask |= 0xff;
195 }
196 marker |= mag << 3;
197
198 // Write the index
199 sf->index_size = 2 + (mag + 1) * sf->count;
200 bufp = sf->buffer;
201
202 *bufp++ = marker;
203 for (i = 0; i < sf->count; ++i) {
204 int this_sz = sf->sizes[i];
205 uint32_t j;
206
207 for (j = 0; j <= mag; ++j) {
208 *bufp++ = this_sz & 0xff;
209 this_sz >>= 8;
210 }
211 }
212 *bufp++ = marker;
213 }
214
215 static SvcInternal *get_svc_internal(SvcContext *svc_ctx) { 147 static SvcInternal *get_svc_internal(SvcContext *svc_ctx) {
216 if (svc_ctx == NULL) return NULL; 148 if (svc_ctx == NULL) return NULL;
217 if (svc_ctx->internal == NULL) { 149 if (svc_ctx->internal == NULL) {
218 SvcInternal *const si = (SvcInternal *)malloc(sizeof(*si)); 150 SvcInternal *const si = (SvcInternal *)malloc(sizeof(*si));
219 if (si != NULL) { 151 if (si != NULL) {
220 memset(si, 0, sizeof(*si)); 152 memset(si, 0, sizeof(*si));
221 } 153 }
222 svc_ctx->internal = si; 154 svc_ctx->internal = si;
223 } 155 }
224 return (SvcInternal *)svc_ctx->internal; 156 return (SvcInternal *)svc_ctx->internal;
(...skipping 30 matching lines...) Expand all
255 strncat(si->message_buffer, buf, 187 strncat(si->message_buffer, buf,
256 sizeof(si->message_buffer) - strlen(si->message_buffer) - 1); 188 sizeof(si->message_buffer) - strlen(si->message_buffer) - 1);
257 } 189 }
258 190
259 if (level == SVC_LOG_ERROR) { 191 if (level == SVC_LOG_ERROR) {
260 si->codec_ctx->err_detail = si->message_buffer; 192 si->codec_ctx->err_detail = si->message_buffer;
261 } 193 }
262 return retval; 194 return retval;
263 } 195 }
264 196
265 static vpx_codec_err_t set_option_encoding_mode(SvcContext *svc_ctx,
266 const char *value_str) {
267 if (strcmp(value_str, "i") == 0) {
268 svc_ctx->encoding_mode = INTER_LAYER_PREDICTION_I;
269 } else if (strcmp(value_str, "alt-ip") == 0) {
270 svc_ctx->encoding_mode = ALT_INTER_LAYER_PREDICTION_IP;
271 } else if (strcmp(value_str, "ip") == 0) {
272 svc_ctx->encoding_mode = INTER_LAYER_PREDICTION_IP;
273 } else if (strcmp(value_str, "gf") == 0) {
274 svc_ctx->encoding_mode = USE_GOLDEN_FRAME;
275 } else {
276 svc_log(svc_ctx, SVC_LOG_ERROR, "invalid encoding mode: %s", value_str);
277 return VPX_CODEC_INVALID_PARAM;
278 }
279 return VPX_CODEC_OK;
280 }
281
282 static vpx_codec_err_t parse_quantizer_values(SvcContext *svc_ctx, 197 static vpx_codec_err_t parse_quantizer_values(SvcContext *svc_ctx,
283 const char *quantizer_values, 198 const char *quantizer_values) {
284 const int is_keyframe) {
285 char *input_string; 199 char *input_string;
286 char *token; 200 char *token;
287 const char *delim = ","; 201 const char *delim = ",";
288 char *save_ptr; 202 char *save_ptr;
289 int found = 0; 203 int found = 0;
290 int i, q; 204 int i, q;
291 vpx_codec_err_t res = VPX_CODEC_OK; 205 vpx_codec_err_t res = VPX_CODEC_OK;
292 SvcInternal *const si = get_svc_internal(svc_ctx); 206 SvcInternal *const si = get_svc_internal(svc_ctx);
293 207
294 if (quantizer_values == NULL || strlen(quantizer_values) == 0) { 208 if (quantizer_values == NULL || strlen(quantizer_values) == 0) {
295 if (is_keyframe) {
296 // If there non settings for key frame, we will apply settings from
297 // non key frame. So just simply return here.
298 return VPX_CODEC_INVALID_PARAM;
299 }
300 input_string = strdup(DEFAULT_QUANTIZER_VALUES); 209 input_string = strdup(DEFAULT_QUANTIZER_VALUES);
301 } else { 210 } else {
302 input_string = strdup(quantizer_values); 211 input_string = strdup(quantizer_values);
303 } 212 }
304 213
305 token = strtok_r(input_string, delim, &save_ptr); 214 token = strtok_r(input_string, delim, &save_ptr);
306 for (i = 0; i < svc_ctx->spatial_layers; ++i) { 215 for (i = 0; i < svc_ctx->spatial_layers; ++i) {
307 if (token != NULL) { 216 if (token != NULL) {
308 q = atoi(token); 217 q = atoi(token);
309 if (q <= 0 || q > 100) { 218 if (q <= 0 || q > 100) {
310 svc_log(svc_ctx, SVC_LOG_ERROR, 219 svc_log(svc_ctx, SVC_LOG_ERROR,
311 "svc-quantizer-values: invalid value %s\n", token); 220 "svc-quantizer-values: invalid value %s\n", token);
312 res = VPX_CODEC_INVALID_PARAM; 221 res = VPX_CODEC_INVALID_PARAM;
313 break; 222 break;
314 } 223 }
315 token = strtok_r(NULL, delim, &save_ptr); 224 token = strtok_r(NULL, delim, &save_ptr);
316 found = i + 1; 225 found = i + 1;
317 } else { 226 } else {
318 q = 0; 227 q = 0;
319 } 228 }
320 if (is_keyframe) { 229 si->quantizer[i + VPX_SS_MAX_LAYERS - svc_ctx->spatial_layers] = q;
321 si->quantizer_keyframe[i + VPX_SS_MAX_LAYERS - svc_ctx->spatial_layers]
322 = q;
323 } else {
324 si->quantizer[i + VPX_SS_MAX_LAYERS - svc_ctx->spatial_layers] = q;
325 }
326 } 230 }
327 if (res == VPX_CODEC_OK && found != svc_ctx->spatial_layers) { 231 if (res == VPX_CODEC_OK && found != svc_ctx->spatial_layers) {
328 svc_log(svc_ctx, SVC_LOG_ERROR, 232 svc_log(svc_ctx, SVC_LOG_ERROR,
329 "svc: quantizers: %d values required, but only %d specified\n", 233 "svc: quantizers: %d values required, but only %d specified\n",
330 svc_ctx->spatial_layers, found); 234 svc_ctx->spatial_layers, found);
331 res = VPX_CODEC_INVALID_PARAM; 235 res = VPX_CODEC_INVALID_PARAM;
332 } 236 }
333 free(input_string); 237 free(input_string);
334 return res; 238 return res;
335 } 239 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 * Format: encoding-mode=<svc_mode>,layers=<layer_count> 304 * Format: encoding-mode=<svc_mode>,layers=<layer_count>
401 * scale-factors=<n1>/<d1>,<n2>/<d2>,... 305 * scale-factors=<n1>/<d1>,<n2>/<d2>,...
402 * quantizers=<q1>,<q2>,... 306 * quantizers=<q1>,<q2>,...
403 * svc_mode = [i|ip|alt_ip|gf] 307 * svc_mode = [i|ip|alt_ip|gf]
404 */ 308 */
405 static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) { 309 static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) {
406 char *input_string; 310 char *input_string;
407 char *option_name; 311 char *option_name;
408 char *option_value; 312 char *option_value;
409 char *input_ptr; 313 char *input_ptr;
410 int is_keyframe_qaunt_set = 0;
411 vpx_codec_err_t res = VPX_CODEC_OK; 314 vpx_codec_err_t res = VPX_CODEC_OK;
412 315
413 if (options == NULL) return VPX_CODEC_OK; 316 if (options == NULL) return VPX_CODEC_OK;
414 input_string = strdup(options); 317 input_string = strdup(options);
415 318
416 // parse option name 319 // parse option name
417 option_name = strtok_r(input_string, "=", &input_ptr); 320 option_name = strtok_r(input_string, "=", &input_ptr);
418 while (option_name != NULL) { 321 while (option_name != NULL) {
419 // parse option value 322 // parse option value
420 option_value = strtok_r(NULL, " ", &input_ptr); 323 option_value = strtok_r(NULL, " ", &input_ptr);
421 if (option_value == NULL) { 324 if (option_value == NULL) {
422 svc_log(svc_ctx, SVC_LOG_ERROR, "option missing value: %s\n", 325 svc_log(svc_ctx, SVC_LOG_ERROR, "option missing value: %s\n",
423 option_name); 326 option_name);
424 res = VPX_CODEC_INVALID_PARAM; 327 res = VPX_CODEC_INVALID_PARAM;
425 break; 328 break;
426 } 329 }
427 if (strcmp("encoding-mode", option_name) == 0) { 330 if (strcmp("layers", option_name) == 0) {
428 res = set_option_encoding_mode(svc_ctx, option_value);
429 if (res != VPX_CODEC_OK) break;
430 } else if (strcmp("layers", option_name) == 0) {
431 svc_ctx->spatial_layers = atoi(option_value); 331 svc_ctx->spatial_layers = atoi(option_value);
432 } else if (strcmp("scale-factors", option_name) == 0) { 332 } else if (strcmp("scale-factors", option_name) == 0) {
433 res = parse_scale_factors(svc_ctx, option_value); 333 res = parse_scale_factors(svc_ctx, option_value);
434 if (res != VPX_CODEC_OK) break; 334 if (res != VPX_CODEC_OK) break;
435 } else if (strcmp("quantizers", option_name) == 0) { 335 } else if (strcmp("quantizers", option_name) == 0) {
436 res = parse_quantizer_values(svc_ctx, option_value, 0); 336 res = parse_quantizer_values(svc_ctx, option_value);
437 if (res != VPX_CODEC_OK) break; 337 if (res != VPX_CODEC_OK) break;
438 if (!is_keyframe_qaunt_set) {
439 SvcInternal *const si = get_svc_internal(svc_ctx);
440 memcpy(get_svc_internal(svc_ctx)->quantizer_keyframe, si->quantizer,
441 sizeof(si->quantizer));
442 }
443 } else if (strcmp("quantizers-keyframe", option_name) == 0) {
444 res = parse_quantizer_values(svc_ctx, option_value, 1);
445 if (res != VPX_CODEC_OK) break;
446 is_keyframe_qaunt_set = 1;
447 } else { 338 } else {
448 svc_log(svc_ctx, SVC_LOG_ERROR, "invalid option: %s\n", option_name); 339 svc_log(svc_ctx, SVC_LOG_ERROR, "invalid option: %s\n", option_name);
449 res = VPX_CODEC_INVALID_PARAM; 340 res = VPX_CODEC_INVALID_PARAM;
450 break; 341 break;
451 } 342 }
452 option_name = strtok_r(NULL, "=", &input_ptr); 343 option_name = strtok_r(NULL, "=", &input_ptr);
453 } 344 }
454 free(input_string); 345 free(input_string);
455 return res; 346 return res;
456 } 347 }
457 348
458 vpx_codec_err_t vpx_svc_set_options(SvcContext *svc_ctx, const char *options) { 349 vpx_codec_err_t vpx_svc_set_options(SvcContext *svc_ctx, const char *options) {
459 SvcInternal *const si = get_svc_internal(svc_ctx); 350 SvcInternal *const si = get_svc_internal(svc_ctx);
460 if (svc_ctx == NULL || options == NULL || si == NULL) { 351 if (svc_ctx == NULL || options == NULL || si == NULL) {
461 return VPX_CODEC_INVALID_PARAM; 352 return VPX_CODEC_INVALID_PARAM;
462 } 353 }
463 strncpy(si->options, options, sizeof(si->options)); 354 strncpy(si->options, options, sizeof(si->options));
464 si->options[sizeof(si->options) - 1] = '\0'; 355 si->options[sizeof(si->options) - 1] = '\0';
465 return VPX_CODEC_OK; 356 return VPX_CODEC_OK;
466 } 357 }
467 358
468 vpx_codec_err_t vpx_svc_set_quantizers(SvcContext *svc_ctx, 359 vpx_codec_err_t vpx_svc_set_quantizers(SvcContext *svc_ctx,
469 const char *quantizers, 360 const char *quantizers) {
470 const int is_for_keyframe) {
471 SvcInternal *const si = get_svc_internal(svc_ctx); 361 SvcInternal *const si = get_svc_internal(svc_ctx);
472 if (svc_ctx == NULL || quantizers == NULL || si == NULL) { 362 if (svc_ctx == NULL || quantizers == NULL || si == NULL) {
473 return VPX_CODEC_INVALID_PARAM; 363 return VPX_CODEC_INVALID_PARAM;
474 } 364 }
475 if (is_for_keyframe) { 365 strncpy(si->quantizers, quantizers, sizeof(si->quantizers));
476 strncpy(si->quantizers_keyframe, quantizers, sizeof(si->quantizers)); 366 si->quantizers[sizeof(si->quantizers) - 1] = '\0';
477 si->quantizers_keyframe[sizeof(si->quantizers_keyframe) - 1] = '\0';
478 } else {
479 strncpy(si->quantizers, quantizers, sizeof(si->quantizers));
480 si->quantizers[sizeof(si->quantizers) - 1] = '\0';
481 }
482 return VPX_CODEC_OK; 367 return VPX_CODEC_OK;
483 } 368 }
484 369
485 vpx_codec_err_t vpx_svc_set_scale_factors(SvcContext *svc_ctx, 370 vpx_codec_err_t vpx_svc_set_scale_factors(SvcContext *svc_ctx,
486 const char *scale_factors) { 371 const char *scale_factors) {
487 SvcInternal *const si = get_svc_internal(svc_ctx); 372 SvcInternal *const si = get_svc_internal(svc_ctx);
488 if (svc_ctx == NULL || scale_factors == NULL || si == NULL) { 373 if (svc_ctx == NULL || scale_factors == NULL || si == NULL) {
489 return VPX_CODEC_INVALID_PARAM; 374 return VPX_CODEC_INVALID_PARAM;
490 } 375 }
491 strncpy(si->scale_factors, scale_factors, sizeof(si->scale_factors)); 376 strncpy(si->scale_factors, scale_factors, sizeof(si->scale_factors));
(...skipping 26 matching lines...) Expand all
518 403
519 if (svc_ctx->spatial_layers == 0) 404 if (svc_ctx->spatial_layers == 0)
520 svc_ctx->spatial_layers = VPX_SS_DEFAULT_LAYERS; 405 svc_ctx->spatial_layers = VPX_SS_DEFAULT_LAYERS;
521 if (svc_ctx->spatial_layers < 1 || 406 if (svc_ctx->spatial_layers < 1 ||
522 svc_ctx->spatial_layers > VPX_SS_MAX_LAYERS) { 407 svc_ctx->spatial_layers > VPX_SS_MAX_LAYERS) {
523 svc_log(svc_ctx, SVC_LOG_ERROR, "spatial layers: invalid value: %d\n", 408 svc_log(svc_ctx, SVC_LOG_ERROR, "spatial layers: invalid value: %d\n",
524 svc_ctx->spatial_layers); 409 svc_ctx->spatial_layers);
525 return VPX_CODEC_INVALID_PARAM; 410 return VPX_CODEC_INVALID_PARAM;
526 } 411 }
527 412
528 res = parse_quantizer_values(svc_ctx, si->quantizers, 0); 413 res = parse_quantizer_values(svc_ctx, si->quantizers);
529 if (res != VPX_CODEC_OK) return res; 414 if (res != VPX_CODEC_OK) return res;
530 415
531 res = parse_quantizer_values(svc_ctx, si->quantizers_keyframe, 1);
532 if (res != VPX_CODEC_OK)
533 memcpy(si->quantizer_keyframe, si->quantizer, sizeof(si->quantizer));
534
535 res = parse_scale_factors(svc_ctx, si->scale_factors); 416 res = parse_scale_factors(svc_ctx, si->scale_factors);
536 if (res != VPX_CODEC_OK) return res; 417 if (res != VPX_CODEC_OK) return res;
537 418
538 // Parse aggregate command line options. Options must start with 419 // Parse aggregate command line options. Options must start with
539 // "layers=xx" then followed by other options 420 // "layers=xx" then followed by other options
540 res = parse_options(svc_ctx, si->options); 421 res = parse_options(svc_ctx, si->options);
541 if (res != VPX_CODEC_OK) return res; 422 if (res != VPX_CODEC_OK) return res;
542 423
543 si->layers = svc_ctx->spatial_layers; 424 si->layers = svc_ctx->spatial_layers;
544 425
(...skipping 22 matching lines...) Expand all
567 if (total > 0) { 448 if (total > 0) {
568 enc_cfg->ss_target_bitrate[i] = (unsigned int) 449 enc_cfg->ss_target_bitrate[i] = (unsigned int)
569 (enc_cfg->rc_target_bitrate * alloc_ratio[i] / total); 450 (enc_cfg->rc_target_bitrate * alloc_ratio[i] / total);
570 } 451 }
571 } 452 }
572 } 453 }
573 454
574 // modify encoder configuration 455 // modify encoder configuration
575 enc_cfg->ss_number_layers = si->layers; 456 enc_cfg->ss_number_layers = si->layers;
576 enc_cfg->ts_number_layers = 1; // Temporal layers not used in this encoder. 457 enc_cfg->ts_number_layers = 1; // Temporal layers not used in this encoder.
577 // Lag in frames not currently supported
578 enc_cfg->g_lag_in_frames = 0;
579 458
580 // TODO(ivanmaltz): determine if these values need to be set explicitly for 459 // TODO(ivanmaltz): determine if these values need to be set explicitly for
581 // svc, or if the normal default/override mechanism can be used 460 // svc, or if the normal default/override mechanism can be used
582 enc_cfg->rc_dropframe_thresh = 0; 461 enc_cfg->rc_dropframe_thresh = 0;
583 enc_cfg->rc_resize_allowed = 0; 462 enc_cfg->rc_resize_allowed = 0;
584 463
585 if (enc_cfg->g_pass == VPX_RC_ONE_PASS) { 464 if (enc_cfg->g_pass == VPX_RC_ONE_PASS) {
586 enc_cfg->rc_min_quantizer = 33; 465 enc_cfg->rc_min_quantizer = 33;
587 enc_cfg->rc_max_quantizer = 33; 466 enc_cfg->rc_max_quantizer = 33;
588 } 467 }
(...skipping 12 matching lines...) Expand all
601 return res; 480 return res;
602 } 481 }
603 482
604 vpx_codec_control(codec_ctx, VP9E_SET_SVC, 1); 483 vpx_codec_control(codec_ctx, VP9E_SET_SVC, 1);
605 vpx_codec_control(codec_ctx, VP8E_SET_TOKEN_PARTITIONS, 1); 484 vpx_codec_control(codec_ctx, VP8E_SET_TOKEN_PARTITIONS, 1);
606 vpx_codec_control(codec_ctx, VP8E_SET_ENABLEAUTOALTREF, 0); 485 vpx_codec_control(codec_ctx, VP8E_SET_ENABLEAUTOALTREF, 0);
607 486
608 return VPX_CODEC_OK; 487 return VPX_CODEC_OK;
609 } 488 }
610 489
490 static void accumulate_frame_size_for_each_layer(SvcInternal *const si,
491 const uint8_t *const buf,
492 const size_t size) {
493 uint8_t marker = buf[size - 1];
494 if ((marker & 0xe0) == 0xc0) {
495 const uint32_t frames = (marker & 0x7) + 1;
496 const uint32_t mag = ((marker >> 3) & 0x3) + 1;
497 const size_t index_sz = 2 + mag * frames;
498
499 uint8_t marker2 = buf[size - index_sz];
500
501 if (size >= index_sz && marker2 == marker) {
502 // found a valid superframe index
503 uint32_t i, j;
504 const uint8_t *x = &buf[size - index_sz + 1];
505
506 // frames has a maximum of 8 and mag has a maximum of 4.
507 for (i = 0; i < frames; i++) {
508 uint32_t this_sz = 0;
509
510 for (j = 0; j < mag; j++)
511 this_sz |= (*x++) << (j * 8);
512 si->bytes_sum[i] += this_sz;
513 }
514 }
515 }
516 }
517
611 // SVC Algorithm flags - these get mapped to VP8_EFLAG_* defined in vp8cx.h 518 // SVC Algorithm flags - these get mapped to VP8_EFLAG_* defined in vp8cx.h
612 519
613 // encoder should reference the last frame 520 // encoder should reference the last frame
614 #define USE_LAST (1 << 0) 521 #define USE_LAST (1 << 0)
615 522
616 // encoder should reference the alt ref frame 523 // encoder should reference the alt ref frame
617 #define USE_ARF (1 << 1) 524 #define USE_ARF (1 << 1)
618 525
619 // encoder should reference the golden frame 526 // encoder should reference the golden frame
620 #define USE_GF (1 << 2) 527 #define USE_GF (1 << 2)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 vpx_enc_frame_flags_t flags = VPX_EFLAG_FORCE_KF; 564 vpx_enc_frame_flags_t flags = VPX_EFLAG_FORCE_KF;
658 SvcInternal *const si = get_svc_internal(svc_ctx); 565 SvcInternal *const si = get_svc_internal(svc_ctx);
659 const int is_keyframe = (si->frame_within_gop == 0); 566 const int is_keyframe = (si->frame_within_gop == 0);
660 567
661 // keyframe layer zero is identical for all modes 568 // keyframe layer zero is identical for all modes
662 if (is_keyframe && si->layer == 0) { 569 if (is_keyframe && si->layer == 0) {
663 si->enc_frame_flags = VPX_EFLAG_FORCE_KF; 570 si->enc_frame_flags = VPX_EFLAG_FORCE_KF;
664 return; 571 return;
665 } 572 }
666 573
667 switch (svc_ctx->encoding_mode) { 574 if (si->layer == 0) {
668 case ALT_INTER_LAYER_PREDICTION_IP: 575 flags = map_vp8_flags(USE_LAST | UPDATE_LAST);
669 if (si->layer == 0) { 576 } else if (is_keyframe) {
670 flags = map_vp8_flags(USE_LAST | UPDATE_LAST); 577 flags = map_vp8_flags(USE_ARF | UPDATE_LAST);
671 } else if (is_keyframe) { 578 } else {
672 if (si->layer == si->layers - 1) { 579 flags = map_vp8_flags(USE_LAST | USE_ARF | UPDATE_LAST);
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 } 580 }
581
723 si->enc_frame_flags = flags; 582 si->enc_frame_flags = flags;
724 } 583 }
725 584
726 vpx_codec_err_t vpx_svc_get_layer_resolution(const SvcContext *svc_ctx, 585 vpx_codec_err_t vpx_svc_get_layer_resolution(const SvcContext *svc_ctx,
727 int layer, 586 int layer,
728 unsigned int *width, 587 unsigned int *width,
729 unsigned int *height) { 588 unsigned int *height) {
730 int w, h, index, num, den; 589 int w, h, index, num, den;
731 const SvcInternal *const si = get_const_svc_internal(svc_ctx); 590 const SvcInternal *const si = get_const_svc_internal(svc_ctx);
732 591
(...skipping 25 matching lines...) Expand all
758 int layer, layer_index; 617 int layer, layer_index;
759 vpx_svc_parameters_t svc_params; 618 vpx_svc_parameters_t svc_params;
760 SvcInternal *const si = get_svc_internal(svc_ctx); 619 SvcInternal *const si = get_svc_internal(svc_ctx);
761 620
762 memset(&svc_params, 0, sizeof(svc_params)); 621 memset(&svc_params, 0, sizeof(svc_params));
763 svc_params.temporal_layer = 0; 622 svc_params.temporal_layer = 0;
764 svc_params.spatial_layer = si->layer; 623 svc_params.spatial_layer = si->layer;
765 svc_params.flags = si->enc_frame_flags; 624 svc_params.flags = si->enc_frame_flags;
766 625
767 layer = si->layer; 626 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, 627 if (VPX_CODEC_OK != vpx_svc_get_layer_resolution(svc_ctx, layer,
776 &svc_params.width, 628 &svc_params.width,
777 &svc_params.height)) { 629 &svc_params.height)) {
778 svc_log(svc_ctx, SVC_LOG_ERROR, "vpx_svc_get_layer_resolution failed\n"); 630 svc_log(svc_ctx, SVC_LOG_ERROR, "vpx_svc_get_layer_resolution failed\n");
779 } 631 }
780 layer_index = layer + VPX_SS_MAX_LAYERS - si->layers; 632 layer_index = layer + VPX_SS_MAX_LAYERS - si->layers;
781 633
782 if (codec_ctx->config.enc->g_pass == VPX_RC_ONE_PASS) { 634 if (codec_ctx->config.enc->g_pass == VPX_RC_ONE_PASS) {
783 if (vpx_svc_is_keyframe(svc_ctx)) { 635 svc_params.min_quantizer = si->quantizer[layer_index];
784 svc_params.min_quantizer = si->quantizer_keyframe[layer_index]; 636 svc_params.max_quantizer = si->quantizer[layer_index];
785 svc_params.max_quantizer = si->quantizer_keyframe[layer_index];
786 } else {
787 svc_params.min_quantizer = si->quantizer[layer_index];
788 svc_params.max_quantizer = si->quantizer[layer_index];
789 }
790 } else { 637 } else {
791 svc_params.min_quantizer = codec_ctx->config.enc->rc_min_quantizer; 638 svc_params.min_quantizer = codec_ctx->config.enc->rc_min_quantizer;
792 svc_params.max_quantizer = codec_ctx->config.enc->rc_max_quantizer; 639 svc_params.max_quantizer = codec_ctx->config.enc->rc_max_quantizer;
793 } 640 }
794 641
795 svc_params.distance_from_i_frame = si->frame_within_gop; 642 svc_params.distance_from_i_frame = si->frame_within_gop;
796 643
797 // Use buffer i for layer i LST 644 // Use buffer i for layer i LST
798 svc_params.lst_fb_idx = si->layer; 645 svc_params.lst_fb_idx = si->layer;
799 646
800 // Use buffer i-1 for layer i Alt (Inter-layer prediction) 647 // Use buffer i-1 for layer i Alt (Inter-layer prediction)
801 if (si->layer != 0) { 648 svc_params.alt_fb_idx = (si->layer > 0) ? si->layer - 1 : 0;
802 const int use_higher_layer = 649 svc_params.gld_fb_idx = svc_params.lst_fb_idx;
803 svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP &&
804 si->frame_within_gop == 0;
805 svc_params.alt_fb_idx = use_higher_layer ? si->layer - 2 : si->layer - 1;
806 }
807
808 if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP) {
809 svc_params.gld_fb_idx = si->layer + 1;
810 } else {
811 if (si->layer < 2 * si->layers - SVC_REFERENCE_FRAMES)
812 svc_params.gld_fb_idx = svc_params.lst_fb_idx;
813 else
814 svc_params.gld_fb_idx = 2 * si->layers - 1 - si->layer;
815 }
816 650
817 svc_log(svc_ctx, SVC_LOG_DEBUG, "SVC frame: %d, layer: %d, %dx%d, q: %d\n", 651 svc_log(svc_ctx, SVC_LOG_DEBUG, "SVC frame: %d, layer: %d, %dx%d, q: %d\n",
818 si->encode_frame_count, si->layer, svc_params.width, 652 si->encode_frame_count, si->layer, svc_params.width,
819 svc_params.height, svc_params.min_quantizer); 653 svc_params.height, svc_params.min_quantizer);
820 654
821 if (svc_params.flags == VPX_EFLAG_FORCE_KF) { 655 if (svc_params.flags == VPX_EFLAG_FORCE_KF) {
822 svc_log(svc_ctx, SVC_LOG_DEBUG, "flags == VPX_EFLAG_FORCE_KF\n"); 656 svc_log(svc_ctx, SVC_LOG_DEBUG, "flags == VPX_EFLAG_FORCE_KF\n");
823 } else { 657 } else {
824 svc_log( 658 svc_log(
825 svc_ctx, SVC_LOG_DEBUG, "Using: LST/GLD/ALT [%2d|%2d|%2d]\n", 659 svc_ctx, SVC_LOG_DEBUG, "Using: LST/GLD/ALT [%2d|%2d|%2d]\n",
(...skipping 13 matching lines...) Expand all
839 /** 673 /**
840 * Encode a frame into multiple layers 674 * Encode a frame into multiple layers
841 * Create a superframe containing the individual layers 675 * Create a superframe containing the individual layers
842 */ 676 */
843 vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, 677 vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
844 struct vpx_image *rawimg, vpx_codec_pts_t pts, 678 struct vpx_image *rawimg, vpx_codec_pts_t pts,
845 int64_t duration, int deadline) { 679 int64_t duration, int deadline) {
846 vpx_codec_err_t res; 680 vpx_codec_err_t res;
847 vpx_codec_iter_t iter; 681 vpx_codec_iter_t iter;
848 const vpx_codec_cx_pkt_t *cx_pkt; 682 const vpx_codec_cx_pkt_t *cx_pkt;
849 struct LayerData *cx_layer_list = NULL; 683 int layer_for_psnr = 0;
850 struct LayerData *layer_data;
851 struct Superframe superframe;
852 SvcInternal *const si = get_svc_internal(svc_ctx); 684 SvcInternal *const si = get_svc_internal(svc_ctx);
853 if (svc_ctx == NULL || codec_ctx == NULL || si == NULL) { 685 if (svc_ctx == NULL || codec_ctx == NULL || si == NULL) {
854 return VPX_CODEC_INVALID_PARAM; 686 return VPX_CODEC_INVALID_PARAM;
855 } 687 }
856 688
857 memset(&superframe, 0, sizeof(superframe));
858 svc_log_reset(svc_ctx); 689 svc_log_reset(svc_ctx);
859 si->rc_stats_buf_used = 0; 690 si->rc_stats_buf_used = 0;
860 691
861 si->layers = svc_ctx->spatial_layers; 692 si->layers = svc_ctx->spatial_layers;
862 if (si->encode_frame_count == 0) { 693 if (si->encode_frame_count == 0) {
863 si->frame_within_gop = 0; 694 si->frame_within_gop = 0;
864 } 695 }
865 si->is_keyframe = (si->frame_within_gop == 0); 696 si->is_keyframe = (si->frame_within_gop == 0);
866 si->frame_size = 0;
867 697
868 if (rawimg != NULL) { 698 if (rawimg != NULL) {
869 svc_log(svc_ctx, SVC_LOG_DEBUG, 699 svc_log(svc_ctx, SVC_LOG_DEBUG,
870 "vpx_svc_encode layers: %d, frame_count: %d, " 700 "vpx_svc_encode layers: %d, frame_count: %d, "
871 "frame_within_gop: %d\n", si->layers, si->encode_frame_count, 701 "frame_within_gop: %d\n", si->layers, si->encode_frame_count,
872 si->frame_within_gop); 702 si->frame_within_gop);
873 } 703 }
874 704
875 // encode each layer 705 if (rawimg != NULL) {
876 for (si->layer = 0; si->layer < si->layers; ++si->layer) { 706 // encode each layer
877 if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP && 707 for (si->layer = 0; si->layer < si->layers; ++si->layer) {
878 si->is_keyframe && (si->layer == 1 || si->layer == 3)) {
879 svc_log(svc_ctx, SVC_LOG_DEBUG, "Skip encoding layer %d\n", si->layer);
880 continue;
881 }
882
883 if (rawimg != NULL) {
884 calculate_enc_frame_flags(svc_ctx); 708 calculate_enc_frame_flags(svc_ctx);
885 set_svc_parameters(svc_ctx, codec_ctx); 709 set_svc_parameters(svc_ctx, codec_ctx);
886 } 710 }
711 }
887 712
888 res = vpx_codec_encode(codec_ctx, rawimg, pts, (uint32_t)duration, 713 res = vpx_codec_encode(codec_ctx, rawimg, pts, (uint32_t)duration, 0,
889 si->enc_frame_flags, deadline); 714 deadline);
890 if (res != VPX_CODEC_OK) { 715 if (res != VPX_CODEC_OK) {
891 return res; 716 return res;
892 } 717 }
893 // save compressed data 718 // save compressed data
894 iter = NULL; 719 iter = NULL;
895 while ((cx_pkt = vpx_codec_get_cx_data(codec_ctx, &iter))) { 720 while ((cx_pkt = vpx_codec_get_cx_data(codec_ctx, &iter))) {
896 switch (cx_pkt->kind) { 721 switch (cx_pkt->kind) {
897 case VPX_CODEC_CX_FRAME_PKT: { 722 case VPX_CODEC_CX_FRAME_PKT: {
898 const uint32_t frame_pkt_size = (uint32_t)(cx_pkt->data.frame.sz); 723 fd_list_add(&si->frame_list, fd_create(cx_pkt->data.frame.buf,
899 si->bytes_sum[si->layer] += frame_pkt_size; 724 cx_pkt->data.frame.sz,
900 svc_log(svc_ctx, SVC_LOG_DEBUG, 725 cx_pkt->data.frame.flags));
901 "SVC frame: %d, layer: %d, size: %u\n", 726 accumulate_frame_size_for_each_layer(si, cx_pkt->data.frame.buf,
902 si->encode_frame_count, si->layer, frame_pkt_size); 727 cx_pkt->data.frame.sz);
903 layer_data = 728
904 ld_create(cx_pkt->data.frame.buf, (size_t)frame_pkt_size); 729 svc_log(svc_ctx, SVC_LOG_DEBUG, "SVC frame: %d, kf: %d, size: %d, "
905 if (layer_data == NULL) { 730 "pts: %d\n", si->frame_received,
906 svc_log(svc_ctx, SVC_LOG_ERROR, "Error allocating LayerData\n"); 731 (cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? 1 : 0,
907 return VPX_CODEC_OK; 732 (int)cx_pkt->data.frame.sz, (int)cx_pkt->data.frame.pts);
733
734 ++si->frame_received;
735 layer_for_psnr = 0;
736 break;
737 }
738 case VPX_CODEC_PSNR_PKT: {
739 int i;
740 svc_log(svc_ctx, SVC_LOG_DEBUG,
741 "SVC frame: %d, layer: %d, PSNR(Total/Y/U/V): "
742 "%2.3f %2.3f %2.3f %2.3f \n",
743 si->frame_received, layer_for_psnr,
744 cx_pkt->data.psnr.psnr[0], cx_pkt->data.psnr.psnr[1],
745 cx_pkt->data.psnr.psnr[2], cx_pkt->data.psnr.psnr[3]);
746 svc_log(svc_ctx, SVC_LOG_DEBUG,
747 "SVC frame: %d, layer: %d, SSE(Total/Y/U/V): "
748 "%2.3f %2.3f %2.3f %2.3f \n",
749 si->frame_received, layer_for_psnr,
750 cx_pkt->data.psnr.sse[0], cx_pkt->data.psnr.sse[1],
751 cx_pkt->data.psnr.sse[2], cx_pkt->data.psnr.sse[3]);
752 for (i = 0; i < COMPONENTS; i++) {
753 si->psnr_sum[layer_for_psnr][i] += cx_pkt->data.psnr.psnr[i];
754 si->sse_sum[layer_for_psnr][i] += cx_pkt->data.psnr.sse[i];
755 }
756 ++layer_for_psnr;
757 break;
758 }
759 case VPX_CODEC_STATS_PKT: {
760 size_t new_size = si->rc_stats_buf_used +
761 cx_pkt->data.twopass_stats.sz;
762
763 if (new_size > si->rc_stats_buf_size) {
764 char *p = (char*)realloc(si->rc_stats_buf, new_size);
765 if (p == NULL) {
766 svc_log(svc_ctx, SVC_LOG_ERROR, "Error allocating stats buf\n");
767 return VPX_CODEC_MEM_ERROR;
908 } 768 }
909 ld_list_add(&cx_layer_list, layer_data); 769 si->rc_stats_buf = p;
770 si->rc_stats_buf_size = new_size;
771 }
910 772
911 // save layer size in superframe index 773 memcpy(si->rc_stats_buf + si->rc_stats_buf_used,
912 superframe.sizes[superframe.count++] = frame_pkt_size; 774 cx_pkt->data.twopass_stats.buf, cx_pkt->data.twopass_stats.sz);
913 superframe.magnitude |= frame_pkt_size; 775 si->rc_stats_buf_used += cx_pkt->data.twopass_stats.sz;
914 break; 776 break;
915 } 777 }
916 case VPX_CODEC_PSNR_PKT: { 778 default: {
917 int i; 779 break;
918 svc_log(svc_ctx, SVC_LOG_DEBUG,
919 "SVC frame: %d, layer: %d, PSNR(Total/Y/U/V): "
920 "%2.3f %2.3f %2.3f %2.3f \n",
921 si->encode_frame_count, si->layer,
922 cx_pkt->data.psnr.psnr[0], cx_pkt->data.psnr.psnr[1],
923 cx_pkt->data.psnr.psnr[2], cx_pkt->data.psnr.psnr[3]);
924 svc_log(svc_ctx, SVC_LOG_DEBUG,
925 "SVC frame: %d, layer: %d, SSE(Total/Y/U/V): "
926 "%2.3f %2.3f %2.3f %2.3f \n",
927 si->encode_frame_count, si->layer,
928 cx_pkt->data.psnr.sse[0], cx_pkt->data.psnr.sse[1],
929 cx_pkt->data.psnr.sse[2], cx_pkt->data.psnr.sse[3]);
930 for (i = 0; i < COMPONENTS; i++) {
931 si->psnr_sum[si->layer][i] += cx_pkt->data.psnr.psnr[i];
932 si->sse_sum[si->layer][i] += cx_pkt->data.psnr.sse[i];
933 }
934 break;
935 }
936 case VPX_CODEC_STATS_PKT: {
937 size_t new_size = si->rc_stats_buf_used +
938 cx_pkt->data.twopass_stats.sz;
939
940 if (new_size > si->rc_stats_buf_size) {
941 char *p = (char*)realloc(si->rc_stats_buf, new_size);
942 if (p == NULL) {
943 svc_log(svc_ctx, SVC_LOG_ERROR, "Error allocating stats buf\n");
944 break;
945 }
946 si->rc_stats_buf = p;
947 si->rc_stats_buf_size = new_size;
948 }
949
950 memcpy(si->rc_stats_buf + si->rc_stats_buf_used,
951 cx_pkt->data.twopass_stats.buf, cx_pkt->data.twopass_stats.sz);
952 si->rc_stats_buf_used += cx_pkt->data.twopass_stats.sz;
953 break;
954 }
955 default: {
956 break;
957 }
958 } 780 }
959 } 781 }
960 if (rawimg == NULL) {
961 break;
962 }
963 } 782 }
964 if (codec_ctx->config.enc->g_pass != VPX_RC_FIRST_PASS) {
965 // add superframe index to layer data list
966 sf_create_index(&superframe);
967 layer_data = ld_create(superframe.buffer, superframe.index_size);
968 ld_list_add(&cx_layer_list, layer_data);
969 783
970 // get accumulated size of layer data
971 si->frame_size = ld_list_get_buffer_size(cx_layer_list);
972 if (si->frame_size > 0) {
973 // all layers encoded, create single buffer with concatenated layers
974 if (si->frame_size > si->buffer_size) {
975 free(si->buffer);
976 si->buffer = malloc(si->frame_size);
977 if (si->buffer == NULL) {
978 ld_list_free(cx_layer_list);
979 return VPX_CODEC_MEM_ERROR;
980 }
981 si->buffer_size = si->frame_size;
982 }
983 // copy layer data into packet
984 ld_list_copy_to_buffer(cx_layer_list, (uint8_t *)si->buffer);
985
986 ld_list_free(cx_layer_list);
987
988 svc_log(svc_ctx, SVC_LOG_DEBUG, "SVC frame: %d, kf: %d, size: %d, "
989 "pts: %d\n", si->encode_frame_count, si->is_keyframe,
990 (int)si->frame_size, (int)pts);
991 }
992 }
993 if (rawimg != NULL) { 784 if (rawimg != NULL) {
994 ++si->frame_within_gop; 785 ++si->frame_within_gop;
995 ++si->encode_frame_count; 786 ++si->encode_frame_count;
996 } 787 }
997 788
998 return VPX_CODEC_OK; 789 return VPX_CODEC_OK;
999 } 790 }
1000 791
1001 const char *vpx_svc_get_message(const SvcContext *svc_ctx) { 792 const char *vpx_svc_get_message(const SvcContext *svc_ctx) {
1002 const SvcInternal *const si = get_const_svc_internal(svc_ctx); 793 const SvcInternal *const si = get_const_svc_internal(svc_ctx);
1003 if (svc_ctx == NULL || si == NULL) return NULL; 794 if (svc_ctx == NULL || si == NULL) return NULL;
1004 return si->message_buffer; 795 return si->message_buffer;
1005 } 796 }
1006 797
1007 void *vpx_svc_get_buffer(const SvcContext *svc_ctx) { 798 // We will maintain a list of output frame buffers since with lag_in_frame
1008 const SvcInternal *const si = get_const_svc_internal(svc_ctx); 799 // we need to output all frame buffers at the end. vpx_svc_get_buffer() will
1009 if (svc_ctx == NULL || si == NULL) return NULL; 800 // remove a frame buffer from the list the put it to a temporal pointer, which
1010 return si->buffer; 801 // will be removed at the next vpx_svc_get_buffer() or when closing encoder.
802 void *vpx_svc_get_buffer(SvcContext *svc_ctx) {
803 SvcInternal *const si = get_svc_internal(svc_ctx);
804 if (svc_ctx == NULL || si == NULL || si->frame_list == NULL) return NULL;
805
806 if (si->frame_temp)
807 fd_free(si->frame_temp);
808
809 si->frame_temp = si->frame_list;
810 si->frame_list = si->frame_list->next;
811
812 return si->frame_temp->buf;
1011 } 813 }
1012 814
1013 size_t vpx_svc_get_frame_size(const SvcContext *svc_ctx) { 815 size_t vpx_svc_get_frame_size(const SvcContext *svc_ctx) {
1014 const SvcInternal *const si = get_const_svc_internal(svc_ctx); 816 const SvcInternal *const si = get_const_svc_internal(svc_ctx);
1015 if (svc_ctx == NULL || si == NULL) return 0; 817 if (svc_ctx == NULL || si == NULL || si->frame_list == NULL) return 0;
1016 return si->frame_size; 818 return si->frame_list->size;
1017 } 819 }
1018 820
1019 int vpx_svc_get_encode_frame_count(const SvcContext *svc_ctx) { 821 int vpx_svc_get_encode_frame_count(const SvcContext *svc_ctx) {
1020 const SvcInternal *const si = get_const_svc_internal(svc_ctx); 822 const SvcInternal *const si = get_const_svc_internal(svc_ctx);
1021 if (svc_ctx == NULL || si == NULL) return 0; 823 if (svc_ctx == NULL || si == NULL) return 0;
1022 return si->encode_frame_count; 824 return si->encode_frame_count;
1023 } 825 }
1024 826
1025 int vpx_svc_is_keyframe(const SvcContext *svc_ctx) { 827 int vpx_svc_is_keyframe(const SvcContext *svc_ctx) {
1026 const SvcInternal *const si = get_const_svc_internal(svc_ctx); 828 const SvcInternal *const si = get_const_svc_internal(svc_ctx);
1027 if (svc_ctx == NULL || si == NULL) return 0; 829 if (svc_ctx == NULL || si == NULL || si->frame_list == NULL) return 0;
1028 return si->is_keyframe; 830 return (si->frame_list->flags & VPX_FRAME_IS_KEY) != 0;
1029 } 831 }
1030 832
1031 void vpx_svc_set_keyframe(SvcContext *svc_ctx) { 833 void vpx_svc_set_keyframe(SvcContext *svc_ctx) {
1032 SvcInternal *const si = get_svc_internal(svc_ctx); 834 SvcInternal *const si = get_svc_internal(svc_ctx);
1033 if (svc_ctx == NULL || si == NULL) return; 835 if (svc_ctx == NULL || si == NULL) return;
1034 si->frame_within_gop = 0; 836 si->frame_within_gop = 0;
1035 } 837 }
1036 838
1037 static double calc_psnr(double d) { 839 static double calc_psnr(double d) {
1038 if (d == 0) return 100; 840 if (d == 0) return 100;
1039 return -10.0 * log(d) / log(10.0); 841 return -10.0 * log(d) / log(10.0);
1040 } 842 }
1041 843
1042 // dump accumulated statistics and reset accumulated values 844 // dump accumulated statistics and reset accumulated values
1043 const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) { 845 const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) {
1044 int number_of_frames, number_of_keyframes, encode_frame_count; 846 int number_of_frames, encode_frame_count;
1045 int i, j; 847 int i, j;
1046 uint32_t bytes_total = 0; 848 uint32_t bytes_total = 0;
1047 double scale[COMPONENTS]; 849 double scale[COMPONENTS];
1048 double psnr[COMPONENTS]; 850 double psnr[COMPONENTS];
1049 double mse[COMPONENTS]; 851 double mse[COMPONENTS];
1050 double y_scale; 852 double y_scale;
1051 853
1052 SvcInternal *const si = get_svc_internal(svc_ctx); 854 SvcInternal *const si = get_svc_internal(svc_ctx);
1053 if (svc_ctx == NULL || si == NULL) return NULL; 855 if (svc_ctx == NULL || si == NULL) return NULL;
1054 856
1055 svc_log_reset(svc_ctx); 857 svc_log_reset(svc_ctx);
1056 858
1057 encode_frame_count = si->encode_frame_count; 859 encode_frame_count = si->encode_frame_count;
1058 if (si->encode_frame_count <= 0) return vpx_svc_get_message(svc_ctx); 860 if (si->encode_frame_count <= 0) return vpx_svc_get_message(svc_ctx);
1059 861
1060 svc_log(svc_ctx, SVC_LOG_INFO, "\n"); 862 svc_log(svc_ctx, SVC_LOG_INFO, "\n");
1061 number_of_keyframes = encode_frame_count / si->kf_dist + 1;
1062 for (i = 0; i < si->layers; ++i) { 863 for (i = 0; i < si->layers; ++i) {
1063 number_of_frames = encode_frame_count; 864 number_of_frames = encode_frame_count;
1064 865
1065 if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP &&
1066 (i == 1 || i == 3)) {
1067 number_of_frames -= number_of_keyframes;
1068 }
1069 svc_log(svc_ctx, SVC_LOG_INFO, 866 svc_log(svc_ctx, SVC_LOG_INFO,
1070 "Layer %d Average PSNR=[%2.3f, %2.3f, %2.3f, %2.3f], Bytes=[%u]\n", 867 "Layer %d Average PSNR=[%2.3f, %2.3f, %2.3f, %2.3f], Bytes=[%u]\n",
1071 i, (double)si->psnr_sum[i][0] / number_of_frames, 868 i, (double)si->psnr_sum[i][0] / number_of_frames,
1072 (double)si->psnr_sum[i][1] / number_of_frames, 869 (double)si->psnr_sum[i][1] / number_of_frames,
1073 (double)si->psnr_sum[i][2] / number_of_frames, 870 (double)si->psnr_sum[i][2] / number_of_frames,
1074 (double)si->psnr_sum[i][3] / number_of_frames, si->bytes_sum[i]); 871 (double)si->psnr_sum[i][3] / number_of_frames, si->bytes_sum[i]);
1075 // the following psnr calculation is deduced from ffmpeg.c#print_report 872 // the following psnr calculation is deduced from ffmpeg.c#print_report
1076 y_scale = si->width * si->height * 255.0 * 255.0 * number_of_frames; 873 y_scale = si->width * si->height * 255.0 * 255.0 * number_of_frames;
1077 scale[1] = y_scale; 874 scale[1] = y_scale;
1078 scale[2] = scale[3] = y_scale / 4; // U or V 875 scale[2] = scale[3] = y_scale / 4; // U or V
(...skipping 26 matching lines...) Expand all
1105 return vpx_svc_get_message(svc_ctx); 902 return vpx_svc_get_message(svc_ctx);
1106 } 903 }
1107 904
1108 void vpx_svc_release(SvcContext *svc_ctx) { 905 void vpx_svc_release(SvcContext *svc_ctx) {
1109 SvcInternal *si; 906 SvcInternal *si;
1110 if (svc_ctx == NULL) return; 907 if (svc_ctx == NULL) return;
1111 // do not use get_svc_internal as it will unnecessarily allocate an 908 // do not use get_svc_internal as it will unnecessarily allocate an
1112 // SvcInternal if it was not already allocated 909 // SvcInternal if it was not already allocated
1113 si = (SvcInternal *)svc_ctx->internal; 910 si = (SvcInternal *)svc_ctx->internal;
1114 if (si != NULL) { 911 if (si != NULL) {
1115 free(si->buffer); 912 fd_free(si->frame_temp);
913 fd_free_list(si->frame_list);
1116 if (si->rc_stats_buf) { 914 if (si->rc_stats_buf) {
1117 free(si->rc_stats_buf); 915 free(si->rc_stats_buf);
1118 } 916 }
1119 free(si); 917 free(si);
1120 svc_ctx->internal = NULL; 918 svc_ctx->internal = NULL;
1121 } 919 }
1122 } 920 }
1123 921
1124 size_t vpx_svc_get_rc_stats_buffer_size(const SvcContext *svc_ctx) { 922 size_t vpx_svc_get_rc_stats_buffer_size(const SvcContext *svc_ctx) {
1125 const SvcInternal *const si = get_const_svc_internal(svc_ctx); 923 const SvcInternal *const si = get_const_svc_internal(svc_ctx);
1126 if (svc_ctx == NULL || si == NULL) return 0; 924 if (svc_ctx == NULL || si == NULL) return 0;
1127 return si->rc_stats_buf_used; 925 return si->rc_stats_buf_used;
1128 } 926 }
1129 927
1130 char *vpx_svc_get_rc_stats_buffer(const SvcContext *svc_ctx) { 928 char *vpx_svc_get_rc_stats_buffer(const SvcContext *svc_ctx) {
1131 const SvcInternal *const si = get_const_svc_internal(svc_ctx); 929 const SvcInternal *const si = get_const_svc_internal(svc_ctx);
1132 if (svc_ctx == NULL || si == NULL) return NULL; 930 if (svc_ctx == NULL || si == NULL) return NULL;
1133 return si->rc_stats_buf; 931 return si->rc_stats_buf;
1134 } 932 }
1135 933
1136 934
OLDNEW
« no previous file with comments | « source/libvpx/vp9/vp9cx.mk ('k') | source/libvpx/vpx/src/vpx_image.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698