/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#include <assert.h>
#include <stdbool.h>

#include "aom_util/aom_pthread.h"

#include "av1/common/warped_motion.h"
#include "av1/common/thread_common.h"

#include "av1/encoder/allintra_vis.h"
#include "av1/encoder/bitstream.h"
#include "av1/encoder/enc_enums.h"
#include "av1/encoder/encodeframe.h"
#include "av1/encoder/encodeframe_utils.h"
#include "av1/encoder/encoder.h"
#include "av1/encoder/encoder_alloc.h"
#include "av1/encoder/ethread.h"
#if !CONFIG_REALTIME_ONLY
#include "av1/encoder/firstpass.h"
#endif
#include "av1/encoder/global_motion.h"
#include "av1/encoder/global_motion_facade.h"
#include "av1/encoder/intra_mode_search_utils.h"
#include "av1/encoder/picklpf.h"
#include "av1/encoder/rdopt.h"
#include "aom_dsp/aom_dsp_common.h"
#include "av1/encoder/temporal_filter.h"
#include "av1/encoder/tpl_model.h"

static inline void accumulate_rd_opt(ThreadData *td, ThreadData *td_t) {
  td->rd_counts.compound_ref_used_flag |=
      td_t->rd_counts.compound_ref_used_flag;
  td->rd_counts.skip_mode_used_flag |= td_t->rd_counts.skip_mode_used_flag;

  for (int i = 0; i < TX_SIZES_ALL; i++) {
    for (int j = 0; j < TX_TYPES; j++)
      td->rd_counts.tx_type_used[i][j] += td_t->rd_counts.tx_type_used[i][j];
  }

  for (int i = 0; i < BLOCK_SIZES_ALL; i++) {
    for (int j = 0; j < 2; j++) {
      td->rd_counts.obmc_used[i][j] += td_t->rd_counts.obmc_used[i][j];
    }
  }

  for (int i = 0; i < 2; i++) {
    td->rd_counts.warped_used[i] += td_t->rd_counts.warped_used[i];
  }

  td->rd_counts.seg_tmp_pred_cost[0] += td_t->rd_counts.seg_tmp_pred_cost[0];
  td->rd_counts.seg_tmp_pred_cost[1] += td_t->rd_counts.seg_tmp_pred_cost[1];

  td->rd_counts.newmv_or_intra_blocks += td_t->rd_counts.newmv_or_intra_blocks;
}

static inline void update_delta_lf_for_row_mt(AV1_COMP *cpi) {
  AV1_COMMON *cm = &cpi->common;
  MACROBLOCKD *xd = &cpi->td.mb.e_mbd;
  const int mib_size = cm->seq_params->mib_size;
  const int frame_lf_count =
      av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
  for (int row = 0; row < cm->tiles.rows; row++) {
    for (int col = 0; col < cm->tiles.cols; col++) {
      TileDataEnc *tile_data = &cpi->tile_data[row * cm->tiles.cols + col];
      const TileInfo *const tile_info = &tile_data->tile_info;
      for (int mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
           mi_row += mib_size) {
        if (mi_row == tile_info->mi_row_start)
          av1_reset_loop_filter_delta(xd, av1_num_planes(cm));
        for (int mi_col = tile_info->mi_col_start;
             mi_col < tile_info->mi_col_end; mi_col += mib_size) {
          const int idx_str = cm->mi_params.mi_stride * mi_row + mi_col;
          MB_MODE_INFO **mi = cm->mi_params.mi_grid_base + idx_str;
          MB_MODE_INFO *mbmi = mi[0];
          if (mbmi->skip_txfm == 1 &&
              (mbmi->bsize == cm->seq_params->sb_size)) {
            for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id)
              mbmi->delta_lf[lf_id] = xd->delta_lf[lf_id];
            mbmi->delta_lf_from_base = xd->delta_lf_from_base;
          } else {
            if (cm->delta_q_info.delta_lf_multi) {
              for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id)
                xd->delta_lf[lf_id] = mbmi->delta_lf[lf_id];
            } else {
              xd->delta_lf_from_base = mbmi->delta_lf_from_base;
            }
          }
        }
      }
    }
  }
}

void av1_row_mt_sync_read_dummy(AV1EncRowMultiThreadSync *row_mt_sync, int r,
                                int c) {
  (void)row_mt_sync;
  (void)r;
  (void)c;
}

void av1_row_mt_sync_write_dummy(AV1EncRowMultiThreadSync *row_mt_sync, int r,
                                 int c, int cols) {
  (void)row_mt_sync;
  (void)r;
  (void)c;
  (void)cols;
}

void av1_row_mt_sync_read(AV1EncRowMultiThreadSync *row_mt_sync, int r, int c) {
#if CONFIG_MULTITHREAD
  const int nsync = row_mt_sync->sync_range;

  if (r) {
    pthread_mutex_t *const mutex = &row_mt_sync->mutex_[r - 1];
    pthread_mutex_lock(mutex);

    while (c > row_mt_sync->num_finished_cols[r - 1] - nsync -
                   row_mt_sync->intrabc_extra_top_right_sb_delay) {
      pthread_cond_wait(&row_mt_sync->cond_[r - 1], mutex);
    }
    pthread_mutex_unlock(mutex);
  }
#else
  (void)row_mt_sync;
  (void)r;
  (void)c;
#endif  // CONFIG_MULTITHREAD
}

void av1_row_mt_sync_write(AV1EncRowMultiThreadSync *row_mt_sync, int r, int c,
                           int cols) {
#if CONFIG_MULTITHREAD
  const int nsync = row_mt_sync->sync_range;
  int cur;
  // Only signal when there are enough encoded blocks for next row to run.
  int sig = 1;

  if (c < cols - 1) {
    cur = c;
    if (c % nsync) sig = 0;
  } else {
    cur = cols + nsync + row_mt_sync->intrabc_extra_top_right_sb_delay;
  }

  if (sig) {
    pthread_mutex_lock(&row_mt_sync->mutex_[r]);

    // When a thread encounters an error, num_finished_cols[r] is set to maximum
    // column number. In this case, the AOMMAX operation here ensures that
    // num_finished_cols[r] is not overwritten with a smaller value thus
    // preventing the infinite waiting of threads in the relevant sync_read()
    // function.
    row_mt_sync->num_finished_cols[r] =
        AOMMAX(row_mt_sync->num_finished_cols[r], cur);

    pthread_cond_signal(&row_mt_sync->cond_[r]);
    pthread_mutex_unlock(&row_mt_sync->mutex_[r]);
  }
#else
  (void)row_mt_sync;
  (void)r;
  (void)c;
  (void)cols;
#endif  // CONFIG_MULTITHREAD
}

// Allocate memory for row synchronization
static void row_mt_sync_mem_alloc(AV1EncRowMultiThreadSync *row_mt_sync,
                                  AV1_COMMON *cm, int rows) {
#if CONFIG_MULTITHREAD
  int i;

  CHECK_MEM_ERROR(cm, row_mt_sync->mutex_,
                  aom_malloc(sizeof(*row_mt_sync->mutex_) * rows));
  if (row_mt_sync->mutex_) {
    for (i = 0; i < rows; ++i) {
      pthread_mutex_init(&row_mt_sync->mutex_[i], NULL);
    }
  }

  CHECK_MEM_ERROR(cm, row_mt_sync->cond_,
                  aom_malloc(sizeof(*row_mt_sync->cond_) * rows));
  if (row_mt_sync->cond_) {
    for (i = 0; i < rows; ++i) {
      pthread_cond_init(&row_mt_sync->cond_[i], NULL);
    }
  }
#endif  // CONFIG_MULTITHREAD

  CHECK_MEM_ERROR(cm, row_mt_sync->num_finished_cols,
                  aom_malloc(sizeof(*row_mt_sync->num_finished_cols) * rows));

  row_mt_sync->rows = rows;
  // Set up nsync.
  row_mt_sync->sync_range = 1;
}

// Deallocate row based multi-threading synchronization related mutex and data
void av1_row_mt_sync_mem_dealloc(AV1EncRowMultiThreadSync *row_mt_sync) {
  if (row_mt_sync != NULL) {
#if CONFIG_MULTITHREAD
    int i;

    if (row_mt_sync->mutex_ != NULL) {
      for (i = 0; i < row_mt_sync->rows; ++i) {
        pthread_mutex_destroy(&row_mt_sync->mutex_[i]);
      }
      aom_free(row_mt_sync->mutex_);
    }
    if (row_mt_sync->cond_ != NULL) {
      for (i = 0; i < row_mt_sync->rows; ++i) {
        pthread_cond_destroy(&row_mt_sync->cond_[i]);
      }
      aom_free(row_mt_sync->cond_);
    }
#endif  // CONFIG_MULTITHREAD
    aom_free(row_mt_sync->num_finished_cols);

    // clear the structure as the source of this call may be dynamic change
    // in tiles in which case this call will be followed by an _alloc()
    // which may fail.
    av1_zero(*row_mt_sync);
  }
}

static inline int get_sb_rows_in_frame(AV1_COMMON *cm) {
  return CEIL_POWER_OF_TWO(cm->mi_params.mi_rows,
                           cm->seq_params->mib_size_log2);
}

static void row_mt_mem_alloc(AV1_COMP *cpi, int max_rows, int max_cols,
                             int alloc_row_ctx) {
  struct AV1Common *cm = &cpi->common;
  AV1EncRowMultiThreadInfo *const enc_row_mt = &cpi->mt_info.enc_row_mt;
  const int tile_cols = cm->tiles.cols;
  const int tile_rows = cm->tiles.rows;
  int tile_col, tile_row;

  av1_row_mt_mem_dealloc(cpi);

  // Allocate memory for row based multi-threading
  assert(cpi->allocated_tiles == tile_cols * tile_rows);
  for (tile_row = 0; tile_row < tile_rows; tile_row++) {
    for (tile_col = 0; tile_col < tile_cols; tile_col++) {
      int tile_index = tile_row * tile_cols + tile_col;
      TileDataEnc *const this_tile = &cpi->tile_data[tile_index];

      row_mt_sync_mem_alloc(&this_tile->row_mt_sync, cm, max_rows);

      if (alloc_row_ctx) {
        assert(max_cols > 0);
        const int num_row_ctx = AOMMAX(1, (max_cols - 1));
        CHECK_MEM_ERROR(cm, this_tile->row_ctx,
                        (FRAME_CONTEXT *)aom_memalign(
                            16, num_row_ctx * sizeof(*this_tile->row_ctx)));
      }
    }
  }
  enc_row_mt->allocated_tile_cols = tile_cols;
  enc_row_mt->allocated_tile_rows = tile_rows;
  const int sb_rows = get_sb_rows_in_frame(cm);
  CHECK_MEM_ERROR(
      cm, enc_row_mt->num_tile_cols_done,
      aom_malloc(sizeof(*enc_row_mt->num_tile_cols_done) * sb_rows));

  enc_row_mt->allocated_rows = max_rows;
  enc_row_mt->allocated_cols = max_cols - 1;
  enc_row_mt->allocated_sb_rows = sb_rows;
}

void av1_row_mt_mem_dealloc(AV1_COMP *cpi) {
  AV1EncRowMultiThreadInfo *const enc_row_mt = &cpi->mt_info.enc_row_mt;
  const int tile_cols = enc_row_mt->allocated_tile_cols;
  const int tile_rows = enc_row_mt->allocated_tile_rows;
  int tile_col, tile_row;

  // Free row based multi-threading sync memory
  for (tile_row = 0; tile_row < tile_rows; tile_row++) {
    for (tile_col = 0; tile_col < tile_cols; tile_col++) {
      int tile_index = tile_row * tile_cols + tile_col;
      TileDataEnc *const this_tile = &cpi->tile_data[tile_index];

      av1_row_mt_sync_mem_dealloc(&this_tile->row_mt_sync);

      if (cpi->oxcf.algo_cfg.cdf_update_mode) {
        aom_free(this_tile->row_ctx);
        this_tile->row_ctx = NULL;
      }
    }
  }
  enc_row_mt->allocated_tile_cols = 0;
  enc_row_mt->allocated_tile_rows = 0;
  aom_free(enc_row_mt->num_tile_cols_done);
  enc_row_mt->num_tile_cols_done = NULL;
  enc_row_mt->allocated_rows = 0;
  enc_row_mt->allocated_cols = 0;
  enc_row_mt->allocated_sb_rows = 0;
}

static inline void assign_tile_to_thread(int *thread_id_to_tile_id,
                                         int num_tiles, int num_workers) {
  int tile_id = 0;
  int i;

  for (i = 0; i < num_workers; i++) {
    thread_id_to_tile_id[i] = tile_id++;
    if (tile_id == num_tiles) tile_id = 0;
  }
}

static inline int get_next_job(TileDataEnc *const tile_data,
                               int *current_mi_row, int mib_size) {
  AV1EncRowMultiThreadSync *const row_mt_sync = &tile_data->row_mt_sync;
  const int mi_row_end = tile_data->tile_info.mi_row_end;

  if (row_mt_sync->next_mi_row < mi_row_end) {
    *current_mi_row = row_mt_sync->next_mi_row;
    row_mt_sync->num_threads_working++;
    row_mt_sync->next_mi_row += mib_size;
    return 1;
  }
  return 0;
}

static inline void switch_tile_and_get_next_job(
    AV1_COMMON *const cm, TileDataEnc *const tile_data, int *cur_tile_id,
    int *current_mi_row, int *end_of_frame, int is_firstpass,
    const BLOCK_SIZE fp_block_size) {
  const int tile_cols = cm->tiles.cols;
  const int tile_rows = cm->tiles.rows;

  int tile_id = -1;  // Stores the tile ID with minimum proc done
  int max_mis_to_encode = 0;
  int min_num_threads_working = INT_MAX;

  for (int tile_row = 0; tile_row < tile_rows; tile_row++) {
    for (int tile_col = 0; tile_col < tile_cols; tile_col++) {
      int tile_index = tile_row * tile_cols + tile_col;
      TileDataEnc *const this_tile = &tile_data[tile_index];
      AV1EncRowMultiThreadSync *const row_mt_sync = &this_tile->row_mt_sync;

#if CONFIG_REALTIME_ONLY
      int num_b_rows_in_tile =
          av1_get_sb_rows_in_tile(cm, &this_tile->tile_info);
      int num_b_cols_in_tile =
          av1_get_sb_cols_in_tile(cm, &this_tile->tile_info);
#else
      int num_b_rows_in_tile =
          is_firstpass
              ? av1_get_unit_rows_in_tile(&this_tile->tile_info, fp_block_size)
              : av1_get_sb_rows_in_tile(cm, &this_tile->tile_info);
      int num_b_cols_in_tile =
          is_firstpass
              ? av1_get_unit_cols_in_tile(&this_tile->tile_info, fp_block_size)
              : av1_get_sb_cols_in_tile(cm, &this_tile->tile_info);
#endif
      int theoretical_limit_on_threads =
          AOMMIN((num_b_cols_in_tile + 1) >> 1, num_b_rows_in_tile);
      int num_threads_working = row_mt_sync->num_threads_working;

      if (num_threads_working < theoretical_limit_on_threads) {
        int num_mis_to_encode =
            this_tile->tile_info.mi_row_end - row_mt_sync->next_mi_row;

        // Tile to be processed by this thread is selected on the basis of
        // availability of jobs:
        // 1) If jobs are available, tile to be processed is chosen on the
        // basis of minimum number of threads working for that tile. If two or
        // more tiles have same number of threads working for them, then the
        // tile with maximum number of jobs available will be chosen.
        // 2) If no jobs are available, then end_of_frame is reached.
        if (num_mis_to_encode > 0) {
          if (num_threads_working < min_num_threads_working) {
            min_num_threads_working = num_threads_working;
            max_mis_to_encode = 0;
          }
          if (num_threads_working == min_num_threads_working &&
              num_mis_to_encode > max_mis_to_encode) {
            tile_id = tile_index;
            max_mis_to_encode = num_mis_to_encode;
          }
        }
      }
    }
  }
  if (tile_id == -1) {
    *end_of_frame = 1;
  } else {
    // Update the current tile id to the tile id that will be processed next,
    // which will be the least processed tile.
    *cur_tile_id = tile_id;
    const int unit_height = mi_size_high[fp_block_size];
    get_next_job(&tile_data[tile_id], current_mi_row,
                 is_firstpass ? unit_height : cm->seq_params->mib_size);
  }
}

#if !CONFIG_REALTIME_ONLY
static void set_firstpass_encode_done(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
  AV1EncRowMultiThreadInfo *const enc_row_mt = &cpi->mt_info.enc_row_mt;
  const int tile_cols = cm->tiles.cols;
  const int tile_rows = cm->tiles.rows;
  const BLOCK_SIZE fp_block_size = cpi->fp_block_size;
  const int unit_height = mi_size_high[fp_block_size];

  // In case of multithreading of firstpass encode, due to top-right
  // dependency, the worker on a firstpass row waits for the completion of the
  // firstpass processing of the top and top-right fp_blocks. Hence, in case a
  // thread (main/worker) encounters an error, update the firstpass processing
  // of every row in the frame to indicate that it is complete in order to avoid
  // dependent workers waiting indefinitely.
  for (int tile_row = 0; tile_row < tile_rows; ++tile_row) {
    for (int tile_col = 0; tile_col < tile_cols; ++tile_col) {
      TileDataEnc *const tile_data =
          &cpi->tile_data[tile_row * tile_cols + tile_col];
      TileInfo *tile = &tile_data->tile_info;
      AV1EncRowMultiThreadSync *const row_mt_sync = &tile_data->row_mt_sync;
      const int unit_cols_in_tile =
          av1_get_unit_cols_in_tile(tile, fp_block_size);
      for (int mi_row = tile->mi_row_start, unit_row_in_tile = 0;
           mi_row < tile->mi_row_end;
           mi_row += unit_height, unit_row_in_tile++) {
        enc_row_mt->sync_write_ptr(row_mt_sync, unit_row_in_tile,
                                   unit_cols_in_tile - 1, unit_cols_in_tile);
      }
    }
  }
}

