| 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 <limits.h> |   11 #include <limits.h> | 
|   12 #include <math.h> |   12 #include <math.h> | 
|   13  |   13  | 
 |   14 #include "vpx_ports/system_state.h" | 
 |   15  | 
|   14 #include "vp9/encoder/vp9_aq_cyclicrefresh.h" |   16 #include "vp9/encoder/vp9_aq_cyclicrefresh.h" | 
|   15  |   17  | 
|   16 #include "vp9/common/vp9_seg_common.h" |   18 #include "vp9/common/vp9_seg_common.h" | 
|   17  |   19  | 
|   18 #include "vp9/encoder/vp9_ratectrl.h" |   20 #include "vp9/encoder/vp9_ratectrl.h" | 
|   19 #include "vp9/encoder/vp9_segmentation.h" |   21 #include "vp9/encoder/vp9_segmentation.h" | 
|   20  |   22  | 
|   21 struct CYCLIC_REFRESH { |   23 struct CYCLIC_REFRESH { | 
|   22   // Percentage of blocks per frame that are targeted as candidates |   24   // Percentage of blocks per frame that are targeted as candidates | 
|   23   // for cyclic refresh. |   25   // for cyclic refresh. | 
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  214                                        MB_MODE_INFO *const mbmi, |  216                                        MB_MODE_INFO *const mbmi, | 
|  215                                        int mi_row, int mi_col, |  217                                        int mi_row, int mi_col, | 
|  216                                        BLOCK_SIZE bsize, |  218                                        BLOCK_SIZE bsize, | 
|  217                                        int64_t rate, |  219                                        int64_t rate, | 
|  218                                        int64_t dist, |  220                                        int64_t dist, | 
|  219                                        int skip) { |  221                                        int skip) { | 
|  220   const VP9_COMMON *const cm = &cpi->common; |  222   const VP9_COMMON *const cm = &cpi->common; | 
|  221   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; |  223   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; | 
|  222   const int bw = num_8x8_blocks_wide_lookup[bsize]; |  224   const int bw = num_8x8_blocks_wide_lookup[bsize]; | 
|  223   const int bh = num_8x8_blocks_high_lookup[bsize]; |  225   const int bh = num_8x8_blocks_high_lookup[bsize]; | 
|  224   const int xmis = MIN(cm->mi_cols - mi_col, bw); |  226   const int xmis = VPXMIN(cm->mi_cols - mi_col, bw); | 
|  225   const int ymis = MIN(cm->mi_rows - mi_row, bh); |  227   const int ymis = VPXMIN(cm->mi_rows - mi_row, bh); | 
|  226   const int block_index = mi_row * cm->mi_cols + mi_col; |  228   const int block_index = mi_row * cm->mi_cols + mi_col; | 
|  227   const int refresh_this_block = candidate_refresh_aq(cr, mbmi, rate, dist, |  229   const int refresh_this_block = candidate_refresh_aq(cr, mbmi, rate, dist, | 
|  228                                                       bsize); |  230                                                       bsize); | 
|  229   // Default is to not update the refresh map. |  231   // Default is to not update the refresh map. | 
|  230   int new_map_value = cr->map[block_index]; |  232   int new_map_value = cr->map[block_index]; | 
|  231   int x = 0; int y = 0; |  233   int x = 0; int y = 0; | 
|  232  |  234  | 
|  233   // If this block is labeled for refresh, check if we should reset the |  235   // If this block is labeled for refresh, check if we should reset the | 
|  234   // segment_id. |  236   // segment_id. | 
|  235   if (cyclic_refresh_segment_id_boosted(mbmi->segment_id)) { |  237   if (cyclic_refresh_segment_id_boosted(mbmi->segment_id)) { | 
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  407     int mi_row = sb_row_index * MI_BLOCK_SIZE; |  409     int mi_row = sb_row_index * MI_BLOCK_SIZE; | 
|  408     int mi_col = sb_col_index * MI_BLOCK_SIZE; |  410     int mi_col = sb_col_index * MI_BLOCK_SIZE; | 
|  409     int qindex_thresh = |  411     int qindex_thresh = | 
|  410         cpi->oxcf.content == VP9E_CONTENT_SCREEN |  412         cpi->oxcf.content == VP9E_CONTENT_SCREEN | 
|  411             ? vp9_get_qindex(&cm->seg, CR_SEGMENT_ID_BOOST2, cm->base_qindex) |  413             ? vp9_get_qindex(&cm->seg, CR_SEGMENT_ID_BOOST2, cm->base_qindex) | 
|  412             : 0; |  414             : 0; | 
|  413     assert(mi_row >= 0 && mi_row < cm->mi_rows); |  415     assert(mi_row >= 0 && mi_row < cm->mi_rows); | 
|  414     assert(mi_col >= 0 && mi_col < cm->mi_cols); |  416     assert(mi_col >= 0 && mi_col < cm->mi_cols); | 
|  415     bl_index = mi_row * cm->mi_cols + mi_col; |  417     bl_index = mi_row * cm->mi_cols + mi_col; | 
|  416     // Loop through all 8x8 blocks in superblock and update map. |  418     // Loop through all 8x8 blocks in superblock and update map. | 
|  417     xmis = MIN(cm->mi_cols - mi_col, |  419     xmis = | 
|  418                num_8x8_blocks_wide_lookup[BLOCK_64X64]); |  420         VPXMIN(cm->mi_cols - mi_col, num_8x8_blocks_wide_lookup[BLOCK_64X64]); | 
|  419     ymis = MIN(cm->mi_rows - mi_row, |  421     ymis = | 
|  420                num_8x8_blocks_high_lookup[BLOCK_64X64]); |  422         VPXMIN(cm->mi_rows - mi_row, num_8x8_blocks_high_lookup[BLOCK_64X64]); | 
|  421     for (y = 0; y < ymis; y++) { |  423     for (y = 0; y < ymis; y++) { | 
|  422       for (x = 0; x < xmis; x++) { |  424       for (x = 0; x < xmis; x++) { | 
|  423         const int bl_index2 = bl_index + y * cm->mi_cols + x; |  425         const int bl_index2 = bl_index + y * cm->mi_cols + x; | 
|  424         // If the block is as a candidate for clean up then mark it |  426         // If the block is as a candidate for clean up then mark it | 
|  425         // for possible boost/refresh (segment 1). The segment id may get |  427         // for possible boost/refresh (segment 1). The segment id may get | 
|  426         // reset to 0 later if block gets coded anything other than ZEROMV. |  428         // reset to 0 later if block gets coded anything other than ZEROMV. | 
|  427         if (cr->map[bl_index2] == 0) { |  429         if (cr->map[bl_index2] == 0) { | 
|  428           if (cr->last_coded_q_map[bl_index2] > qindex_thresh) |  430           if (cr->last_coded_q_map[bl_index2] > qindex_thresh) | 
|  429             sum_map++; |  431             sum_map++; | 
|  430         } else if (cr->map[bl_index2] < 0) { |  432         } else if (cr->map[bl_index2] < 0) { | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
|  452 // Set cyclic refresh parameters. |  454 // Set cyclic refresh parameters. | 
|  453 void vp9_cyclic_refresh_update_parameters(VP9_COMP *const cpi) { |  455 void vp9_cyclic_refresh_update_parameters(VP9_COMP *const cpi) { | 
|  454   const RATE_CONTROL *const rc = &cpi->rc; |  456   const RATE_CONTROL *const rc = &cpi->rc; | 
|  455   const VP9_COMMON *const cm = &cpi->common; |  457   const VP9_COMMON *const cm = &cpi->common; | 
|  456   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; |  458   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; | 
|  457   cr->percent_refresh = 10; |  459   cr->percent_refresh = 10; | 
|  458   cr->max_qdelta_perc = 50; |  460   cr->max_qdelta_perc = 50; | 
|  459   cr->time_for_refresh = 0; |  461   cr->time_for_refresh = 0; | 
|  460   // Use larger delta-qp (increase rate_ratio_qdelta) for first few (~4) |  462   // Use larger delta-qp (increase rate_ratio_qdelta) for first few (~4) | 
|  461   // periods of the refresh cycle, after a key frame. |  463   // periods of the refresh cycle, after a key frame. | 
|  462   if (rc->frames_since_key <  4 * cr->percent_refresh) |  464   // Account for larger interval on base layer for temporal layers. | 
 |  465   if (cr->percent_refresh > 0 && | 
 |  466       rc->frames_since_key <  (4 * cpi->svc.number_temporal_layers) * | 
 |  467       (100 / cr->percent_refresh)) | 
|  463     cr->rate_ratio_qdelta = 3.0; |  468     cr->rate_ratio_qdelta = 3.0; | 
|  464   else |  469   else | 
|  465     cr->rate_ratio_qdelta = 2.0; |  470     cr->rate_ratio_qdelta = 2.0; | 
|  466   // Adjust some parameters for low resolutions at low bitrates. |  471   // Adjust some parameters for low resolutions at low bitrates. | 
|  467   if (cm->width <= 352 && |  472   if (cm->width <= 352 && | 
|  468       cm->height <= 288 && |  473       cm->height <= 288 && | 
|  469       rc->avg_frame_bandwidth < 3400) { |  474       rc->avg_frame_bandwidth < 3400) { | 
|  470     cr->motion_thresh = 4; |  475     cr->motion_thresh = 4; | 
|  471     cr->rate_boost_fac = 10; |  476     cr->rate_boost_fac = 10; | 
|  472   } else { |  477   } else { | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
|  496     if (cm->frame_type == KEY_FRAME) { |  501     if (cm->frame_type == KEY_FRAME) { | 
|  497       memset(cr->last_coded_q_map, MAXQ, |  502       memset(cr->last_coded_q_map, MAXQ, | 
|  498              cm->mi_rows * cm->mi_cols * sizeof(*cr->last_coded_q_map)); |  503              cm->mi_rows * cm->mi_cols * sizeof(*cr->last_coded_q_map)); | 
|  499       cr->sb_index = 0; |  504       cr->sb_index = 0; | 
|  500     } |  505     } | 
|  501     return; |  506     return; | 
|  502   } else { |  507   } else { | 
|  503     int qindex_delta = 0; |  508     int qindex_delta = 0; | 
|  504     int qindex2; |  509     int qindex2; | 
|  505     const double q = vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth); |  510     const double q = vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth); | 
|  506     vp9_clear_system_state(); |  511     vpx_clear_system_state(); | 
|  507     // Set rate threshold to some multiple (set to 2 for now) of the target |  512     // Set rate threshold to some multiple (set to 2 for now) of the target | 
|  508     // rate (target is given by sb64_target_rate and scaled by 256). |  513     // rate (target is given by sb64_target_rate and scaled by 256). | 
|  509     cr->thresh_rate_sb = ((int64_t)(rc->sb64_target_rate) << 8) << 2; |  514     cr->thresh_rate_sb = ((int64_t)(rc->sb64_target_rate) << 8) << 2; | 
|  510     // Distortion threshold, quadratic in Q, scale factor to be adjusted. |  515     // Distortion threshold, quadratic in Q, scale factor to be adjusted. | 
|  511     // q will not exceed 457, so (q * q) is within 32bit; see: |  516     // q will not exceed 457, so (q * q) is within 32bit; see: | 
|  512     // vp9_convert_qindex_to_q(), vp9_ac_quant(), ac_qlookup*[]. |  517     // vp9_convert_qindex_to_q(), vp9_ac_quant(), ac_qlookup*[]. | 
|  513     cr->thresh_dist_sb = ((int64_t)(q * q)) << 2; |  518     cr->thresh_dist_sb = ((int64_t)(q * q)) << 2; | 
|  514  |  519  | 
|  515     // Set up segmentation. |  520     // Set up segmentation. | 
|  516     // Clear down the segment map. |  521     // Clear down the segment map. | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  539  |  544  | 
|  540     // Compute rd-mult for segment BOOST1. |  545     // Compute rd-mult for segment BOOST1. | 
|  541     qindex2 = clamp(cm->base_qindex + cm->y_dc_delta_q + qindex_delta, 0, MAXQ); |  546     qindex2 = clamp(cm->base_qindex + cm->y_dc_delta_q + qindex_delta, 0, MAXQ); | 
|  542  |  547  | 
|  543     cr->rdmult = vp9_compute_rd_mult(cpi, qindex2); |  548     cr->rdmult = vp9_compute_rd_mult(cpi, qindex2); | 
|  544  |  549  | 
|  545     vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST1, SEG_LVL_ALT_Q, qindex_delta); |  550     vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST1, SEG_LVL_ALT_Q, qindex_delta); | 
|  546  |  551  | 
|  547     // Set a more aggressive (higher) q delta for segment BOOST2. |  552     // Set a more aggressive (higher) q delta for segment BOOST2. | 
|  548     qindex_delta = compute_deltaq( |  553     qindex_delta = compute_deltaq( | 
|  549         cpi, cm->base_qindex, MIN(CR_MAX_RATE_TARGET_RATIO, |  554         cpi, cm->base_qindex, | 
|  550         0.1 * cr->rate_boost_fac * cr->rate_ratio_qdelta)); |  555         VPXMIN(CR_MAX_RATE_TARGET_RATIO, | 
 |  556                0.1 * cr->rate_boost_fac * cr->rate_ratio_qdelta)); | 
|  551     cr->qindex_delta[2] = qindex_delta; |  557     cr->qindex_delta[2] = qindex_delta; | 
|  552     vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q, qindex_delta); |  558     vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q, qindex_delta); | 
|  553  |  559  | 
|  554     // Update the segmentation and refresh map. |  560     // Update the segmentation and refresh map. | 
|  555     cyclic_refresh_update_map(cpi); |  561     cyclic_refresh_update_map(cpi); | 
|  556   } |  562   } | 
|  557 } |  563 } | 
|  558  |  564  | 
|  559 int vp9_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr) { |  565 int vp9_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr) { | 
|  560   return cr->rdmult; |  566   return cr->rdmult; | 
|  561 } |  567 } | 
|  562  |  568  | 
|  563 void vp9_cyclic_refresh_reset_resize(VP9_COMP *const cpi) { |  569 void vp9_cyclic_refresh_reset_resize(VP9_COMP *const cpi) { | 
|  564   const VP9_COMMON *const cm = &cpi->common; |  570   const VP9_COMMON *const cm = &cpi->common; | 
|  565   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; |  571   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; | 
|  566   memset(cr->map, 0, cm->mi_rows * cm->mi_cols); |  572   memset(cr->map, 0, cm->mi_rows * cm->mi_cols); | 
|  567   cr->sb_index = 0; |  573   cr->sb_index = 0; | 
|  568   cpi->refresh_golden_frame = 1; |  574   cpi->refresh_golden_frame = 1; | 
|  569 } |  575 } | 
| OLD | NEW |