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 |