static int fp_enc_row_mt_worker_hook(void *arg1, void *unused) {
  EncWorkerData *const thread_data = (EncWorkerData *)arg1;
  AV1_COMP *const cpi = thread_data->cpi;
  int thread_id = thread_data->thread_id;
  AV1EncRowMultiThreadInfo *const enc_row_mt = &cpi->mt_info.enc_row_mt;
#if CONFIG_MULTITHREAD
  pthread_mutex_t *enc_row_mt_mutex_ = enc_row_mt->mutex_;
#endif
  (void)unused;
  struct aom_internal_error_info *const error_info = &thread_data->error_info;
  MACROBLOCKD *const xd = &thread_data->td->mb.e_mbd;
  xd->error_info = error_info;

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(error_info->jmp)) {
    error_info->setjmp = 0;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(enc_row_mt_mutex_);
    enc_row_mt->firstpass_mt_exit = true;
    pthread_mutex_unlock(enc_row_mt_mutex_);
#endif
    set_firstpass_encode_done(cpi);
    return 0;
  }
  error_info->setjmp = 1;

  AV1_COMMON *const cm = &cpi->common;
  int cur_tile_id = enc_row_mt->thread_id_to_tile_id[thread_id];
  assert(cur_tile_id != -1);

  const BLOCK_SIZE fp_block_size = cpi->fp_block_size;
  const int unit_height = mi_size_high[fp_block_size];
  int end_of_frame = 0;
  while (1) {
    int current_mi_row = -1;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(enc_row_mt_mutex_);
#endif
    bool firstpass_mt_exit = enc_row_mt->firstpass_mt_exit;
    if (!firstpass_mt_exit && !get_next_job(&cpi->tile_data[cur_tile_id],
                                            &current_mi_row, unit_height)) {
      // No jobs are available for the current tile. Query for the status of
      // other tiles and get the next job if available
      switch_tile_and_get_next_job(cm, cpi->tile_data, &cur_tile_id,
                                   &current_mi_row, &end_of_frame, 1,
                                   fp_block_size);
    }
#if CONFIG_MULTITHREAD
    pthread_mutex_unlock(enc_row_mt_mutex_);
#endif
    // When firstpass_mt_exit is set to true, other workers need not pursue any
    // further jobs.
    if (firstpass_mt_exit || end_of_frame) break;

    TileDataEnc *const this_tile = &cpi->tile_data[cur_tile_id];
    AV1EncRowMultiThreadSync *const row_mt_sync = &this_tile->row_mt_sync;
    ThreadData *td = thread_data->td;

    assert(current_mi_row != -1 &&
           current_mi_row < this_tile->tile_info.mi_row_end);

    const int unit_height_log2 = mi_size_high_log2[fp_block_size];
    av1_first_pass_row(cpi, td, this_tile, current_mi_row >> unit_height_log2,
                       fp_block_size);
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(enc_row_mt_mutex_);
#endif
    row_mt_sync->num_threads_working--;
#if CONFIG_MULTITHREAD
    pthread_mutex_unlock(enc_row_mt_mutex_);
#endif
  }
  error_info->setjmp = 0;
  return 1;
}
#endif

static void launch_loop_filter_rows(AV1_COMMON *cm, EncWorkerData *thread_data,
                                    AV1EncRowMultiThreadInfo *enc_row_mt,
                                    int mib_size_log2) {
  AV1LfSync *const lf_sync = (AV1LfSync *)thread_data->lf_sync;
  const int sb_rows = get_sb_rows_in_frame(cm);
  AV1LfMTInfo *cur_job_info;
  bool row_mt_exit = false;
  (void)enc_row_mt;
#if CONFIG_MULTITHREAD
  pthread_mutex_t *enc_row_mt_mutex_ = enc_row_mt->mutex_;
#endif

  while ((cur_job_info = get_lf_job_info(lf_sync)) != NULL) {
    LFWorkerData *const lf_data = (LFWorkerData *)thread_data->lf_data;
    const int lpf_opt_level = cur_job_info->lpf_opt_level;
    (void)sb_rows;
#if CONFIG_MULTITHREAD
    const int cur_sb_row = cur_job_info->mi_row >> mib_size_log2;
    const int next_sb_row = AOMMIN(sb_rows - 1, cur_sb_row + 1);
    // Wait for current and next superblock row to finish encoding.
    pthread_mutex_lock(enc_row_mt_mutex_);
    while (!enc_row_mt->row_mt_exit &&
           (enc_row_mt->num_tile_cols_done[cur_sb_row] < cm->tiles.cols ||
            enc_row_mt->num_tile_cols_done[next_sb_row] < cm->tiles.cols)) {
      pthread_cond_wait(enc_row_mt->cond_, enc_row_mt_mutex_);
    }
    row_mt_exit = enc_row_mt->row_mt_exit;
    pthread_mutex_unlock(enc_row_mt_mutex_);
#endif
    if (row_mt_exit) return;

    av1_thread_loop_filter_rows(
        lf_data->frame_buffer, lf_data->cm, lf_data->planes, lf_data->xd,
        cur_job_info->mi_row, cur_job_info->plane, cur_job_info->dir,
        lpf_opt_level, lf_sync, &thread_data->error_info, lf_data->params_buf,
        lf_data->tx_buf, mib_size_log2);
  }
}

static void set_encoding_done(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
  const int tile_cols = cm->tiles.cols;
  const int tile_rows = cm->tiles.rows;
  AV1EncRowMultiThreadInfo *const enc_row_mt = &cpi->mt_info.enc_row_mt;
  const int mib_size = cm->seq_params->mib_size;

  // In case of row-multithreading, due to top-right dependency, the worker on
  // an SB row waits for the completion of the encode of the top and top-right
  // SBs. Hence, in case a thread (main/worker) encounters an error, update that
  // encoding of every SB row in the frame is complete in order to avoid the
  // dependent workers of every tile from waiting indefinitely.
  for (int tile_row = 0; tile_row < tile_rows; tile_row++) {
    for (int tile_col = 0; tile_col < tile_cols; tile_col++) {
      TileDataEnc *const this_tile =
          &cpi->tile_data[tile_row * tile_cols + tile_col];
      const TileInfo *const tile_info = &this_tile->tile_info;
      AV1EncRowMultiThreadSync *const row_mt_sync = &this_tile->row_mt_sync;
      const int sb_cols_in_tile = av1_get_sb_cols_in_tile(cm, tile_info);
      for (int mi_row = tile_info->mi_row_start, sb_row_in_tile = 0;
           mi_row < tile_info->mi_row_end;
           mi_row += mib_size, sb_row_in_tile++) {
        enc_row_mt->sync_write_ptr(row_mt_sync, sb_row_in_tile,
                                   sb_cols_in_tile - 1, sb_cols_in_tile);
      }
    }
  }
}

static bool lpf_mt_with_enc_enabled(int pipeline_lpf_mt_with_enc,
                                    const int filter_level[2]) {
  return pipeline_lpf_mt_with_enc && (filter_level[0] || filter_level[1]);
}

static int enc_row_mt_worker_hook(void *arg1, void *unused) {
  EncWorkerData *const thread_data = (EncWorkerData *)arg1;
  AV1_COMP *const cpi = thread_data->cpi;
  int thread_id = thread_data->thread_id;
  AV1EncRowMultiThreadInfo *const enc_row_mt = &cpi->mt_info.enc_row_mt;
#if CONFIG_MULTITHREAD
  pthread_mutex_t *enc_row_mt_mutex_ = enc_row_mt->mutex_;
#endif
  (void)unused;

  struct aom_internal_error_info *const error_info = &thread_data->error_info;
  AV1LfSync *const lf_sync = thread_data->lf_sync;
  MACROBLOCKD *const xd = &thread_data->td->mb.e_mbd;
  xd->error_info = error_info;
  AV1_COMMON *volatile const cm = &cpi->common;
  volatile const bool do_pipelined_lpf_mt_with_enc = lpf_mt_with_enc_enabled(
      cpi->mt_info.pipeline_lpf_mt_with_enc, cm->lf.filter_level);

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(error_info->jmp)) {
    error_info->setjmp = 0;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(enc_row_mt_mutex_);
    enc_row_mt->row_mt_exit = true;
    // Wake up all the workers waiting in launch_loop_filter_rows() to exit in
    // case of an error.
    pthread_cond_broadcast(enc_row_mt->cond_);
    pthread_mutex_unlock(enc_row_mt_mutex_);
#endif
    set_encoding_done(cpi);

    if (do_pipelined_lpf_mt_with_enc) {
#if CONFIG_MULTITHREAD
      pthread_mutex_lock(lf_sync->job_mutex);
      lf_sync->lf_mt_exit = true;
      pthread_mutex_unlock(lf_sync->job_mutex);
#endif
      av1_set_vert_loop_filter_done(&cpi->common, lf_sync,
                                    cpi->common.seq_params->mib_size_log2);
    }
    return 0;
  }
  error_info->setjmp = 1;

  const int mib_size_log2 = cm->seq_params->mib_size_log2;
  int cur_tile_id = enc_row_mt->thread_id_to_tile_id[thread_id];

  // Preallocate the pc_tree for realtime coding to reduce the cost of memory
  // allocation.
  if (cpi->sf.rt_sf.use_nonrd_pick_mode) {
    thread_data->td->pc_root = av1_alloc_pc_tree_node(cm->seq_params->sb_size);
    if (!thread_data->td->pc_root)
      aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
                         "Failed to allocate PC_TREE");
  } else {
    thread_data->td->pc_root = NULL;
  }

  assert(cur_tile_id != -1);

  const BLOCK_SIZE fp_block_size = cpi->fp_block_size;
  int end_of_frame = 0;
  bool row_mt_exit = false;

  // When master thread does not have a valid job to process, xd->tile_ctx
  // is not set and it contains NULL pointer. This can result in NULL pointer
  // access violation if accessed beyond the encode stage. Hence, updating
  // thread_data->td->mb.e_mbd.tile_ctx is initialized with common frame
  // context to avoid NULL pointer access in subsequent stages.
  thread_data->td->mb.e_mbd.tile_ctx = cm->fc;
  while (1) {
    int current_mi_row = -1;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(enc_row_mt_mutex_);
#endif
    row_mt_exit = enc_row_mt->row_mt_exit;
    // row_mt_exit check here can be avoided as it is checked after
    // sync_read_ptr() in encode_sb_row(). However, checking row_mt_exit here,
    // tries to return before calling the function get_next_job().
    if (!row_mt_exit &&
        !get_next_job(&cpi->tile_data[cur_tile_id], &current_mi_row,
                      cm->seq_params->mib_size)) {
      // No jobs are available for the current tile. Query for the status of
      // other tiles and get the next job if available
      switch_tile_and_get_next_job(cm, cpi->tile_data, &cur_tile_id,
                                   &current_mi_row, &end_of_frame, 0,
                                   fp_block_size);
    }
#if CONFIG_MULTITHREAD
    pthread_mutex_unlock(enc_row_mt_mutex_);
#endif
    // When row_mt_exit is set to true, other workers need not pursue any
    // further jobs.
    if (row_mt_exit) {
      error_info->setjmp = 0;
      return 1;
    }

    if (end_of_frame) break;

    TileDataEnc *const this_tile = &cpi->tile_data[cur_tile_id];
    AV1EncRowMultiThreadSync *const row_mt_sync = &this_tile->row_mt_sync;
    const TileInfo *const tile_info = &this_tile->tile_info;
    const int tile_row = tile_info->tile_row;
    const int tile_col = tile_info->tile_col;
    ThreadData *td = thread_data->td;
    const int sb_row = current_mi_row >> mib_size_log2;

    assert(current_mi_row != -1 && current_mi_row <= tile_info->mi_row_end);

    td->mb.e_mbd.tile_ctx = td->tctx;
    td->mb.tile_pb_ctx = &this_tile->tctx;
    td->abs_sum_level = 0;

    if (this_tile->allow_update_cdf) {
      td->mb.row_ctx = this_tile->row_ctx;
      if (current_mi_row == tile_info->mi_row_start)
        *td->mb.e_mbd.tile_ctx = this_tile->tctx;
    } else {
      *td->mb.e_mbd.tile_ctx = this_tile->tctx;
    }

    av1_init_above_context(&cm->above_contexts, av1_num_planes(cm), tile_row,
                           &td->mb.e_mbd);
#if !CONFIG_REALTIME_ONLY
    cfl_init(&td->mb.e_mbd.cfl, cm->seq_params);
#endif
    if (td->mb.txfm_search_info.mb_rd_record != NULL) {
      av1_crc32c_calculator_init(
          &td->mb.txfm_search_info.mb_rd_record->crc_calculator);
    }

    av1_encode_sb_row(cpi, td, tile_row, tile_col, current_mi_row);
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(enc_row_mt_mutex_);
#endif
    this_tile->abs_sum_level += td->abs_sum_level;
    row_mt_sync->num_threads_working--;
    enc_row_mt->num_tile_cols_done[sb_row]++;
#if CONFIG_MULTITHREAD
    pthread_cond_broadcast(enc_row_mt->cond_);
    pthread_mutex_unlock(enc_row_mt_mutex_);
#endif
  }
  if (do_pipelined_lpf_mt_with_enc) {
    // Loop-filter a superblock row if encoding of the current and next
    // superblock row is complete.
    // TODO(deepa.kg @ittiam.com) Evaluate encoder speed by interleaving
    // encoding and loop filter stage.
    launch_loop_filter_rows(cm, thread_data, enc_row_mt, mib_size_log2);
  }
  av1_free_pc_tree_recursive(thread_data->td->pc_root, av1_num_planes(cm), 0, 0,
                             cpi->sf.part_sf.partition_search_type);
  thread_data->td->pc_root = NULL;
  error_info->setjmp = 0;
  return 1;
}

static int enc_worker_hook(void *arg1, void *unused) {
  EncWorkerData *const thread_data = (EncWorkerData *)arg1;
  AV1_COMP *const cpi = thread_data->cpi;
  MACROBLOCKD *const xd = &thread_data->td->mb.e_mbd;
  struct aom_internal_error_info *const error_info = &thread_data->error_info;
  const AV1_COMMON *const cm = &cpi->common;
  const int tile_cols = cm->tiles.cols;
  const int tile_rows = cm->tiles.rows;
  int t;

  (void)unused;

  xd->error_info = error_info;

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(error_info->jmp)) {
    error_info->setjmp = 0;
    return 0;
  }
  error_info->setjmp = 1;

  // Preallocate the pc_tree for realtime coding to reduce the cost of memory
  // allocation.
  if (cpi->sf.rt_sf.use_nonrd_pick_mode) {
    thread_data->td->pc_root = av1_alloc_pc_tree_node(cm->seq_params->sb_size);
    if (!thread_data->td->pc_root)
      aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
                         "Failed to allocate PC_TREE");
  } else {
    thread_data->td->pc_root = NULL;
  }

  for (t = thread_data->start; t < tile_rows * tile_cols;
       t += cpi->mt_info.num_workers) {
    int tile_row = t / tile_cols;
    int tile_col = t % tile_cols;

    TileDataEnc *const this_tile =
        &cpi->tile_data[tile_row * cm->tiles.cols + tile_col];
    thread_data->td->mb.e_mbd.tile_ctx = &this_tile->tctx;
    thread_data->td->mb.tile_pb_ctx = &this_tile->tctx;
    av1_encode_tile(cpi, thread_data->td, tile_row, tile_col);
  }

  av1_free_pc_tree_recursive(thread_data->td->pc_root, av1_num_planes(cm), 0, 0,
                             cpi->sf.part_sf.partition_search_type);
  thread_data->td->pc_root = NULL;
  error_info->setjmp = 0;
  return 1;
}

void av1_init_frame_mt(AV1_PRIMARY *ppi, AV1_COMP *cpi) {
  cpi->mt_info.workers = ppi->p_mt_info.workers;
  cpi->mt_info.num_workers = ppi->p_mt_info.num_workers;
  cpi->mt_info.tile_thr_data = ppi->p_mt_info.tile_thr_data;
  int i;
  for (i = MOD_FP; i < NUM_MT_MODULES; i++) {
    cpi->mt_info.num_mod_workers[i] =
        AOMMIN(cpi->mt_info.num_workers, ppi->p_mt_info.num_mod_workers[i]);
  }
}

void av1_init_cdef_worker(AV1_COMP *cpi) {
  // The allocation is done only for level 0 parallel frames. No change
  // in config is supported in the middle of a parallel encode set, since the
  // rest of the MT modules also do not support dynamic change of config.
  if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) return;
  PrimaryMultiThreadInfo *const p_mt_info = &cpi->ppi->p_mt_info;
  int num_cdef_workers = av1_get_num_mod_workers_for_alloc(p_mt_info, MOD_CDEF);

  av1_alloc_cdef_buffers(&cpi->common, &p_mt_info->cdef_worker,
                         &cpi->mt_info.cdef_sync, num_cdef_workers, 1);
  cpi->mt_info.cdef_worker = p_mt_info->cdef_worker;
}

#if !CONFIG_REALTIME_ONLY
void av1_init_lr_mt_buffers(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
  AV1LrSync *lr_sync = &cpi->mt_info.lr_row_sync;
  if (lr_sync->sync_range) {
    if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0)
      return;
    int num_lr_workers = lr_sync->num_workers;
    lr_sync->lrworkerdata[num_lr_workers - 1].rst_tmpbuf = cm->rst_tmpbuf;
    lr_sync->lrworkerdata[num_lr_workers - 1].rlbs = cm->rlbs;
  }
}
#endif

#if CONFIG_MULTITHREAD
void av1_init_mt_sync(AV1_COMP *cpi, int is_first_pass) {
  AV1_COMMON *const cm = &cpi->common;
  MultiThreadInfo *const mt_info = &cpi->mt_info;

  if (setjmp(cm->error->jmp)) {
    cm->error->setjmp = 0;
    aom_internal_error_copy(&cpi->ppi->error, cm->error);
  }
  cm->error->setjmp = 1;
  // Initialize enc row MT object.
  if (is_first_pass || cpi->oxcf.row_mt == 1) {
    AV1EncRowMultiThreadInfo *enc_row_mt = &mt_info->enc_row_mt;
    if (enc_row_mt->mutex_ == NULL) {
      CHECK_MEM_ERROR(cm, enc_row_mt->mutex_,
                      aom_malloc(sizeof(*(enc_row_mt->mutex_))));
      if (enc_row_mt->mutex_) pthread_mutex_init(enc_row_mt->mutex_, NULL);
    }
    if (enc_row_mt->cond_ == NULL) {
      CHECK_MEM_ERROR(cm, enc_row_mt->cond_,
                      aom_malloc(sizeof(*(enc_row_mt->cond_))));
      if (enc_row_mt->cond_) pthread_cond_init(enc_row_mt->cond_, NULL);
    }
  }

  if (!is_first_pass) {
    // Initialize global motion MT object.
    AV1GlobalMotionSync *gm_sync = &mt_info->gm_sync;
    if (gm_sync->mutex_ == NULL) {
      CHECK_MEM_ERROR(cm, gm_sync->mutex_,
                      aom_malloc(sizeof(*(gm_sync->mutex_))));
      if (gm_sync->mutex_) pthread_mutex_init(gm_sync->mutex_, NULL);
    }
#if !CONFIG_REALTIME_ONLY
    // Initialize temporal filtering MT object.
    AV1TemporalFilterSync *tf_sync = &mt_info->tf_sync;
    if (tf_sync->mutex_ == NULL) {
      CHECK_MEM_ERROR(cm, tf_sync->mutex_,
                      aom_malloc(sizeof(*tf_sync->mutex_)));
      if (tf_sync->mutex_) pthread_mutex_init(tf_sync->mutex_, NULL);
    }
#endif  // !CONFIG_REALTIME_ONLY
        // Initialize CDEF MT object.
    AV1CdefSync *cdef_sync = &mt_info->cdef_sync;
    if (cdef_sync->mutex_ == NULL) {
      CHECK_MEM_ERROR(cm, cdef_sync->mutex_,
                      aom_malloc(sizeof(*(cdef_sync->mutex_))));
      if (cdef_sync->mutex_) pthread_mutex_init(cdef_sync->mutex_, NULL);
    }

    // Initialize loop filter MT object.
    AV1LfSync *lf_sync = &mt_info->lf_row_sync;
    // Number of superblock rows
    const int sb_rows =
        CEIL_POWER_OF_TWO(cm->height >> MI_SIZE_LOG2, MAX_MIB_SIZE_LOG2);
    PrimaryMultiThreadInfo *const p_mt_info = &cpi->ppi->p_mt_info;
    int num_lf_workers = av1_get_num_mod_workers_for_alloc(p_mt_info, MOD_LPF);

    if (!lf_sync->sync_range || sb_rows != lf_sync->rows ||
        num_lf_workers > lf_sync->num_workers) {
      av1_loop_filter_dealloc(lf_sync);
      av1_loop_filter_alloc(lf_sync, cm, sb_rows, cm->width, num_lf_workers);
    }

    // Initialize tpl MT object.
    AV1TplRowMultiThreadInfo *tpl_row_mt = &mt_info->tpl_row_mt;
    if (tpl_row_mt->mutex_ == NULL) {
      CHECK_MEM_ERROR(cm, tpl_row_mt->mutex_,
                      aom_malloc(sizeof(*(tpl_row_mt->mutex_))));
      if (tpl_row_mt->mutex_) pthread_mutex_init(tpl_row_mt->mutex_, NULL);
    }

#if !CONFIG_REALTIME_ONLY
    if (is_restoration_used(cm)) {
      // Initialize loop restoration MT object.
      AV1LrSync *lr_sync = &mt_info->lr_row_sync;
      int rst_unit_size = cpi->sf.lpf_sf.min_lr_unit_size;
      int num_rows_lr = av1_lr_count_units(rst_unit_size, cm->height);
      int num_lr_workers = av1_get_num_mod_workers_for_alloc(p_mt_info, MOD_LR);
      const int num_planes = av1_num_planes(cm);
      if (!lr_sync->sync_range || num_rows_lr > lr_sync->rows ||
          num_lr_workers > lr_sync->num_workers ||
          num_planes > lr_sync->num_planes) {
        av1_loop_restoration_dealloc(lr_sync);
        av1_loop_restoration_alloc(lr_sync, cm, num_lr_workers, num_rows_lr,
                                   num_planes, cm->width);
      }
    }
#endif

    // Initialization of pack bitstream MT object.
    AV1EncPackBSSync *pack_bs_sync = &mt_info->pack_bs_sync;
    if (pack_bs_sync->mutex_ == NULL) {
      CHECK_MEM_ERROR(cm, pack_bs_sync->mutex_,
                      aom_malloc(sizeof(*pack_bs_sync->mutex_)));
      if (pack_bs_sync->mutex_) pthread_mutex_init(pack_bs_sync->mutex_, NULL);
    }
  }
  cm->error->setjmp = 0;
}
#endif  // CONFIG_MULTITHREAD

