17ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian/*
27ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
37ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *
47ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *  Use of this source code is governed by a BSD-style license
57ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *  that can be found in the LICENSE file in the root of the source
67ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *  tree. An additional intellectual property rights grant can be found
77ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *  in the file PATENTS.  All contributing project authors may
87ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *  be found in the AUTHORS file in the root of the source tree.
97ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian */
107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "./vpx_config.h"
127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "vpx_mem/vpx_mem.h"
137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "vp9/common/vp9_entropymode.h"
147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "vp9/common/vp9_thread_common.h"
157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "vp9/common/vp9_reconinter.h"
167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "vp9/common/vp9_loopfilter.h"
177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_MULTITHREAD
197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic INLINE void mutex_lock(pthread_mutex_t *const mutex) {
207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const int kMaxTryLocks = 4000;
217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  int locked = 0;
227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  int i;
237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < kMaxTryLocks; ++i) {
257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    if (!pthread_mutex_trylock(mutex)) {
267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      locked = 1;
277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      break;
287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    }
297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (!locked)
327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    pthread_mutex_lock(mutex);
337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif  // CONFIG_MULTITHREAD
357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic INLINE void sync_read(VP9LfSync *const lf_sync, int r, int c) {
377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_MULTITHREAD
387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const int nsync = lf_sync->sync_range;
397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (r && !(c & (nsync - 1))) {
417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    pthread_mutex_t *const mutex = &lf_sync->mutex_[r - 1];
427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    mutex_lock(mutex);
437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    while (c > lf_sync->cur_sb_col[r - 1] - nsync) {
457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      pthread_cond_wait(&lf_sync->cond_[r - 1], mutex);
467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    }
477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    pthread_mutex_unlock(mutex);
487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#else
507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  (void)lf_sync;
517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  (void)r;
527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  (void)c;
537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif  // CONFIG_MULTITHREAD
547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic INLINE void sync_write(VP9LfSync *const lf_sync, int r, int c,
577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                              const int sb_cols) {
587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_MULTITHREAD
597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const int nsync = lf_sync->sync_range;
607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  int cur;
617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // Only signal when there are enough filtered SB for next row to run.
627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  int sig = 1;
637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (c < sb_cols - 1) {
657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    cur = c;
667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    if (c % nsync)
677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      sig = 0;
687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  } else {
697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    cur = sb_cols + nsync;
707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (sig) {
737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    mutex_lock(&lf_sync->mutex_[r]);
747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    lf_sync->cur_sb_col[r] = cur;
767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    pthread_cond_signal(&lf_sync->cond_[r]);
787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    pthread_mutex_unlock(&lf_sync->mutex_[r]);
797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#else
817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  (void)lf_sync;
827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  (void)r;
837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  (void)c;
847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  (void)sb_cols;
857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif  // CONFIG_MULTITHREAD
867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// Implement row loopfiltering for each thread.
897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic INLINE
907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid thread_loop_filter_rows(const YV12_BUFFER_CONFIG *const frame_buffer,
917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                             VP9_COMMON *const cm,
927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                             struct macroblockd_plane planes[MAX_MB_PLANE],
937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                             int start, int stop, int y_only,
947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                             VP9LfSync *const lf_sync) {
957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const int num_planes = y_only ? 1 : MAX_MB_PLANE;
967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const int sb_cols = mi_cols_aligned_to_sb(cm->mi_cols) >> MI_BLOCK_SIZE_LOG2;
977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  int mi_row, mi_col;
987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  enum lf_path path;
997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (y_only)
1007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    path = LF_PATH_444;
1017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  else if (planes[1].subsampling_y == 1 && planes[1].subsampling_x == 1)
1027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    path = LF_PATH_420;
1037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  else if (planes[1].subsampling_y == 0 && planes[1].subsampling_x == 0)
1047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    path = LF_PATH_444;
1057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  else
1067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    path = LF_PATH_SLOW;
1077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (mi_row = start; mi_row < stop;
1097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian       mi_row += lf_sync->num_workers * MI_BLOCK_SIZE) {
1107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    MODE_INFO **const mi = cm->mi_grid_visible + mi_row * cm->mi_stride;
1117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MI_BLOCK_SIZE) {
1137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      const int r = mi_row >> MI_BLOCK_SIZE_LOG2;
1147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      const int c = mi_col >> MI_BLOCK_SIZE_LOG2;
1157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      LOOP_FILTER_MASK lfm;
1167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      int plane;
1177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      sync_read(lf_sync, r, c);
1197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      vp9_setup_dst_planes(planes, frame_buffer, mi_row, mi_col);
1217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      // TODO(JBB): Make setup_mask work for non 420.
1237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      vp9_setup_mask(cm, mi_row, mi_col, mi + mi_col, cm->mi_stride,
1247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                     &lfm);
1257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      vp9_filter_block_plane_ss00(cm, &planes[0], mi_row, &lfm);
1277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      for (plane = 1; plane < num_planes; ++plane) {
1287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        switch (path) {
1297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian          case LF_PATH_420:
1307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            vp9_filter_block_plane_ss11(cm, &planes[plane], mi_row, &lfm);
1317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            break;
1327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian          case LF_PATH_444:
1337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            vp9_filter_block_plane_ss00(cm, &planes[plane], mi_row, &lfm);
1347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            break;
1357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian          case LF_PATH_SLOW:
1367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            vp9_filter_block_plane_non420(cm, &planes[plane], mi + mi_col,
1377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                          mi_row, mi_col);
1387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            break;
1397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        }
1407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      }
1417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      sync_write(lf_sync, r, c, sb_cols);
1437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    }
1447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
1457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
1467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// Row-based multi-threaded loopfilter hook
1487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic int loop_filter_row_worker(VP9LfSync *const lf_sync,
1497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                  LFWorkerData *const lf_data) {
1507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  thread_loop_filter_rows(lf_data->frame_buffer, lf_data->cm, lf_data->planes,
1517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                          lf_data->start, lf_data->stop, lf_data->y_only,
1527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                          lf_sync);
1537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  return 1;
1547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
1557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic void loop_filter_rows_mt(YV12_BUFFER_CONFIG *frame,
1577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                VP9_COMMON *cm,
1587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                struct macroblockd_plane planes[MAX_MB_PLANE],
1597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                int start, int stop, int y_only,
1607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                VPxWorker *workers, int nworkers,
1617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                VP9LfSync *lf_sync) {
1627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
1637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // Number of superblock rows and cols
1647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const int sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2;
1657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // Decoder may allocate more threads than number of tiles based on user's
1667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // input.
1677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const int tile_cols = 1 << cm->log2_tile_cols;
1687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const int num_workers = MIN(nworkers, tile_cols);
1697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  int i;
1707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (!lf_sync->sync_range || sb_rows != lf_sync->rows ||
1727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      num_workers > lf_sync->num_workers) {
1737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    vp9_loop_filter_dealloc(lf_sync);
1747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    vp9_loop_filter_alloc(lf_sync, cm, sb_rows, cm->width, num_workers);
1757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
1767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // Initialize cur_sb_col to -1 for all SB rows.
1787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  memset(lf_sync->cur_sb_col, -1, sizeof(*lf_sync->cur_sb_col) * sb_rows);
1797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // Set up loopfilter thread data.
1817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // The decoder is capping num_workers because it has been observed that using
1827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // more threads on the loopfilter than there are cores will hurt performance
1837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // on Android. This is because the system will only schedule the tile decode
1847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // workers on cores equal to the number of tile columns. Then if the decoder
1857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // tries to use more threads for the loopfilter, it will hurt performance
1867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // because of contention. If the multithreading code changes in the future
1877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // then the number of workers used by the loopfilter should be revisited.
1887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < num_workers; ++i) {
1897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    VPxWorker *const worker = &workers[i];
1907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    LFWorkerData *const lf_data = &lf_sync->lfdata[i];
1917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    worker->hook = (VPxWorkerHook)loop_filter_row_worker;
1937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    worker->data1 = lf_sync;
1947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    worker->data2 = lf_data;
1957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    // Loopfilter data
1977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    vp9_loop_filter_data_reset(lf_data, frame, cm, planes);
1987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    lf_data->start = start + i * MI_BLOCK_SIZE;
1997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    lf_data->stop = stop;
2007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    lf_data->y_only = y_only;
2017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    // Start loopfiltering
2037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    if (i == num_workers - 1) {
2047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      winterface->execute(worker);
2057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    } else {
2067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      winterface->launch(worker);
2077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    }
2087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
2097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // Wait till all rows are finished
2117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < num_workers; ++i) {
2127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    winterface->sync(&workers[i]);
2137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
2147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
2157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid vp9_loop_filter_frame_mt(YV12_BUFFER_CONFIG *frame,
2177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                              VP9_COMMON *cm,
2187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                              struct macroblockd_plane planes[MAX_MB_PLANE],
2197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                              int frame_filter_level,
2207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                              int y_only, int partial_frame,
2217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                              VPxWorker *workers, int num_workers,
2227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                              VP9LfSync *lf_sync) {
2237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  int start_mi_row, end_mi_row, mi_rows_to_filter;
2247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (!frame_filter_level) return;
2267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  start_mi_row = 0;
2287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  mi_rows_to_filter = cm->mi_rows;
2297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (partial_frame && cm->mi_rows > 8) {
2307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    start_mi_row = cm->mi_rows >> 1;
2317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    start_mi_row &= 0xfffffff8;
2327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    mi_rows_to_filter = MAX(cm->mi_rows / 8, 8);
2337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
2347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  end_mi_row = start_mi_row + mi_rows_to_filter;
2357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  vp9_loop_filter_frame_init(cm, frame_filter_level);
2367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  loop_filter_rows_mt(frame, cm, planes, start_mi_row, end_mi_row,
2387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                      y_only, workers, num_workers, lf_sync);
2397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
2407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// Set up nsync by width.
2427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic INLINE int get_sync_range(int width) {
2437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // nsync numbers are picked by testing. For example, for 4k
2447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // video, using 4 gives best performance.
2457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (width < 640)
2467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    return 1;
2477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  else if (width <= 1280)
2487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    return 2;
2497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  else if (width <= 4096)
2507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    return 4;
2517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  else
2527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    return 8;
2537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
2547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// Allocate memory for lf row synchronization
2567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid vp9_loop_filter_alloc(VP9LfSync *lf_sync, VP9_COMMON *cm, int rows,
2577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                           int width, int num_workers) {
2587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  lf_sync->rows = rows;
2597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_MULTITHREAD
2607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  {
2617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    int i;
2627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    CHECK_MEM_ERROR(cm, lf_sync->mutex_,
2647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                    vpx_malloc(sizeof(*lf_sync->mutex_) * rows));
2657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    if (lf_sync->mutex_) {
2667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      for (i = 0; i < rows; ++i) {
2677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        pthread_mutex_init(&lf_sync->mutex_[i], NULL);
2687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      }
2697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    }
2707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    CHECK_MEM_ERROR(cm, lf_sync->cond_,
2727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                    vpx_malloc(sizeof(*lf_sync->cond_) * rows));
2737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    if (lf_sync->cond_) {
2747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      for (i = 0; i < rows; ++i) {
2757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        pthread_cond_init(&lf_sync->cond_[i], NULL);
2767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      }
2777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    }
2787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
2797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif  // CONFIG_MULTITHREAD
2807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  CHECK_MEM_ERROR(cm, lf_sync->lfdata,
2827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                  vpx_malloc(num_workers * sizeof(*lf_sync->lfdata)));
2837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  lf_sync->num_workers = num_workers;
2847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  CHECK_MEM_ERROR(cm, lf_sync->cur_sb_col,
2867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                  vpx_malloc(sizeof(*lf_sync->cur_sb_col) * rows));
2877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // Set up nsync.
2897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  lf_sync->sync_range = get_sync_range(width);
2907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
2917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// Deallocate lf synchronization related mutex and data
2937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid vp9_loop_filter_dealloc(VP9LfSync *lf_sync) {
2947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (lf_sync != NULL) {
2957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_MULTITHREAD
2967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    int i;
2977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    if (lf_sync->mutex_ != NULL) {
2997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      for (i = 0; i < lf_sync->rows; ++i) {
3007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        pthread_mutex_destroy(&lf_sync->mutex_[i]);
3017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      }
3027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      vpx_free(lf_sync->mutex_);
3037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    }
3047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    if (lf_sync->cond_ != NULL) {
3057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      for (i = 0; i < lf_sync->rows; ++i) {
3067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        pthread_cond_destroy(&lf_sync->cond_[i]);
3077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      }
3087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      vpx_free(lf_sync->cond_);
3097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    }
3107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif  // CONFIG_MULTITHREAD
3117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    vpx_free(lf_sync->lfdata);
3127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    vpx_free(lf_sync->cur_sb_col);
3137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    // clear the structure as the source of this call may be a resize in which
3147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    // case this call will be followed by an _alloc() which may fail.
3157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    vp9_zero(*lf_sync);
3167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
3177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
3187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// Accumulate frame counts.
3207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid vp9_accumulate_frame_counts(VP9_COMMON *cm, FRAME_COUNTS *counts,
3217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                 int is_dec) {
3227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  int i, j, k, l, m;
3237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < BLOCK_SIZE_GROUPS; i++)
3257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < INTRA_MODES; j++)
3267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.y_mode[i][j] += counts->y_mode[i][j];
3277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < INTRA_MODES; i++)
3297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < INTRA_MODES; j++)
3307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.uv_mode[i][j] += counts->uv_mode[i][j];
3317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < PARTITION_CONTEXTS; i++)
3337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < PARTITION_TYPES; j++)
3347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.partition[i][j] += counts->partition[i][j];
3357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  if (is_dec) {
3377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    int n;
3387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (i = 0; i < TX_SIZES; i++)
3397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      for (j = 0; j < PLANE_TYPES; j++)
3407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        for (k = 0; k < REF_TYPES; k++)
3417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian          for (l = 0; l < COEF_BANDS; l++)
3427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            for (m = 0; m < COEFF_CONTEXTS; m++) {
3437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian              cm->counts.eob_branch[i][j][k][l][m] +=
3447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                  counts->eob_branch[i][j][k][l][m];
3457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian              for (n = 0; n < UNCONSTRAINED_NODES + 1; n++)
3467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                cm->counts.coef[i][j][k][l][m][n] +=
3477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                    counts->coef[i][j][k][l][m][n];
3487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            }
3497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  } else {
3507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (i = 0; i < TX_SIZES; i++)
3517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      for (j = 0; j < PLANE_TYPES; j++)
3527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        for (k = 0; k < REF_TYPES; k++)
3537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian          for (l = 0; l < COEF_BANDS; l++)
3547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian            for (m = 0; m < COEFF_CONTEXTS; m++)
3557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian              cm->counts.eob_branch[i][j][k][l][m] +=
3567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                  counts->eob_branch[i][j][k][l][m];
3577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                // In the encoder, cm->counts.coef is only updated at frame
3587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                // level, so not need to accumulate it here.
3597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                // for (n = 0; n < UNCONSTRAINED_NODES + 1; n++)
3607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                //   cm->counts.coef[i][j][k][l][m][n] +=
3617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                //       counts->coef[i][j][k][l][m][n];
3627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
3637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
3657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < SWITCHABLE_FILTERS; j++)
3667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.switchable_interp[i][j] += counts->switchable_interp[i][j];
3677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < INTER_MODE_CONTEXTS; i++)
3697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < INTER_MODES; j++)
3707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.inter_mode[i][j] += counts->inter_mode[i][j];
3717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
3737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < 2; j++)
3747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.intra_inter[i][j] += counts->intra_inter[i][j];
3757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < COMP_INTER_CONTEXTS; i++)
3777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < 2; j++)
3787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.comp_inter[i][j] += counts->comp_inter[i][j];
3797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < REF_CONTEXTS; i++)
3817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < 2; j++)
3827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      for (k = 0; k < 2; k++)
3837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.single_ref[i][j][k] += counts->single_ref[i][j][k];
3847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < REF_CONTEXTS; i++)
3867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < 2; j++)
3877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.comp_ref[i][j] += counts->comp_ref[i][j];
3887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
3907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < TX_SIZES; j++)
3917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.tx.p32x32[i][j] += counts->tx.p32x32[i][j];
3927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < TX_SIZES - 1; j++)
3947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.tx.p16x16[i][j] += counts->tx.p16x16[i][j];
3957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < TX_SIZES - 2; j++)
3977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.tx.p8x8[i][j] += counts->tx.p8x8[i][j];
3987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
3997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
4007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < TX_SIZES; i++)
4017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    cm->counts.tx.tx_totals[i] += counts->tx.tx_totals[i];
4027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
4037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < SKIP_CONTEXTS; i++)
4047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (j = 0; j < 2; j++)
4057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      cm->counts.skip[i][j] += counts->skip[i][j];
4067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
4077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (i = 0; i < MV_JOINTS; i++)
4087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    cm->counts.mv.joints[i] += counts->mv.joints[i];
4097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
4107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  for (k = 0; k < 2; k++) {
4117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    nmv_component_counts *comps = &cm->counts.mv.comps[k];
4127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    nmv_component_counts *comps_t = &counts->mv.comps[k];
4137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
4147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (i = 0; i < 2; i++) {
4157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      comps->sign[i] += comps_t->sign[i];
4167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      comps->class0_hp[i] += comps_t->class0_hp[i];
4177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      comps->hp[i] += comps_t->hp[i];
4187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    }
4197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
4207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (i = 0; i < MV_CLASSES; i++)
4217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      comps->classes[i] += comps_t->classes[i];
4227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
4237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (i = 0; i < CLASS0_SIZE; i++) {
4247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      comps->class0[i] += comps_t->class0[i];
4257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      for (j = 0; j < MV_FP_SIZE; j++)
4267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        comps->class0_fp[i][j] += comps_t->class0_fp[i][j];
4277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    }
4287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
4297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (i = 0; i < MV_OFFSET_BITS; i++)
4307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      for (j = 0; j < 2; j++)
4317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian        comps->bits[i][j] += comps_t->bits[i][j];
4327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
4337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian    for (i = 0; i < MV_FP_SIZE; i++)
4347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian      comps->fp[i] += comps_t->fp[i];
4357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  }
4367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
437