#include "src/decoder_impl.h"

#include <algorithm>
#include <atomic>
#include <cassert>
#include <iterator>
#include <new>
#include <utility>

#include "src/dsp/common.h"
#include "src/dsp/constants.h"
#include "src/dsp/dsp.h"
#include "src/loop_filter_mask.h"
#include "src/loop_restoration_info.h"
#include "src/post_filter.h"
#include "src/prediction_mask.h"
#include "src/quantizer.h"
#include "src/utils/blocking_counter.h"
#include "src/utils/common.h"
#include "src/utils/logging.h"
#include "src/utils/parameter_tree.h"
#include "src/utils/raw_bit_reader.h"
#include "src/utils/segmentation.h"
#include "src/utils/threadpool.h"
#include "src/yuv_buffer.h"

namespace libgav1 {
namespace {

constexpr int kMaxBlockWidth4x4 = 32;
constexpr int kMaxBlockHeight4x4 = 32;

// A cleanup helper class that releases the frame buffer reference held in
// |frame| in the destructor.
class RefCountedBufferPtrCleanup {
 public:
  explicit RefCountedBufferPtrCleanup(RefCountedBufferPtr* frame)
      : frame_(*frame) {}

  // Not copyable or movable.
  RefCountedBufferPtrCleanup(const RefCountedBufferPtrCleanup&) = delete;
  RefCountedBufferPtrCleanup& operator=(const RefCountedBufferPtrCleanup&) =
      delete;

  ~RefCountedBufferPtrCleanup() { frame_ = nullptr; }