// Computes the number of workers to be considered while allocating memory for a
// multi-threaded module under FPMT.
int av1_get_num_mod_workers_for_alloc(const PrimaryMultiThreadInfo *p_mt_info,
                                      MULTI_THREADED_MODULES mod_name) {
  int num_mod_workers = p_mt_info->num_mod_workers[mod_name];
  if (p_mt_info->num_mod_workers[MOD_FRAME_ENC] > 1) {
    // TODO(anyone): Change num_mod_workers to num_mod_workers[MOD_FRAME_ENC].
    // As frame parallel jobs will only perform multi-threading for the encode
    // stage, we can limit the allocations according to num_enc_workers per
    // frame parallel encode(a.k.a num_mod_workers[MOD_FRAME_ENC]).
    num_mod_workers = p_mt_info->num_workers;
  }
  return num_mod_workers;
}

void av1_init_tile_thread_data(AV1_PRIMARY *ppi, int is_first_pass) {
  PrimaryMultiThreadInfo *const p_mt_info = &ppi->p_mt_info;

  assert(p_mt_info->workers != NULL);
  assert(p_mt_info->tile_thr_data != NULL);

  const int is_highbitdepth = ppi->seq_params.use_highbitdepth;
  int num_workers = p_mt_info->num_workers;
  int num_enc_workers = av1_get_num_mod_workers_for_alloc(p_mt_info, MOD_ENC);
  assert(num_enc_workers <= num_workers);
  for (int i = num_workers - 1; i >= 0; i--) {
    EncWorkerData *const thread_data = &p_mt_info->tile_thr_data[i];

    if (i > 0) {
      // Allocate thread data.
      ThreadData *td;
      AOM_CHECK_MEM_ERROR(&ppi->error, td, aom_memalign(32, sizeof(*td)));
      av1_zero(*td);
      thread_data->original_td = thread_data->td = td;

      // Set up shared coeff buffers.
      av1_setup_shared_coeff_buffer(&ppi->seq_params, &td->shared_coeff_buf,
                                    &ppi->error);
      AOM_CHECK_MEM_ERROR(&ppi->error, td->tmp_conv_dst,
                          aom_memalign(32, MAX_SB_SIZE * MAX_SB_SIZE *
                                               sizeof(*td->tmp_conv_dst)));

      if (i < p_mt_info->num_mod_workers[MOD_FP]) {
        // Set up firstpass PICK_MODE_CONTEXT.
        td->firstpass_ctx =
            av1_alloc_pmc(ppi->cpi, BLOCK_16X16, &td->shared_coeff_buf);
        if (!td->firstpass_ctx)
          aom_internal_error(&ppi->error, AOM_CODEC_MEM_ERROR,
                             "Failed to allocate PICK_MODE_CONTEXT");
      }

      AOM_CHECK_MEM_ERROR(
          &ppi->error, td->upsample_pred,
          aom_memalign(16, (1 + is_highbitdepth) * ((MAX_SB_SIZE + 16) + 16) *
                               MAX_SB_SIZE * sizeof(*td->upsample_pred)));

      if (!is_first_pass && i < num_enc_workers) {
        // Set up sms_tree.
        if (av1_setup_sms_tree(ppi->cpi, td)) {
          aom_internal_error(&ppi->error, AOM_CODEC_MEM_ERROR,
                             "Failed to allocate SMS tree");
        }

        for (int x = 0; x < 2; x++) {
          AOM_CHECK_MEM_ERROR(
              &ppi->error, td->hash_value_buffer[x],
              (uint32_t *)aom_malloc(AOM_BUFFER_SIZE_FOR_BLOCK_HASH *
                                     sizeof(*td->hash_value_buffer[x])));
        }

        // Allocate frame counters in thread data.
        AOM_CHECK_MEM_ERROR(&ppi->error, td->counts,
                            aom_calloc(1, sizeof(*td->counts)));

        // Allocate buffers used by palette coding mode.
        AOM_CHECK_MEM_ERROR(&ppi->error, td->palette_buffer,
                            aom_memalign(16, sizeof(*td->palette_buffer)));

        // The buffers 'tmp_pred_bufs[]', 'comp_rd_buffer' and 'obmc_buffer' are
        // used in inter frames to store intermediate inter mode prediction
        // results and are not required for allintra encoding mode. Hence, the
        // memory allocations for these buffers are avoided for allintra
        // encoding mode.
        if (ppi->cpi->oxcf.kf_cfg.key_freq_max != 0) {
          alloc_obmc_buffers(&td->obmc_buffer, &ppi->error);

          alloc_compound_type_rd_buffers(&ppi->error, &td->comp_rd_buffer);

          for (int j = 0; j < 2; ++j) {
            AOM_CHECK_MEM_ERROR(
                &ppi->error, td->tmp_pred_bufs[j],
                aom_memalign(32, 2 * MAX_MB_PLANE * MAX_SB_SQUARE *
                                     sizeof(*td->tmp_pred_bufs[j])));
          }
        }

        const int plane_types = PLANE_TYPES >> ppi->seq_params.monochrome;
        AOM_CHECK_MEM_ERROR(&ppi->error, td->pixel_gradient_info,
                            aom_malloc(sizeof(*td->pixel_gradient_info) *
                                       plane_types * MAX_SB_SQUARE));

        if (is_src_var_for_4x4_sub_blocks_caching_enabled(ppi->cpi)) {
          const BLOCK_SIZE sb_size = ppi->cpi->common.seq_params->sb_size;
          const int mi_count_in_sb =
              mi_size_wide[sb_size] * mi_size_high[sb_size];

          AOM_CHECK_MEM_ERROR(
              &ppi->error, td->src_var_info_of_4x4_sub_blocks,
              aom_malloc(sizeof(*td->src_var_info_of_4x4_sub_blocks) *
                         mi_count_in_sb));
        }

        if (ppi->cpi->sf.part_sf.partition_search_type == VAR_BASED_PARTITION) {
          const int num_64x64_blocks =
              (ppi->seq_params.sb_size == BLOCK_64X64) ? 1 : 4;
          AOM_CHECK_MEM_ERROR(
              &ppi->error, td->vt64x64,
              aom_malloc(sizeof(*td->vt64x64) * num_64x64_blocks));
        }
      }
    }

    if (!is_first_pass && ppi->cpi->oxcf.row_mt == 1 && i < num_enc_workers) {
      if (i == 0) {
        for (int j = 0; j < ppi->num_fp_contexts; j++) {
          AOM_CHECK_MEM_ERROR(&ppi->error, ppi->parallel_cpi[j]->td.tctx,
                              (FRAME_CONTEXT *)aom_memalign(
                                  16, sizeof(*ppi->parallel_cpi[j]->td.tctx)));
        }
      } else {
        AOM_CHECK_MEM_ERROR(
            &ppi->error, thread_data->td->tctx,
            (FRAME_CONTEXT *)aom_memalign(16, sizeof(*thread_data->td->tctx)));
      }
    }
  }

  // Record the number of workers in encode stage multi-threading for which
  // allocation is done.
  p_mt_info->prev_num_enc_workers = num_enc_workers;
}

void av1_create_workers(AV1_PRIMARY *ppi, int num_workers) {
  PrimaryMultiThreadInfo *const p_mt_info = &ppi->p_mt_info;
  const AVxWorkerInterface *const winterface = aom_get_worker_interface();
  assert(p_mt_info->num_workers == 0);

  AOM_CHECK_MEM_ERROR(&ppi->error, p_mt_info->workers,
                      aom_malloc(num_workers * sizeof(*p_mt_info->workers)));

  AOM_CHECK_MEM_ERROR(
      &ppi->error, p_mt_info->tile_thr_data,
      aom_calloc(num_workers, sizeof(*p_mt_info->tile_thr_data)));

  for (int i = 0; i < num_workers; ++i) {
    AVxWorker *const worker = &p_mt_info->workers[i];
    EncWorkerData *const thread_data = &p_mt_info->tile_thr_data[i];

    winterface->init(worker);
    worker->thread_name = "aom enc worker";

    thread_data->thread_id = i;
    // Set the starting tile for each thread.
    thread_data->start = i;

    if (i > 0) {
      // Create threads
      if (!winterface->reset(worker))
        aom_internal_error(&ppi->error, AOM_CODEC_ERROR,
                           "Tile encoder thread creation failed");
    }
    winterface->sync(worker);

    // Ensure p_mt_info->num_workers is the number of threads successfuly
    // created. Important to av1_terminate_workers().
    ++p_mt_info->num_workers;
  }
}

// This function will change the state and free the mutex of corresponding
// workers and terminate the object. The object can not be re-used unless a call
// to reset() is made.
void av1_terminate_workers(AV1_PRIMARY *ppi) {
  PrimaryMultiThreadInfo *const p_mt_info = &ppi->p_mt_info;
  for (int t = 0; t < p_mt_info->num_workers; ++t) {
    AVxWorker *const worker = &p_mt_info->workers[t];
    aom_get_worker_interface()->end(worker);
  }
}

// This function returns 1 if frame parallel encode is supported for
// the current configuration. Returns 0 otherwise.
static inline int is_fpmt_config(const AV1_PRIMARY *ppi,
                                 const AV1EncoderConfig *oxcf) {
  // FPMT is enabled for AOM_Q and AOM_VBR.
  // TODO(Tarun): Test and enable resize config.
  if (oxcf->rc_cfg.mode == AOM_CBR || oxcf->rc_cfg.mode == AOM_CQ) {
    return 0;
  }
  if (ppi->use_svc) {
    return 0;
  }
  if (oxcf->tile_cfg.enable_large_scale_tile) {
    return 0;
  }
  if (oxcf->dec_model_cfg.timing_info_present) {
    return 0;
  }
  if (oxcf->mode != GOOD) {
    return 0;
  }
  if (oxcf->tool_cfg.error_resilient_mode) {
    return 0;
  }
  if (oxcf->resize_cfg.resize_mode) {
    return 0;
  }
  if (oxcf->pass != AOM_RC_SECOND_PASS) {
    return 0;
  }
  if (oxcf->max_threads < 2) {
    return 0;
  }
  if (!oxcf->fp_mt) {
    return 0;
  }

  return 1;
}

int av1_check_fpmt_config(AV1_PRIMARY *const ppi,
                          const AV1EncoderConfig *const oxcf) {
  if (is_fpmt_config(ppi, oxcf)) return 1;
  // Reset frame parallel configuration for unsupported config
  if (ppi->num_fp_contexts > 1) {
    for (int i = 1; i < ppi->num_fp_contexts; i++) {
      // Release the previously-used frame-buffer
      if (ppi->parallel_cpi[i]->common.cur_frame != NULL) {
        --ppi->parallel_cpi[i]->common.cur_frame->ref_count;
        ppi->parallel_cpi[i]->common.cur_frame = NULL;
      }
    }

    int cur_gf_index = ppi->cpi->gf_frame_index;
    int reset_size = AOMMAX(0, ppi->gf_group.size - cur_gf_index);
    av1_zero_array(&ppi->gf_group.frame_parallel_level[cur_gf_index],
                   reset_size);
    av1_zero_array(&ppi->gf_group.is_frame_non_ref[cur_gf_index], reset_size);
    av1_zero_array(&ppi->gf_group.src_offset[cur_gf_index], reset_size);
    memset(&ppi->gf_group.skip_frame_refresh[cur_gf_index][0], INVALID_IDX,
           sizeof(ppi->gf_group.skip_frame_refresh[cur_gf_index][0]) *
               reset_size * REF_FRAMES);
    memset(&ppi->gf_group.skip_frame_as_ref[cur_gf_index], INVALID_IDX,
           sizeof(ppi->gf_group.skip_frame_as_ref[cur_gf_index]) * reset_size);
    ppi->num_fp_contexts = 1;
  }
  return 0;
}

// A large value for threads used to compute the max num_enc_workers
// possible for each resolution.
#define MAX_THREADS 100

// Computes the max number of enc workers possible for each resolution.
static inline int compute_max_num_enc_workers(
    CommonModeInfoParams *const mi_params, int mib_size_log2) {
  int num_sb_rows = CEIL_POWER_OF_TWO(mi_params->mi_rows, mib_size_log2);
  int num_sb_cols = CEIL_POWER_OF_TWO(mi_params->mi_cols, mib_size_log2);

  return AOMMIN((num_sb_cols + 1) >> 1, num_sb_rows);
}

// Computes the number of frame parallel(fp) contexts to be created
// based on the number of max_enc_workers.
int av1_compute_num_fp_contexts(AV1_PRIMARY *ppi, AV1EncoderConfig *oxcf) {
  ppi->p_mt_info.num_mod_workers[MOD_FRAME_ENC] = 0;
  if (!av1_check_fpmt_config(ppi, oxcf)) {
    return 1;
  }
  int max_num_enc_workers = compute_max_num_enc_workers(
      &ppi->cpi->common.mi_params, ppi->cpi->common.seq_params->mib_size_log2);
  // Scaling factors and rounding factors used to tune worker_per_frame
  // computation.
  int rounding_factor[2] = { 2, 4 };
  int scaling_factor[2] = { 4, 8 };
  int is_480p_or_lesser =
      AOMMIN(oxcf->frm_dim_cfg.width, oxcf->frm_dim_cfg.height) <= 480;
  int is_sb_64 = 0;
  if (ppi->cpi != NULL)
    is_sb_64 = ppi->cpi->common.seq_params->sb_size == BLOCK_64X64;
  // A parallel frame encode has at least 1/4th the
  // theoretical limit of max enc workers in default case. For resolutions
  // larger than 480p, if SB size is 64x64, optimal performance is obtained with
  // limit of 1/8.
  int index = (!is_480p_or_lesser && is_sb_64) ? 1 : 0;
  int workers_per_frame =
      AOMMAX(1, (max_num_enc_workers + rounding_factor[index]) /
                    scaling_factor[index]);
  int max_threads = oxcf->max_threads;
  int num_fp_contexts = max_threads / workers_per_frame;
  // Based on empirical results, FPMT gains with multi-tile are significant when
  // more parallel frames are available. Use FPMT with multi-tile encode only
  // when sufficient threads are available for parallel encode of
  // MAX_PARALLEL_FRAMES frames.
  if (oxcf->tile_cfg.tile_columns > 0 || oxcf->tile_cfg.tile_rows > 0) {
    if (num_fp_contexts < MAX_PARALLEL_FRAMES) num_fp_contexts = 1;
  }

  num_fp_contexts = clamp(num_fp_contexts, 1, MAX_PARALLEL_FRAMES);
  // Limit recalculated num_fp_contexts to ppi->num_fp_contexts.
  num_fp_contexts = (ppi->num_fp_contexts == 1)
                        ? num_fp_contexts
                        : AOMMIN(num_fp_contexts, ppi->num_fp_contexts);
  if (num_fp_contexts > 1) {
    ppi->p_mt_info.num_mod_workers[MOD_FRAME_ENC] =
        AOMMIN(max_num_enc_workers * num_fp_contexts, oxcf->max_threads);
  }
  return num_fp_contexts;
}

// Computes the number of workers to process each of the parallel frames.
static inline int compute_num_workers_per_frame(
    const int num_workers, const int parallel_frame_count) {
  // Number of level 2 workers per frame context (floor division).
  int workers_per_frame = (num_workers / parallel_frame_count);
  return workers_per_frame;
}

static inline void restore_workers_after_fpmt(AV1_PRIMARY *ppi,
                                              int parallel_frame_count,
                                              int num_fpmt_workers_prepared);

