Adds a blockiness metric to internal stats.
Change-Id: Iedceeb020492050063acf3fd2326f96c29db9ae5
This commit is contained in:
		
							
								
								
									
										229
									
								
								test/blockiness_test.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								test/blockiness_test.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,229 @@ | ||||
| /* | ||||
|  *  Copyright (c) 2012 The WebM project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include <string.h> | ||||
| #include <limits.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| #include "./vpx_config.h" | ||||
| #if CONFIG_VP9_ENCODER | ||||
| #include "./vp9_rtcd.h" | ||||
| #endif | ||||
|  | ||||
| #include "test/acm_random.h" | ||||
| #include "test/clear_system_state.h" | ||||
| #include "test/register_state_check.h" | ||||
| #include "test/util.h" | ||||
| #include "third_party/googletest/src/include/gtest/gtest.h" | ||||
|  | ||||
| #include "vpx_mem/vpx_mem.h" | ||||
|  | ||||
|  | ||||
| extern "C" | ||||
| double vp9_get_blockiness(const unsigned char *img1, int img1_pitch, | ||||
|                           const unsigned char *img2, int img2_pitch, | ||||
|                           int width, int height); | ||||
|  | ||||
| using libvpx_test::ACMRandom; | ||||
|  | ||||
| namespace { | ||||
| class BlockinessTestBase : public ::testing::Test { | ||||
|  public: | ||||
|   BlockinessTestBase(int width, int height) : width_(width), height_(height) {} | ||||
|  | ||||
|   static void SetUpTestCase() { | ||||
|     source_data_ = reinterpret_cast<uint8_t*>( | ||||
|         vpx_memalign(kDataAlignment, kDataBufferSize)); | ||||
|     reference_data_ = reinterpret_cast<uint8_t*>( | ||||
|         vpx_memalign(kDataAlignment, kDataBufferSize)); | ||||
|   } | ||||
|  | ||||
|   static void TearDownTestCase() { | ||||
|     vpx_free(source_data_); | ||||
|     source_data_ = NULL; | ||||
|     vpx_free(reference_data_); | ||||
|     reference_data_ = NULL; | ||||
|   } | ||||
|  | ||||
|   virtual void TearDown() { | ||||
|     libvpx_test::ClearSystemState(); | ||||
|   } | ||||
|  | ||||
|  protected: | ||||
|   // Handle frames up to 640x480 | ||||
|   static const int kDataAlignment = 16; | ||||
|   static const int kDataBufferSize = 640*480; | ||||
|  | ||||
|   virtual void SetUp() { | ||||
|     source_stride_ = (width_ + 31) & ~31; | ||||
|     reference_stride_ = width_ * 2; | ||||
|     rnd_.Reset(ACMRandom::DeterministicSeed()); | ||||
|   } | ||||
|  | ||||
|   void FillConstant(uint8_t *data, int stride, uint8_t fill_constant, | ||||
|                     int width, int height) { | ||||
|     for (int h = 0; h < height; ++h) { | ||||
|       for (int w = 0; w < width; ++w) { | ||||
|         data[h * stride + w] = fill_constant; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void FillConstant(uint8_t *data, int stride, uint8_t fill_constant) { | ||||
|     FillConstant(data, stride, fill_constant, width_, height_); | ||||
|   } | ||||
|  | ||||
|   void FillRandom(uint8_t *data, int stride, int width, int height) { | ||||
|     for (int h = 0; h < height; ++h) { | ||||
|       for (int w = 0; w < width; ++w) { | ||||
|         data[h * stride + w] = rnd_.Rand8(); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void FillRandom(uint8_t *data, int stride) { | ||||
|     FillRandom(data, stride, width_, height_); | ||||
|   } | ||||
|  | ||||
|   void FillRandomBlocky(uint8_t *data, int stride) { | ||||
|     for (int h = 0; h < height_; h += 4) { | ||||
|       for (int w = 0; w < width_; w += 4) { | ||||
|         FillRandom(data + h * stride + w, stride, 4, 4); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void FillCheckerboard(uint8_t *data, int stride) { | ||||
|     for (int h = 0; h < height_; h += 4) { | ||||
|       for (int w = 0; w < width_; w += 4) { | ||||
|         if (((h/4) ^ (w/4)) & 1) | ||||
|           FillConstant(data + h * stride + w, stride, 255, 4, 4); | ||||
|         else | ||||
|           FillConstant(data + h * stride + w, stride, 0, 4, 4); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void Blur(uint8_t *data, int stride, int taps) { | ||||
|     int sum = 0; | ||||
|     int half_taps = taps / 2; | ||||
|     for (int h = 0; h < height_; ++h) { | ||||
|       for (int w = 0; w < taps; ++w) { | ||||
|         sum += data[w + h * stride]; | ||||
|       } | ||||
|       for (int w = taps; w < width_; ++w) { | ||||
|         sum += data[w + h * stride] - data[w - taps + h * stride]; | ||||
|         data[w - half_taps + h * stride] = (sum + half_taps) / taps; | ||||
|       } | ||||
|     } | ||||
|     for (int w = 0; w < width_; ++w) { | ||||
|       for (int h = 0; h < taps; ++h) { | ||||
|         sum += data[h + w * stride]; | ||||
|       } | ||||
|       for (int h = taps; h < height_; ++h) { | ||||
|         sum += data[w + h * stride] - data[(h - taps) * stride + w]; | ||||
|         data[(h - half_taps) * stride + w] = (sum + half_taps) / taps; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   int width_, height_; | ||||
|   static uint8_t* source_data_; | ||||
|   int source_stride_; | ||||
|   static uint8_t* reference_data_; | ||||
|   int reference_stride_; | ||||
|  | ||||
|   ACMRandom rnd_; | ||||
| }; | ||||
|  | ||||
| #if CONFIG_VP9_ENCODER | ||||
| typedef std::tr1::tuple<int, int> BlockinessParam; | ||||
| class BlockinessVP9Test | ||||
|     : public BlockinessTestBase, | ||||
|       public ::testing::WithParamInterface<BlockinessParam> { | ||||
|  public: | ||||
|   BlockinessVP9Test() : BlockinessTestBase(GET_PARAM(0), GET_PARAM(1)) {} | ||||
|  | ||||
|  protected: | ||||
|   int CheckBlockiness() { | ||||
|     return vp9_get_blockiness(source_data_, source_stride_, | ||||
|                               reference_data_, reference_stride_, | ||||
|                               width_, height_); | ||||
|   } | ||||
| }; | ||||
| #endif  // CONFIG_VP9_ENCODER | ||||
|  | ||||
| uint8_t* BlockinessTestBase::source_data_ = NULL; | ||||
| uint8_t* BlockinessTestBase::reference_data_ = NULL; | ||||
|  | ||||
| #if CONFIG_VP9_ENCODER | ||||
| TEST_P(BlockinessVP9Test, SourceBlockierThanReference) { | ||||
|   // Source is blockier than reference. | ||||
|   FillRandomBlocky(source_data_, source_stride_); | ||||
|   FillConstant(reference_data_, reference_stride_, 128); | ||||
|   int super_blocky = CheckBlockiness(); | ||||
|  | ||||
|   EXPECT_EQ(0, super_blocky) << "Blocky source should produce 0 blockiness."; | ||||
| } | ||||
|  | ||||
| TEST_P(BlockinessVP9Test, ReferenceBlockierThanSource) { | ||||
|   // Source is blockier than reference. | ||||
|   FillConstant(source_data_, source_stride_, 128); | ||||
|   FillRandomBlocky(reference_data_, reference_stride_); | ||||
|   int super_blocky = CheckBlockiness(); | ||||
|  | ||||
|   EXPECT_GT(super_blocky, 0.0) | ||||
|       << "Blocky reference should score high for blockiness."; | ||||
| } | ||||
|  | ||||
| TEST_P(BlockinessVP9Test, BlurringDecreasesBlockiness) { | ||||
|   // Source is blockier than reference. | ||||
|   FillConstant(source_data_, source_stride_, 128); | ||||
|   FillRandomBlocky(reference_data_, reference_stride_); | ||||
|   int super_blocky = CheckBlockiness(); | ||||
|  | ||||
|   Blur(reference_data_, reference_stride_, 4); | ||||
|   int less_blocky = CheckBlockiness(); | ||||
|  | ||||
|   EXPECT_GT(super_blocky, less_blocky) | ||||
|       << "A straight blur should decrease blockiness."; | ||||
| } | ||||
|  | ||||
| TEST_P(BlockinessVP9Test, WorstCaseBlockiness) { | ||||
|   // Source is blockier than reference. | ||||
|   FillConstant(source_data_, source_stride_, 128); | ||||
|   FillCheckerboard(reference_data_, reference_stride_); | ||||
|  | ||||
|   int super_blocky = CheckBlockiness(); | ||||
|  | ||||
|   Blur(reference_data_, reference_stride_, 4); | ||||
|   int less_blocky = CheckBlockiness(); | ||||
|  | ||||
|   EXPECT_GT(super_blocky, less_blocky) | ||||
|       << "A straight blur should decrease blockiness."; | ||||
| } | ||||
| #endif  // CONFIG_VP9_ENCODER | ||||
|  | ||||
|  | ||||
| using std::tr1::make_tuple; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // C functions | ||||
|  | ||||
| #if CONFIG_VP9_ENCODER | ||||
| const BlockinessParam c_vp9_tests[] = { | ||||
|   make_tuple(320, 240), | ||||
|   make_tuple(318, 242), | ||||
|   make_tuple(318, 238), | ||||
| }; | ||||
| INSTANTIATE_TEST_CASE_P(C, BlockinessVP9Test, ::testing::ValuesIn(c_vp9_tests)); | ||||
| #endif | ||||
|  | ||||
| }  // namespace | ||||
| @@ -150,6 +150,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9)         += vp9_intrapred_test.cc | ||||
|  | ||||
| ifeq ($(CONFIG_VP9_ENCODER),yes) | ||||
| LIBVPX_TEST_SRCS-$(CONFIG_SPATIAL_SVC) += svc_test.cc | ||||
| LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += blockiness_test.cc | ||||
| endif | ||||
|  | ||||
| ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_TEMPORAL_DENOISING),yesyes) | ||||
|   | ||||
							
								
								
									
										138
									
								
								vp9/encoder/vp9_blockiness.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								vp9/encoder/vp9_blockiness.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| /* | ||||
|  *  Copyright (c) 2014 The WebM project authors. All Rights Reserved. | ||||
|  * | ||||
|  *  Use of this source code is governed by a BSD-style license | ||||
|  *  that can be found in the LICENSE file in the root of the source | ||||
|  *  tree. An additional intellectual property rights grant can be found | ||||
|  *  in the file PATENTS.  All contributing project authors may | ||||
|  *  be found in the AUTHORS file in the root of the source tree. | ||||
|  */ | ||||
|  | ||||
| #include "./vpx_config.h" | ||||
| #include "./vp9_rtcd.h" | ||||
| #include "vp9/common/vp9_common.h" | ||||
| #include "vp9/common/vp9_convolve.h" | ||||
| #include "vp9/common/vp9_filter.h" | ||||
| #include "vpx/vpx_integer.h" | ||||
| #include "vpx_ports/mem.h" | ||||
|  | ||||
| static int horizontal_filter(const uint8_t *s) { | ||||
|   return (s[1] - s[-2]) * 2 + (s[-1] - s[0]) * 6; | ||||
| } | ||||
|  | ||||
| static int vertical_filter(const uint8_t *s, int p) { | ||||
|   return (s[p] - s[-2 * p]) * 2 + (s[-p] - s[0]) * 6; | ||||
| } | ||||
|  | ||||
| static int variance(int sum, int sum_squared, int size) { | ||||
|   return sum_squared / size - (sum / size) * (sum / size); | ||||
| } | ||||
| // Calculate a blockiness level for a vertical block edge. | ||||
| // This function returns a new blockiness metric that's defined as | ||||
|  | ||||
| //              p0 p1 p2 p3 | ||||
| //              q0 q1 q2 q3 | ||||
| // block edge -> | ||||
| //              r0 r1 r2 r3 | ||||
| //              s0 s1 s2 s3 | ||||
|  | ||||
| // blockiness =  p0*-2+q0*6+r0*-6+s0*2 + | ||||
| //               p1*-2+q1*6+r1*-6+s1*2 + | ||||
| //               p2*-2+q2*6+r2*-6+s2*2 + | ||||
| //               p3*-2+q3*6+r3*-6+s3*2 ; | ||||
|  | ||||
| // reconstructed_blockiness = abs(blockiness from reconstructed buffer - | ||||
| //                                blockiness from source buffer,0) | ||||
| // | ||||
| // I make the assumption that flat blocks are much more visible than high | ||||
| // contrast blocks. As such, I scale the result of the blockiness calc | ||||
| // by dividing the blockiness by the variance of the pixels on either side | ||||
| // of the edge as follows: | ||||
| // var_0 = (q0^2+q1^2+q2^2+q3^2) - ((q0 + q1 + q2 + q3) / 4 )^2 | ||||
| // var_1 = (r0^2+r1^2+r2^2+r3^2) - ((r0 + r1 + r2 + r3) / 4 )^2 | ||||
| // The returned blockiness is the scaled value | ||||
| // Reconstructed blockiness / ( 1 + var_0 + var_1 ) ; | ||||
| int blockiness_vertical(const uint8_t *s, int sp, const uint8_t *r, int rp, | ||||
|                         int size) { | ||||
|   int s_blockiness = 0; | ||||
|   int r_blockiness = 0; | ||||
|   int sum_0 = 0; | ||||
|   int sum_sq_0 = 0; | ||||
|   int sum_1 = 0; | ||||
|   int sum_sq_1 = 0; | ||||
|   int i; | ||||
|   int var_0; | ||||
|   int var_1; | ||||
|   for (i = 0; i < size; ++i, s += sp, r += rp) { | ||||
|     s_blockiness += horizontal_filter(s); | ||||
|     r_blockiness += horizontal_filter(r); | ||||
|     sum_0 += s[0]; | ||||
|     sum_sq_0 += s[0]*s[0]; | ||||
|     sum_1 += s[-1]; | ||||
|     sum_sq_1 += s[-1]*s[-1]; | ||||
|   } | ||||
|   var_0 = variance(sum_0, sum_sq_0, size); | ||||
|   var_1 = variance(sum_1, sum_sq_1, size); | ||||
|   r_blockiness = abs(r_blockiness); | ||||
|   s_blockiness = abs(s_blockiness); | ||||
|  | ||||
|   if (r_blockiness > s_blockiness) | ||||
|     return (r_blockiness - s_blockiness) / (1 + var_0 + var_1); | ||||
|   else | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| // Calculate a blockiness level for a horizontal block edge | ||||
| // same as above. | ||||
| int blockiness_horizontal(const uint8_t *s, int sp, const uint8_t *r, int rp, | ||||
|                           int size) { | ||||
|   int s_blockiness = 0; | ||||
|   int r_blockiness = 0; | ||||
|   int sum_0 = 0; | ||||
|   int sum_sq_0 = 0; | ||||
|   int sum_1 = 0; | ||||
|   int sum_sq_1 = 0; | ||||
|   int i; | ||||
|   int var_0; | ||||
|   int var_1; | ||||
|   for (i = 0; i < size; ++i, ++s, ++r) { | ||||
|     s_blockiness += vertical_filter(s, sp); | ||||
|     r_blockiness += vertical_filter(r, rp); | ||||
|     sum_0 += s[0]; | ||||
|     sum_sq_0 += s[0] * s[0]; | ||||
|     sum_1 += s[-sp]; | ||||
|     sum_sq_1 += s[-sp] * s[-sp]; | ||||
|   } | ||||
|   var_0 = variance(sum_0, sum_sq_0, size); | ||||
|   var_1 = variance(sum_1, sum_sq_1, size); | ||||
|   r_blockiness = abs(r_blockiness); | ||||
|   s_blockiness = abs(s_blockiness); | ||||
|  | ||||
|   if (r_blockiness > s_blockiness) | ||||
|     return (r_blockiness - s_blockiness) / (1 + var_0 + var_1); | ||||
|   else | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| // This function returns the blockiness for the entire frame currently by | ||||
| // looking at all borders in steps of 4. | ||||
| double vp9_get_blockiness(const unsigned char *img1, int img1_pitch, | ||||
|                           const unsigned char *img2, int img2_pitch, | ||||
|                           int width, int height ) { | ||||
|   double blockiness = 0; | ||||
|   int i, j; | ||||
|   vp9_clear_system_state(); | ||||
|   for (i = 0; i < height; i += 4, img1 += img1_pitch * 4, | ||||
|        img2 += img2_pitch * 4) { | ||||
|     for (j = 0; j < width; j += 4) { | ||||
|       if (i > 0 && i < height && j > 0 && j < width) { | ||||
|         blockiness += blockiness_vertical(img1 + j, img1_pitch, | ||||
|                                           img2 + j, img2_pitch, 4); | ||||
|         blockiness += blockiness_horizontal(img1 + j, img1_pitch, | ||||
|                                             img2 + j, img2_pitch, 4); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   blockiness /= width * height / 16; | ||||
|   return blockiness; | ||||
| } | ||||
| @@ -1583,6 +1583,8 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf, | ||||
|   cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS; | ||||
| #if CONFIG_INTERNAL_STATS | ||||
|   cpi->b_calculate_ssimg = 0; | ||||
|   cpi->b_calculate_blockiness = 1; | ||||
|  | ||||
|  | ||||
|   cpi->count = 0; | ||||
|   cpi->bytes = 0; | ||||
| @@ -1624,6 +1626,15 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf, | ||||
|   cpi->total_psnrhvs_u = 0; | ||||
|   cpi->total_psnrhvs_v = 0; | ||||
|   cpi->total_psnrhvs_all = 0; | ||||
|  | ||||
|   if (cpi->b_calculate_blockiness) { | ||||
|     cpi->total_blockiness = 0; | ||||
|   } | ||||
|  | ||||
|   if (cpi->b_calculate_blockiness) { | ||||
|     cpi->total_blockiness = 0; | ||||
|   } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   cpi->first_time_stamp_ever = INT64_MAX; | ||||
| @@ -1831,7 +1842,6 @@ void vp9_remove_compressor(VP9_COMP *cpi) { | ||||
|  | ||||
|   if (cpi && (cm->current_video_frame > 0)) { | ||||
| #if CONFIG_INTERNAL_STATS | ||||
|  | ||||
|     vp9_clear_system_state(); | ||||
|  | ||||
|     // printf("\n8x8-4x4:%d-%d\n", cpi->t8x8_count, cpi->t4x4_count); | ||||
| @@ -1854,19 +1864,28 @@ void vp9_remove_compressor(VP9_COMP *cpi) { | ||||
|                             (double)cpi->totalp_sq_error); | ||||
|         const double total_ssim = 100 * pow(cpi->summed_quality / | ||||
|                                                 cpi->summed_weights, 8.0); | ||||
|         const double totalp_ssim = 100 * pow(cpi->summedp_quality / | ||||
|                                                 cpi->summedp_weights, 8.0); | ||||
|  | ||||
|  | ||||
|         fprintf(f, "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t" | ||||
|         if (cpi->b_calculate_blockiness) { | ||||
|           fprintf(f, "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t" | ||||
|                 "VPXSSIM\tVPSSIMP\tFASTSSIM\tPSNRHVS\tTime(ms)\n"); | ||||
|         fprintf(f, "%7.2f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t" | ||||
|                 "%7.3f\t%7.3f\t%7.3f\t%8.0f\n", | ||||
|                 dr, cpi->total / cpi->count, total_psnr, | ||||
|                 cpi->totalp / cpi->count, totalp_psnr, total_ssim, totalp_ssim, | ||||
|           fprintf(f, "%7.2f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t" | ||||
|                 "%7.3f\t%7.3f\t%8.0f\n", | ||||
|                   dr, cpi->total / cpi->count, total_psnr, | ||||
|                   cpi->totalp / cpi->count, totalp_psnr, total_ssim, | ||||
|                 cpi->total_fastssim_all / cpi->count, | ||||
|                 cpi->total_psnrhvs_all / cpi->count, | ||||
|                 total_encode_time); | ||||
|         } else { | ||||
|           fprintf(f, "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t" | ||||
|                 "VPXSSIM\tVPSSIMP\tBlockiness\tFASTSSIM\tPSNRHVS\tTime(ms)\n"); | ||||
|           fprintf(f, "%7.2f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t" | ||||
|                   "%7.3f\t%7.3f\t%7.3f\t%8.0f\n", | ||||
|                   dr, cpi->total / cpi->count, total_psnr, | ||||
|                   cpi->totalp / cpi->count, totalp_psnr, total_ssim, | ||||
|                   cpi->total_blockiness / cpi->count, | ||||
|                   cpi->total_fastssim_all / cpi->count, | ||||
|                   cpi->total_psnrhvs_all / cpi->count, | ||||
|                   total_encode_time); | ||||
|         } | ||||
|       } | ||||
|  | ||||
|  | ||||
| @@ -3786,6 +3805,12 @@ static void check_src_altref(VP9_COMP *cpi, | ||||
|   } | ||||
| } | ||||
|  | ||||
| #if CONFIG_INTERNAL_STATS | ||||
| extern double vp9_get_blockiness(const unsigned char *img1, int img1_pitch, | ||||
|                                  const unsigned char *img2, int img2_pitch, | ||||
|                                  int width, int height); | ||||
| #endif | ||||
|  | ||||
| int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, | ||||
|                             size_t *size, uint8_t *dest, | ||||
|                             int64_t *time_stamp, int64_t *time_end, int flush) { | ||||
| @@ -4135,7 +4160,12 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, | ||||
| #endif | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       if (cpi->b_calculate_blockiness) | ||||
|         cpi->total_blockiness += | ||||
|             vp9_get_blockiness(cpi->Source->y_buffer, cpi->Source->y_stride, | ||||
|                                cm->frame_to_show->y_buffer, | ||||
|                                cm->frame_to_show->y_stride, | ||||
|                                cpi->Source->y_width, cpi->Source->y_height); | ||||
|  | ||||
|       if (cpi->b_calculate_ssimg) { | ||||
|         double y, u, v, frame_all; | ||||
|   | ||||
| @@ -402,6 +402,8 @@ typedef struct VP9_COMP { | ||||
|   uint64_t totalp_sq_error; | ||||
|   uint64_t totalp_samples; | ||||
|  | ||||
|   double total_blockiness; | ||||
|  | ||||
|   int    bytes; | ||||
|   double summed_quality; | ||||
|   double summed_weights; | ||||
| @@ -426,6 +428,7 @@ typedef struct VP9_COMP { | ||||
|   double total_psnrhvs_all; | ||||
|  | ||||
|   int b_calculate_ssimg; | ||||
|   int b_calculate_blockiness; | ||||
| #endif | ||||
|   int b_calculate_psnr; | ||||
|  | ||||
|   | ||||
| @@ -81,6 +81,8 @@ VP9_CX_SRCS-yes += encoder/vp9_resize.c | ||||
| VP9_CX_SRCS-yes += encoder/vp9_resize.h | ||||
| VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += encoder/vp9_ssim.c | ||||
| VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += encoder/vp9_ssim.h | ||||
| VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += encoder/vp9_blockiness.c | ||||
|  | ||||
| VP9_CX_SRCS-yes += encoder/vp9_tokenize.c | ||||
| VP9_CX_SRCS-yes += encoder/vp9_treewriter.c | ||||
| VP9_CX_SRCS-yes += encoder/vp9_variance.c | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jim Bankoski
					Jim Bankoski