 private:
  RefCountedBufferPtr& frame_;
};

}  // namespace

// static
StatusCode DecoderImpl::Create(const DecoderSettings* settings,
                               std::unique_ptr<DecoderImpl>* output) {
  if (settings->threads <= 0) {
    LIBGAV1_DLOG(ERROR, "Invalid settings->threads: %d.", settings->threads);
    return kLibgav1StatusInvalidArgument;
  }
  std::unique_ptr<DecoderImpl> impl(new (std::nothrow) DecoderImpl(settings));
  if (impl == nullptr) {
    LIBGAV1_DLOG(ERROR, "Failed to allocate DecoderImpl.");
    return kLibgav1StatusOutOfMemory;
  }
  const StatusCode status = impl->Init();
  if (status != kLibgav1StatusOk) return status;
  *output = std::move(impl);
  return kLibgav1StatusOk;
}

DecoderImpl::DecoderImpl(const DecoderSettings* settings)
    : buffer_pool_(*settings), settings_(*settings) {
  dsp::DspInit();
  GenerateWedgeMask(state_.wedge_master_mask.data(), state_.wedge_masks.data());
}

DecoderImpl::~DecoderImpl() {
  // The frame buffer references need to be released before |buffer_pool_| is
  // destroyed.
  ReleaseOutputFrame();
  assert(state_.current_frame == nullptr);
  for (auto& reference_frame : state_.reference_frame) {
    reference_frame = nullptr;
  }
}

StatusCode DecoderImpl::Init() {
  const int max_allowed_frames =
      settings_.frame_parallel ? settings_.threads : 1;
  assert(max_allowed_frames > 0);
  if (!encoded_frames_.Init(max_allowed_frames)) {
    LIBGAV1_DLOG(ERROR, "encoded_frames_.Init() failed.");
    return kLibgav1StatusOutOfMemory;
  }
  return kLibgav1StatusOk;
}

StatusCode DecoderImpl::EnqueueFrame(const uint8_t* data, size_t size,
                                     int64_t user_private_data) {
  if (data == nullptr) {
    // This has to actually flush the decoder.
    return kLibgav1StatusOk;
  }
  if (encoded_frames_.Full()) {
    return kLibgav1StatusResourceExhausted;
  }
  encoded_frames_.Push(EncodedFrame(data, size, user_private_data));
  return kLibgav1StatusOk;
}

// DequeueFrame() follows the following policy to avoid holding unnecessary
// frame buffer references in state_.current_frame and output_frame_.
//
// 1. state_.current_frame must be null when DequeueFrame() returns (success
// or failure).
//
// 2. output_frame_ must be null when DequeueFrame() returns false.
StatusCode DecoderImpl::DequeueFrame(const DecoderBuffer** out_ptr) {
  if (out_ptr == nullptr) {
    LIBGAV1_DLOG(ERROR, "Invalid argument: out_ptr == nullptr.");
    return kLibgav1StatusInvalidArgument;
  }
  assert(state_.current_frame == nullptr);
  // We assume a call to DequeueFrame() indicates that the caller is no longer
  // using the previous output frame, so we can release it.
  ReleaseOutputFrame();
  if (encoded_frames_.Empty()) {
    // No encoded frame to decode. Not an error.
    *out_ptr = nullptr;
    return kLibgav1StatusOk;
  }
  const EncodedFrame encoded_frame = encoded_frames_.Pop();
  std::unique_ptr<ObuParser> obu(new (std::nothrow) ObuParser(
      encoded_frame.data, encoded_frame.size, &state_));
  if (obu == nullptr) {
    LIBGAV1_DLOG(ERROR, "Failed to initialize OBU parser.");
    return kLibgav1StatusOutOfMemory;
  }
  if (state_.has_sequence_header) {
    obu->set_sequence_header(state_.sequence_header);
  }
  RefCountedBufferPtrCleanup current_frame_cleanup(&state_.current_frame);
  RefCountedBufferPtr displayable_frame;
  StatusCode status;
  while (obu->HasData()) {
    state_.current_frame = buffer_pool_.GetFreeBuffer();
    if (state_.current_frame == nullptr) {
      LIBGAV1_DLOG(ERROR, "Could not get current_frame from the buffer pool.");
      return kLibgav1StatusResourceExhausted;
    }

    if (!obu->ParseOneFrame()) {
      LIBGAV1_DLOG(ERROR, "Failed to parse OBU.");
      return kLibgav1StatusUnknownError;
    }
    if (std::find_if(obu->obu_headers().begin(), obu->obu_headers().end(),
                     [](const ObuHeader& obu_header) {
                       return obu_header.type == kObuSequenceHeader;
                     }) != obu->obu_headers().end()) {
      state_.sequence_header = obu->sequence_header();
      state_.has_sequence_header = true;
    }
    if (!obu->frame_header().show_existing_frame) {
      if (obu->tile_groups().empty()) {
        // This means that the last call to ParseOneFrame() did not actually
        // have any tile groups. This could happen in rare cases (for example,
        // if there is a Metadata OBU after the TileGroup OBU). We currently do
        // not have a reason to handle those cases, so we simply continue.
        continue;
      }
      status = DecodeTiles(obu.get());
      if (status != kLibgav1StatusOk) {
        return status;
      }
    }
    UpdateReferenceFrames(obu->frame_header().refresh_frame_flags);
    if (obu->frame_header().show_frame ||
        obu->frame_header().show_existing_frame) {
      if (displayable_frame != nullptr) {
        // This can happen if there are multiple spatial/temporal layers. We
        // don't care about it for now, so simply return the last displayable
        // frame.
        // TODO(b/129153372): Add support for outputting multiple
        // spatial/temporal layers.
        LIBGAV1_DLOG(
            WARNING,
            "More than one displayable frame found. Using the last one.");
      }
      displayable_frame = std::move(state_.current_frame);
      if (obu->sequence_header().film_grain_params_present &&
          displayable_frame->film_grain_params().apply_grain &&
          (settings_.post_filter_mask & 0x10) != 0) {
        RefCountedBufferPtr film_grain_frame;
        if (!obu->frame_header().show_existing_frame &&
            obu->frame_header().refresh_frame_flags == 0) {
          // If show_existing_frame is true, then the current frame is a
          // previously saved reference frame. If refresh_frame_flags is
          // nonzero, then the UpdateReferenceFrames() call above has saved the
          // current frame as a reference frame. Therefore, if both of these
          // conditions are false, then the current frame is not saved as a
          // reference frame. displayable_frame should hold the only reference
          // to the current frame.
          assert(displayable_frame.use_count() == 1);
          // Add film grain noise in place.
          film_grain_frame = displayable_frame;
        } else {
          film_grain_frame = buffer_pool_.GetFreeBuffer();
          if (film_grain_frame == nullptr) {
            LIBGAV1_DLOG(
                ERROR, "Could not get film_grain_frame from the buffer pool.");
            return kLibgav1StatusResourceExhausted;
          }
          if (!film_grain_frame->Realloc(
                  displayable_frame->buffer()->bitdepth(),
                  displayable_frame->buffer()->is_monochrome(),
                  displayable_frame->upscaled_width(),
                  displayable_frame->frame_height(),
                  displayable_frame->buffer()->subsampling_x(),
                  displayable_frame->buffer()->subsampling_y(),
                  /*border=*/0,
                  /*byte_alignment=*/0)) {
            LIBGAV1_DLOG(ERROR, "film_grain_frame->Realloc() failed.");
            return kLibgav1StatusOutOfMemory;
          }
          film_grain_frame->set_chroma_sample_position(
              displayable_frame->chroma_sample_position());
        }
        const dsp::Dsp* const dsp =
            dsp::GetDspTable(displayable_frame->buffer()->bitdepth());
        if (!dsp->film_grain_synthesis(
                displayable_frame->buffer()->data(kPlaneY),
                displayable_frame->buffer()->stride(kPlaneY),
                displayable_frame->buffer()->data(kPlaneU),
                displayable_frame->buffer()->stride(kPlaneU),
                displayable_frame->buffer()->data(kPlaneV),
                displayable_frame->buffer()->stride(kPlaneV),
                displayable_frame->film_grain_params(),
                displayable_frame->buffer()->is_monochrome(),
                obu->sequence_header().color_config.matrix_coefficients ==
                    kMatrixCoefficientIdentity,
                displayable_frame->upscaled_width(),
                displayable_frame->frame_height(),
                displayable_frame->buffer()->subsampling_x(),
                displayable_frame->buffer()->subsampling_y(),
                film_grain_frame->buffer()->data(kPlaneY),
                film_grain_frame->buffer()->stride(kPlaneY),
                film_grain_frame->buffer()->data(kPlaneU),
                film_grain_frame->buffer()->stride(kPlaneU),
                film_grain_frame->buffer()->data(kPlaneV),
                film_grain_frame->buffer()->stride(kPlaneV))) {
          LIBGAV1_DLOG(ERROR, "dsp->film_grain_synthesis() failed.");
          return kLibgav1StatusOutOfMemory;
        }
        displayable_frame = std::move(film_grain_frame);
      }
    }
  }
  if (displayable_frame == nullptr) {
    // No displayable frame in the encoded frame. Not an error.
    *out_ptr = nullptr;
    return kLibgav1StatusOk;
  }
  status = CopyFrameToOutputBuffer(displayable_frame);
  if (status != kLibgav1StatusOk) {
    return status;
  }
  buffer_.user_private_data = encoded_frame.user_private_data;
  *out_ptr = &buffer_;
  return kLibgav1StatusOk;
}

bool DecoderImpl::AllocateCurrentFrame(const ObuFrameHeader& frame_header) {
  const ColorConfig& color_config = state_.sequence_header.color_config;
  state_.current_frame->set_chroma_sample_position(
      color_config.chroma_sample_position);
  return state_.current_frame->Realloc(
      color_config.bitdepth, color_config.is_monochrome,
      frame_header.upscaled_width, frame_header.height,
      color_config.subsampling_x, color_config.subsampling_y, kBorderPixels,
      /*byte_alignment=*/0);
}

StatusCode DecoderImpl::CopyFrameToOutputBuffer(
    const RefCountedBufferPtr& frame) {
  YuvBuffer* yuv_buffer = frame->buffer();

  buffer_.chroma_sample_position = frame->chroma_sample_position();

  if (yuv_buffer->is_monochrome()) {
    buffer_.image_format = kImageFormatMonochrome400;
  } else {
    if (yuv_buffer->subsampling_x() == 0 && yuv_buffer->subsampling_y() == 0) {
      buffer_.image_format = kImageFormatYuv444;
    } else if (yuv_buffer->subsampling_x() == 1 &&
               yuv_buffer->subsampling_y() == 0) {
      buffer_.image_format = kImageFormatYuv422;
    } else if (yuv_buffer->subsampling_x() == 1 &&
               yuv_buffer->subsampling_y() == 1) {
      buffer_.image_format = kImageFormatYuv420;
    } else {
      LIBGAV1_DLOG(ERROR,
                   "Invalid chroma subsampling values: cannot determine buffer "
                   "image format.");
      return kLibgav1StatusInvalidArgument;
    }
  }

  buffer_.bitdepth = yuv_buffer->bitdepth();
  const int num_planes =
      yuv_buffer->is_monochrome() ? kMaxPlanesMonochrome : kMaxPlanes;
  int plane = 0;
  for (; plane < num_planes; ++plane) {
    buffer_.stride[plane] = yuv_buffer->stride(plane);
    buffer_.plane[plane] = yuv_buffer->data(plane);
    buffer_.displayed_width[plane] = yuv_buffer->displayed_width(plane);
    buffer_.displayed_height[plane] = yuv_buffer->displayed_height(plane);
  }
  for (; plane < kMaxPlanes; ++plane) {
    buffer_.stride[plane] = 0;
    buffer_.plane[plane] = nullptr;
    buffer_.displayed_width[plane] = 0;
    buffer_.displayed_height[plane] = 0;
  }
  buffer_.buffer_private_data = frame->buffer_private_data();
  output_frame_ = frame;
  return kLibgav1StatusOk;
}

void DecoderImpl::ReleaseOutputFrame() {
  for (auto& plane : buffer_.plane) {
    plane = nullptr;
  }
  output_frame_ = nullptr;
}

StatusCode DecoderImpl::DecodeTiles(const ObuParser* obu) {
  if (PostFilter::DoDeblock(obu->frame_header(), settings_.post_filter_mask) &&
      !loop_filter_mask_.Reset(obu->frame_header().width,
                               obu->frame_header().height)) {
    LIBGAV1_DLOG(ERROR, "Failed to allocate memory for loop filter masks.");
    return kLibgav1StatusOutOfMemory;
  }
  LoopRestorationInfo loop_restoration_info(
      obu->frame_header().loop_restoration, obu->frame_header().upscaled_width,
      obu->frame_header().height,
      obu->sequence_header().color_config.subsampling_x,
      obu->sequence_header().color_config.subsampling_y,
      obu->sequence_header().color_config.is_monochrome);
  if (!loop_restoration_info.Allocate()) {
    LIBGAV1_DLOG(ERROR,
                 "Failed to allocate memory for loop restoration info units.");
    return kLibgav1StatusOutOfMemory;
  }
  if (!AllocateCurrentFrame(obu->frame_header())) {
    LIBGAV1_DLOG(ERROR, "Failed to allocate memory for the decoder buffer.");
    return kLibgav1StatusOutOfMemory;
  }
  Array2D<int16_t> cdef_index;
  if (obu->sequence_header().enable_cdef) {
    if (!cdef_index.Reset(
            DivideBy16(obu->frame_header().rows4x4 + kMaxBlockHeight4x4),
            DivideBy16(obu->frame_header().columns4x4 + kMaxBlockWidth4x4))) {
      LIBGAV1_DLOG(ERROR, "Failed to allocate memory for cdef index.");
      return kLibgav1StatusOutOfMemory;
    }
  }
  if (!inter_transform_sizes_.Reset(
          obu->frame_header().rows4x4 + kMaxBlockHeight4x4,
          obu->frame_header().columns4x4 + kMaxBlockWidth4x4,
          /*zero_initialize=*/false)) {
    LIBGAV1_DLOG(ERROR, "Failed to allocate memory for inter_transform_sizes.");
    return kLibgav1StatusOutOfMemory;
  }
  if (obu->frame_header().use_ref_frame_mvs &&
      !state_.motion_field_mv.Reset(DivideBy2(obu->frame_header().rows4x4),
                                    DivideBy2(obu->frame_header().columns4x4),
                                    /*zero_initialize=*/false)) {
    LIBGAV1_DLOG(ERROR,
                 "Failed to allocate memory for temporal motion vectors.");
    return kLibgav1StatusOutOfMemory;
  }

  // The addition of kMaxBlockHeight4x4 and kMaxBlockWidth4x4 is necessary so
  // that the block parameters cache can be filled in for the last row/column
  // without having to check for boundary conditions.
  BlockParametersHolder block_parameters_holder(
      obu->frame_header().rows4x4 + kMaxBlockHeight4x4,
      obu->frame_header().columns4x4 + kMaxBlockWidth4x4,
      obu->sequence_header().use_128x128_superblock);
  if (!block_parameters_holder.Init()) {
    return kLibgav1StatusOutOfMemory;
  }
  const dsp::Dsp* const dsp =
      dsp::GetDspTable(obu->sequence_header().color_config.bitdepth);
  if (dsp == nullptr) {
    LIBGAV1_DLOG(ERROR, "Failed to get the dsp table for bitdepth %d.",
                 obu->sequence_header().color_config.bitdepth);
    return kLibgav1StatusInternalError;
  }
  // If prev_segment_ids is a null pointer, it is treated as if it pointed to
  // a segmentation map containing all 0s.
  const SegmentationMap* prev_segment_ids = nullptr;
  if (obu->frame_header().primary_reference_frame == kPrimaryReferenceNone) {
    symbol_decoder_context_.Initialize(
        obu->frame_header().quantizer.base_index);
  } else {
    const int index =
        obu->frame_header()
            .reference_frame_index[obu->frame_header().primary_reference_frame];
    const RefCountedBuffer* prev_frame = state_.reference_frame[index].get();
    symbol_decoder_context_ = prev_frame->FrameContext();
    if (obu->frame_header().segmentation.enabled &&
        prev_frame->columns4x4() == obu->frame_header().columns4x4 &&
        prev_frame->rows4x4() == obu->frame_header().rows4x4) {
      prev_segment_ids = prev_frame->segmentation_map();
    }
  }

  const uint8_t tile_size_bytes = obu->frame_header().tile_info.tile_size_bytes;
  const int tile_count = obu->tile_groups().back().end + 1;
  assert(tile_count >= 1);
  Vector<std::unique_ptr<Tile>> tiles;
  if (!tiles.reserve(tile_count)) {
    LIBGAV1_DLOG(ERROR, "tiles.reserve(%d) failed.\n", tile_count);
    return kLibgav1StatusOutOfMemory;
  }
  if (!threading_strategy_.Reset(obu->frame_header(), settings_.threads)) {
    return kLibgav1StatusOutOfMemory;
  }

  if (threading_strategy_.row_thread_pool(0) != nullptr) {
    if (residual_buffer_pool_ == nullptr) {
      residual_buffer_pool_.reset(new (std::nothrow) ResidualBufferPool(
          obu->sequence_header().use_128x128_superblock,
          obu->sequence_header().color_config.subsampling_x,
          obu->sequence_header().color_config.subsampling_y,
          obu->sequence_header().color_config.bitdepth == 8 ? sizeof(int16_t)
                                                            : sizeof(int32_t)));
      if (residual_buffer_pool_ == nullptr) {
        LIBGAV1_DLOG(ERROR, "Failed to allocate residual buffer.\n");
        return kLibgav1StatusOutOfMemory;
      }
    } else {
      residual_buffer_pool_->Reset(
          obu->sequence_header().use_128x128_superblock,
          obu->sequence_header().color_config.subsampling_x,
          obu->sequence_header().color_config.subsampling_y,
          obu->sequence_header().color_config.bitdepth == 8 ? sizeof(int16_t)
                                                            : sizeof(int32_t));
    }
  }

  const bool do_cdef =
      PostFilter::DoCdef(obu->frame_header(), settings_.post_filter_mask);
  const int num_planes = obu->sequence_header().color_config.is_monochrome
                             ? kMaxPlanesMonochrome
                             : kMaxPlanes;
  const bool do_restoration =
      PostFilter::DoRestoration(obu->frame_header().loop_restoration,
                                settings_.post_filter_mask, num_planes);
  if (threading_strategy_.post_filter_thread_pool() != nullptr &&
      (do_cdef || do_restoration)) {
    const int window_buffer_width = PostFilter::GetWindowBufferWidth(
        threading_strategy_.post_filter_thread_pool(), obu->frame_header());
    size_t threaded_window_buffer_size =
        window_buffer_width *
        PostFilter::GetWindowBufferHeight(
            threading_strategy_.post_filter_thread_pool(),
            obu->frame_header()) *
        (obu->sequence_header().color_config.bitdepth == 8 ? sizeof(uint8_t)
                                                           : sizeof(uint16_t));
    if (do_cdef && !do_restoration) {
      // TODO(chengchen): for cdef U, V planes, if there's subsampling, we can
      // use smaller buffer.
      threaded_window_buffer_size *= num_planes;
    }
    if (threaded_window_buffer_size_ < threaded_window_buffer_size) {
      // threaded_window_buffer_ will be subdivided by PostFilter into windows
      // of width 512 pixels. Each row in the window is filtered by a worker
      // thread. To avoid false sharing, each 512-pixel row processed by one
      // thread should not share a cache line with a row processed by another
      // thread. So we align threaded_window_buffer_ to the cache line size.
      // In addition, it is faster to memcpy from an aligned buffer.
      //
      // On Linux, the cache line size can be looked up with the command:
      //   getconf LEVEL1_DCACHE_LINESIZE
      //
      // The cache line size should ideally be queried at run time. 64 is a
      // common cache line size of x86 CPUs. Web searches showed the cache line
      // size of ARM CPUs is 32 or 64 bytes. So aligning to 64-byte boundary
      // will work for all CPUs that we care about, even though it is excessive
      // for some ARM CPUs.
      constexpr size_t kCacheLineSize = 64;
      // To avoid false sharing, PostFilter's window width in bytes should also
      // be a multiple of the cache line size. For simplicity, we check the
      // window width in pixels.
      assert(window_buffer_width % kCacheLineSize == 0);
      threaded_window_buffer_ = MakeAlignedUniquePtr<uint8_t>(
          kCacheLineSize, threaded_window_buffer_size);
      if (threaded_window_buffer_ == nullptr) {
        LIBGAV1_DLOG(ERROR,
                     "Failed to allocate threaded loop restoration buffer.\n");
        threaded_window_buffer_size_ = 0;
        return kLibgav1StatusOutOfMemory;
      }
      threaded_window_buffer_size_ = threaded_window_buffer_size;
    }
  }

  PostFilter post_filter(
      obu->frame_header(), obu->sequence_header(), &loop_filter_mask_,
      cdef_index, &loop_restoration_info, &block_parameters_holder,
      state_.current_frame->buffer(), dsp,
      threading_strategy_.post_filter_thread_pool(),
      threaded_window_buffer_.get(), settings_.post_filter_mask);
  SymbolDecoderContext saved_symbol_decoder_context;
  int tile_index = 0;
  BlockingCounterWithStatus pending_tiles(tile_count);
  for (const auto& tile_group : obu->tile_groups()) {
    size_t bytes_left = tile_group.data_size;
    size_t byte_offset = 0;
    // The for loop in 5.11.1.
    for (int tile_number = tile_group.start; tile_number <= tile_group.end;
         ++tile_number) {
      size_t tile_size = 0;
      if (tile_number != tile_group.end) {
        RawBitReader bit_reader(tile_group.data + byte_offset, bytes_left);
        if (!bit_reader.ReadLittleEndian(tile_size_bytes, &tile_size)) {
          LIBGAV1_DLOG(ERROR, "Could not read tile size for tile #%d",
                       tile_number);
          return kLibgav1StatusBitstreamError;
        }
        ++tile_size;
        byte_offset += tile_size_bytes;
        bytes_left -= tile_size_bytes;
        if (tile_size > bytes_left) {
          LIBGAV1_DLOG(ERROR, "Invalid tile size %zu for tile #%d", tile_size,
                       tile_number);
          return kLibgav1StatusBitstreamError;
        }
      } else {
        tile_size = bytes_left;
      }

      std::unique_ptr<Tile> tile(new (std::nothrow) Tile(
          tile_number, tile_group.data + byte_offset, tile_size,
          obu->sequence_header(), obu->frame_header(),
          state_.current_frame.get(), state_.reference_frame_sign_bias,
          state_.reference_frame, &state_.motion_field_mv,
          state_.reference_order_hint, state_.wedge_masks,
          symbol_decoder_context_, &saved_symbol_decoder_context,
          prev_segment_ids, &post_filter, &block_parameters_holder, &cdef_index,
          &inter_transform_sizes_, dsp,
          threading_strategy_.row_thread_pool(tile_index++),
          residual_buffer_pool_.get(), &decoder_scratch_buffer_pool_,
          &pending_tiles));
      if (tile == nullptr) {
        LIBGAV1_DLOG(ERROR, "Failed to allocate tile.");
        return kLibgav1StatusOutOfMemory;
      }
      tiles.push_back_unchecked(std::move(tile));

      byte_offset += tile_size;
      bytes_left -= tile_size;
    }
  }
  assert(tiles.size() == static_cast<size_t>(tile_count));
  bool tile_decoding_failed = false;
  if (threading_strategy_.tile_thread_pool() == nullptr) {
    for (const auto& tile_ptr : tiles) {
      if (!tile_decoding_failed) {
        if (!tile_ptr->Decode(/*is_main_thread=*/true)) {
          LIBGAV1_DLOG(ERROR, "Error decoding tile #%d", tile_ptr->number());
          tile_decoding_failed = true;
        }
      } else {
        pending_tiles.Decrement(false);
      }
    }
  } else {
    const int num_workers = threading_strategy_.tile_thread_count();
    BlockingCounterWithStatus pending_workers(num_workers);
    std::atomic<int> tile_counter(0);
    // Submit tile decoding jobs to the thread pool.
    for (int i = 0; i < num_workers; ++i) {
      threading_strategy_.tile_thread_pool()->Schedule(
          [&tiles, tile_count, &tile_counter, &pending_workers,
           &pending_tiles]() {
            bool failed = false;
            int index;
            while ((index = tile_counter.fetch_add(
                        1, std::memory_order_relaxed)) < tile_count) {
              if (!failed) {
                const auto& tile_ptr = tiles[index];
                if (!tile_ptr->Decode(/*is_main_thread=*/false)) {
                  LIBGAV1_DLOG(ERROR, "Error decoding tile #%d",
                               tile_ptr->number());
                  failed = true;
                }
              } else {
                pending_tiles.Decrement(false);
              }
            }
            pending_workers.Decrement(!failed);
          });
    }
    // Have the current thread partake in tile decoding.
    int index;
    while ((index = tile_counter.fetch_add(1, std::memory_order_relaxed)) <
           tile_count) {
      if (!tile_decoding_failed) {
        const auto& tile_ptr = tiles[index];
        if (!tile_ptr->Decode(/*is_main_thread=*/true)) {
          LIBGAV1_DLOG(ERROR, "Error decoding tile #%d", tile_ptr->number());
          tile_decoding_failed = true;
        }
      } else {
        pending_tiles.Decrement(false);
      }
    }
    // Wait until all the workers are done. This ensures that all the tiles have
    // been parsed.
    tile_decoding_failed |= !pending_workers.Wait();
  }
  // Wait until all the tiles have been decoded.
  tile_decoding_failed |= !pending_tiles.Wait();

  // At this point, all the tiles have been parsed and decoded and the
  // threadpool will be empty.
  if (tile_decoding_failed) return kLibgav1StatusUnknownError;

  if (obu->frame_header().enable_frame_end_update_cdf) {
    symbol_decoder_context_ = saved_symbol_decoder_context;
  }
  state_.current_frame->SetFrameContext(symbol_decoder_context_);
  if (post_filter.DoDeblock()) {
    loop_filter_mask_.Build(obu->sequence_header(), obu->frame_header(),
                            obu->tile_groups().front().start,
                            obu->tile_groups().back().end,
                            block_parameters_holder, inter_transform_sizes_);
  }
  if (!post_filter.ApplyFiltering()) {
    LIBGAV1_DLOG(ERROR, "Error applying in-loop filtering.");
    return kLibgav1StatusUnknownError;
  }
  SetCurrentFrameSegmentationMap(obu->frame_header(), prev_segment_ids);
  return kLibgav1StatusOk;
}

void DecoderImpl::SetCurrentFrameSegmentationMap(
    const ObuFrameHeader& frame_header,
    const SegmentationMap* prev_segment_ids) {
  if (!frame_header.segmentation.enabled) {
    // All segment_id's are 0.
    state_.current_frame->segmentation_map()->Clear();
  } else if (!frame_header.segmentation.update_map) {
    // Copy from prev_segment_ids.
    if (prev_segment_ids == nullptr) {
      // Treat a null prev_segment_ids pointer as if it pointed to a
      // segmentation map containing all 0s.
      state_.current_frame->segmentation_map()->Clear();
    } else {
      state_.current_frame->segmentation_map()->CopyFrom(*prev_segment_ids);
    }
  }
}

void DecoderImpl::UpdateReferenceFrames(int refresh_frame_flags) {
  for (int ref_index = 0, mask = refresh_frame_flags; mask != 0;
       ++ref_index, mask >>= 1) {
    if ((mask & 1) != 0) {
      state_.reference_valid[ref_index] = true;
      state_.reference_frame_id[ref_index] = state_.current_frame_id;
      state_.reference_frame[ref_index] = state_.current_frame;
      state_.reference_order_hint[ref_index] = state_.order_hint;
    }
  }
}

}  // namespace libgav1