// Prepare level 1 workers. This function is only called for
// parallel_frame_count > 1. This function populates the mt_info structure of
// frame level contexts appropriately by dividing the total number of available
// workers amongst the frames as level 2 workers. It also populates the hook and
// data members of level 1 workers.
static inline void prepare_fpmt_workers(AV1_PRIMARY *ppi,
                                        AV1_COMP_DATA *first_cpi_data,
                                        AVxWorkerHook hook,
                                        int parallel_frame_count) {
  assert(parallel_frame_count <= ppi->num_fp_contexts &&
         parallel_frame_count > 1);

  PrimaryMultiThreadInfo *const p_mt_info = &ppi->p_mt_info;
  int num_workers = p_mt_info->num_workers;

  volatile int frame_idx = 0;
  volatile int i = 0;
  while (i < num_workers) {
    // Assign level 1 worker
    AVxWorker *frame_worker = p_mt_info->p_workers[frame_idx] =
        &p_mt_info->workers[i];
    AV1_COMP *cur_cpi = ppi->parallel_cpi[frame_idx];
    MultiThreadInfo *mt_info = &cur_cpi->mt_info;
    // This 'aom_internal_error_info' pointer is not derived from the local
    // pointer ('AV1_COMMON *const cm') to silence the compiler warning
    // "variable 'cm' might be clobbered by 'longjmp' or 'vfork' [-Wclobbered]".
    struct aom_internal_error_info *const error = cur_cpi->common.error;

    // The jmp_buf is valid only within the scope of the function that calls
    // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
    // before it returns.
    if (setjmp(error->jmp)) {
      error->setjmp = 0;
      restore_workers_after_fpmt(ppi, parallel_frame_count, i);
      aom_internal_error_copy(&ppi->error, error);
    }
    error->setjmp = 1;

    AV1_COMMON *const cm = &cur_cpi->common;
    // Assign start of level 2 worker pool
    mt_info->workers = &p_mt_info->workers[i];
    mt_info->tile_thr_data = &p_mt_info->tile_thr_data[i];
    // Assign number of workers for each frame in the parallel encode set.
    mt_info->num_workers = compute_num_workers_per_frame(
        num_workers - i, parallel_frame_count - frame_idx);
    for (int j = MOD_FP; j < NUM_MT_MODULES; j++) {
      mt_info->num_mod_workers[j] =
          AOMMIN(mt_info->num_workers, p_mt_info->num_mod_workers[j]);
    }
    if (p_mt_info->cdef_worker != NULL) {
      mt_info->cdef_worker = &p_mt_info->cdef_worker[i];

      // Back up the original cdef_worker pointers.
      mt_info->restore_state_buf.cdef_srcbuf = mt_info->cdef_worker->srcbuf;
      const int num_planes = av1_num_planes(cm);
      for (int plane = 0; plane < num_planes; plane++)
        mt_info->restore_state_buf.cdef_colbuf[plane] =
            mt_info->cdef_worker->colbuf[plane];
    }
#if !CONFIG_REALTIME_ONLY
    if (is_restoration_used(cm)) {
      // Back up the original LR buffers before update.
      int idx = i + mt_info->num_workers - 1;
      assert(idx < mt_info->lr_row_sync.num_workers);
      mt_info->restore_state_buf.rst_tmpbuf =
          mt_info->lr_row_sync.lrworkerdata[idx].rst_tmpbuf;
      mt_info->restore_state_buf.rlbs =
          mt_info->lr_row_sync.lrworkerdata[idx].rlbs;

      // Update LR buffers.
      mt_info->lr_row_sync.lrworkerdata[idx].rst_tmpbuf = cm->rst_tmpbuf;
      mt_info->lr_row_sync.lrworkerdata[idx].rlbs = cm->rlbs;
    }
#endif

    i += mt_info->num_workers;

    // At this stage, the thread specific CDEF buffers for the current frame's
    // 'common' and 'cdef_sync' only need to be allocated. 'cdef_worker' has
    // already been allocated across parallel frames.
    av1_alloc_cdef_buffers(cm, &p_mt_info->cdef_worker, &mt_info->cdef_sync,
                           p_mt_info->num_workers, 0);

    frame_worker->hook = hook;
    frame_worker->data1 = cur_cpi;
    frame_worker->data2 = (frame_idx == 0)
                              ? first_cpi_data
                              : &ppi->parallel_frames_data[frame_idx - 1];
    frame_idx++;
    error->setjmp = 0;
  }
  p_mt_info->p_num_workers = parallel_frame_count;
}

// Launch level 1 workers to perform frame parallel encode.
static inline void launch_fpmt_workers(AV1_PRIMARY *ppi) {
  const AVxWorkerInterface *const winterface = aom_get_worker_interface();
  int num_workers = ppi->p_mt_info.p_num_workers;

  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *const worker = ppi->p_mt_info.p_workers[i];
    if (i == 0)
      winterface->execute(worker);
    else
      winterface->launch(worker);
  }
}

// Restore worker states after parallel encode.
static inline void restore_workers_after_fpmt(AV1_PRIMARY *ppi,
                                              int parallel_frame_count,
                                              int num_fpmt_workers_prepared) {
  assert(parallel_frame_count <= ppi->num_fp_contexts &&
         parallel_frame_count > 1);
  (void)parallel_frame_count;

  PrimaryMultiThreadInfo *const p_mt_info = &ppi->p_mt_info;

  int frame_idx = 0;
  int i = 0;
  while (i < num_fpmt_workers_prepared) {
    AV1_COMP *cur_cpi = ppi->parallel_cpi[frame_idx];
    MultiThreadInfo *mt_info = &cur_cpi->mt_info;
    const AV1_COMMON *const cm = &cur_cpi->common;
    const int num_planes = av1_num_planes(cm);

    // Restore the original cdef_worker pointers.
    if (p_mt_info->cdef_worker != NULL) {
      mt_info->cdef_worker->srcbuf = mt_info->restore_state_buf.cdef_srcbuf;
      for (int plane = 0; plane < num_planes; plane++)
        mt_info->cdef_worker->colbuf[plane] =
            mt_info->restore_state_buf.cdef_colbuf[plane];
    }
#if !CONFIG_REALTIME_ONLY
    if (is_restoration_used(cm)) {
      // Restore the original LR buffers.
      int idx = i + mt_info->num_workers - 1;
      assert(idx < mt_info->lr_row_sync.num_workers);
      mt_info->lr_row_sync.lrworkerdata[idx].rst_tmpbuf =
          mt_info->restore_state_buf.rst_tmpbuf;
      mt_info->lr_row_sync.lrworkerdata[idx].rlbs =
          mt_info->restore_state_buf.rlbs;
    }
#endif

    frame_idx++;
    i += mt_info->num_workers;
  }
}

// Synchronize level 1 workers.
static inline void sync_fpmt_workers(AV1_PRIMARY *ppi,
                                     int frames_in_parallel_set) {
  const AVxWorkerInterface *const winterface = aom_get_worker_interface();
  int num_workers = ppi->p_mt_info.p_num_workers;
  int had_error = 0;
  // Points to error in the earliest display order frame in the parallel set.
  const struct aom_internal_error_info *error = NULL;

  // Encoding ends.
  for (int i = num_workers - 1; i >= 0; --i) {
    AVxWorker *const worker = ppi->p_mt_info.p_workers[i];
    if (!winterface->sync(worker)) {
      had_error = 1;
      error = ppi->parallel_cpi[i]->common.error;
    }
  }

  restore_workers_after_fpmt(ppi, frames_in_parallel_set,
                             ppi->p_mt_info.num_workers);

  if (had_error) aom_internal_error_copy(&ppi->error, error);
}

static int get_compressed_data_hook(void *arg1, void *arg2) {
  AV1_COMP *cpi = (AV1_COMP *)arg1;
  AV1_COMP_DATA *cpi_data = (AV1_COMP_DATA *)arg2;
  int status = av1_get_compressed_data(cpi, cpi_data);

  // AOM_CODEC_OK(0) means no error.
  return !status;
}

// This function encodes the raw frame data for each frame in parallel encode
// set, and outputs the frame bit stream to the designated buffers.
void av1_compress_parallel_frames(AV1_PRIMARY *const ppi,
                                  AV1_COMP_DATA *const first_cpi_data) {
  // Bitmask for the frame buffers referenced by cpi->scaled_ref_buf
  // corresponding to frames in the current parallel encode set.
  int ref_buffers_used_map = 0;
  int frames_in_parallel_set = av1_init_parallel_frame_context(
      first_cpi_data, ppi, &ref_buffers_used_map);
  prepare_fpmt_workers(ppi, first_cpi_data, get_compressed_data_hook,
                       frames_in_parallel_set);
  launch_fpmt_workers(ppi);
  sync_fpmt_workers(ppi, frames_in_parallel_set);

  // Release cpi->scaled_ref_buf corresponding to frames in the current parallel
  // encode set.
  for (int i = 0; i < frames_in_parallel_set; ++i) {
    av1_release_scaled_references_fpmt(ppi->parallel_cpi[i]);
  }
  av1_decrement_ref_counts_fpmt(ppi->cpi->common.buffer_pool,
                                ref_buffers_used_map);
}

static inline void launch_workers(MultiThreadInfo *const mt_info,
                                  int num_workers) {
  const AVxWorkerInterface *const winterface = aom_get_worker_interface();
  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *const worker = &mt_info->workers[i];
    worker->had_error = 0;
    if (i == 0)
      winterface->execute(worker);
    else
      winterface->launch(worker);
  }
}

static inline void sync_enc_workers(MultiThreadInfo *const mt_info,
                                    AV1_COMMON *const cm, int num_workers) {
  const AVxWorkerInterface *const winterface = aom_get_worker_interface();
  const AVxWorker *const worker_main = &mt_info->workers[0];
  int had_error = worker_main->had_error;
  struct aom_internal_error_info error_info;

  // Read the error_info of main thread.
  if (had_error) {
    error_info = ((EncWorkerData *)worker_main->data1)->error_info;
  }

  // Encoding ends.
  for (int i = num_workers - 1; i > 0; i--) {
    AVxWorker *const worker = &mt_info->workers[i];
    if (!winterface->sync(worker)) {
      had_error = 1;
      error_info = ((EncWorkerData *)worker->data1)->error_info;
    }
  }

  if (had_error) aom_internal_error_copy(cm->error, &error_info);

  // Restore xd->error_info of the main thread back to cm->error so that the
  // multithreaded code, when executed using a single thread, has a valid
  // xd->error_info.
  MACROBLOCKD *const xd = &((EncWorkerData *)worker_main->data1)->td->mb.e_mbd;
  xd->error_info = cm->error;
}

static inline void accumulate_counters_enc_workers(AV1_COMP *cpi,
                                                   int num_workers) {
  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *const worker = &cpi->mt_info.workers[i];
    EncWorkerData *const thread_data = (EncWorkerData *)worker->data1;
    cpi->intrabc_used |= thread_data->td->intrabc_used;
    cpi->deltaq_used |= thread_data->td->deltaq_used;
    // Accumulate rtc counters.
    if (!frame_is_intra_only(&cpi->common))
      av1_accumulate_rtc_counters(cpi, &thread_data->td->mb);
    cpi->palette_pixel_num += thread_data->td->mb.palette_pixels;
    if (thread_data->td != &cpi->td) {
      // Keep these conditional expressions in sync with the corresponding ones
      // in prepare_enc_workers().
      if (cpi->sf.inter_sf.mv_cost_upd_level != INTERNAL_COST_UPD_OFF) {
        aom_free(thread_data->td->mv_costs_alloc);
        thread_data->td->mv_costs_alloc = NULL;
      }
      if (cpi->sf.intra_sf.dv_cost_upd_level != INTERNAL_COST_UPD_OFF) {
        aom_free(thread_data->td->dv_costs_alloc);
        thread_data->td->dv_costs_alloc = NULL;
      }
    }
    av1_dealloc_mb_data(&thread_data->td->mb, av1_num_planes(&cpi->common));

    // Accumulate counters.
    if (i > 0) {
      av1_accumulate_frame_counts(&cpi->counts, thread_data->td->counts);
      accumulate_rd_opt(&cpi->td, thread_data->td);
      cpi->td.mb.txfm_search_info.txb_split_count +=
          thread_data->td->mb.txfm_search_info.txb_split_count;
#if CONFIG_SPEED_STATS
      cpi->td.mb.txfm_search_info.tx_search_count +=
          thread_data->td->mb.txfm_search_info.tx_search_count;
#endif  // CONFIG_SPEED_STATS
    }
  }
}

static inline void prepare_enc_workers(AV1_COMP *cpi, AVxWorkerHook hook,
                                       int num_workers) {
  MultiThreadInfo *const mt_info = &cpi->mt_info;
  AV1_COMMON *const cm = &cpi->common;

  // If a previous frame's encode raised an error after this function ran,
  // accumulate_counters_enc_workers() was skipped via longjmp and the mb
  // buffers (including cpi->td.mb) were never freed. Free them here so the
  // shallow copy of cpi->td.mb below cannot leave a worker's mb aliasing
  // cpi->td.mb's heap allocations on a subsequent partial-allocation failure
  // (which would double-free in encoder_destroy()).
  for (int i = num_workers - 1; i >= 0; i--) {
    EncWorkerData *const thread_data = &mt_info->tile_thr_data[i];
    ThreadData *const td = (i == 0) ? &cpi->td : thread_data->original_td;
    if (td) av1_dealloc_mb_data(&td->mb, av1_num_planes(cm));
  }

  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *const worker = &mt_info->workers[i];
    EncWorkerData *const thread_data = &mt_info->tile_thr_data[i];

    worker->hook = hook;
    worker->data1 = thread_data;
    worker->data2 = NULL;

    thread_data->thread_id = i;
    // Set the starting tile for each thread.
    thread_data->start = i;

    thread_data->cpi = cpi;
    if (i == 0) {
      thread_data->td = &cpi->td;
    } else {
      thread_data->td = thread_data->original_td;
    }

    thread_data->td->intrabc_used = 0;
    thread_data->td->deltaq_used = 0;
    thread_data->td->abs_sum_level = 0;
    thread_data->td->rd_counts.seg_tmp_pred_cost[0] = 0;
    thread_data->td->rd_counts.seg_tmp_pred_cost[1] = 0;

    // Before encoding a frame, copy the thread data from cpi.
    if (thread_data->td != &cpi->td) {
      thread_data->td->mb = cpi->td.mb;
      thread_data->td->rd_counts = cpi->td.rd_counts;
      thread_data->td->mb.obmc_buffer = thread_data->td->obmc_buffer;

      for (int x = 0; x < 2; x++) {
        thread_data->td->mb.intrabc_hash_info.hash_value_buffer[x] =
            thread_data->td->hash_value_buffer[x];
      }
      // Keep these conditional expressions in sync with the corresponding ones
      // in accumulate_counters_enc_workers().
      if (cpi->sf.inter_sf.mv_cost_upd_level != INTERNAL_COST_UPD_OFF) {
        CHECK_MEM_ERROR(
            cm, thread_data->td->mv_costs_alloc,
            (MvCosts *)aom_malloc(sizeof(*thread_data->td->mv_costs_alloc)));
        thread_data->td->mb.mv_costs = thread_data->td->mv_costs_alloc;
        *thread_data->td->mb.mv_costs = *cpi->td.mb.mv_costs;
      }
      if (cpi->sf.intra_sf.dv_cost_upd_level != INTERNAL_COST_UPD_OFF) {
        // Reset dv_costs to NULL for worker threads when dv cost update is
        // enabled so that only dv_cost_upd_level needs to be checked before the
        // aom_free() call for the same.
        thread_data->td->mb.dv_costs = NULL;
        if (av1_need_dv_costs(cpi)) {
          CHECK_MEM_ERROR(cm, thread_data->td->dv_costs_alloc,
                          (IntraBCMVCosts *)aom_malloc(
                              sizeof(*thread_data->td->dv_costs_alloc)));
          thread_data->td->mb.dv_costs = thread_data->td->dv_costs_alloc;
          *thread_data->td->mb.dv_costs = *cpi->td.mb.dv_costs;
        }
      }
    }
    av1_alloc_mb_data(cpi, &thread_data->td->mb);

    // Reset rtc counters.
    av1_init_rtc_counters(&thread_data->td->mb);

    thread_data->td->mb.palette_pixels = 0;

    if (thread_data->td->counts != &cpi->counts) {
      *thread_data->td->counts = cpi->counts;
    }

    if (i > 0) {
      thread_data->td->mb.palette_buffer = thread_data->td->palette_buffer;
      thread_data->td->mb.comp_rd_buffer = thread_data->td->comp_rd_buffer;
      thread_data->td->mb.tmp_conv_dst = thread_data->td->tmp_conv_dst;
      thread_data->td->mb.upsample_pred = thread_data->td->upsample_pred;
      for (int j = 0; j < 2; ++j) {
        thread_data->td->mb.tmp_pred_bufs[j] =
            thread_data->td->tmp_pred_bufs[j];
      }
      thread_data->td->mb.pixel_gradient_info =
          thread_data->td->pixel_gradient_info;

      thread_data->td->mb.src_var_info_of_4x4_sub_blocks =
          thread_data->td->src_var_info_of_4x4_sub_blocks;

      thread_data->td->mb.e_mbd.tmp_conv_dst = thread_data->td->mb.tmp_conv_dst;
      thread_data->td->mb.e_mbd.tmp_upsample_pred =
          thread_data->td->mb.upsample_pred;
      for (int j = 0; j < 2; ++j) {
        thread_data->td->mb.e_mbd.tmp_obmc_bufs[j] =
            thread_data->td->mb.tmp_pred_bufs[j];
      }
    }
  }
}

#if !CONFIG_REALTIME_ONLY
static inline void fp_prepare_enc_workers(AV1_COMP *cpi, AVxWorkerHook hook,
                                          int num_workers) {
  AV1_COMMON *const cm = &cpi->common;
  MultiThreadInfo *const mt_info = &cpi->mt_info;
  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *const worker = &mt_info->workers[i];
    EncWorkerData *const thread_data = &mt_info->tile_thr_data[i];

    worker->hook = hook;
    worker->data1 = thread_data;
    worker->data2 = NULL;

    thread_data->thread_id = i;
    // Set the starting tile for each thread.
    thread_data->start = i;

    thread_data->cpi = cpi;
    if (i == 0) {
      thread_data->td = &cpi->td;
    } else {
      thread_data->td = thread_data->original_td;
      // Before encoding a frame, copy the thread data from cpi.
      thread_data->td->mb = cpi->td.mb;
    }
    av1_alloc_src_diff_buf(cm, &thread_data->td->mb);
  }
}
#endif

// Computes the number of workers for row multi-threading of encoding stage
static inline int compute_num_enc_row_mt_workers(const AV1_COMMON *cm,
                                                 int max_threads) {
  TileInfo tile_info;
  const int tile_cols = cm->tiles.cols;
  const int tile_rows = cm->tiles.rows;
  int total_num_threads_row_mt = 0;
  for (int row = 0; row < tile_rows; row++) {
    for (int col = 0; col < tile_cols; col++) {
      av1_tile_init(&tile_info, cm, row, col);
      const int num_sb_rows_in_tile = av1_get_sb_rows_in_tile(cm, &tile_info);
      const int num_sb_cols_in_tile = av1_get_sb_cols_in_tile(cm, &tile_info);
      total_num_threads_row_mt +=
          AOMMIN((num_sb_cols_in_tile + 1) >> 1, num_sb_rows_in_tile);
    }
  }
  return AOMMIN(max_threads, total_num_threads_row_mt);
}

// Computes the number of workers for tile multi-threading of encoding stage
static inline int compute_num_enc_tile_mt_workers(const AV1_COMMON *cm,
                                                  int max_threads) {
  const int tile_cols = cm->tiles.cols;
  const int tile_rows = cm->tiles.rows;
  return AOMMIN(max_threads, tile_cols * tile_rows);
}

// Find max worker of all MT stages
int av1_get_max_num_workers(const AV1_COMP *cpi) {
  int max_num_workers = 0;
  for (int i = MOD_FP; i < NUM_MT_MODULES; i++)
    max_num_workers =
        AOMMAX(cpi->ppi->p_mt_info.num_mod_workers[i], max_num_workers);
  assert(max_num_workers >= 1);
  return AOMMIN(max_num_workers, cpi->oxcf.max_threads);
}

// Computes the number of workers for encoding stage (row/tile multi-threading)
static int compute_num_enc_workers(const AV1_COMP *cpi, int max_workers) {
  if (max_workers <= 1) return 1;
  if (cpi->oxcf.row_mt)
    return compute_num_enc_row_mt_workers(&cpi->common, max_workers);
  else
    return compute_num_enc_tile_mt_workers(&cpi->common, max_workers);
}

