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

Side by Side Diff: source/libvpx/vp9/vp9_cx_iface.c

Issue 181493009: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 9 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/vp9_common.mk ('k') | source/libvpx/vp9/vp9_dx_iface.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) 2010 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2010 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
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 257
258 if ((img->d_w != ctx->cfg.g_w) || (img->d_h != ctx->cfg.g_h)) 258 if ((img->d_w != ctx->cfg.g_w) || (img->d_h != ctx->cfg.g_h))
259 ERROR("Image size must match encoder init configuration size"); 259 ERROR("Image size must match encoder init configuration size");
260 260
261 return VPX_CODEC_OK; 261 return VPX_CODEC_OK;
262 } 262 }
263 263
264 264
265 static vpx_codec_err_t set_vp9e_config(VP9_CONFIG *oxcf, 265 static vpx_codec_err_t set_vp9e_config(VP9_CONFIG *oxcf,
266 vpx_codec_enc_cfg_t cfg, 266 vpx_codec_enc_cfg_t cfg,
267 struct vp9_extracfg vp8_cfg) { 267 struct vp9_extracfg vp9_cfg) {
268 oxcf->version = cfg.g_profile; 268 oxcf->version = cfg.g_profile;
269 oxcf->width = cfg.g_w; 269 oxcf->width = cfg.g_w;
270 oxcf->height = cfg.g_h; 270 oxcf->height = cfg.g_h;
271 /* guess a frame rate if out of whack, use 30 */ 271 /* guess a frame rate if out of whack, use 30 */
272 oxcf->framerate = (double)(cfg.g_timebase.den) 272 oxcf->framerate = (double)(cfg.g_timebase.den)
273 / (double)(cfg.g_timebase.num); 273 / (double)(cfg.g_timebase.num);
274 274
275 if (oxcf->framerate > 180) { 275 if (oxcf->framerate > 180) {
276 oxcf->framerate = 30; 276 oxcf->framerate = 30;
277 } 277 }
278 278
279 switch (cfg.g_pass) { 279 switch (cfg.g_pass) {
280 case VPX_RC_ONE_PASS: 280 case VPX_RC_ONE_PASS:
281 oxcf->mode = MODE_GOODQUALITY; 281 oxcf->mode = MODE_GOODQUALITY;
282 break; 282 break;
283 case VPX_RC_FIRST_PASS: 283 case VPX_RC_FIRST_PASS:
284 oxcf->mode = MODE_FIRSTPASS; 284 oxcf->mode = MODE_FIRSTPASS;
285 break; 285 break;
286 case VPX_RC_LAST_PASS: 286 case VPX_RC_LAST_PASS:
287 oxcf->mode = MODE_SECONDPASS_BEST; 287 oxcf->mode = MODE_SECONDPASS_BEST;
288 break; 288 break;
289 } 289 }
290 290
291 if (cfg.g_pass == VPX_RC_FIRST_PASS) { 291 if (cfg.g_pass == VPX_RC_FIRST_PASS) {
292 oxcf->allow_lag = 0;
293 oxcf->lag_in_frames = 0; 292 oxcf->lag_in_frames = 0;
294 } else { 293 } else {
295 oxcf->allow_lag = (cfg.g_lag_in_frames) > 0;
296 oxcf->lag_in_frames = cfg.g_lag_in_frames; 294 oxcf->lag_in_frames = cfg.g_lag_in_frames;
297 } 295 }
298 296
299 oxcf->end_usage = USAGE_LOCAL_FILE_PLAYBACK; 297 oxcf->end_usage = USAGE_LOCAL_FILE_PLAYBACK;
300 if (cfg.rc_end_usage == VPX_CQ) 298 if (cfg.rc_end_usage == VPX_CQ)
301 oxcf->end_usage = USAGE_CONSTRAINED_QUALITY; 299 oxcf->end_usage = USAGE_CONSTRAINED_QUALITY;
302 else if (cfg.rc_end_usage == VPX_Q) 300 else if (cfg.rc_end_usage == VPX_Q)
303 oxcf->end_usage = USAGE_CONSTANT_QUALITY; 301 oxcf->end_usage = USAGE_CONSTANT_QUALITY;
304 else if (cfg.rc_end_usage == VPX_CBR) 302 else if (cfg.rc_end_usage == VPX_CBR)
305 oxcf->end_usage = USAGE_STREAM_FROM_SERVER; 303 oxcf->end_usage = USAGE_STREAM_FROM_SERVER;
306 304
307 oxcf->target_bandwidth = cfg.rc_target_bitrate; 305 oxcf->target_bandwidth = cfg.rc_target_bitrate;
308 oxcf->rc_max_intra_bitrate_pct = vp8_cfg.rc_max_intra_bitrate_pct; 306 oxcf->rc_max_intra_bitrate_pct = vp9_cfg.rc_max_intra_bitrate_pct;
309 307
310 oxcf->best_allowed_q = cfg.rc_min_quantizer; 308 oxcf->best_allowed_q = cfg.rc_min_quantizer;
311 oxcf->worst_allowed_q = cfg.rc_max_quantizer; 309 oxcf->worst_allowed_q = cfg.rc_max_quantizer;
312 oxcf->cq_level = vp8_cfg.cq_level; 310 oxcf->cq_level = vp9_cfg.cq_level;
313 oxcf->fixed_q = -1; 311 oxcf->fixed_q = -1;
314 312
315 oxcf->under_shoot_pct = cfg.rc_undershoot_pct; 313 oxcf->under_shoot_pct = cfg.rc_undershoot_pct;
316 oxcf->over_shoot_pct = cfg.rc_overshoot_pct; 314 oxcf->over_shoot_pct = cfg.rc_overshoot_pct;
317 315
318 oxcf->maximum_buffer_size = cfg.rc_buf_sz; 316 oxcf->maximum_buffer_size = cfg.rc_buf_sz;
319 oxcf->starting_buffer_level = cfg.rc_buf_initial_sz; 317 oxcf->starting_buffer_level = cfg.rc_buf_initial_sz;
320 oxcf->optimal_buffer_level = cfg.rc_buf_optimal_sz; 318 oxcf->optimal_buffer_level = cfg.rc_buf_optimal_sz;
321 319
322 oxcf->drop_frames_water_mark = cfg.rc_dropframe_thresh; 320 oxcf->drop_frames_water_mark = cfg.rc_dropframe_thresh;
323 321
324 oxcf->two_pass_vbrbias = cfg.rc_2pass_vbr_bias_pct; 322 oxcf->two_pass_vbrbias = cfg.rc_2pass_vbr_bias_pct;
325 oxcf->two_pass_vbrmin_section = cfg.rc_2pass_vbr_minsection_pct; 323 oxcf->two_pass_vbrmin_section = cfg.rc_2pass_vbr_minsection_pct;
326 oxcf->two_pass_vbrmax_section = cfg.rc_2pass_vbr_maxsection_pct; 324 oxcf->two_pass_vbrmax_section = cfg.rc_2pass_vbr_maxsection_pct;
327 325
328 oxcf->auto_key = cfg.kf_mode == VPX_KF_AUTO 326 oxcf->auto_key = cfg.kf_mode == VPX_KF_AUTO
329 && cfg.kf_min_dist != cfg.kf_max_dist; 327 && cfg.kf_min_dist != cfg.kf_max_dist;
330 // oxcf->kf_min_dist = cfg.kf_min_dis; 328 // oxcf->kf_min_dist = cfg.kf_min_dis;
331 oxcf->key_freq = cfg.kf_max_dist; 329 oxcf->key_freq = cfg.kf_max_dist;
332 330
333 oxcf->cpu_used = vp8_cfg.cpu_used; 331 oxcf->cpu_used = vp9_cfg.cpu_used;
334 oxcf->encode_breakout = vp8_cfg.static_thresh; 332 oxcf->encode_breakout = vp9_cfg.static_thresh;
335 oxcf->play_alternate = vp8_cfg.enable_auto_alt_ref; 333 oxcf->play_alternate = vp9_cfg.enable_auto_alt_ref;
336 oxcf->noise_sensitivity = vp8_cfg.noise_sensitivity; 334 oxcf->noise_sensitivity = vp9_cfg.noise_sensitivity;
337 oxcf->sharpness = vp8_cfg.sharpness; 335 oxcf->sharpness = vp9_cfg.sharpness;
338 336
339 oxcf->two_pass_stats_in = cfg.rc_twopass_stats_in; 337 oxcf->two_pass_stats_in = cfg.rc_twopass_stats_in;
340 oxcf->output_pkt_list = vp8_cfg.pkt_list; 338 oxcf->output_pkt_list = vp9_cfg.pkt_list;
341 339
342 oxcf->arnr_max_frames = vp8_cfg.arnr_max_frames; 340 oxcf->arnr_max_frames = vp9_cfg.arnr_max_frames;
343 oxcf->arnr_strength = vp8_cfg.arnr_strength; 341 oxcf->arnr_strength = vp9_cfg.arnr_strength;
344 oxcf->arnr_type = vp8_cfg.arnr_type; 342 oxcf->arnr_type = vp9_cfg.arnr_type;
345 343
346 oxcf->tuning = vp8_cfg.tuning; 344 oxcf->tuning = vp9_cfg.tuning;
347 345
348 oxcf->tile_columns = vp8_cfg.tile_columns; 346 oxcf->tile_columns = vp9_cfg.tile_columns;
349 oxcf->tile_rows = vp8_cfg.tile_rows; 347 oxcf->tile_rows = vp9_cfg.tile_rows;
350 348
351 oxcf->lossless = vp8_cfg.lossless; 349 oxcf->lossless = vp9_cfg.lossless;
352 350
353 oxcf->error_resilient_mode = cfg.g_error_resilient; 351 oxcf->error_resilient_mode = cfg.g_error_resilient;
354 oxcf->frame_parallel_decoding_mode = vp8_cfg.frame_parallel_decoding_mode; 352 oxcf->frame_parallel_decoding_mode = vp9_cfg.frame_parallel_decoding_mode;
355 353
356 oxcf->aq_mode = vp8_cfg.aq_mode; 354 oxcf->aq_mode = vp9_cfg.aq_mode;
357 355
358 oxcf->ss_number_layers = cfg.ss_number_layers; 356 oxcf->ss_number_layers = cfg.ss_number_layers;
359 357
358 if (oxcf->ss_number_layers > 1) {
359 memcpy(oxcf->ss_target_bitrate, cfg.ss_target_bitrate,
360 sizeof(cfg.ss_target_bitrate));
361 } else if (oxcf->ss_number_layers == 1) {
362 oxcf->ss_target_bitrate[0] = (int)oxcf->target_bandwidth;
363 }
364
360 oxcf->ts_number_layers = cfg.ts_number_layers; 365 oxcf->ts_number_layers = cfg.ts_number_layers;
361 366
362 if (oxcf->ts_number_layers > 1) { 367 if (oxcf->ts_number_layers > 1) {
363 memcpy(oxcf->ts_target_bitrate, cfg.ts_target_bitrate, 368 memcpy(oxcf->ts_target_bitrate, cfg.ts_target_bitrate,
364 sizeof(cfg.ts_target_bitrate)); 369 sizeof(cfg.ts_target_bitrate));
365 memcpy(oxcf->ts_rate_decimator, cfg.ts_rate_decimator, 370 memcpy(oxcf->ts_rate_decimator, cfg.ts_rate_decimator,
366 sizeof(cfg.ts_rate_decimator)); 371 sizeof(cfg.ts_rate_decimator));
367 } else if (oxcf->ts_number_layers == 1) { 372 } else if (oxcf->ts_number_layers == 1) {
368 oxcf->ts_target_bitrate[0] = oxcf->target_bandwidth; 373 oxcf->ts_target_bitrate[0] = (int)oxcf->target_bandwidth;
369 oxcf->ts_rate_decimator[0] = 1; 374 oxcf->ts_rate_decimator[0] = 1;
370 } 375 }
371 376
372 /* 377 /*
373 printf("Current VP9 Settings: \n"); 378 printf("Current VP9 Settings: \n");
374 printf("target_bandwidth: %d\n", oxcf->target_bandwidth); 379 printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
375 printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity); 380 printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
376 printf("sharpness: %d\n", oxcf->sharpness); 381 printf("sharpness: %d\n", oxcf->sharpness);
377 printf("cpu_used: %d\n", oxcf->cpu_used); 382 printf("cpu_used: %d\n", oxcf->cpu_used);
378 printf("Mode: %d\n", oxcf->mode); 383 printf("Mode: %d\n", oxcf->mode);
379 printf("auto_key: %d\n", oxcf->auto_key); 384 printf("auto_key: %d\n", oxcf->auto_key);
380 printf("key_freq: %d\n", oxcf->key_freq); 385 printf("key_freq: %d\n", oxcf->key_freq);
381 printf("end_usage: %d\n", oxcf->end_usage); 386 printf("end_usage: %d\n", oxcf->end_usage);
382 printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct); 387 printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct);
383 printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct); 388 printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct);
384 printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level); 389 printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level);
385 printf("optimal_buffer_level: %d\n", oxcf->optimal_buffer_level); 390 printf("optimal_buffer_level: %d\n", oxcf->optimal_buffer_level);
386 printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size); 391 printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size);
387 printf("fixed_q: %d\n", oxcf->fixed_q); 392 printf("fixed_q: %d\n", oxcf->fixed_q);
388 printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q); 393 printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q);
389 printf("best_allowed_q: %d\n", oxcf->best_allowed_q); 394 printf("best_allowed_q: %d\n", oxcf->best_allowed_q);
390 printf("two_pass_vbrbias: %d\n", oxcf->two_pass_vbrbias); 395 printf("two_pass_vbrbias: %d\n", oxcf->two_pass_vbrbias);
391 printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section); 396 printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
392 printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section); 397 printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
393 printf("allow_lag: %d\n", oxcf->allow_lag);
394 printf("lag_in_frames: %d\n", oxcf->lag_in_frames); 398 printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
395 printf("play_alternate: %d\n", oxcf->play_alternate); 399 printf("play_alternate: %d\n", oxcf->play_alternate);
396 printf("Version: %d\n", oxcf->Version); 400 printf("Version: %d\n", oxcf->Version);
397 printf("encode_breakout: %d\n", oxcf->encode_breakout); 401 printf("encode_breakout: %d\n", oxcf->encode_breakout);
398 printf("error resilient: %d\n", oxcf->error_resilient_mode); 402 printf("error resilient: %d\n", oxcf->error_resilient_mode);
399 printf("frame parallel detokenization: %d\n", 403 printf("frame parallel detokenization: %d\n",
400 oxcf->frame_parallel_decoding_mode); 404 oxcf->frame_parallel_decoding_mode);
401 */ 405 */
402 return VPX_CODEC_OK; 406 return VPX_CODEC_OK;
403 } 407 }
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 marker |= mag << 3; 636 marker |= mag << 3;
633 637
634 /* Write the index */ 638 /* Write the index */
635 index_sz = 2 + (mag + 1) * ctx->pending_frame_count; 639 index_sz = 2 + (mag + 1) * ctx->pending_frame_count;
636 if (ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz) { 640 if (ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz) {
637 uint8_t *x = ctx->pending_cx_data + ctx->pending_cx_data_sz; 641 uint8_t *x = ctx->pending_cx_data + ctx->pending_cx_data_sz;
638 int i, j; 642 int i, j;
639 643
640 *x++ = marker; 644 *x++ = marker;
641 for (i = 0; i < ctx->pending_frame_count; i++) { 645 for (i = 0; i < ctx->pending_frame_count; i++) {
642 int this_sz = ctx->pending_frame_sizes[i]; 646 unsigned int this_sz = (unsigned int)ctx->pending_frame_sizes[i];
643 647
644 for (j = 0; j <= mag; j++) { 648 for (j = 0; j <= mag; j++) {
645 *x++ = this_sz & 0xff; 649 *x++ = this_sz & 0xff;
646 this_sz >>= 8; 650 this_sz >>= 8;
647 } 651 }
648 } 652 }
649 *x++ = marker; 653 *x++ = marker;
650 ctx->pending_cx_data_sz += index_sz; 654 ctx->pending_cx_data_sz += index_sz;
651 } 655 }
652 return index_sz; 656 return index_sz;
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 vpx_svc_layer_id_t *data = va_arg(args, vpx_svc_layer_id_t *); 1046 vpx_svc_layer_id_t *data = va_arg(args, vpx_svc_layer_id_t *);
1043 VP9_COMP *cpi = (VP9_COMP *)ctx->cpi; 1047 VP9_COMP *cpi = (VP9_COMP *)ctx->cpi;
1044 cpi->svc.spatial_layer_id = data->spatial_layer_id; 1048 cpi->svc.spatial_layer_id = data->spatial_layer_id;
1045 cpi->svc.temporal_layer_id = data->temporal_layer_id; 1049 cpi->svc.temporal_layer_id = data->temporal_layer_id;
1046 // Checks on valid layer_id input. 1050 // Checks on valid layer_id input.
1047 if (cpi->svc.temporal_layer_id < 0 || 1051 if (cpi->svc.temporal_layer_id < 0 ||
1048 cpi->svc.temporal_layer_id >= (int)ctx->cfg.ts_number_layers) { 1052 cpi->svc.temporal_layer_id >= (int)ctx->cfg.ts_number_layers) {
1049 return VPX_CODEC_INVALID_PARAM; 1053 return VPX_CODEC_INVALID_PARAM;
1050 } 1054 }
1051 if (cpi->svc.spatial_layer_id < 0 || 1055 if (cpi->svc.spatial_layer_id < 0 ||
1052 cpi->svc.spatial_layer_id >= ctx->cfg.ss_number_layers) { 1056 cpi->svc.spatial_layer_id >= (int)ctx->cfg.ss_number_layers) {
1053 return VPX_CODEC_INVALID_PARAM; 1057 return VPX_CODEC_INVALID_PARAM;
1054 } 1058 }
1055 return VPX_CODEC_OK; 1059 return VPX_CODEC_OK;
1056 } 1060 }
1057 1061
1058 static vpx_codec_err_t vp9e_set_svc_parameters(vpx_codec_alg_priv_t *ctx, 1062 static vpx_codec_err_t vp9e_set_svc_parameters(vpx_codec_alg_priv_t *ctx,
1059 int ctr_id, va_list args) { 1063 int ctr_id, va_list args) {
1060 VP9_COMP *cpi = (VP9_COMP *)ctx->cpi; 1064 VP9_COMP *cpi = (VP9_COMP *)ctx->cpi;
1061 vpx_svc_parameters_t *params = va_arg(args, vpx_svc_parameters_t *); 1065 vpx_svc_parameters_t *params = va_arg(args, vpx_svc_parameters_t *);
1062 1066
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 50, /* rc_two_pass_vbrbias */ 1160 50, /* rc_two_pass_vbrbias */
1157 0, /* rc_two_pass_vbrmin_section */ 1161 0, /* rc_two_pass_vbrmin_section */
1158 2000, /* rc_two_pass_vbrmax_section */ 1162 2000, /* rc_two_pass_vbrmax_section */
1159 1163
1160 /* keyframing settings (kf) */ 1164 /* keyframing settings (kf) */
1161 VPX_KF_AUTO, /* g_kfmode*/ 1165 VPX_KF_AUTO, /* g_kfmode*/
1162 0, /* kf_min_dist */ 1166 0, /* kf_min_dist */
1163 9999, /* kf_max_dist */ 1167 9999, /* kf_max_dist */
1164 1168
1165 VPX_SS_DEFAULT_LAYERS, /* ss_number_layers */ 1169 VPX_SS_DEFAULT_LAYERS, /* ss_number_layers */
1170 {0}, /* ss_target_bitrate */
1166 1, /* ts_number_layers */ 1171 1, /* ts_number_layers */
1167 {0}, /* ts_target_bitrate */ 1172 {0}, /* ts_target_bitrate */
1168 {0}, /* ts_rate_decimator */ 1173 {0}, /* ts_rate_decimator */
1169 0, /* ts_periodicity */ 1174 0, /* ts_periodicity */
1170 {0}, /* ts_layer_id */ 1175 {0}, /* ts_layer_id */
1171 #if VPX_ENCODER_ABI_VERSION == (1 + VPX_CODEC_ABI_VERSION) 1176 #if VPX_ENCODER_ABI_VERSION == (1 + VPX_CODEC_ABI_VERSION)
1172 "vp8.fpf" /* first pass filename */ 1177 "vp8.fpf" /* first pass filename */
1173 #endif 1178 #endif
1174 } 1179 }
1175 }, 1180 },
(...skipping 23 matching lines...) Expand all
1199 }, 1204 },
1200 { // NOLINT 1205 { // NOLINT
1201 vp9e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t peek_si; */ 1206 vp9e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t peek_si; */
1202 vp9e_encode, /* vpx_codec_encode_fn_t encode; */ 1207 vp9e_encode, /* vpx_codec_encode_fn_t encode; */
1203 vp9e_get_cxdata, /* vpx_codec_get_cx_data_fn_t frame_get; */ 1208 vp9e_get_cxdata, /* vpx_codec_get_cx_data_fn_t frame_get; */
1204 vp9e_set_config, 1209 vp9e_set_config,
1205 NOT_IMPLEMENTED, 1210 NOT_IMPLEMENTED,
1206 vp9e_get_preview, 1211 vp9e_get_preview,
1207 } /* encoder functions */ 1212 } /* encoder functions */
1208 }; 1213 };
OLDNEW
« no previous file with comments | « source/libvpx/vp9/vp9_common.mk ('k') | source/libvpx/vp9/vp9_dx_iface.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698