| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2014 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 #include <math.h> | 11 #include <math.h> |
| 12 | 12 |
| 13 #include "vp9/encoder/vp9_encoder.h" | 13 #include "vp9/encoder/vp9_encoder.h" |
| 14 #include "vp9/encoder/vp9_svc_layercontext.h" | 14 #include "vp9/encoder/vp9_svc_layercontext.h" |
| 15 #include "vp9/encoder/vp9_extend.h" | 15 #include "vp9/encoder/vp9_extend.h" |
| 16 | 16 |
| 17 void vp9_init_layer_context(VP9_COMP *const cpi) { | 17 void vp9_init_layer_context(VP9_COMP *const cpi) { |
| 18 SVC *const svc = &cpi->svc; | 18 SVC *const svc = &cpi->svc; |
| 19 const VP9EncoderConfig *const oxcf = &cpi->oxcf; | 19 const VP9EncoderConfig *const oxcf = &cpi->oxcf; |
| 20 int layer; | 20 int layer; |
| 21 int layer_end; | 21 int layer_end; |
| 22 int alt_ref_idx = svc->number_spatial_layers * svc->number_temporal_layers; | 22 int alt_ref_idx = svc->number_spatial_layers; |
| 23 | 23 |
| 24 svc->spatial_layer_id = 0; | 24 svc->spatial_layer_id = 0; |
| 25 svc->temporal_layer_id = 0; | 25 svc->temporal_layer_id = 0; |
| 26 | 26 |
| 27 if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) { | 27 if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) { |
| 28 layer_end = svc->number_temporal_layers; | 28 layer_end = svc->number_temporal_layers; |
| 29 } else { | 29 } else { |
| 30 layer_end = svc->number_spatial_layers; | 30 layer_end = svc->number_spatial_layers; |
| 31 } | 31 } |
| 32 | 32 |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 ++lc->frames_from_key_frame; | 226 ++lc->frames_from_key_frame; |
| 227 } | 227 } |
| 228 | 228 |
| 229 int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) { | 229 int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) { |
| 230 return is_two_pass_svc(cpi) && | 230 return is_two_pass_svc(cpi) && |
| 231 cpi->svc.spatial_layer_id > 0 && | 231 cpi->svc.spatial_layer_id > 0 && |
| 232 cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame; | 232 cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame; |
| 233 } | 233 } |
| 234 | 234 |
| 235 #if CONFIG_SPATIAL_SVC | 235 #if CONFIG_SPATIAL_SVC |
| 236 int vp9_svc_lookahead_push(const VP9_COMP *const cpi, struct lookahead_ctx *ctx, | 236 static void get_layer_resolution(const int width_org, const int height_org, |
| 237 YV12_BUFFER_CONFIG *src, int64_t ts_start, | 237 const int num, const int den, |
| 238 int64_t ts_end, unsigned int flags) { | 238 int *width_out, int *height_out) { |
| 239 struct lookahead_entry *buf; | 239 int w, h; |
| 240 int i, index; | |
| 241 | 240 |
| 242 if (vp9_lookahead_push(ctx, src, ts_start, ts_end, flags)) | 241 if (width_out == NULL || height_out == NULL || den == 0) |
| 243 return 1; | 242 return; |
| 244 | 243 |
| 245 index = ctx->write_idx - 1; | 244 w = width_org * num / den; |
| 246 if (index < 0) | 245 h = height_org * num / den; |
| 247 index += ctx->max_sz; | |
| 248 | 246 |
| 249 buf = ctx->buf + index; | 247 // make height and width even to make chrome player happy |
| 248 w += w % 2; |
| 249 h += h % 2; |
| 250 | 250 |
| 251 if (buf == NULL) | 251 *width_out = w; |
| 252 return 1; | 252 *height_out = h; |
| 253 | |
| 254 // Store svc parameters for each layer | |
| 255 for (i = 0; i < cpi->svc.number_spatial_layers; ++i) | |
| 256 buf->svc_params[i] = cpi->svc.layer_context[i].svc_params_received; | |
| 257 | |
| 258 return 0; | |
| 259 } | 253 } |
| 260 | 254 |
| 261 static int copy_svc_params(VP9_COMP *const cpi, struct lookahead_entry *buf) { | 255 int vp9_svc_start_frame(VP9_COMP *const cpi) { |
| 262 int layer_id; | 256 int width = 0, height = 0; |
| 263 vpx_svc_parameters_t *layer_param; | |
| 264 LAYER_CONTEXT *lc; | 257 LAYER_CONTEXT *lc; |
| 265 int count = 1 << (cpi->svc.number_temporal_layers - 1); | 258 int count = 1 << (cpi->svc.number_temporal_layers - 1); |
| 266 | 259 |
| 267 // Find the next layer to be encoded | 260 cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode; |
| 268 for (layer_id = 0; layer_id < cpi->svc.number_spatial_layers; ++layer_id) { | |
| 269 if (buf->svc_params[layer_id].spatial_layer >=0) | |
| 270 break; | |
| 271 } | |
| 272 | |
| 273 if (layer_id == cpi->svc.number_spatial_layers) | |
| 274 return 1; | |
| 275 | |
| 276 layer_param = &buf->svc_params[layer_id]; | |
| 277 cpi->svc.spatial_layer_id = layer_param->spatial_layer; | |
| 278 cpi->svc.temporal_layer_id = layer_param->temporal_layer; | |
| 279 cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; | |
| 280 | |
| 281 lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id]; | 261 lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id]; |
| 282 | 262 |
| 283 cpi->svc.temporal_layer_id = 0; | 263 cpi->svc.temporal_layer_id = 0; |
| 284 while ((lc->current_video_frame_in_layer % count) != 0) { | 264 while ((lc->current_video_frame_in_layer % count) != 0) { |
| 285 ++cpi->svc.temporal_layer_id; | 265 ++cpi->svc.temporal_layer_id; |
| 286 count >>= 1; | 266 count >>= 1; |
| 287 } | 267 } |
| 288 | 268 |
| 289 cpi->lst_fb_idx = | 269 cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; |
| 290 cpi->svc.spatial_layer_id * cpi->svc.number_temporal_layers + | |
| 291 cpi->svc.temporal_layer_id; | |
| 292 if (lc->frames_from_key_frame < cpi->svc.number_temporal_layers) | |
| 293 cpi->ref_frame_flags &= ~VP9_LAST_FLAG; | |
| 294 | 270 |
| 295 if (cpi->svc.spatial_layer_id == 0) { | 271 cpi->lst_fb_idx = cpi->svc.spatial_layer_id; |
| 296 if (cpi->svc.temporal_layer_id == 0) | 272 |
| 297 cpi->gld_fb_idx = lc->gold_ref_idx >= 0 ? | 273 if (cpi->svc.spatial_layer_id == 0) |
| 298 lc->gold_ref_idx : cpi->lst_fb_idx; | 274 cpi->gld_fb_idx = (lc->gold_ref_idx >= 0) ? |
| 299 else | 275 lc->gold_ref_idx : cpi->lst_fb_idx; |
| 300 cpi->gld_fb_idx = cpi->lst_fb_idx - 1; | 276 else |
| 301 } else { | 277 cpi->gld_fb_idx = cpi->svc.spatial_layer_id - 1; |
| 302 if (cpi->svc.temporal_layer_id == 0) | |
| 303 cpi->gld_fb_idx = cpi->svc.spatial_layer_id - | |
| 304 cpi->svc.number_temporal_layers; | |
| 305 else | |
| 306 cpi->gld_fb_idx = cpi->lst_fb_idx - 1; | |
| 307 } | |
| 308 | 278 |
| 309 if (lc->current_video_frame_in_layer == 0) { | 279 if (lc->current_video_frame_in_layer == 0) { |
| 310 if (cpi->svc.spatial_layer_id >= 2) { | 280 if (cpi->svc.spatial_layer_id >= 2) { |
| 311 cpi->alt_fb_idx = | 281 cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2; |
| 312 cpi->svc.spatial_layer_id - 2 * cpi->svc.number_temporal_layers; | |
| 313 } else { | 282 } else { |
| 314 cpi->alt_fb_idx = cpi->lst_fb_idx; | 283 cpi->alt_fb_idx = cpi->lst_fb_idx; |
| 315 cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_ALT_FLAG); | 284 cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_ALT_FLAG); |
| 316 } | 285 } |
| 317 } else { | 286 } else { |
| 318 if (cpi->oxcf.ss_play_alternate[cpi->svc.spatial_layer_id]) { | 287 if (cpi->oxcf.ss_play_alternate[cpi->svc.spatial_layer_id]) { |
| 319 cpi->alt_fb_idx = lc->alt_ref_idx; | 288 cpi->alt_fb_idx = lc->alt_ref_idx; |
| 320 if (!lc->has_alt_frame) | 289 if (!lc->has_alt_frame) |
| 321 cpi->ref_frame_flags &= (~VP9_ALT_FLAG); | 290 cpi->ref_frame_flags &= (~VP9_ALT_FLAG); |
| 322 } else { | 291 } else { |
| 323 // Find a proper alt_fb_idx for layers that don't have alt ref frame | 292 // Find a proper alt_fb_idx for layers that don't have alt ref frame |
| 324 if (cpi->svc.spatial_layer_id == 0) { | 293 if (cpi->svc.spatial_layer_id == 0) { |
| 325 cpi->alt_fb_idx = cpi->lst_fb_idx; | 294 cpi->alt_fb_idx = cpi->lst_fb_idx; |
| 326 } else { | 295 } else { |
| 327 LAYER_CONTEXT *lc_lower = | 296 LAYER_CONTEXT *lc_lower = |
| 328 &cpi->svc.layer_context[cpi->svc.spatial_layer_id - 1]; | 297 &cpi->svc.layer_context[cpi->svc.spatial_layer_id - 1]; |
| 329 | 298 |
| 330 if (cpi->oxcf.ss_play_alternate[cpi->svc.spatial_layer_id - 1] && | 299 if (cpi->oxcf.ss_play_alternate[cpi->svc.spatial_layer_id - 1] && |
| 331 lc_lower->alt_ref_source != NULL) | 300 lc_lower->alt_ref_source != NULL) |
| 332 cpi->alt_fb_idx = lc_lower->alt_ref_idx; | 301 cpi->alt_fb_idx = lc_lower->alt_ref_idx; |
| 333 else if (cpi->svc.spatial_layer_id >= 2) | 302 else if (cpi->svc.spatial_layer_id >= 2) |
| 334 cpi->alt_fb_idx = | 303 cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2; |
| 335 cpi->svc.spatial_layer_id - 2 * cpi->svc.number_temporal_layers; | |
| 336 else | 304 else |
| 337 cpi->alt_fb_idx = cpi->lst_fb_idx; | 305 cpi->alt_fb_idx = cpi->lst_fb_idx; |
| 338 } | 306 } |
| 339 } | 307 } |
| 340 } | 308 } |
| 341 | 309 |
| 342 if (vp9_set_size_literal(cpi, layer_param->width, layer_param->height) != 0) | 310 get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height, |
| 311 lc->scaling_factor_num, lc->scaling_factor_den, |
| 312 &width, &height); |
| 313 if (vp9_set_size_literal(cpi, width, height) != 0) |
| 343 return VPX_CODEC_INVALID_PARAM; | 314 return VPX_CODEC_INVALID_PARAM; |
| 344 | 315 |
| 345 cpi->oxcf.worst_allowed_q = | 316 cpi->oxcf.worst_allowed_q = vp9_quantizer_to_qindex(lc->max_q); |
| 346 vp9_quantizer_to_qindex(layer_param->max_quantizer); | 317 cpi->oxcf.best_allowed_q = vp9_quantizer_to_qindex(lc->min_q); |
| 347 cpi->oxcf.best_allowed_q = | |
| 348 vp9_quantizer_to_qindex(layer_param->min_quantizer); | |
| 349 | 318 |
| 350 vp9_change_config(cpi, &cpi->oxcf); | 319 vp9_change_config(cpi, &cpi->oxcf); |
| 351 | 320 |
| 352 vp9_set_high_precision_mv(cpi, 1); | 321 vp9_set_high_precision_mv(cpi, 1); |
| 353 | 322 |
| 354 cpi->alt_ref_source = get_layer_context(cpi)->alt_ref_source; | 323 cpi->alt_ref_source = get_layer_context(cpi)->alt_ref_source; |
| 355 | 324 |
| 356 return 0; | 325 return 0; |
| 357 } | 326 } |
| 358 | 327 |
| 359 struct lookahead_entry *vp9_svc_lookahead_peek(VP9_COMP *const cpi, | |
| 360 struct lookahead_ctx *ctx, | |
| 361 int index, int copy_params) { | |
| 362 struct lookahead_entry *buf = vp9_lookahead_peek(ctx, index); | |
| 363 | |
| 364 if (buf != NULL && copy_params != 0) { | |
| 365 if (copy_svc_params(cpi, buf) != 0) | |
| 366 return NULL; | |
| 367 } | |
| 368 return buf; | |
| 369 } | |
| 370 | |
| 371 struct lookahead_entry *vp9_svc_lookahead_pop(VP9_COMP *const cpi, | 328 struct lookahead_entry *vp9_svc_lookahead_pop(VP9_COMP *const cpi, |
| 372 struct lookahead_ctx *ctx, | 329 struct lookahead_ctx *ctx, |
| 373 int drain) { | 330 int drain) { |
| 374 struct lookahead_entry *buf = NULL; | 331 struct lookahead_entry *buf = NULL; |
| 375 | 332 |
| 376 if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) { | 333 if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) { |
| 377 buf = vp9_svc_lookahead_peek(cpi, ctx, 0, 1); | 334 buf = vp9_lookahead_peek(ctx, 0); |
| 378 if (buf != NULL) { | 335 if (buf != NULL) { |
| 379 // Only remove the buffer when pop the highest layer. Simply set the | 336 // Only remove the buffer when pop the highest layer. |
| 380 // spatial_layer to -1 for lower layers. | |
| 381 buf->svc_params[cpi->svc.spatial_layer_id].spatial_layer = -1; | |
| 382 if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) { | 337 if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) { |
| 383 vp9_lookahead_pop(ctx, drain); | 338 vp9_lookahead_pop(ctx, drain); |
| 384 } | 339 } |
| 385 } | 340 } |
| 386 } | 341 } |
| 387 | 342 |
| 388 return buf; | 343 return buf; |
| 389 } | 344 } |
| 390 #endif | 345 #endif |
| OLD | NEW |