void av1_encode_tiles_mt(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
  MultiThreadInfo *const mt_info = &cpi->mt_info;
  const int tile_cols = cm->tiles.cols;
  const int tile_rows = cm->tiles.rows;
  int num_workers = mt_info->num_mod_workers[MOD_ENC];

  assert(IMPLIES(cpi->tile_data == NULL, cpi->allocated_tiles == 0));
  if (cpi->allocated_tiles != tile_cols * tile_rows) av1_alloc_tile_data(cpi);

  av1_init_tile_data(cpi);
  num_workers = AOMMIN(num_workers, mt_info->num_workers);

  prepare_enc_workers(cpi, enc_worker_hook, num_workers);
  launch_workers(&cpi->mt_info, num_workers);
  sync_enc_workers(&cpi->mt_info, cm, num_workers);
  accumulate_counters_enc_workers(cpi, num_workers);
}

// Accumulate frame counts. FRAME_COUNTS consist solely of 'unsigned int'
// members, so we treat it as an array, and sum over the whole length.
void av1_accumulate_frame_counts(FRAME_COUNTS *acc_counts,
                                 const FRAME_COUNTS *counts) {
  unsigned int *const acc = (unsigned int *)acc_counts;
  const unsigned int *const cnt = (const unsigned int *)counts;

  const unsigned int n_counts = sizeof(FRAME_COUNTS) / sizeof(unsigned int);

  for (unsigned int i = 0; i < n_counts; i++) acc[i] += cnt[i];
}

// Computes the maximum number of sb rows and sb_cols across tiles which are
// used to allocate memory for multi-threaded encoding with row-mt=1.
static inline void compute_max_sb_rows_cols(const AV1_COMMON *cm,
                                            int *max_sb_rows_in_tile,
                                            int *max_sb_cols_in_tile) {
  const int tile_rows = cm->tiles.rows;
  const int mib_size_log2 = cm->seq_params->mib_size_log2;
  const int num_mi_rows = cm->mi_params.mi_rows;
  const int *const row_start_sb = cm->tiles.row_start_sb;
  for (int row = 0; row < tile_rows; row++) {
    const int mi_row_start = row_start_sb[row] << mib_size_log2;
    const int mi_row_end =
        AOMMIN(row_start_sb[row + 1] << mib_size_log2, num_mi_rows);
    const int num_sb_rows_in_tile =
        CEIL_POWER_OF_TWO(mi_row_end - mi_row_start, mib_size_log2);
    *max_sb_rows_in_tile = AOMMAX(*max_sb_rows_in_tile, num_sb_rows_in_tile);
  }

  const int tile_cols = cm->tiles.cols;
  const int num_mi_cols = cm->mi_params.mi_cols;
  const int *const col_start_sb = cm->tiles.col_start_sb;
  for (int col = 0; col < tile_cols; col++) {
    const int mi_col_start = col_start_sb[col] << mib_size_log2;
    const int mi_col_end =
        AOMMIN(col_start_sb[col + 1] << mib_size_log2, num_mi_cols);
    const int num_sb_cols_in_tile =
        CEIL_POWER_OF_TWO(mi_col_end - mi_col_start, mib_size_log2);
    *max_sb_cols_in_tile = AOMMAX(*max_sb_cols_in_tile, num_sb_cols_in_tile);
  }
}

#if !CONFIG_REALTIME_ONLY
// Computes the number of workers for firstpass stage (row/tile multi-threading)
int av1_fp_compute_num_enc_workers(AV1_COMP *cpi) {
  AV1_COMMON *cm = &cpi->common;
  const int tile_cols = cm->tiles.cols;
  const int tile_rows = cm->tiles.rows;
  int total_num_threads_row_mt = 0;
  TileInfo tile_info;

  if (cpi->oxcf.max_threads <= 1) return 1;

  for (int row = 0; row < tile_rows; row++) {
    for (int col = 0; col < tile_cols; col++) {
      av1_tile_init(&tile_info, cm, row, col);
      const int num_mb_rows_in_tile =
          av1_get_unit_rows_in_tile(&tile_info, cpi->fp_block_size);
      const int num_mb_cols_in_tile =
          av1_get_unit_cols_in_tile(&tile_info, cpi->fp_block_size);
      total_num_threads_row_mt +=
          AOMMIN((num_mb_cols_in_tile + 1) >> 1, num_mb_rows_in_tile);
    }
  }
  return AOMMIN(cpi->oxcf.max_threads, total_num_threads_row_mt);
}

// Computes the maximum number of mb_rows for row multi-threading of firstpass
// stage
static inline int fp_compute_max_mb_rows(const AV1_COMMON *cm,
                                         BLOCK_SIZE fp_block_size) {
  const int tile_rows = cm->tiles.rows;
  const int unit_height_log2 = mi_size_high_log2[fp_block_size];
  const int mib_size_log2 = cm->seq_params->mib_size_log2;
  const int num_mi_rows = cm->mi_params.mi_rows;
  const int *const row_start_sb = cm->tiles.row_start_sb;
  int max_mb_rows = 0;

  for (int row = 0; row < tile_rows; row++) {
    const int mi_row_start = row_start_sb[row] << mib_size_log2;
    const int mi_row_end =
        AOMMIN(row_start_sb[row + 1] << mib_size_log2, num_mi_rows);
    const int num_mb_rows_in_tile =
        CEIL_POWER_OF_TWO(mi_row_end - mi_row_start, unit_height_log2);
    max_mb_rows = AOMMAX(max_mb_rows, num_mb_rows_in_tile);
  }
  return max_mb_rows;
}
#endif

static void lpf_pipeline_mt_init(AV1_COMP *cpi, int num_workers) {
  // Pipelining of loop-filtering after encoding is enabled when loop-filter
  // level is chosen based on quantizer and frame type. It is disabled in case
  // of 'LOOPFILTER_SELECTIVELY' as the stats collected during encoding stage
  // decides the filter level. Loop-filtering is disabled in case
  // of non-reference frames and for frames with intra block copy tool enabled.
  AV1_COMMON *cm = &cpi->common;
  const int use_loopfilter = is_loopfilter_used(cm);
  const int use_superres = av1_superres_scaled(cm);
  const int use_cdef = is_cdef_used(cm);
  const int use_restoration = is_restoration_used(cm);
  MultiThreadInfo *const mt_info = &cpi->mt_info;
  MACROBLOCKD *xd = &cpi->td.mb.e_mbd;

  const unsigned int skip_apply_postproc_filters =
      derive_skip_apply_postproc_filters(cpi, use_loopfilter, use_cdef,
                                         use_superres, use_restoration);
  mt_info->pipeline_lpf_mt_with_enc =
      (cpi->oxcf.mode == REALTIME) && (cpi->oxcf.speed >= 5) &&
      (cpi->sf.lpf_sf.lpf_pick == LPF_PICK_FROM_Q) &&
      (cpi->oxcf.algo_cfg.loopfilter_control != LOOPFILTER_SELECTIVELY) &&
      !cpi->ppi->rtc_ref.non_reference_frame && !cm->features.allow_intrabc &&
      ((skip_apply_postproc_filters & SKIP_APPLY_LOOPFILTER) == 0);

  if (!mt_info->pipeline_lpf_mt_with_enc) return;

  set_postproc_filter_default_params(cm);

  if (!use_loopfilter) return;

  const LPF_PICK_METHOD method = cpi->sf.lpf_sf.lpf_pick;
  assert(method == LPF_PICK_FROM_Q);
  assert(cpi->oxcf.algo_cfg.loopfilter_control != LOOPFILTER_SELECTIVELY);

  av1_pick_filter_level(cpi->source, cpi, method);

  struct loopfilter *lf = &cm->lf;
  const int plane_start = 0;
  const int plane_end = av1_num_planes(cm);
  int planes_to_lf[MAX_MB_PLANE];
  if (lpf_mt_with_enc_enabled(cpi->mt_info.pipeline_lpf_mt_with_enc,
                              lf->filter_level)) {
    set_planes_to_loop_filter(lf, planes_to_lf, plane_start, plane_end);
    int lpf_opt_level = get_lpf_opt_level(&cpi->sf);
    assert(lpf_opt_level == 2);

    const int start_mi_row = 0;
    const int end_mi_row = start_mi_row + cm->mi_params.mi_rows;

    av1_loop_filter_frame_init(cm, plane_start, plane_end);

    assert(mt_info->num_mod_workers[MOD_ENC] ==
           mt_info->num_mod_workers[MOD_LPF]);
    loop_filter_frame_mt_init(cm, start_mi_row, end_mi_row, planes_to_lf,
                              mt_info->num_mod_workers[MOD_LPF],
                              &mt_info->lf_row_sync, lpf_opt_level,
                              cm->seq_params->mib_size_log2);

    for (int i = num_workers - 1; i >= 0; i--) {
      EncWorkerData *const thread_data = &mt_info->tile_thr_data[i];
      // Initialize loopfilter data
      thread_data->lf_sync = &mt_info->lf_row_sync;
      thread_data->lf_data = &thread_data->lf_sync->lfdata[i];
      loop_filter_data_reset(thread_data->lf_data, &cm->cur_frame->buf, cm, xd);
    }
  }
}

void av1_encode_tiles_row_mt(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
  MultiThreadInfo *const mt_info = &cpi->mt_info;
  AV1EncRowMultiThreadInfo *const enc_row_mt = &mt_info->enc_row_mt;
  const int tile_cols = cm->tiles.cols;
  const int tile_rows = cm->tiles.rows;
  const int sb_rows_in_frame = get_sb_rows_in_frame(cm);
  int *thread_id_to_tile_id = enc_row_mt->thread_id_to_tile_id;
  int max_sb_rows_in_tile = 0, max_sb_cols_in_tile = 0;
  int num_workers = mt_info->num_mod_workers[MOD_ENC];

  compute_max_sb_rows_cols(cm, &max_sb_rows_in_tile, &max_sb_cols_in_tile);
  const bool alloc_row_mt_mem =
      (enc_row_mt->allocated_tile_cols != tile_cols ||
       enc_row_mt->allocated_tile_rows != tile_rows ||
       enc_row_mt->allocated_rows != max_sb_rows_in_tile ||
       enc_row_mt->allocated_cols != (max_sb_cols_in_tile - 1) ||
       enc_row_mt->allocated_sb_rows != sb_rows_in_frame);
  const bool alloc_tile_data = cpi->allocated_tiles != tile_cols * tile_rows;

  assert(IMPLIES(cpi->tile_data == NULL, alloc_tile_data));
  assert(IMPLIES(cpi->tile_data == NULL, cpi->allocated_tiles == 0));
  if (alloc_tile_data) {
    av1_alloc_tile_data(cpi);
  }

  assert(IMPLIES(alloc_tile_data, alloc_row_mt_mem));
  if (alloc_row_mt_mem) {
    row_mt_mem_alloc(cpi, max_sb_rows_in_tile, max_sb_cols_in_tile,
                     cpi->oxcf.algo_cfg.cdf_update_mode);
  }

  num_workers = AOMMIN(num_workers, mt_info->num_workers);
  lpf_pipeline_mt_init(cpi, num_workers);

  av1_init_tile_data(cpi);

  memset(thread_id_to_tile_id, -1,
         sizeof(*thread_id_to_tile_id) * MAX_NUM_THREADS);
  memset(enc_row_mt->num_tile_cols_done, 0,
         sizeof(*enc_row_mt->num_tile_cols_done) * sb_rows_in_frame);
  enc_row_mt->row_mt_exit = false;

  for (int tile_row = 0; tile_row < tile_rows; tile_row++) {
    for (int tile_col = 0; tile_col < tile_cols; tile_col++) {
      int tile_index = tile_row * tile_cols + tile_col;
      TileDataEnc *const this_tile = &cpi->tile_data[tile_index];
      AV1EncRowMultiThreadSync *const row_mt_sync = &this_tile->row_mt_sync;

      // Initialize num_finished_cols to -1 for all rows.
      memset(row_mt_sync->num_finished_cols, -1,
             sizeof(*row_mt_sync->num_finished_cols) * max_sb_rows_in_tile);
      row_mt_sync->next_mi_row = this_tile->tile_info.mi_row_start;
      row_mt_sync->num_threads_working = 0;
      row_mt_sync->intrabc_extra_top_right_sb_delay =
          av1_get_intrabc_extra_top_right_sb_delay(cm);

      av1_inter_mode_data_init(this_tile);
      av1_zero_above_context(cm, &cpi->td.mb.e_mbd,
                             this_tile->tile_info.mi_col_start,
                             this_tile->tile_info.mi_col_end, tile_row);
    }
  }

  assign_tile_to_thread(thread_id_to_tile_id, tile_cols * tile_rows,
                        num_workers);
  prepare_enc_workers(cpi, enc_row_mt_worker_hook, num_workers);
  launch_workers(&cpi->mt_info, num_workers);
  sync_enc_workers(&cpi->mt_info, cm, num_workers);
  if (cm->delta_q_info.delta_lf_present_flag) update_delta_lf_for_row_mt(cpi);
  accumulate_counters_enc_workers(cpi, num_workers);
}

#if !CONFIG_REALTIME_ONLY
static void dealloc_thread_data_src_diff_buf(AV1_COMP *cpi, int num_workers) {
  for (int i = num_workers - 1; i >= 0; --i) {
    EncWorkerData *const thread_data = &cpi->mt_info.tile_thr_data[i];
    if (thread_data->td != &cpi->td)
      av1_dealloc_src_diff_buf(&thread_data->td->mb,
                               av1_num_planes(&cpi->common));
  }
}

void av1_fp_encode_tiles_row_mt(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
  MultiThreadInfo *const mt_info = &cpi->mt_info;
  AV1EncRowMultiThreadInfo *const enc_row_mt = &mt_info->enc_row_mt;
  const int tile_cols = cm->tiles.cols;
  const int tile_rows = cm->tiles.rows;
  int *thread_id_to_tile_id = enc_row_mt->thread_id_to_tile_id;
  int num_workers = 0;
  int max_mb_rows = 0;

  max_mb_rows = fp_compute_max_mb_rows(cm, cpi->fp_block_size);
  const bool alloc_row_mt_mem = enc_row_mt->allocated_tile_cols != tile_cols ||
                                enc_row_mt->allocated_tile_rows != tile_rows ||
                                enc_row_mt->allocated_rows != max_mb_rows;
  const bool alloc_tile_data = cpi->allocated_tiles != tile_cols * tile_rows;

  assert(IMPLIES(cpi->tile_data == NULL, alloc_tile_data));
  assert(IMPLIES(cpi->tile_data == NULL, cpi->allocated_tiles == 0));
  if (alloc_tile_data) {
    av1_alloc_tile_data(cpi);
  }

  assert(IMPLIES(alloc_tile_data, alloc_row_mt_mem));
  if (alloc_row_mt_mem) {
    row_mt_mem_alloc(cpi, max_mb_rows, -1, 0);
  }

  av1_init_tile_data(cpi);

  // For pass = 1, compute the no. of workers needed. For single-pass encode
  // (pass = 0), no. of workers are already computed.
  if (mt_info->num_mod_workers[MOD_FP] == 0)
    num_workers = av1_fp_compute_num_enc_workers(cpi);
  else
    num_workers = mt_info->num_mod_workers[MOD_FP];

  memset(thread_id_to_tile_id, -1,
         sizeof(*thread_id_to_tile_id) * MAX_NUM_THREADS);
  enc_row_mt->firstpass_mt_exit = false;

  for (int tile_row = 0; tile_row < tile_rows; tile_row++) {
    for (int tile_col = 0; tile_col < tile_cols; tile_col++) {
      int tile_index = tile_row * tile_cols + tile_col;
      TileDataEnc *const this_tile = &cpi->tile_data[tile_index];
      AV1EncRowMultiThreadSync *const row_mt_sync = &this_tile->row_mt_sync;

      // Initialize num_finished_cols to -1 for all rows.
      memset(row_mt_sync->num_finished_cols, -1,
             sizeof(*row_mt_sync->num_finished_cols) * max_mb_rows);
      row_mt_sync->next_mi_row = this_tile->tile_info.mi_row_start;
      row_mt_sync->num_threads_working = 0;

      // intraBC mode is not evaluated during first-pass encoding. Hence, no
      // additional top-right delay is required.
      row_mt_sync->intrabc_extra_top_right_sb_delay = 0;
    }
  }

  num_workers = AOMMIN(num_workers, mt_info->num_workers);
  assign_tile_to_thread(thread_id_to_tile_id, tile_cols * tile_rows,
                        num_workers);
  fp_prepare_enc_workers(cpi, fp_enc_row_mt_worker_hook, num_workers);
  launch_workers(&cpi->mt_info, num_workers);
  sync_enc_workers(&cpi->mt_info, cm, num_workers);
  dealloc_thread_data_src_diff_buf(cpi, num_workers);
}

void av1_tpl_row_mt_sync_read_dummy(AV1TplRowMultiThreadSync *tpl_mt_sync,
                                    int r, int c) {
  (void)tpl_mt_sync;
  (void)r;
  (void)c;
}

void av1_tpl_row_mt_sync_write_dummy(AV1TplRowMultiThreadSync *tpl_mt_sync,
                                     int r, int c, int cols) {
  (void)tpl_mt_sync;
  (void)r;
  (void)c;
  (void)cols;
}

void av1_tpl_row_mt_sync_read(AV1TplRowMultiThreadSync *tpl_row_mt_sync, int r,
                              int c) {
#if CONFIG_MULTITHREAD
  int nsync = tpl_row_mt_sync->sync_range;

  if (r) {
    pthread_mutex_t *const mutex = &tpl_row_mt_sync->mutex_[r - 1];
    pthread_mutex_lock(mutex);

    while (c > tpl_row_mt_sync->num_finished_cols[r - 1] - nsync)
      pthread_cond_wait(&tpl_row_mt_sync->cond_[r - 1], mutex);
    pthread_mutex_unlock(mutex);
  }
#else
  (void)tpl_row_mt_sync;
  (void)r;
  (void)c;
#endif  // CONFIG_MULTITHREAD
}

void av1_tpl_row_mt_sync_write(AV1TplRowMultiThreadSync *tpl_row_mt_sync, int r,
                               int c, int cols) {
#if CONFIG_MULTITHREAD
  int nsync = tpl_row_mt_sync->sync_range;
  int cur;
  // Only signal when there are enough encoded blocks for next row to run.
  int sig = 1;

  if (c < cols - 1) {
    cur = c;
    if (c % nsync) sig = 0;
  } else {
    cur = cols + nsync;
  }

  if (sig) {
    pthread_mutex_lock(&tpl_row_mt_sync->mutex_[r]);

    // When a thread encounters an error, num_finished_cols[r] is set to maximum
    // column number. In this case, the AOMMAX operation here ensures that
    // num_finished_cols[r] is not overwritten with a smaller value thus
    // preventing the infinite waiting of threads in the relevant sync_read()
    // function.
    tpl_row_mt_sync->num_finished_cols[r] =
        AOMMAX(tpl_row_mt_sync->num_finished_cols[r], cur);

    pthread_cond_signal(&tpl_row_mt_sync->cond_[r]);
    pthread_mutex_unlock(&tpl_row_mt_sync->mutex_[r]);
  }
#else
  (void)tpl_row_mt_sync;
  (void)r;
  (void)c;
  (void)cols;
#endif  // CONFIG_MULTITHREAD
}

