| Index: source/libvpx/vp9/encoder/vp9_encoder.c
|
| diff --git a/source/libvpx/vp9/encoder/vp9_encoder.c b/source/libvpx/vp9/encoder/vp9_encoder.c
|
| index 3c0f52e145a2660d0bc22a6c9dde79bbda8aa265..b79bc00d23720b0a33fd2b6f156a102344c7a220 100644
|
| --- a/source/libvpx/vp9/encoder/vp9_encoder.c
|
| +++ b/source/libvpx/vp9/encoder/vp9_encoder.c
|
| @@ -756,6 +756,8 @@ static void init_config(struct VP9_COMP *cpi, VP9EncoderConfig *oxcf) {
|
| cm->height = oxcf->height;
|
| vp9_alloc_compressor_data(cpi);
|
|
|
| + cpi->svc.temporal_layering_mode = oxcf->temporal_layering_mode;
|
| +
|
| // Single thread case: use counts in common.
|
| cpi->td.counts = &cm->counts;
|
|
|
| @@ -2054,6 +2056,65 @@ void vp9_remove_compressor(VP9_COMP *cpi) {
|
| #endif
|
| }
|
|
|
| +/* TODO(yaowu): The block_variance calls the unoptimized versions of variance()
|
| + * and highbd_8_variance(). It should not.
|
| + */
|
| +static void encoder_variance(const uint8_t *a, int a_stride,
|
| + const uint8_t *b, int b_stride,
|
| + int w, int h, unsigned int *sse, int *sum) {
|
| + int i, j;
|
| +
|
| + *sum = 0;
|
| + *sse = 0;
|
| +
|
| + for (i = 0; i < h; i++) {
|
| + for (j = 0; j < w; j++) {
|
| + const int diff = a[j] - b[j];
|
| + *sum += diff;
|
| + *sse += diff * diff;
|
| + }
|
| +
|
| + a += a_stride;
|
| + b += b_stride;
|
| + }
|
| +}
|
| +
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| +static void encoder_highbd_variance64(const uint8_t *a8, int a_stride,
|
| + const uint8_t *b8, int b_stride,
|
| + int w, int h, uint64_t *sse,
|
| + uint64_t *sum) {
|
| + int i, j;
|
| +
|
| + uint16_t *a = CONVERT_TO_SHORTPTR(a8);
|
| + uint16_t *b = CONVERT_TO_SHORTPTR(b8);
|
| + *sum = 0;
|
| + *sse = 0;
|
| +
|
| + for (i = 0; i < h; i++) {
|
| + for (j = 0; j < w; j++) {
|
| + const int diff = a[j] - b[j];
|
| + *sum += diff;
|
| + *sse += diff * diff;
|
| + }
|
| + a += a_stride;
|
| + b += b_stride;
|
| + }
|
| +}
|
| +
|
| +static void encoder_highbd_8_variance(const uint8_t *a8, int a_stride,
|
| + const uint8_t *b8, int b_stride,
|
| + int w, int h,
|
| + unsigned int *sse, int *sum) {
|
| + uint64_t sse_long = 0;
|
| + uint64_t sum_long = 0;
|
| + encoder_highbd_variance64(a8, a_stride, b8, b_stride, w, h,
|
| + &sse_long, &sum_long);
|
| + *sse = (unsigned int)sse_long;
|
| + *sum = (int)sum_long;
|
| +}
|
| +#endif // CONFIG_VP9_HIGHBITDEPTH
|
| +
|
| static int64_t get_sse(const uint8_t *a, int a_stride,
|
| const uint8_t *b, int b_stride,
|
| int width, int height) {
|
| @@ -2065,15 +2126,15 @@ static int64_t get_sse(const uint8_t *a, int a_stride,
|
| int x, y;
|
|
|
| if (dw > 0) {
|
| - variance(&a[width - dw], a_stride, &b[width - dw], b_stride,
|
| - dw, height, &sse, &sum);
|
| + encoder_variance(&a[width - dw], a_stride, &b[width - dw], b_stride,
|
| + dw, height, &sse, &sum);
|
| total_sse += sse;
|
| }
|
|
|
| if (dh > 0) {
|
| - variance(&a[(height - dh) * a_stride], a_stride,
|
| - &b[(height - dh) * b_stride], b_stride,
|
| - width - dw, dh, &sse, &sum);
|
| + encoder_variance(&a[(height - dh) * a_stride], a_stride,
|
| + &b[(height - dh) * b_stride], b_stride,
|
| + width - dw, dh, &sse, &sum);
|
| total_sse += sse;
|
| }
|
|
|
| @@ -2126,14 +2187,15 @@ static int64_t highbd_get_sse(const uint8_t *a, int a_stride,
|
| unsigned int sse = 0;
|
| int sum = 0;
|
| if (dw > 0) {
|
| - highbd_8_variance(&a[width - dw], a_stride, &b[width - dw], b_stride,
|
| - dw, height, &sse, &sum);
|
| + encoder_highbd_8_variance(&a[width - dw], a_stride,
|
| + &b[width - dw], b_stride,
|
| + dw, height, &sse, &sum);
|
| total_sse += sse;
|
| }
|
| if (dh > 0) {
|
| - highbd_8_variance(&a[(height - dh) * a_stride], a_stride,
|
| - &b[(height - dh) * b_stride], b_stride,
|
| - width - dw, dh, &sse, &sum);
|
| + encoder_highbd_8_variance(&a[(height - dh) * a_stride], a_stride,
|
| + &b[(height - dh) * b_stride], b_stride,
|
| + width - dw, dh, &sse, &sum);
|
| total_sse += sse;
|
| }
|
| for (y = 0; y < height / 16; ++y) {
|
| @@ -2265,8 +2327,9 @@ static void generate_psnr_packet(VP9_COMP *cpi) {
|
| pkt.data.psnr.psnr[i] = psnr.psnr[i];
|
| }
|
| pkt.kind = VPX_CODEC_PSNR_PKT;
|
| - if (is_two_pass_svc(cpi))
|
| - cpi->svc.layer_context[cpi->svc.spatial_layer_id].psnr_pkt = pkt.data.psnr;
|
| + if (cpi->use_svc)
|
| + cpi->svc.layer_context[cpi->svc.spatial_layer_id *
|
| + cpi->svc.number_temporal_layers].psnr_pkt = pkt.data.psnr;
|
| else
|
| vpx_codec_pkt_list_add(cpi->output_pkt_list, &pkt);
|
| }
|
| @@ -3667,9 +3730,11 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
| }
|
| cm->prev_frame = cm->cur_frame;
|
|
|
| - if (is_two_pass_svc(cpi))
|
| - cpi->svc.layer_context[cpi->svc.spatial_layer_id].last_frame_type =
|
| - cm->frame_type;
|
| + if (cpi->use_svc)
|
| + cpi->svc.layer_context[cpi->svc.spatial_layer_id *
|
| + cpi->svc.number_temporal_layers +
|
| + cpi->svc.temporal_layer_id].last_frame_type =
|
| + cm->frame_type;
|
| }
|
|
|
| static void SvcEncode(VP9_COMP *cpi, size_t *size, uint8_t *dest,
|
| @@ -3930,6 +3995,8 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
| #endif
|
| if (oxcf->pass == 2)
|
| vp9_restore_layer_context(cpi);
|
| + } else if (is_one_pass_cbr_svc(cpi)) {
|
| + vp9_one_pass_cbr_svc_start_layer(cpi);
|
| }
|
|
|
| vpx_usec_timer_start(&cmptimer);
|
| @@ -3948,9 +4015,11 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
| // Normal defaults
|
| cm->reset_frame_context = 0;
|
| cm->refresh_frame_context = 1;
|
| - cpi->refresh_last_frame = 1;
|
| - cpi->refresh_golden_frame = 0;
|
| - cpi->refresh_alt_ref_frame = 0;
|
| + if (!is_one_pass_cbr_svc(cpi)) {
|
| + cpi->refresh_last_frame = 1;
|
| + cpi->refresh_golden_frame = 0;
|
| + cpi->refresh_alt_ref_frame = 0;
|
| + }
|
|
|
| // Should we encode an arf frame.
|
| arf_src_index = get_arf_src_index(cpi);
|
| @@ -4006,12 +4075,11 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
| }
|
|
|
| // Read in the source frame.
|
| -#if CONFIG_SPATIAL_SVC
|
| - if (is_two_pass_svc(cpi))
|
| + if (cpi->use_svc)
|
| source = vp9_svc_lookahead_pop(cpi, cpi->lookahead, flush);
|
| else
|
| -#endif
|
| source = vp9_lookahead_pop(cpi->lookahead, flush);
|
| +
|
| if (source != NULL) {
|
| cm->show_frame = 1;
|
| cm->intra_only = 0;
|
| @@ -4060,8 +4128,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
| adjust_frame_rate(cpi, source);
|
| }
|
|
|
| - if (cpi->svc.number_temporal_layers > 1 &&
|
| - oxcf->rc_mode == VPX_CBR) {
|
| + if (is_one_pass_cbr_svc(cpi)) {
|
| vp9_update_temporal_layer_framerate(cpi);
|
| vp9_restore_layer_context(cpi);
|
| }
|
| @@ -4143,11 +4210,10 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
| }
|
|
|
| // Save layer specific state.
|
| - if ((cpi->svc.number_temporal_layers > 1 &&
|
| - oxcf->rc_mode == VPX_CBR) ||
|
| - ((cpi->svc.number_temporal_layers > 1 ||
|
| - cpi->svc.number_spatial_layers > 1) &&
|
| - oxcf->pass == 2)) {
|
| + if (is_one_pass_cbr_svc(cpi) ||
|
| + ((cpi->svc.number_temporal_layers > 1 ||
|
| + cpi->svc.number_spatial_layers > 1) &&
|
| + oxcf->pass == 2)) {
|
| vp9_save_layer_context(cpi);
|
| }
|
|
|
| @@ -4343,6 +4409,12 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
| // May need the empty frame after an visible frame.
|
| cpi->svc.encode_empty_frame_state = NEED_TO_ENCODE;
|
| }
|
| + } else if (is_one_pass_cbr_svc(cpi)) {
|
| + if (cm->show_frame) {
|
| + ++cpi->svc.spatial_layer_to_encode;
|
| + if (cpi->svc.spatial_layer_to_encode >= cpi->svc.number_spatial_layers)
|
| + cpi->svc.spatial_layer_to_encode = 0;
|
| + }
|
| }
|
| return 0;
|
| }
|
|
|