// Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING 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. // ----------------------------------------------------------------------------- // // Macroblock analysis // // Author: Skal ([email protected]) #include <stdlib.h> #include <string.h> #include <assert.h> #include "src/enc/vp8i_enc.h" #include "src/enc/cost_enc.h" #include "src/utils/utils.h" #define MAX_ITERS_K_MEANS … //------------------------------------------------------------------------------ // Smooth the segment map by replacing isolated block by the majority of its // neighbours. static void SmoothSegmentMap(VP8Encoder* const enc) { … } //------------------------------------------------------------------------------ // set segment susceptibility alpha_ / beta_ static WEBP_INLINE int clip(int v, int m, int M) { … } static void SetSegmentAlphas(VP8Encoder* const enc, const int centers[NUM_MB_SEGMENTS], int mid) { … } //------------------------------------------------------------------------------ // Compute susceptibility based on DCT-coeff histograms: // the higher, the "easier" the macroblock is to compress. #define MAX_ALPHA … #define ALPHA_SCALE … #define DEFAULT_ALPHA … #define IS_BETTER_ALPHA(alpha, best_alpha) … static int FinalAlphaValue(int alpha) { … } static int GetAlpha(const VP8Histogram* const histo) { … } static void InitHistogram(VP8Histogram* const histo) { … } //------------------------------------------------------------------------------ // Simplified k-Means, to assign Nb segments based on alpha-histogram static void AssignSegments(VP8Encoder* const enc, const int alphas[MAX_ALPHA + 1]) { … } //------------------------------------------------------------------------------ // Macroblock analysis: collect histogram for each mode, deduce the maximal // susceptibility and set best modes for this macroblock. // Segment assignment is done later. // Number of modes to inspect for alpha_ evaluation. We don't need to test all // the possible modes during the analysis phase: we risk falling into a local // optimum, or be subject to boundary effect #define MAX_INTRA16_MODE … #define MAX_INTRA4_MODE … #define MAX_UV_MODE … static int MBAnalyzeBestIntra16Mode(VP8EncIterator* const it) { … } static int FastMBAnalyze(VP8EncIterator* const it) { … } static int MBAnalyzeBestUVMode(VP8EncIterator* const it) { … } static void MBAnalyze(VP8EncIterator* const it, int alphas[MAX_ALPHA + 1], int* const alpha, int* const uv_alpha) { … } static void DefaultMBInfo(VP8MBInfo* const mb) { … } //------------------------------------------------------------------------------ // Main analysis loop: // Collect all susceptibilities for each macroblock and record their // distribution in alphas[]. Segments is assigned a-posteriori, based on // this histogram. // We also pick an intra16 prediction mode, which shouldn't be considered // final except for fast-encode settings. We can also pick some intra4 modes // and decide intra4/intra16, but that's usually almost always a bad choice at // this stage. static void ResetAllMBInfo(VP8Encoder* const enc) { … } // struct used to collect job result SegmentJob; // main work call static int DoSegmentsJob(void* arg1, void* arg2) { … } #ifdef WEBP_USE_THREAD static void MergeJobs(const SegmentJob* const src, SegmentJob* const dst) { int i; for (i = 0; i <= MAX_ALPHA; ++i) dst->alphas[i] += src->alphas[i]; dst->alpha += src->alpha; dst->uv_alpha += src->uv_alpha; } #endif // initialize the job struct with some tasks to perform static void InitSegmentJob(VP8Encoder* const enc, SegmentJob* const job, int start_row, int end_row) { … } // main entry point int VP8EncAnalyze(VP8Encoder* const enc) { … }