static inline void set_mode_estimation_done(AV1_COMP *cpi) {
  const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
  TplParams *const tpl_data = &cpi->ppi->tpl_data;
  const BLOCK_SIZE bsize =
      convert_length_to_bsize(cpi->ppi->tpl_data.tpl_bsize_1d);
  const int mi_height = mi_size_high[bsize];
  AV1TplRowMultiThreadInfo *const tpl_row_mt = &cpi->mt_info.tpl_row_mt;
  const int tplb_cols_in_tile =
      ROUND_POWER_OF_TWO(mi_params->mi_cols, mi_size_wide_log2[bsize]);
  // In case of tpl row-multithreading, due to top-right dependency, the worker
  // on an mb_row waits for the completion of the tpl processing of the top and
  // top-right blocks. Hence, in case a thread (main/worker) encounters an
  // error, update that the tpl processing of every mb_row in the frame is
  // complete in order to avoid dependent workers waiting indefinitely.
  for (int mi_row = 0, tplb_row = 0; mi_row < mi_params->mi_rows;
       mi_row += mi_height, tplb_row++) {
    (*tpl_row_mt->sync_write_ptr)(&tpl_data->tpl_mt_sync, tplb_row,
                                  tplb_cols_in_tile - 1, tplb_cols_in_tile);
  }
}

// Each worker calls tpl_worker_hook() and computes the tpl data.
static int tpl_worker_hook(void *arg1, void *unused) {
  (void)unused;
  EncWorkerData *thread_data = (EncWorkerData *)arg1;
  AV1_COMP *cpi = thread_data->cpi;
  AV1_COMMON *cm = &cpi->common;
  MACROBLOCK *x = &thread_data->td->mb;
  MACROBLOCKD *xd = &x->e_mbd;
  TplTxfmStats *tpl_txfm_stats = &thread_data->td->tpl_txfm_stats;
  TplBuffers *tpl_tmp_buffers = &thread_data->td->tpl_tmp_buffers;
  CommonModeInfoParams *mi_params = &cm->mi_params;
  int num_active_workers = cpi->ppi->tpl_data.tpl_mt_sync.num_threads_working;

  struct aom_internal_error_info *const error_info = &thread_data->error_info;
  xd->error_info = error_info;
  AV1TplRowMultiThreadInfo *const tpl_row_mt = &cpi->mt_info.tpl_row_mt;
  (void)tpl_row_mt;
#if CONFIG_MULTITHREAD
  pthread_mutex_t *tpl_error_mutex_ = tpl_row_mt->mutex_;
#endif

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(error_info->jmp)) {
    error_info->setjmp = 0;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(tpl_error_mutex_);
    tpl_row_mt->tpl_mt_exit = true;
    pthread_mutex_unlock(tpl_error_mutex_);
#endif
    set_mode_estimation_done(cpi);
    return 0;
  }
  error_info->setjmp = 1;

  BLOCK_SIZE bsize = convert_length_to_bsize(cpi->ppi->tpl_data.tpl_bsize_1d);
  TX_SIZE tx_size = max_txsize_lookup[bsize];
  int mi_height = mi_size_high[bsize];

  av1_init_tpl_txfm_stats(tpl_txfm_stats);

  for (int mi_row = thread_data->start * mi_height; mi_row < mi_params->mi_rows;
       mi_row += num_active_workers * mi_height) {
    // Motion estimation row boundary
    av1_set_mv_row_limits(mi_params, &x->mv_limits, mi_row, mi_height,
                          cpi->oxcf.border_in_pixels);
    xd->mb_to_top_edge = -GET_MV_SUBPEL(mi_row * MI_SIZE);
    xd->mb_to_bottom_edge =
        GET_MV_SUBPEL((mi_params->mi_rows - mi_height - mi_row) * MI_SIZE);
    av1_mc_flow_dispenser_row(cpi, tpl_txfm_stats, tpl_tmp_buffers, x, mi_row,
                              bsize, tx_size);
  }
  error_info->setjmp = 0;
  return 1;
}

// Deallocate tpl synchronization related mutex and data.
void av1_tpl_dealloc(AV1TplRowMultiThreadSync *tpl_sync) {
  assert(tpl_sync != NULL);

#if CONFIG_MULTITHREAD
  if (tpl_sync->mutex_ != NULL) {
    for (int i = 0; i < tpl_sync->rows; ++i)
      pthread_mutex_destroy(&tpl_sync->mutex_[i]);
    aom_free(tpl_sync->mutex_);
  }
  if (tpl_sync->cond_ != NULL) {
    for (int i = 0; i < tpl_sync->rows; ++i)
      pthread_cond_destroy(&tpl_sync->cond_[i]);
    aom_free(tpl_sync->cond_);
  }
#endif  // CONFIG_MULTITHREAD

  aom_free(tpl_sync->num_finished_cols);
  // clear the structure as the source of this call may be a resize in which
  // case this call will be followed by an _alloc() which may fail.
  av1_zero(*tpl_sync);
}

// Allocate memory for tpl row synchronization.
static void av1_tpl_alloc(AV1TplRowMultiThreadSync *tpl_sync, AV1_COMMON *cm,
                          int mb_rows) {
  tpl_sync->rows = mb_rows;
#if CONFIG_MULTITHREAD
  {
    CHECK_MEM_ERROR(cm, tpl_sync->mutex_,
                    aom_malloc(sizeof(*tpl_sync->mutex_) * mb_rows));
    if (tpl_sync->mutex_) {
      for (int i = 0; i < mb_rows; ++i)
        pthread_mutex_init(&tpl_sync->mutex_[i], NULL);
    }

    CHECK_MEM_ERROR(cm, tpl_sync->cond_,
                    aom_malloc(sizeof(*tpl_sync->cond_) * mb_rows));
    if (tpl_sync->cond_) {
      for (int i = 0; i < mb_rows; ++i)
        pthread_cond_init(&tpl_sync->cond_[i], NULL);
    }
  }
#endif  // CONFIG_MULTITHREAD
  CHECK_MEM_ERROR(cm, tpl_sync->num_finished_cols,
                  aom_malloc(sizeof(*tpl_sync->num_finished_cols) * mb_rows));

  // Set up nsync.
  tpl_sync->sync_range = 1;
}

// Each worker is prepared by assigning the hook function and individual thread
// data.
static inline void prepare_tpl_workers(AV1_COMP *cpi, AVxWorkerHook hook,
                                       int num_workers) {
  MultiThreadInfo *mt_info = &cpi->mt_info;
  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *worker = &mt_info->workers[i];
    EncWorkerData *thread_data = &mt_info->tile_thr_data[i];

    worker->hook = hook;
    worker->data1 = thread_data;
    worker->data2 = NULL;

    thread_data->thread_id = i;
    // Set the starting tile for each thread.
    thread_data->start = i;

    thread_data->cpi = cpi;
    if (i == 0) {
      thread_data->td = &cpi->td;
    } else {
      thread_data->td = thread_data->original_td;
    }

    // Before encoding a frame, copy the thread data from cpi.
    if (thread_data->td != &cpi->td) {
      thread_data->td->mb = cpi->td.mb;
      // OBMC buffers are used only to init MS params and remain unused when
      // called from tpl, hence set the buffers to defaults.
      av1_init_obmc_buffer(&thread_data->td->mb.obmc_buffer);
      if (!tpl_alloc_temp_buffers(&thread_data->td->tpl_tmp_buffers,
                                  cpi->ppi->tpl_data.tpl_bsize_1d)) {
        aom_internal_error(cpi->common.error, AOM_CODEC_MEM_ERROR,
                           "Error allocating tpl data");
      }
      thread_data->td->mb.tmp_conv_dst = thread_data->td->tmp_conv_dst;
      thread_data->td->mb.e_mbd.tmp_conv_dst = thread_data->td->mb.tmp_conv_dst;
      thread_data->td->mb.upsample_pred = thread_data->td->upsample_pred;
      thread_data->td->mb.e_mbd.tmp_upsample_pred =
          thread_data->td->mb.upsample_pred;
    }
  }
}

#if CONFIG_BITRATE_ACCURACY
// Accumulate transform stats after tpl.
static void tpl_accumulate_txfm_stats(ThreadData *main_td,
                                      const MultiThreadInfo *mt_info,
                                      int num_workers) {
  TplTxfmStats *accumulated_stats = &main_td->tpl_txfm_stats;
  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *const worker = &mt_info->workers[i];
    EncWorkerData *const thread_data = (EncWorkerData *)worker->data1;
    ThreadData *td = thread_data->td;
    if (td != main_td) {
      const TplTxfmStats *tpl_txfm_stats = &td->tpl_txfm_stats;
      av1_accumulate_tpl_txfm_stats(tpl_txfm_stats, accumulated_stats);
    }
  }
}
#endif  // CONFIG_BITRATE_ACCURACY

// Implements multi-threading for tpl.
void av1_mc_flow_dispenser_mt(AV1_COMP *cpi) {
  AV1_COMMON *cm = &cpi->common;
  CommonModeInfoParams *mi_params = &cm->mi_params;
  MultiThreadInfo *mt_info = &cpi->mt_info;
  TplParams *tpl_data = &cpi->ppi->tpl_data;
  AV1TplRowMultiThreadSync *tpl_sync = &tpl_data->tpl_mt_sync;
  int mb_rows = mi_params->mb_rows;
  int num_workers =
      AOMMIN(mt_info->num_mod_workers[MOD_TPL], mt_info->num_workers);

  if (mb_rows != tpl_sync->rows) {
    av1_tpl_dealloc(tpl_sync);
    av1_tpl_alloc(tpl_sync, cm, mb_rows);
  }
  tpl_sync->num_threads_working = num_workers;
  mt_info->tpl_row_mt.tpl_mt_exit = false;

  // Initialize cur_mb_col to -1 for all MB rows.
  memset(tpl_sync->num_finished_cols, -1,
         sizeof(*tpl_sync->num_finished_cols) * mb_rows);

  prepare_tpl_workers(cpi, tpl_worker_hook, num_workers);
  launch_workers(&cpi->mt_info, num_workers);
  sync_enc_workers(&cpi->mt_info, cm, num_workers);
#if CONFIG_BITRATE_ACCURACY
  tpl_accumulate_txfm_stats(&cpi->td, &cpi->mt_info, num_workers);
#endif  // CONFIG_BITRATE_ACCURACY
  for (int i = num_workers - 1; i >= 0; i--) {
    EncWorkerData *thread_data = &mt_info->tile_thr_data[i];
    ThreadData *td = thread_data->td;
    if (td != &cpi->td) tpl_dealloc_temp_buffers(&td->tpl_tmp_buffers);
  }
}

// Deallocate memory for temporal filter multi-thread synchronization.
void av1_tf_mt_dealloc(AV1TemporalFilterSync *tf_sync) {
  assert(tf_sync != NULL);
#if CONFIG_MULTITHREAD
  if (tf_sync->mutex_ != NULL) {
    pthread_mutex_destroy(tf_sync->mutex_);
    aom_free(tf_sync->mutex_);
  }
#endif  // CONFIG_MULTITHREAD
  tf_sync->next_tf_row = 0;
}

// Checks if a job is available. If job is available,
// populates next_tf_row and returns 1, else returns 0.
static inline int tf_get_next_job(AV1TemporalFilterSync *tf_mt_sync,
                                  int *current_mb_row, int mb_rows) {
  int do_next_row = 0;
#if CONFIG_MULTITHREAD
  pthread_mutex_t *tf_mutex_ = tf_mt_sync->mutex_;
  pthread_mutex_lock(tf_mutex_);
#endif
  if (!tf_mt_sync->tf_mt_exit && tf_mt_sync->next_tf_row < mb_rows) {
    *current_mb_row = tf_mt_sync->next_tf_row;
    tf_mt_sync->next_tf_row++;
    do_next_row = 1;
  }
#if CONFIG_MULTITHREAD
  pthread_mutex_unlock(tf_mutex_);
#endif
  return do_next_row;
}

// Hook function for each thread in temporal filter multi-threading.
static int tf_worker_hook(void *arg1, void *unused) {
  (void)unused;
  EncWorkerData *thread_data = (EncWorkerData *)arg1;
  AV1_COMP *cpi = thread_data->cpi;
  ThreadData *td = thread_data->td;
  TemporalFilterCtx *tf_ctx = &cpi->tf_ctx;
  AV1TemporalFilterSync *tf_sync = &cpi->mt_info.tf_sync;
  const struct scale_factors *scale = &cpi->tf_ctx.sf;

#if CONFIG_MULTITHREAD
  pthread_mutex_t *tf_mutex_ = tf_sync->mutex_;
#endif
  MACROBLOCKD *const xd = &thread_data->td->mb.e_mbd;
  struct aom_internal_error_info *const error_info = &thread_data->error_info;
  xd->error_info = error_info;

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(error_info->jmp)) {
    error_info->setjmp = 0;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(tf_mutex_);
    tf_sync->tf_mt_exit = true;
    pthread_mutex_unlock(tf_mutex_);
#endif
    return 0;
  }
  error_info->setjmp = 1;

  const int num_planes = av1_num_planes(&cpi->common);
  assert(num_planes >= 1 && num_planes <= MAX_MB_PLANE);

  MACROBLOCKD *mbd = &td->mb.e_mbd;
  uint8_t *input_buffer[MAX_MB_PLANE];
  MB_MODE_INFO **input_mb_mode_info;
  tf_save_state(mbd, &input_mb_mode_info, input_buffer, num_planes);
  tf_setup_macroblockd(mbd, &td->tf_data, scale);

  int current_mb_row = -1;

  while (tf_get_next_job(tf_sync, &current_mb_row, tf_ctx->mb_rows))
    av1_tf_do_filtering_row(cpi, td, current_mb_row);

  tf_restore_state(mbd, input_mb_mode_info, input_buffer, num_planes);

  error_info->setjmp = 0;
  return 1;
}

// Assigns temporal filter hook function and thread data to each worker.
static void prepare_tf_workers(AV1_COMP *cpi, AVxWorkerHook hook,
                               int num_workers, int is_highbitdepth) {
  MultiThreadInfo *mt_info = &cpi->mt_info;
  mt_info->tf_sync.next_tf_row = 0;
  mt_info->tf_sync.tf_mt_exit = false;
  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *worker = &mt_info->workers[i];
    EncWorkerData *thread_data = &mt_info->tile_thr_data[i];

    worker->hook = hook;
    worker->data1 = thread_data;
    worker->data2 = NULL;

    thread_data->thread_id = i;
    // Set the starting tile for each thread.
    thread_data->start = i;

    thread_data->cpi = cpi;
    if (i == 0) {
      thread_data->td = &cpi->td;
    } else {
      thread_data->td = thread_data->original_td;
    }

    // Before encoding a frame, copy the thread data from cpi.
    if (thread_data->td != &cpi->td) {
      thread_data->td->mb = cpi->td.mb;
      // OBMC buffers are used only to init MS params and remain unused when
      // called from tf, hence set the buffers to defaults.
      av1_init_obmc_buffer(&thread_data->td->mb.obmc_buffer);
      if (!tf_alloc_and_reset_data(&thread_data->td->tf_data,
                                   cpi->tf_ctx.num_pels, is_highbitdepth)) {
        aom_internal_error(cpi->common.error, AOM_CODEC_MEM_ERROR,
                           "Error allocating temporal filter data");
      }
      thread_data->td->mb.upsample_pred = thread_data->td->upsample_pred;
      thread_data->td->mb.e_mbd.tmp_upsample_pred =
          thread_data->td->mb.upsample_pred;
    }
  }
}

// Deallocate thread specific data for temporal filter.
static void tf_dealloc_thread_data(AV1_COMP *cpi, int num_workers,
                                   int is_highbitdepth) {
  MultiThreadInfo *mt_info = &cpi->mt_info;
  for (int i = num_workers - 1; i >= 0; i--) {
    EncWorkerData *thread_data = &mt_info->tile_thr_data[i];
    ThreadData *td = thread_data->td;
    if (td != &cpi->td) tf_dealloc_data(&td->tf_data, is_highbitdepth);
  }
}

// Accumulate sse and sum after temporal filtering.
static void tf_accumulate_frame_diff(AV1_COMP *cpi, int num_workers) {
  FRAME_DIFF *total_diff = &cpi->td.tf_data.diff;
  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *const worker = &cpi->mt_info.workers[i];
    EncWorkerData *const thread_data = (EncWorkerData *)worker->data1;
    ThreadData *td = thread_data->td;
    FRAME_DIFF *diff = &td->tf_data.diff;
    if (td != &cpi->td) {
      total_diff->sse += diff->sse;
      total_diff->sum += diff->sum;
    }
  }
}

// Implements multi-threading for temporal filter.
void av1_tf_do_filtering_mt(AV1_COMP *cpi) {
  AV1_COMMON *cm = &cpi->common;
  MultiThreadInfo *mt_info = &cpi->mt_info;
  const int is_highbitdepth = cpi->tf_ctx.is_highbitdepth;

  int num_workers =
      AOMMIN(mt_info->num_mod_workers[MOD_TF], mt_info->num_workers);

  prepare_tf_workers(cpi, tf_worker_hook, num_workers, is_highbitdepth);
  launch_workers(mt_info, num_workers);
  sync_enc_workers(mt_info, cm, num_workers);
  tf_accumulate_frame_diff(cpi, num_workers);
  tf_dealloc_thread_data(cpi, num_workers, is_highbitdepth);
}

// Checks if a job is available in the current direction. If a job is available,
// frame_idx will be populated and returns 1, else returns 0.
static inline int get_next_gm_job(AV1_COMP *cpi, int *frame_idx, int cur_dir) {
  GlobalMotionInfo *gm_info = &cpi->gm_info;
  GlobalMotionJobInfo *job_info = &cpi->mt_info.gm_sync.job_info;

  int total_refs = gm_info->num_ref_frames[cur_dir];
  int8_t cur_frame_to_process = job_info->next_frame_to_process[cur_dir];

  if (cur_frame_to_process < total_refs && !job_info->early_exit[cur_dir]) {
    *frame_idx = gm_info->reference_frames[cur_dir][cur_frame_to_process].frame;
    job_info->next_frame_to_process[cur_dir] += 1;
    return 1;
  }
  return 0;
}

// Switches the current direction and calls the function get_next_gm_job() if
// the speed feature 'prune_ref_frame_for_gm_search' is not set.
static inline void switch_direction(AV1_COMP *cpi, int *frame_idx,
                                    int *cur_dir) {
  if (cpi->sf.gm_sf.prune_ref_frame_for_gm_search) return;
  // Switch the direction and get next job
  *cur_dir = !(*cur_dir);
  get_next_gm_job(cpi, frame_idx, *(cur_dir));
}

// Hook function for each thread in global motion multi-threading.
static int gm_mt_worker_hook(void *arg1, void *unused) {
  (void)unused;

  EncWorkerData *thread_data = (EncWorkerData *)arg1;
  AV1_COMP *cpi = thread_data->cpi;
  GlobalMotionInfo *gm_info = &cpi->gm_info;
  AV1GlobalMotionSync *gm_sync = &cpi->mt_info.gm_sync;
  GlobalMotionJobInfo *job_info = &gm_sync->job_info;
  int thread_id = thread_data->thread_id;
  GlobalMotionData *gm_thread_data = &thread_data->td->gm_data;
#if CONFIG_MULTITHREAD
  pthread_mutex_t *gm_mt_mutex_ = gm_sync->mutex_;
#endif

  MACROBLOCKD *const xd = &thread_data->td->mb.e_mbd;
  struct aom_internal_error_info *const error_info = &thread_data->error_info;
  xd->error_info = error_info;

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(error_info->jmp)) {
    error_info->setjmp = 0;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(gm_mt_mutex_);
    gm_sync->gm_mt_exit = true;
    pthread_mutex_unlock(gm_mt_mutex_);
#endif
    return 0;
  }
  error_info->setjmp = 1;

  int cur_dir = job_info->thread_id_to_dir[thread_id];
  bool gm_mt_exit = false;
  while (1) {
    int ref_buf_idx = -1;

#if CONFIG_MULTITHREAD
    pthread_mutex_lock(gm_mt_mutex_);
#endif

    gm_mt_exit = gm_sync->gm_mt_exit;
    // Populates ref_buf_idx(the reference frame type) for which global motion
    // estimation will be done.
    if (!gm_mt_exit && !get_next_gm_job(cpi, &ref_buf_idx, cur_dir)) {
      // No jobs are available for the current direction. Switch
      // to other direction and get the next job, if available.
      switch_direction(cpi, &ref_buf_idx, &cur_dir);
    }

#if CONFIG_MULTITHREAD
    pthread_mutex_unlock(gm_mt_mutex_);
#endif

    // When gm_mt_exit is set to true, other workers need not pursue any
    // further jobs.
    if (gm_mt_exit || ref_buf_idx == -1) break;

    // Compute global motion for the given ref_buf_idx.
    av1_compute_gm_for_valid_ref_frames(
        cpi, error_info, gm_info->ref_buf, ref_buf_idx,
        gm_thread_data->motion_models, gm_thread_data->segment_map,
        gm_info->segment_map_w, gm_info->segment_map_h);

#if CONFIG_MULTITHREAD
    pthread_mutex_lock(gm_mt_mutex_);
#endif
    // If global motion w.r.t. current ref frame is
    // INVALID/TRANSLATION/IDENTITY, skip the evaluation of global motion w.r.t
    // the remaining ref frames in that direction.
    if (cpi->sf.gm_sf.prune_ref_frame_for_gm_search &&
        cpi->common.global_motion[ref_buf_idx].wmtype <= TRANSLATION)
      job_info->early_exit[cur_dir] = 1;

#if CONFIG_MULTITHREAD
    pthread_mutex_unlock(gm_mt_mutex_);
#endif
  }
  error_info->setjmp = 0;
  return 1;
}

// Assigns global motion hook function and thread data to each worker.
static inline void prepare_gm_workers(AV1_COMP *cpi, AVxWorkerHook hook,
                                      int num_workers) {
  MultiThreadInfo *mt_info = &cpi->mt_info;
  mt_info->gm_sync.gm_mt_exit = false;
  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *worker = &mt_info->workers[i];
    EncWorkerData *thread_data = &mt_info->tile_thr_data[i];

    worker->hook = hook;
    worker->data1 = thread_data;
    worker->data2 = NULL;

    thread_data->thread_id = i;
    // Set the starting tile for each thread.
    thread_data->start = i;

    thread_data->cpi = cpi;
    if (i == 0) {
      thread_data->td = &cpi->td;
    } else {
      thread_data->td = thread_data->original_td;
    }

    if (thread_data->td != &cpi->td)
      gm_alloc_data(cpi, &thread_data->td->gm_data);
  }
}

// Assigns available threads to past/future direction.
static inline void assign_thread_to_dir(int8_t *thread_id_to_dir,
                                        int num_workers) {
  int8_t frame_dir_idx = 0;

  for (int i = 0; i < num_workers; i++) {
    thread_id_to_dir[i] = frame_dir_idx++;
    if (frame_dir_idx == MAX_DIRECTIONS) frame_dir_idx = 0;
  }
}

// Computes number of workers for global motion multi-threading.
static inline int compute_gm_workers(const AV1_COMP *cpi) {
  int total_refs =
      cpi->gm_info.num_ref_frames[0] + cpi->gm_info.num_ref_frames[1];
  int num_gm_workers = cpi->sf.gm_sf.prune_ref_frame_for_gm_search
                           ? AOMMIN(MAX_DIRECTIONS, total_refs)
                           : total_refs;
  num_gm_workers = AOMMIN(num_gm_workers, cpi->mt_info.num_workers);
  return (num_gm_workers);
}

// Frees the memory allocated for each worker in global motion multi-threading.
static inline void gm_dealloc_thread_data(AV1_COMP *cpi, int num_workers) {
  MultiThreadInfo *mt_info = &cpi->mt_info;
  for (int j = 0; j < num_workers; j++) {
    EncWorkerData *thread_data = &mt_info->tile_thr_data[j];
    ThreadData *td = thread_data->td;
    if (td != &cpi->td) gm_dealloc_data(&td->gm_data);
  }
}

// Implements multi-threading for global motion.
void av1_global_motion_estimation_mt(AV1_COMP *cpi) {
  GlobalMotionJobInfo *job_info = &cpi->mt_info.gm_sync.job_info;

  av1_zero(*job_info);

  int num_workers = compute_gm_workers(cpi);

  assign_thread_to_dir(job_info->thread_id_to_dir, num_workers);
  prepare_gm_workers(cpi, gm_mt_worker_hook, num_workers);
  launch_workers(&cpi->mt_info, num_workers);
  sync_enc_workers(&cpi->mt_info, &cpi->common, num_workers);
  gm_dealloc_thread_data(cpi, num_workers);
}
#endif  // !CONFIG_REALTIME_ONLY

static inline int get_next_job_allintra(
    AV1EncRowMultiThreadSync *const row_mt_sync, const int mi_row_end,
    int *current_mi_row, int mib_size) {
  if (row_mt_sync->next_mi_row < mi_row_end) {
    *current_mi_row = row_mt_sync->next_mi_row;
    row_mt_sync->num_threads_working++;
    row_mt_sync->next_mi_row += mib_size;
    return 1;
  }
  return 0;
}

static inline void prepare_wiener_var_workers(AV1_COMP *const cpi,
                                              AVxWorkerHook hook,
                                              const int num_workers) {
  MultiThreadInfo *const mt_info = &cpi->mt_info;
  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *const worker = &mt_info->workers[i];
    EncWorkerData *const thread_data = &mt_info->tile_thr_data[i];

    worker->hook = hook;
    worker->data1 = thread_data;
    worker->data2 = NULL;

    thread_data->thread_id = i;
    // Set the starting tile for each thread, in this case the preprocessing
    // stage does not need tiles. So we set it to 0.
    thread_data->start = 0;

    thread_data->cpi = cpi;
    if (i == 0) {
      thread_data->td = &cpi->td;
    } else {
      thread_data->td = thread_data->original_td;
    }

    if (thread_data->td != &cpi->td) {
      thread_data->td->mb = cpi->td.mb;
      av1_alloc_mb_wiener_var_pred_buf(&cpi->common, thread_data->td);
    }
  }
}

static void set_mb_wiener_var_calc_done(AV1_COMP *const cpi) {
  const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
  const BLOCK_SIZE bsize = cpi->weber_bsize;
  const int mb_step = mi_size_wide[bsize];
  assert(MB_WIENER_MT_UNIT_SIZE < BLOCK_SIZES_ALL);
  const int mt_unit_step = mi_size_wide[MB_WIENER_MT_UNIT_SIZE];
  const int mt_unit_cols =
      (mi_params->mi_cols + (mt_unit_step >> 1)) / mt_unit_step;
  const AV1EncAllIntraMultiThreadInfo *const intra_mt = &cpi->mt_info.intra_mt;
  AV1EncRowMultiThreadSync *const intra_row_mt_sync =
      &cpi->ppi->intra_row_mt_sync;

  // Update the wiener variance computation of every row in the frame to
  // indicate that it is complete in order to avoid dependent workers waiting
  // indefinitely.
  for (int mi_row = 0, mt_thread_id = 0; mi_row < mi_params->mi_rows;
       mi_row += mb_step, ++mt_thread_id) {
    intra_mt->intra_sync_write_ptr(intra_row_mt_sync, mt_thread_id,
                                   mt_unit_cols - 1, mt_unit_cols);
  }
}

static int cal_mb_wiener_var_hook(void *arg1, void *unused) {
  (void)unused;
  EncWorkerData *const thread_data = (EncWorkerData *)arg1;
  AV1_COMP *const cpi = thread_data->cpi;
  MACROBLOCK *x = &thread_data->td->mb;
  MACROBLOCKD *xd = &x->e_mbd;
  const BLOCK_SIZE bsize = cpi->weber_bsize;
  const int mb_step = mi_size_wide[bsize];
  AV1EncRowMultiThreadSync *const intra_row_mt_sync =
      &cpi->ppi->intra_row_mt_sync;
  AV1EncRowMultiThreadInfo *const enc_row_mt = &cpi->mt_info.enc_row_mt;
  (void)enc_row_mt;
#if CONFIG_MULTITHREAD
  pthread_mutex_t *enc_row_mt_mutex = enc_row_mt->mutex_;
#endif

  struct aom_internal_error_info *const error_info = &thread_data->error_info;
  xd->error_info = error_info;

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(error_info->jmp)) {
    error_info->setjmp = 0;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(enc_row_mt_mutex);
    enc_row_mt->mb_wiener_mt_exit = true;
    pthread_mutex_unlock(enc_row_mt_mutex);
#endif
    set_mb_wiener_var_calc_done(cpi);
    return 0;
  }
  error_info->setjmp = 1;
  DECLARE_ALIGNED(32, int16_t, src_diff[32 * 32]);
  DECLARE_ALIGNED(32, tran_low_t, coeff[32 * 32]);
  DECLARE_ALIGNED(32, tran_low_t, qcoeff[32 * 32]);
  DECLARE_ALIGNED(32, tran_low_t, dqcoeff[32 * 32]);
  double sum_rec_distortion = 0;
  double sum_est_rate = 0;
  while (1) {
    int current_mi_row = -1;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(enc_row_mt_mutex);
#endif
    int has_jobs = enc_row_mt->mb_wiener_mt_exit
                       ? 0
                       : get_next_job_allintra(intra_row_mt_sync,
                                               cpi->common.mi_params.mi_rows,
                                               &current_mi_row, mb_step);
#if CONFIG_MULTITHREAD
    pthread_mutex_unlock(enc_row_mt_mutex);
#endif
    if (!has_jobs) break;
    // TODO(chengchen): properly accumulate the distortion and rate.
    av1_calc_mb_wiener_var_row(cpi, x, xd, current_mi_row, src_diff, coeff,
                               qcoeff, dqcoeff, &sum_rec_distortion,
                               &sum_est_rate,
                               thread_data->td->wiener_tmp_pred_buf);
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(enc_row_mt_mutex);
#endif
    intra_row_mt_sync->num_threads_working--;
#if CONFIG_MULTITHREAD
    pthread_mutex_unlock(enc_row_mt_mutex);
#endif
  }
  error_info->setjmp = 0;
  return 1;
}

static void dealloc_mb_wiener_var_mt_data(AV1_COMP *cpi, int num_workers) {
  av1_row_mt_sync_mem_dealloc(&cpi->ppi->intra_row_mt_sync);

  MultiThreadInfo *mt_info = &cpi->mt_info;
  for (int j = 0; j < num_workers; ++j) {
    EncWorkerData *thread_data = &mt_info->tile_thr_data[j];
    ThreadData *td = thread_data->td;
    if (td != &cpi->td) av1_dealloc_mb_wiener_var_pred_buf(td);
  }
}

// This function is the multi-threading version of computing the wiener
// variance.
// Note that the wiener variance is used for allintra mode (1 pass) and its
// computation is before the frame encoding, so we don't need to consider
// the number of tiles, instead we allocate all available threads to
// the computation.
void av1_calc_mb_wiener_var_mt(AV1_COMP *cpi, int num_workers,
                               double *sum_rec_distortion,
                               double *sum_est_rate) {
  (void)sum_rec_distortion;
  (void)sum_est_rate;
  AV1_COMMON *const cm = &cpi->common;
  MultiThreadInfo *const mt_info = &cpi->mt_info;
  AV1EncRowMultiThreadSync *const intra_row_mt_sync =
      &cpi->ppi->intra_row_mt_sync;

  // TODO(chengchen): the memory usage could be improved.
  const int mi_rows = cm->mi_params.mi_rows;
  row_mt_sync_mem_alloc(intra_row_mt_sync, cm, mi_rows);

  intra_row_mt_sync->intrabc_extra_top_right_sb_delay = 0;
  intra_row_mt_sync->num_threads_working = num_workers;
  intra_row_mt_sync->next_mi_row = 0;
  memset(intra_row_mt_sync->num_finished_cols, -1,
         sizeof(*intra_row_mt_sync->num_finished_cols) * mi_rows);
  mt_info->enc_row_mt.mb_wiener_mt_exit = false;

  prepare_wiener_var_workers(cpi, cal_mb_wiener_var_hook, num_workers);
  launch_workers(mt_info, num_workers);
  sync_enc_workers(mt_info, cm, num_workers);
  dealloc_mb_wiener_var_mt_data(cpi, num_workers);
}

// Compare and order tiles based on absolute sum of tx coeffs.
static int compare_tile_order(const void *a, const void *b) {
  const PackBSTileOrder *const tile_a = (const PackBSTileOrder *)a;
  const PackBSTileOrder *const tile_b = (const PackBSTileOrder *)b;

  if (tile_a->abs_sum_level > tile_b->abs_sum_level)
    return -1;
  else if (tile_a->abs_sum_level == tile_b->abs_sum_level)
    return (tile_a->tile_idx > tile_b->tile_idx ? 1 : -1);
  else
    return 1;
}

// Get next tile index to be processed for pack bitstream
static inline int get_next_pack_bs_tile_idx(
    AV1EncPackBSSync *const pack_bs_sync, const int num_tiles) {
  assert(pack_bs_sync->next_job_idx <= num_tiles);
  if (pack_bs_sync->next_job_idx == num_tiles) return -1;

  return pack_bs_sync->pack_bs_tile_order[pack_bs_sync->next_job_idx++]
      .tile_idx;
}

// Calculates bitstream chunk size based on total buffer size and tile or tile
// group size.
static inline size_t get_bs_chunk_size(int tg_or_tile_size,
                                       const int frame_or_tg_size,
                                       size_t *remain_buf_size,
                                       size_t max_buf_size, int is_last_chunk) {
  size_t this_chunk_size;
  assert(*remain_buf_size > 0);
  if (is_last_chunk) {
    this_chunk_size = *remain_buf_size;
    *remain_buf_size = 0;
  } else {
    const uint64_t size_scale = (uint64_t)max_buf_size * tg_or_tile_size;
    this_chunk_size = (size_t)(size_scale / frame_or_tg_size);
    *remain_buf_size -= this_chunk_size;
    assert(*remain_buf_size > 0);
  }
  assert(this_chunk_size > 0);
  return this_chunk_size;
}

// Initializes params required for pack bitstream tile.
static void init_tile_pack_bs_params(AV1_COMP *const cpi, uint8_t *const dst,
                                     size_t dst_size,
                                     struct aom_write_bit_buffer *saved_wb,
                                     PackBSParams *const pack_bs_params_arr,
                                     uint8_t obu_extn_header) {
  MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
  AV1_COMMON *const cm = &cpi->common;
  const CommonTileParams *const tiles = &cm->tiles;
  const int num_tiles = tiles->cols * tiles->rows;
  // Fixed size tile groups for the moment
  const int num_tg_hdrs = cpi->num_tg;
  // Tile group size in terms of number of tiles.
  const int tg_size_in_tiles = (num_tiles + num_tg_hdrs - 1) / num_tg_hdrs;
  uint8_t *tile_dst = dst;
  uint8_t *tile_data_curr = dst;
  // Max tile group count can not be more than MAX_TILES.
  int tg_size_mi[MAX_TILES] = { 0 };  // Size of tile group in mi units
  int tile_idx;
  int tg_idx = 0;
  int tile_count_in_tg = 0;
  int new_tg = 1;

  // Populate pack bitstream params of all tiles.
  for (tile_idx = 0; tile_idx < num_tiles; tile_idx++) {
    const TileInfo *const tile_info = &cpi->tile_data[tile_idx].tile_info;
    PackBSParams *const pack_bs_params = &pack_bs_params_arr[tile_idx];
    // Calculate tile size in mi units.
    const int tile_size_mi = (tile_info->mi_col_end - tile_info->mi_col_start) *
                             (tile_info->mi_row_end - tile_info->mi_row_start);
    int is_last_tile_in_tg = 0;
    tile_count_in_tg++;
    if (tile_count_in_tg == tg_size_in_tiles || tile_idx == (num_tiles - 1))
      is_last_tile_in_tg = 1;

    // Populate pack bitstream params of this tile.
    pack_bs_params->curr_tg_hdr_size = 0;
    pack_bs_params->obu_extn_header = obu_extn_header;
    pack_bs_params->saved_wb = saved_wb;
    pack_bs_params->obu_header_size = 0;
    pack_bs_params->is_last_tile_in_tg = is_last_tile_in_tg;
    pack_bs_params->new_tg = new_tg;
    pack_bs_params->tile_col = tile_info->tile_col;
    pack_bs_params->tile_row = tile_info->tile_row;
    pack_bs_params->tile_size_mi = tile_size_mi;
    tg_size_mi[tg_idx] += tile_size_mi;

    if (new_tg) new_tg = 0;
    if (is_last_tile_in_tg) {
      tile_count_in_tg = 0;
      new_tg = 1;
      tg_idx++;
    }
  }

  assert(dst_size > 0);
  size_t tg_buf_size[MAX_TILES] = { 0 };
  size_t max_buf_size = dst_size;
  size_t remain_buf_size = max_buf_size;
  const int frame_size_mi = cm->mi_params.mi_rows * cm->mi_params.mi_cols;

  tile_idx = 0;
  // Prepare obu, tile group and frame header of each tile group.
  for (tg_idx = 0; tg_idx < cpi->num_tg; tg_idx++) {
    PackBSParams *const pack_bs_params = &pack_bs_params_arr[tile_idx];
    int is_last_tg = tg_idx == cpi->num_tg - 1;
    // Prorate bitstream buffer size based on tile group size and available
    // buffer size. This buffer will be used to store headers and tile data.
    tg_buf_size[tg_idx] =
        get_bs_chunk_size(tg_size_mi[tg_idx], frame_size_mi, &remain_buf_size,
                          max_buf_size, is_last_tg);

    pack_bs_params->dst = tile_dst;
    pack_bs_params->tile_data_curr = tile_dst;

    // Write obu, tile group and frame header at first tile in the tile
    // group.
    av1_write_obu_tg_tile_headers(cpi, xd, pack_bs_params, tile_idx);
    tile_dst += tg_buf_size[tg_idx];

    // Exclude headers from tile group buffer size.
    tg_buf_size[tg_idx] -= pack_bs_params->curr_tg_hdr_size;
    tile_idx += tg_size_in_tiles;
  }

  tg_idx = 0;
  // Calculate bitstream buffer size of each tile in the tile group.
  for (tile_idx = 0; tile_idx < num_tiles; tile_idx++) {
    PackBSParams *const pack_bs_params = &pack_bs_params_arr[tile_idx];

    if (pack_bs_params->new_tg) {
      max_buf_size = tg_buf_size[tg_idx];
      remain_buf_size = max_buf_size;
    }

    // Prorate bitstream buffer size of this tile based on tile size and
    // available buffer size. For this proration, header size is not accounted.
    const size_t tile_buf_size = get_bs_chunk_size(
        pack_bs_params->tile_size_mi, tg_size_mi[tg_idx], &remain_buf_size,
        max_buf_size, pack_bs_params->is_last_tile_in_tg);
    pack_bs_params->tile_buf_size = tile_buf_size;

    // Update base address of bitstream buffer for tile and tile group.
    if (pack_bs_params->new_tg) {
      tile_dst = pack_bs_params->dst;
      tile_data_curr = pack_bs_params->tile_data_curr;
      // Account header size in first tile of a tile group.
      pack_bs_params->tile_buf_size += pack_bs_params->curr_tg_hdr_size;
    } else {
      pack_bs_params->dst = tile_dst;
      pack_bs_params->tile_data_curr = tile_data_curr;
    }

    if (pack_bs_params->is_last_tile_in_tg) tg_idx++;
    tile_dst += pack_bs_params->tile_buf_size;
  }
}

// Worker hook function of pack bitsteam multithreading.
static int pack_bs_worker_hook(void *arg1, void *arg2) {
  EncWorkerData *const thread_data = (EncWorkerData *)arg1;
  PackBSParams *const pack_bs_params = (PackBSParams *)arg2;
  AV1_COMP *const cpi = thread_data->cpi;
  AV1_COMMON *const cm = &cpi->common;
  AV1EncPackBSSync *const pack_bs_sync = &cpi->mt_info.pack_bs_sync;
  const CommonTileParams *const tiles = &cm->tiles;
  const int num_tiles = tiles->cols * tiles->rows;

#if CONFIG_MULTITHREAD
  pthread_mutex_t *const pack_bs_mutex = pack_bs_sync->mutex_;
#endif
  MACROBLOCKD *const xd = &thread_data->td->mb.e_mbd;
  struct aom_internal_error_info *const error_info = &thread_data->error_info;
  xd->error_info = error_info;

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(error_info->jmp)) {
    error_info->setjmp = 0;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(pack_bs_mutex);
    pack_bs_sync->pack_bs_mt_exit = true;
    pthread_mutex_unlock(pack_bs_mutex);
#endif
    return 0;
  }
  error_info->setjmp = 1;

  while (1) {
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(pack_bs_mutex);
#endif
    const int tile_idx =
        pack_bs_sync->pack_bs_mt_exit
            ? -1
            : get_next_pack_bs_tile_idx(pack_bs_sync, num_tiles);
#if CONFIG_MULTITHREAD
    pthread_mutex_unlock(pack_bs_mutex);
#endif
    // When pack_bs_mt_exit is set to true, other workers need not pursue any
    // further jobs.
    if (tile_idx == -1) break;
    TileDataEnc *this_tile = &cpi->tile_data[tile_idx];
    thread_data->td->mb.e_mbd.tile_ctx = &this_tile->tctx;

    av1_pack_tile_info(cpi, thread_data->td, &pack_bs_params[tile_idx]);
  }

  error_info->setjmp = 0;
  return 1;
}

// Prepares thread data and workers of pack bitsteam multithreading.
static void prepare_pack_bs_workers(AV1_COMP *const cpi,
                                    PackBSParams *const pack_bs_params,
                                    AVxWorkerHook hook, const int num_workers) {
  MultiThreadInfo *const mt_info = &cpi->mt_info;
  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *worker = &mt_info->workers[i];
    EncWorkerData *const thread_data = &mt_info->tile_thr_data[i];
    if (i == 0) {
      thread_data->td = &cpi->td;
    } else {
      thread_data->td = thread_data->original_td;
    }

    if (thread_data->td != &cpi->td) thread_data->td->mb = cpi->td.mb;

    thread_data->cpi = cpi;
    thread_data->start = i;
    thread_data->thread_id = i;
    av1_reset_pack_bs_thread_data(thread_data->td);

    worker->hook = hook;
    worker->data1 = thread_data;
    worker->data2 = pack_bs_params;
  }

  AV1_COMMON *const cm = &cpi->common;
  AV1EncPackBSSync *const pack_bs_sync = &mt_info->pack_bs_sync;
  const uint16_t num_tiles = cm->tiles.rows * cm->tiles.cols;
  pack_bs_sync->next_job_idx = 0;
  pack_bs_sync->pack_bs_mt_exit = false;

  PackBSTileOrder *const pack_bs_tile_order = pack_bs_sync->pack_bs_tile_order;
  // Reset tile order data of pack bitstream
  av1_zero_array(pack_bs_tile_order, num_tiles);

  // Populate pack bitstream tile order structure
  for (uint16_t tile_idx = 0; tile_idx < num_tiles; tile_idx++) {
    pack_bs_tile_order[tile_idx].abs_sum_level =
        cpi->tile_data[tile_idx].abs_sum_level;
    pack_bs_tile_order[tile_idx].tile_idx = tile_idx;
  }

  // Sort tiles in descending order based on tile area.
  qsort(pack_bs_tile_order, num_tiles, sizeof(*pack_bs_tile_order),
        compare_tile_order);
}

// Accumulates data after pack bitsteam processing.
static void accumulate_pack_bs_data(
    AV1_COMP *const cpi, const PackBSParams *const pack_bs_params_arr,
    uint8_t *const dst, uint32_t *total_size, const FrameHeaderInfo *fh_info,
    int *const largest_tile_id, unsigned int *max_tile_size,
    uint32_t *const obu_header_size, uint8_t **tile_data_start,
    const int num_workers) {
  const AV1_COMMON *const cm = &cpi->common;
  const CommonTileParams *const tiles = &cm->tiles;
  const int tile_count = tiles->cols * tiles->rows;
  // Fixed size tile groups for the moment
  size_t curr_tg_data_size = 0;
  int is_first_tg = 1;
  uint8_t *curr_tg_start = dst;
  size_t src_offset = 0;
  size_t dst_offset = 0;

  for (int tile_idx = 0; tile_idx < tile_count; tile_idx++) {
    // PackBSParams stores all parameters required to pack tile and header
    // info.
    const PackBSParams *const pack_bs_params = &pack_bs_params_arr[tile_idx];
    uint32_t tile_size = 0;

    if (pack_bs_params->new_tg) {
      curr_tg_start = dst + *total_size;
      curr_tg_data_size = pack_bs_params->curr_tg_hdr_size;
      *tile_data_start += pack_bs_params->curr_tg_hdr_size;
      *obu_header_size = pack_bs_params->obu_header_size;
    }
    curr_tg_data_size +=
        pack_bs_params->buf.size + (pack_bs_params->is_last_tile_in_tg ? 0 : 4);

    if (pack_bs_params->buf.size > *max_tile_size) {
      *largest_tile_id = tile_idx;
      *max_tile_size = (unsigned int)pack_bs_params->buf.size;
    }
    tile_size +=
        (uint32_t)pack_bs_params->buf.size + *pack_bs_params->total_size;

    // Pack all the chunks of tile bitstreams together
    if (tile_idx != 0) memmove(dst + dst_offset, dst + src_offset, tile_size);

    if (pack_bs_params->is_last_tile_in_tg)
      av1_write_last_tile_info(
          cpi, fh_info, pack_bs_params->saved_wb, &curr_tg_data_size,
          curr_tg_start, &tile_size, tile_data_start, largest_tile_id,
          &is_first_tg, *obu_header_size, pack_bs_params->obu_extn_header);
    src_offset += pack_bs_params->tile_buf_size;
    dst_offset += tile_size;
    *total_size += tile_size;
  }

  // Accumulate thread data
  MultiThreadInfo *const mt_info = &cpi->mt_info;
  for (int idx = num_workers - 1; idx >= 0; idx--) {
    ThreadData const *td = mt_info->tile_thr_data[idx].td;
    av1_accumulate_pack_bs_thread_data(cpi, td);
  }
}

void av1_write_tile_obu_mt(AV1_COMP *const cpi, uint8_t *const dst,
                           size_t dst_size, uint32_t *total_size,
                           struct aom_write_bit_buffer *saved_wb,
                           uint8_t obu_extn_header,
                           const FrameHeaderInfo *fh_info,
                           int *const largest_tile_id,
                           unsigned int *max_tile_size,
                           uint32_t *const obu_header_size,
                           uint8_t **tile_data_start, const int num_workers) {
  MultiThreadInfo *const mt_info = &cpi->mt_info;

  PackBSParams pack_bs_params[MAX_TILES];
  uint32_t tile_size[MAX_TILES] = { 0 };

  for (int tile_idx = 0; tile_idx < MAX_TILES; tile_idx++)
    pack_bs_params[tile_idx].total_size = &tile_size[tile_idx];

  init_tile_pack_bs_params(cpi, dst, dst_size, saved_wb, pack_bs_params,
                           obu_extn_header);
  prepare_pack_bs_workers(cpi, pack_bs_params, pack_bs_worker_hook,
                          num_workers);
  launch_workers(mt_info, num_workers);
  sync_enc_workers(mt_info, &cpi->common, num_workers);
  accumulate_pack_bs_data(cpi, pack_bs_params, dst, total_size, fh_info,
                          largest_tile_id, max_tile_size, obu_header_size,
                          tile_data_start, num_workers);
}

// Deallocate memory for CDEF search multi-thread synchronization.
void av1_cdef_mt_dealloc(AV1CdefSync *cdef_sync) {
  (void)cdef_sync;
  assert(cdef_sync != NULL);
#if CONFIG_MULTITHREAD
  if (cdef_sync->mutex_ != NULL) {
    pthread_mutex_destroy(cdef_sync->mutex_);
    aom_free(cdef_sync->mutex_);
  }
#endif  // CONFIG_MULTITHREAD
}

// Updates the row and column indices of the next job to be processed.
// Also updates end_of_frame flag when the processing of all blocks is complete.
static void update_next_job_info(AV1CdefSync *cdef_sync, int nvfb, int nhfb) {
  cdef_sync->fbc++;
  if (cdef_sync->fbc == nhfb) {
    cdef_sync->fbr++;
    if (cdef_sync->fbr == nvfb) {
      cdef_sync->end_of_frame = 1;
    } else {
      cdef_sync->fbc = 0;
    }
  }
}

// Initializes cdef_sync parameters.
static inline void cdef_reset_job_info(AV1CdefSync *cdef_sync) {
#if CONFIG_MULTITHREAD
  if (cdef_sync->mutex_) pthread_mutex_init(cdef_sync->mutex_, NULL);
#endif  // CONFIG_MULTITHREAD
  cdef_sync->end_of_frame = 0;
  cdef_sync->fbr = 0;
  cdef_sync->fbc = 0;
  cdef_sync->cdef_mt_exit = false;
}

// Checks if a job is available. If job is available,
// populates next job information and returns 1, else returns 0.
static inline int cdef_get_next_job(AV1CdefSync *cdef_sync,
                                    CdefSearchCtx *cdef_search_ctx,
                                    volatile int *cur_fbr,
                                    volatile int *cur_fbc,
                                    volatile int *sb_count) {
#if CONFIG_MULTITHREAD
  pthread_mutex_lock(cdef_sync->mutex_);
#endif  // CONFIG_MULTITHREAD
  int do_next_block = 0;
  const int nvfb = cdef_search_ctx->nvfb;
  const int nhfb = cdef_search_ctx->nhfb;

  // If a block is skip, do not process the block and
  // check the skip condition for the next block.
  while (!cdef_sync->cdef_mt_exit && !cdef_sync->end_of_frame &&
         cdef_sb_skip(cdef_search_ctx->mi_params, cdef_sync->fbr,
                      cdef_sync->fbc)) {
    update_next_job_info(cdef_sync, nvfb, nhfb);
  }

  // Populates information needed for current job and update the row,
  // column indices of the next block to be processed.
  if (!cdef_sync->cdef_mt_exit && cdef_sync->end_of_frame == 0) {
    do_next_block = 1;
    *cur_fbr = cdef_sync->fbr;
    *cur_fbc = cdef_sync->fbc;
    *sb_count = cdef_search_ctx->sb_count;
    cdef_search_ctx->sb_count++;
    update_next_job_info(cdef_sync, nvfb, nhfb);
  }
#if CONFIG_MULTITHREAD
  pthread_mutex_unlock(cdef_sync->mutex_);
#endif  // CONFIG_MULTITHREAD
  return do_next_block;
}

// Hook function for each thread in CDEF search multi-threading.
static int cdef_filter_block_worker_hook(void *arg1, void *arg2) {
  EncWorkerData *thread_data = (EncWorkerData *)arg1;
  AV1CdefSync *const cdef_sync = (AV1CdefSync *)arg2;

#if CONFIG_MULTITHREAD
  pthread_mutex_t *cdef_mutex_ = cdef_sync->mutex_;
#endif
  struct aom_internal_error_info *const error_info = &thread_data->error_info;
  CdefSearchCtx *cdef_search_ctx = thread_data->cpi->cdef_search_ctx;

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(error_info->jmp)) {
    error_info->setjmp = 0;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(cdef_mutex_);
    cdef_sync->cdef_mt_exit = true;
    pthread_mutex_unlock(cdef_mutex_);
#endif
    return 0;
  }
  error_info->setjmp = 1;

  volatile int cur_fbr, cur_fbc, sb_count;
  while (cdef_get_next_job(cdef_sync, cdef_search_ctx, &cur_fbr, &cur_fbc,
                           &sb_count)) {
    av1_cdef_mse_calc_block(cdef_search_ctx, error_info, cur_fbr, cur_fbc,
                            sb_count,
                            thread_data->cpi->sf.lpf_sf.adaptive_cdef_mode);
  }
  error_info->setjmp = 0;
  return 1;
}

// Assigns CDEF search hook function and thread data to each worker.
static void prepare_cdef_workers(AV1_COMP *cpi, AVxWorkerHook hook,
                                 int num_workers) {
  MultiThreadInfo *mt_info = &cpi->mt_info;
  for (int i = num_workers - 1; i >= 0; i--) {
    AVxWorker *worker = &mt_info->workers[i];
    EncWorkerData *thread_data = &mt_info->tile_thr_data[i];

    thread_data->cpi = cpi;
    worker->hook = hook;
    worker->data1 = thread_data;
    worker->data2 = &mt_info->cdef_sync;
  }
}

// Implements multi-threading for CDEF search.
void av1_cdef_mse_calc_frame_mt(AV1_COMP *cpi) {
  MultiThreadInfo *mt_info = &cpi->mt_info;
  AV1CdefSync *cdef_sync = &mt_info->cdef_sync;
  const int num_workers = mt_info->num_mod_workers[MOD_CDEF_SEARCH];

  cdef_reset_job_info(cdef_sync);
  prepare_cdef_workers(cpi, cdef_filter_block_worker_hook, num_workers);
  launch_workers(mt_info, num_workers);
  sync_enc_workers(mt_info, &cpi->common, num_workers);
}

// Computes num_workers for temporal filter multi-threading.
static inline int compute_num_tf_workers(const AV1_COMP *cpi) {
  // For single-pass encode, using no. of workers as per tf block size was not
  // found to improve speed. Hence the thread assignment for single-pass encode
  // is kept based on compute_num_enc_workers().
  if (cpi->oxcf.pass < AOM_RC_SECOND_PASS)
    return compute_num_enc_workers(cpi, cpi->oxcf.max_threads);

  if (cpi->oxcf.max_threads <= 1) return 1;

  const int frame_height = cpi->common.height;
  const BLOCK_SIZE block_size = TF_BLOCK_SIZE;
  const int mb_height = block_size_high[block_size];
  const int mb_rows = get_num_blocks(frame_height, mb_height);
  return AOMMIN(cpi->oxcf.max_threads, mb_rows);
}

// Computes num_workers for tpl multi-threading.
static inline int compute_num_tpl_workers(AV1_COMP *cpi) {
  return compute_num_enc_workers(cpi, cpi->oxcf.max_threads);
}

// Computes num_workers for loop filter multi-threading.
static inline int compute_num_lf_workers(AV1_COMP *cpi) {
  return compute_num_enc_workers(cpi, cpi->oxcf.max_threads);
}

// Computes num_workers for cdef multi-threading.
static inline int compute_num_cdef_workers(AV1_COMP *cpi) {
  return compute_num_enc_workers(cpi, cpi->oxcf.max_threads);
}

// Computes num_workers for loop-restoration multi-threading.
static inline int compute_num_lr_workers(AV1_COMP *cpi) {
  return compute_num_enc_workers(cpi, cpi->oxcf.max_threads);
}

// Computes num_workers for pack bitstream multi-threading.
static inline int compute_num_pack_bs_workers(AV1_COMP *cpi) {
  if (cpi->oxcf.max_threads <= 1) return 1;
  return compute_num_enc_tile_mt_workers(&cpi->common, cpi->oxcf.max_threads);
}

// Computes num_workers for all intra multi-threading.
static inline int compute_num_ai_workers(AV1_COMP *cpi) {
  if (cpi->oxcf.max_threads <= 1) return 1;
  // The multi-threading implementation of deltaq-mode = 3 in allintra
  // mode is based on row multi threading.
  if (!cpi->oxcf.row_mt) return 1;
  cpi->weber_bsize = BLOCK_8X8;
  const BLOCK_SIZE bsize = cpi->weber_bsize;
  const int mb_step = mi_size_wide[bsize];
  const int num_mb_rows = cpi->common.mi_params.mi_rows / mb_step;
  return AOMMIN(num_mb_rows, cpi->oxcf.max_threads);
}

static int compute_num_mod_workers(AV1_COMP *cpi,
                                   MULTI_THREADED_MODULES mod_name) {
  int num_mod_workers = 0;
  switch (mod_name) {
    case MOD_FP:
      if (cpi->oxcf.pass >= AOM_RC_SECOND_PASS)
        num_mod_workers = 0;
      else
        num_mod_workers = compute_num_enc_workers(cpi, cpi->oxcf.max_threads);
      break;
    case MOD_TF: num_mod_workers = compute_num_tf_workers(cpi); break;
    case MOD_TPL: num_mod_workers = compute_num_tpl_workers(cpi); break;
    case MOD_GME: num_mod_workers = 1; break;
    case MOD_ENC:
      num_mod_workers = compute_num_enc_workers(cpi, cpi->oxcf.max_threads);
      break;
    case MOD_LPF: num_mod_workers = compute_num_lf_workers(cpi); break;
    case MOD_CDEF_SEARCH:
      num_mod_workers = compute_num_cdef_workers(cpi);
      break;
    case MOD_CDEF: num_mod_workers = compute_num_cdef_workers(cpi); break;
    case MOD_LR: num_mod_workers = compute_num_lr_workers(cpi); break;
    case MOD_PACK_BS: num_mod_workers = compute_num_pack_bs_workers(cpi); break;
    case MOD_FRAME_ENC:
      num_mod_workers = cpi->ppi->p_mt_info.num_mod_workers[MOD_FRAME_ENC];
      break;
    case MOD_AI:
      if (cpi->oxcf.pass == AOM_RC_ONE_PASS) {
        num_mod_workers = compute_num_ai_workers(cpi);
      } else {
        num_mod_workers = 0;
      }
      break;
    default: assert(0); break;
  }
  return (num_mod_workers);
}
// Computes the number of workers for each MT modules in the encoder
void av1_compute_num_workers_for_mt(AV1_COMP *cpi) {
  for (int i = MOD_FP; i < NUM_MT_MODULES; i++) {
    cpi->ppi->p_mt_info.num_mod_workers[i] =
        compute_num_mod_workers(cpi, (MULTI_THREADED_MODULES)i);
  }
}
