// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "codec_adapter_vaapi_decoder.h"

#include <fuchsia/media/cpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/fit/defer.h>
#include <lib/media/codec_impl/fourcc.h>
#include <lib/stdcompat/span.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/assert.h>
#include <zircon/status.h>

#include <condition_variable>
#include <memory>
#include <mutex>
#include <optional>
#include <unordered_map>

#include <fbl/algorithm.h>
#include <safemath/checked_math.h>
#include <safemath/safe_conversions.h>
#include <va/va_drmcommon.h>

#include "geometry.h"
#include "h264_accelerator.h"
#include "media/gpu/h264_decoder.h"
#include "media/gpu/vp9_decoder.h"
#include "mjpeg_accelerator.h"
#include "mjpeg_decoder.h"
#include "vp9_accelerator.h"

// This class manages output buffers when the client selects a linear buffer output. Since the
// output is linear the client will have to deswizzle the output from the decoded picture buffer
// (DPB) meaning that we can't directly share the output with the client. The manager will be
// responsible for creating the DPB surfaces used by the decoder and reconstructing them when a mid
// stream configuration change is required. This buffer manager will also be responsible for copying
// the output from the DBPs to the CodecBuffers the client provides us.
class LinearBufferManager : public SurfaceBufferManager {
 public:
  LinearBufferManager(std::mutex& codec_lock, CodecFailureCallback failure_callback)
      : SurfaceBufferManager(codec_lock, std::move(failure_callback)) {}
  ~LinearBufferManager() override = default;

  void AddBuffer(const CodecBuffer* buffer) override { output_buffer_pool_.AddBuffer(buffer); }

  void RecycleBuffer(const CodecBuffer* buffer) override {
    LinearOutput local_output;
    {
      std::lock_guard<std::mutex> guard(codec_lock_);
      ZX_DEBUG_ASSERT(in_use_by_client_.find(buffer) != in_use_by_client_.end());
      local_output = std::move(in_use_by_client_[buffer]);
      in_use_by_client_.erase(buffer);
    }
    // ~ local_output, which may trigger a buffer free callback.
  }

  void DeconfigureBuffers() override {
    // First drop all the buffers that are currently in use by the client, this will return them
    // back to the ouput_buffer_pool_.
    {
      std::map<const CodecBuffer*, LinearOutput> to_drop;
      {
        std::lock_guard<std::mutex> lock(codec_lock_);
        std::swap(to_drop, in_use_by_client_);
      }
    }
    // ~to_drop

    ZX_DEBUG_ASSERT(!output_buffer_pool_.has_buffers_in_use());

    // Once all the buffers have been returned to the bool, deallocate them
    output_buffer_pool_.Reset(false);
  }

  scoped_refptr<VASurface> GetDPBSurface() override {
    uint64_t surface_generation;
    VASurfaceID surface_id;
    gfx::Size pic_size;

    {
      std::lock_guard<std::mutex> guard(surface_lock_);
      if (dpb_surfaces_.empty()) {
        return {};
      }
      surface_id = dpb_surfaces_.back().release();
      dpb_surfaces_.pop_back();
      surface_generation = surface_generation_;
      pic_size = dpb_surface_size_;
    }

    // Called once the reference count of the surface hits 0, meaning that it is no longer in use by
    // the decoder. If the surface_generation_ is the same as when the surface was created, then we
    // transfer ownership back to the |dpb_surfaces_| data structure. If however the surface
    // generation parameters have changed then we destroy the surface by calling
    // vaDestroySurfaces().
    VASurface::ReleaseCB release_cb = [this, surface_generation](VASurfaceID surface_id) {
      std::lock_guard lock(surface_lock_);
      if (surface_generation_ == surface_generation) {
        dpb_surfaces_.emplace_back(surface_id);
      } else {
        auto status =
            vaDestroySurfaces(VADisplayWrapper::GetSingleton()->display(), &surface_id, 1);

        if (status != VA_STATUS_SUCCESS) {
          FX_SLOG(WARNING, "vaDestroySurfaces failed", FX_KV("error_str", vaErrorStr(status)));
        }
      }
    };

    return std::make_shared<VASurface>(surface_id, pic_size, VA_RT_FORMAT_YUV420,
                                       std::move(release_cb));
  }

  std::optional<std::pair<const CodecBuffer*, uint32_t>> ProcessOutputSurface(
      scoped_refptr<VASurface> va_surface) override {
    const CodecBuffer* buffer = output_buffer_pool_.AllocateBuffer();

    // Check to make sure the |output_buffer_pool_| was not canceled.
    if (!buffer) {
      return std::nullopt;
    }

    // If any errors happen, release the buffer back into the pool unless canceled.
    auto release_buffer = fit::defer([&]() { output_buffer_pool_.FreeBuffer(buffer->base()); });

    // Even though there can be surfaces of varying different resolutions, we can always be
    // guaranteed that the current surface will be able to hold the current frame. And we should
    // base all calculations based on the current surface and not |dpb_surface_size_|.
    const auto& surface_size = va_surface->size();

    // Calculate the size of the Y and UV planes for the given surface. We will be populating these
    // values into various VADRMPRIMESurfaceDescriptor fields which are of type uint32_t. Ensure
    // that the values can be represented as a uint32_t
    //
    // We calculating the |aligned_stride_checked| we use the width of the current surface. The
    // picture width might be smaller, but we still need the stride of the actual surface in order
    // to calculate the correct size. For the Y and UV plane height we use |coded_picture_size_|
    // which holds the current picture size since the height is based on the current picture size
    // and the width is based on the overall surface stride.
    //
    // TODO(https://fxbug.dev/42073228): We should consider making the created surface only as big
    // as needed to hold the image generated by |coded_picture_size_| instead of the the current
    // size of the surface. This would require that we inform the client that update |bytes_per_row|
    // to reflect the current size of the smaller surface. The below method works fine, we do end up
    // create an image backed by a surface that can be larger than |coded_picture_size_| which will
    // increase the amount of time to deswizzle and copy to our VMO since we will end up copying
    // junk data in the DPB that was not a part of the current decode operation.
    auto aligned_stride_checked = safemath::MakeCheckedNum(surface_size.width()).Cast<uint32_t>();
    auto aligned_y_height = safemath::checked_cast<uint32_t>(coded_picture_size_.height());
    auto aligned_uv_height = safemath::checked_cast<uint32_t>(coded_picture_size_.height()) / 2u;
    auto y_plane_size_checked =
        safemath::CheckMul(aligned_stride_checked, aligned_y_height).Cast<uint32_t>();
    auto uv_plane_size_checked =
        safemath::CheckMul(aligned_stride_checked, aligned_uv_height).Cast<uint32_t>();
    auto total_plane_size_checked = (y_plane_size_checked + uv_plane_size_checked).Cast<uint32_t>();

    uint32_t aligned_stride, y_plane_size, total_plane_size;
    if (!aligned_stride_checked.IsValid()) {
      FX_SLOG(ERROR, "Ouput stride can not be represented as uint32_t");
      return std::nullopt;
    }
    aligned_stride = aligned_stride_checked.ValueOrDie();

    if (!y_plane_size_checked.IsValid()) {
      FX_SLOG(ERROR, "Y-Plane size can not be represented as uint32_t");
      return std::nullopt;
    }
    y_plane_size = y_plane_size_checked.ValueOrDie();

    if (!total_plane_size_checked.IsValid()) {
      FX_SLOG(ERROR, "Total plane size can not be represented as uint32_t");
      return std::nullopt;
    }
    total_plane_size = total_plane_size_checked.ValueOrDie();

    ZX_ASSERT_MSG(buffer->size() >= total_plane_size,
                  "Picture size (%u bytes) exceeds buffer size (%zu bytes)", total_plane_size,
                  buffer->size());

    zx::vmo vmo_dup;
    zx_status_t zx_status = buffer->vmo().duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo_dup);
    if (zx_status != ZX_OK) {
      FX_SLOG(ERROR, "Failed to duplicate vmo",
              FX_KV("error_str", zx_status_get_string(zx_status)));
      return std::nullopt;
    }

    // For the moment we use DRM_PRIME_2 to represent VMOs.
    // To specify the destination VMO, we need two VASurfaceAttrib, one to set the
    // VASurfaceAttribMemoryType to VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 and one for the
    // VADRMPRIMESurfaceDescriptor.
    VADRMPRIMESurfaceDescriptor ext_attrib{};
    VASurfaceAttrib attrib[2] = {
        {.type = VASurfaceAttribMemoryType,
         .flags = VA_SURFACE_ATTRIB_SETTABLE,
         .value = {.type = VAGenericValueTypeInteger,
                   .value = {.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2}}},
        {.type = VASurfaceAttribExternalBufferDescriptor,
         .flags = VA_SURFACE_ATTRIB_SETTABLE,
         .value = {.type = VAGenericValueTypePointer, .value = {.p = &ext_attrib}}},
    };

    // VADRMPRIMESurfaceDescriptor width will match the output stride instead of the coded width.
    ext_attrib.width = surface_size.width();
    ext_attrib.height = coded_picture_size_.height();
    ext_attrib.fourcc = VA_FOURCC_NV12;  // 2 plane YCbCr
    ext_attrib.num_objects = 1;
    ext_attrib.objects[0].fd = vmo_dup.release();
    ext_attrib.objects[0].drm_format_modifier = fuchsia::sysmem::FORMAT_MODIFIER_LINEAR;
    ext_attrib.objects[0].size = static_cast<uint32_t>(buffer->size());
    ext_attrib.num_layers = 1;
    ext_attrib.layers[0].drm_format = make_fourcc('N', 'V', '1', '2');
    ext_attrib.layers[0].num_planes = 2;

    // Y plane
    ext_attrib.layers[0].object_index[0] = 0;
    ext_attrib.layers[0].pitch[0] = aligned_stride;
    ext_attrib.layers[0].offset[0] = 0;

    // UV Plane
    ext_attrib.layers[0].object_index[1] = 0;
    ext_attrib.layers[0].pitch[1] = aligned_stride;
    ext_attrib.layers[0].offset[1] = y_plane_size;

    VAStatus status = vaSyncSurface(VADisplayWrapper::GetSingleton()->display(), va_surface->id());

    if (status != VA_STATUS_SUCCESS) {
      // Get more information of the error, if possible. vaQuerySurfaceError can only be called iff
      // vaSyncSurface returns VA_STATUS_ERROR_DECODING_ERROR. If that is the case then we call
      // vaQuerySurfaceError which will return an array of macroblock error structures which tells
      // us what offending macroblocks caused the error and what type of error was encountered.
      bool detailed_query = false;
      if (status == VA_STATUS_ERROR_DECODING_ERROR) {
        VASurfaceDecodeMBErrors* decode_mb_errors;
        VAStatus query_status = vaQuerySurfaceError(
            VADisplayWrapper::GetSingleton()->display(), va_surface->id(),
            VA_STATUS_ERROR_DECODING_ERROR, reinterpret_cast<void**>(&decode_mb_errors));

        if (query_status == VA_STATUS_SUCCESS) {
          detailed_query = true;
          FX_SLOG(ERROR, "SyncSurface failed due to the following macroblock errors ...");

          // Limit the amount of errors we can display, just to ensure we don't enter an infinite
          // loop or spam the log with messages
          static constexpr uint32_t kMaxMBErrors = 10u;
          uint32_t mb_error_count = 0u;

          while ((decode_mb_errors != nullptr) && (decode_mb_errors->status != -1) &&
                 (mb_error_count < kMaxMBErrors)) {
            FX_SLOG(
                ERROR, "SyncSurface a macroblock error",
                FX_KV("decode_error", (decode_mb_errors->decode_error_type == VADecodeSliceMissing)
                                          ? "VADecodeSliceMissing"
                                          : "VADecodeMBError"),
                FX_KV("start_mb", decode_mb_errors->start_mb),
                FX_KV("end_mb", decode_mb_errors->end_mb),
                FX_KV("num_mb", decode_mb_errors->num_mb));
            decode_mb_errors++;
            mb_error_count++;
          }
        }
      }

      // If the error was not VA_STATUS_ERROR_DECODING_ERROR or vaQuerySurfaceError returned an
      // error, just log a generic error message.
      if (!detailed_query) {
        FX_SLOG(ERROR, "SyncSurface failed", FX_KV("error_str", vaErrorStr(status)));
      }

      return std::nullopt;
    }

    // Create the surface backed by the destination VMO. Since we are using
    // VADRMPRIMESurfaceDescriptor, the width and height of the vaCreateSurfaces() call will be
    // overridden by |ext_attrib.width| and |ext_attrib.height|.
    VASurfaceID processed_surface_id;
    status =
        vaCreateSurfaces(VADisplayWrapper::GetSingleton()->display(), VA_RT_FORMAT_YUV420,
                         ext_attrib.width, ext_attrib.height, &processed_surface_id, 1, attrib, 2);
    if (status != VA_STATUS_SUCCESS) {
      FX_SLOG(WARNING, "vaCreateSurfaces failed", FX_KV("error_str", vaErrorStr(status)));
      return std::nullopt;
    }

    ScopedSurfaceID processed_surface(processed_surface_id);

    // Set up a VAImage for the destination VMO.
    VAImage image;
    status =
        vaDeriveImage(VADisplayWrapper::GetSingleton()->display(), processed_surface.id(), &image);
    if (status != VA_STATUS_SUCCESS) {
      FX_SLOG(WARNING, "vaDeriveImage failed", FX_KV("error_str", vaErrorStr(status)));
      return std::nullopt;
    }

    {
      ScopedImageID scoped_image(image.image_id);

      // Copy from potentially-tiled surface to output surface. Intel decoders only
      // support writing to Y-tiled textures, so this copy is necessary for linear
      // output.
      status = vaGetImage(VADisplayWrapper::GetSingleton()->display(), va_surface->id(), 0, 0,
                          surface_size.width(), coded_picture_size_.height(), scoped_image.id());
      if (status != VA_STATUS_SUCCESS) {
        FX_SLOG(WARNING, "vaGetImage failed", FX_KV("error_str", vaErrorStr(status)));
        return std::nullopt;
      }
    }
    // ~processed_surface: Clean up the image; the data was already copied to the destination VMO
    // above.

    {
      std::lock_guard<std::mutex> guard(codec_lock_);
      ZX_DEBUG_ASSERT(in_use_by_client_.count(buffer) == 0);

      in_use_by_client_.emplace(buffer, LinearOutput(buffer, this));
    }
    // ~guard

    // LinearOutput has taken ownership of the buffer.
    release_buffer.cancel();

    return std::make_pair(buffer, total_plane_size);
  }

  void Reset() override { output_buffer_pool_.Reset(true); }

  void StopAllWaits() override { output_buffer_pool_.StopAllWaits(); }

  gfx::Size GetRequiredSurfaceSize(const gfx::Size& picture_size) override {
    std::lock_guard<std::mutex> guard(surface_lock_);
    return GetRequiredSurfaceSizeLocked(picture_size);
  }

  bool NeedsKeyframeForBufferAllocation() const override { return false; }

 protected:
  gfx::Size GetRequiredSurfaceSizeLocked(const gfx::Size& picture_size) FXL_REQUIRE(surface_lock_) {
    // Given the new picture size and the current surface size, create a surface size that will
    // allow us to hold decoded picture without shrinking the dimensions of the current DPB surface.
    // Since media-driver does not allow the surfaces to become smaller, ensure that the surface
    // dimensions are always at least equal to what they were before this function call.
    uint32_t unaligned_surface_width =
        safemath::checked_cast<uint32_t>(std::max(picture_size.width(), dpb_surface_size_.width()));
    uint32_t unaligned_surface_height = safemath::checked_cast<uint32_t>(
        std::max(picture_size.height(), dpb_surface_size_.height()));

    uint32_t aligned_surface_width = fbl::round_up(
        unaligned_surface_width, CodecAdapterVaApiDecoder::kLinearSurfaceWidthAlignment);
    uint32_t aligned_surface_height = fbl::round_up(
        unaligned_surface_height, CodecAdapterVaApiDecoder::kLinearSurfaceHeightAlignment);

    return {safemath::checked_cast<int>(aligned_surface_width),
            safemath::checked_cast<int>(aligned_surface_height)};
  }

  void OnSurfaceGenerationUpdatedLocked(size_t num_of_surfaces)
      FXL_REQUIRE(surface_lock_) override {
    // Clear all existing DPB surfaces that are not currently allocated to a reference frame. Any
    // surfaces that are currently being used as a reference frame will still be allocated for as
    // long as they are held by the decoder. Once they are no longer referenced they will be
    // destroyed instead of being returned back to |dpb_surfaces_|.
    dpb_surfaces_.clear();

    // Given the new picture size and the current surface size, create a surface size that will
    // allow us to hold decoded picture without shrinking the dimensions of the current DPB surface.
    // Since media-driver does not allow the surfaces to become smaller, ensure that the surface
    // dimensions are always at least equal to what they were before this function call.
    dpb_surface_size_ = GetRequiredSurfaceSizeLocked(coded_picture_size_);
    FX_SLOG(DEBUG, "Increased DPB surface size",
            FX_KV("dpb_surface_width", dpb_surface_size_.width()),
            FX_KV("dpb_surface_height", dpb_surface_size_.height()));

    // Create the new number for requested DBP surfaces at the picture size.
    //
    // TODO(https://fxbug.dev/42073230): Consider only replacing amount of unused surfaces in
    // |dpb_surfaces_| and then allocate the replacement surfaces once the old one is destroyed.
    // This way reduce the overall memory usage but more information gathering would need to be done
    // to show that we would not need to increase the number of DPB surfaces needed todo the decode
    // operation, or we can do sysmem incremental allocation and use it here.
    VASurfaceAttrib attrib = {.type = VASurfaceAttribPixelFormat,
                              .flags = VA_SURFACE_ATTRIB_SETTABLE,
                              .value = {.type = VAGenericValueTypeInteger,
                                        .value = {.i = make_fourcc('N', 'V', '1', '2')}}};
    std::vector<VASurfaceID> va_surfaces(num_of_surfaces, VA_INVALID_SURFACE);
    VAStatus va_res =
        vaCreateSurfaces(VADisplayWrapper::GetSingleton()->display(), VA_RT_FORMAT_YUV420,
                         dpb_surface_size_.width(), dpb_surface_size_.height(), va_surfaces.data(),
                         static_cast<uint32_t>(va_surfaces.size()), &attrib, 1);

    if (va_res != VA_STATUS_SUCCESS) {
      std::ostringstream ss;
      ss << "vaCreateSurfaces failed: " << vaErrorStr(va_res);
      SetCodecFailure(ss.str());
      return;
    }

    for (VASurfaceID id : va_surfaces) {
      dpb_surfaces_.emplace_back(id);
    }
  }

 private:
  // VA-API outputs are distinct from the DPB and are stored in a regular
  // BufferPool, since the hardware doesn't necessarily support decoding to a
  // linear format like downstream consumers might need.
  class LinearOutput {
   public:
    LinearOutput() = default;
    LinearOutput(const CodecBuffer* buffer, LinearBufferManager* buffer_manager)
        : codec_buffer_(buffer), buffer_manager_(buffer_manager) {}
    ~LinearOutput() {
      if (buffer_manager_) {
        buffer_manager_->output_buffer_pool_.FreeBuffer(codec_buffer_->base());
      }
    }

    // Delete copying
    LinearOutput(const LinearOutput&) noexcept = delete;
    LinearOutput& operator=(const LinearOutput&) noexcept = delete;

    // Allow moving
    LinearOutput(LinearOutput&& other) noexcept {
      codec_buffer_ = other.codec_buffer_;
      buffer_manager_ = other.buffer_manager_;
      other.buffer_manager_ = nullptr;
    }

    LinearOutput& operator=(LinearOutput&& other) noexcept {
      codec_buffer_ = other.codec_buffer_;
      buffer_manager_ = other.buffer_manager_;
      other.buffer_manager_ = nullptr;
      return *this;
    }

   private:
    const CodecBuffer* codec_buffer_ = nullptr;
    LinearBufferManager* buffer_manager_ = nullptr;
  };

  // The order of output_buffer_pool_ and in_use_by_client_ matters, so that
  // destruction of in_use_by_client_ happens first, because those destructing
  // will return buffers to output_buffer_pool_.
  BufferPool output_buffer_pool_;
  std::map<const CodecBuffer*, LinearOutput> in_use_by_client_ FXL_GUARDED_BY(codec_lock_);

  // Holds the DPB surfaces that are allocated but not currently in use by the decoder. Once
  // GetDPBSurface() is called, the surface is then transferred from the ScopedSurfaceID RAII
  // wrapper to the a scoped_refptr<VASurface> wrapper and can not be destroyed until all references
  // of the wrapper are released.
  std::vector<ScopedSurfaceID> dpb_surfaces_ FXL_GUARDED_BY(surface_lock_) = {};
};

// This class manages output buffers when the client selects a tiled buffer output. Since the output
// is tiled the client will directly share the output from the decoded picture buffer (DPB). The
// manager will be responsible for creating the DPB surfaces that are backed by CodecBuffers the
// client provides us. The manager is also responsible for reconfiguring surfaces when a mid stream
// configuration change is required.
class TiledBufferManager : public SurfaceBufferManager {
 public:
  TiledBufferManager(std::mutex& codec_lock, CodecFailureCallback failure_callback)
      : SurfaceBufferManager(codec_lock, std::move(failure_callback)) {}
  ~TiledBufferManager() override = default;

  void AddBuffer(const CodecBuffer* buffer) override { output_buffer_pool_.AddBuffer(buffer); }

  void RecycleBuffer(const CodecBuffer* buffer) override {
    scoped_refptr<VASurface> to_drop;
    {
      std::lock_guard<std::mutex> guard(codec_lock_);
      ZX_DEBUG_ASSERT(in_use_by_client_.count(buffer) != 0);
      auto map_itr = in_use_by_client_.find(buffer);
      to_drop = std::move(map_itr->second);
      in_use_by_client_.erase(map_itr);
    }
    // ~ to_drop, which may trigger a buffer free callback if the decoder is no longer referencing
    // the frame
  }

  void DeconfigureBuffers() override {
    // Drop all references to buffers referenced by the client but keep the ones referenced by the
    // decoder
    {
      std::unordered_multimap<const CodecBuffer*, scoped_refptr<VASurface>> to_drop;
      {
        std::lock_guard<std::mutex> lock(codec_lock_);
        std::swap(to_drop, in_use_by_client_);
      }
    }
    // ~to_drop

    {
      std::lock_guard<std::mutex> guard(surface_lock_);
      allocated_free_surfaces_.clear();
    }

    ZX_DEBUG_ASSERT(!output_buffer_pool_.has_buffers_in_use());
  }

  // Getting a DPB requires that the surface is not in use by the client. This differs from the
  // linear version where DPB were not backed by a VMO. This function will block until a buffer is
  // recycled by the client or the manager is reset by the codec.
  scoped_refptr<VASurface> GetDPBSurface() override {
    const CodecBuffer* buffer = output_buffer_pool_.AllocateBuffer();

    if (!buffer) {
      return {};
    }

    // If any errors happen, release the buffer back into the pool
    auto release_buffer = fit::defer([&]() { output_buffer_pool_.FreeBuffer(buffer->base()); });

    std::lock_guard<std::mutex> guard(surface_lock_);
    VASurfaceID vmo_surface_id;

    // Check to see if there already is a surface allocated for this buffer
    auto map_itr = allocated_free_surfaces_.find(buffer);
    if (map_itr != allocated_free_surfaces_.end()) {
      vmo_surface_id = map_itr->second.release();
      allocated_free_surfaces_.erase(map_itr);
    } else {
      zx::vmo vmo_dup;
      zx_status_t zx_status = buffer->vmo().duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo_dup);
      if (zx_status != ZX_OK) {
        FX_SLOG(WARNING, "Failed to duplicate vmo",
                FX_KV("error_str", zx_status_get_string(zx_status)));
        return {};
      }

      const auto aligned_stride_checked = GetAlignedStride(dpb_surface_size_);
      const auto& [y_plane_checked, uv_plane_checked] = GetSurfacePlaneSizes(dpb_surface_size_);
      const auto pic_size_checked = (y_plane_checked + uv_plane_checked).Cast<uint32_t>();

      if (!aligned_stride_checked.IsValid()) {
        FX_SLOG(WARNING, "Aligned stride overflowed");
        return {};
      }

      if (!pic_size_checked.IsValid()) {
        FX_SLOG(WARNING, "Output picture size overflowed");
        return {};
      }

      size_t pic_size_bytes = static_cast<size_t>(pic_size_checked.ValueOrDie());
      ZX_ASSERT_MSG(buffer->size() >= pic_size_bytes,
                    "surface size (%zu bytes) exceeds buffer size (%zu bytes)", pic_size_bytes,
                    buffer->size());

      // For the moment we use DRM_PRIME_2 to represent VMOs.
      // To specify the destination VMO, we need two VASurfaceAttrib, one to set the
      // VASurfaceAttribMemoryType to VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 and one for the
      // VADRMPRIMESurfaceDescriptor.
      VADRMPRIMESurfaceDescriptor ext_attrib{};
      VASurfaceAttrib attrib[2] = {
          {.type = VASurfaceAttribMemoryType,
           .flags = VA_SURFACE_ATTRIB_SETTABLE,
           .value = {.type = VAGenericValueTypeInteger,
                     .value = {.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2}}},
          {.type = VASurfaceAttribExternalBufferDescriptor,
           .flags = VA_SURFACE_ATTRIB_SETTABLE,
           .value = {.type = VAGenericValueTypePointer, .value = {.p = &ext_attrib}}},
      };

      // VADRMPRIMESurfaceDescriptor
      ext_attrib.width = dpb_surface_size_.width();
      ext_attrib.height = dpb_surface_size_.height();
      ext_attrib.fourcc = VA_FOURCC_NV12;  // 2 plane YCbCr
      ext_attrib.num_objects = 1;
      ext_attrib.objects[0].fd = vmo_dup.release();
      ext_attrib.objects[0].drm_format_modifier =
          fuchsia::sysmem::FORMAT_MODIFIER_INTEL_I915_Y_TILED;
      ext_attrib.objects[0].size = pic_size_checked.ValueOrDie();
      ext_attrib.num_layers = 1;
      ext_attrib.layers[0].drm_format = make_fourcc('N', 'V', '1', '2');
      ext_attrib.layers[0].num_planes = 2;

      // Y plane
      ext_attrib.layers[0].object_index[0] = 0;
      ext_attrib.layers[0].pitch[0] = aligned_stride_checked.ValueOrDie();
      ext_attrib.layers[0].offset[0] = 0;

      // UV Plane
      ext_attrib.layers[0].object_index[1] = 0;
      ext_attrib.layers[0].pitch[1] = aligned_stride_checked.ValueOrDie();
      ext_attrib.layers[0].offset[1] = y_plane_checked.ValueOrDie();

      // Create one surface backed by the destination VMO.
      VAStatus status = vaCreateSurfaces(VADisplayWrapper::GetSingleton()->display(),
                                         VA_RT_FORMAT_YUV420, dpb_surface_size_.width(),
                                         dpb_surface_size_.height(), &vmo_surface_id, 1, attrib, 2);
      if (status != VA_STATUS_SUCCESS) {
        FX_SLOG(WARNING, "vaCreateSurfaces failed", FX_KV("error_str", vaErrorStr(status)));
        return {};
      }
    }

    gfx::Size dpb_surface_size = dpb_surface_size_;
    uint64_t surface_generation = surface_generation_;

    // Callback that is called when the ref_count of this new constructed surface hits 0, This
    // occurs when the surface is no longer being used in the decoder (aka a new frame has replaced
    // us) and is no longer in use by the client (surface has been removed from in_use_by_client_).
    // Therefore once the VASurface release callback is called we can return this surface (and
    // therefore the VMO backing the surface) back into the pool of available surfaces.
    VASurface::ReleaseCB release_cb = [this, buffer, surface_generation](VASurfaceID surface_id) {
      {
        std::lock_guard<std::mutex> guard(surface_lock_);
        ZX_ASSERT(surface_to_buffer_.erase(surface_id) == 1);

        if (surface_generation_ == surface_generation) {
          allocated_free_surfaces_.emplace(buffer, surface_id);
        } else {
          auto status =
              vaDestroySurfaces(VADisplayWrapper::GetSingleton()->display(), &surface_id, 1);

          if (status != VA_STATUS_SUCCESS) {
            FX_SLOG(WARNING, "vaDestroySurfaces failed", FX_KV("error_str", vaErrorStr(status)));
          }
        }
      }
      // ~guard

      output_buffer_pool_.FreeBuffer(buffer->base());
    };

    ZX_ASSERT(surface_to_buffer_.count(vmo_surface_id) == 0);
    surface_to_buffer_.emplace(vmo_surface_id, buffer);

    release_buffer.cancel();
    return std::make_shared<VASurface>(vmo_surface_id, dpb_surface_size, VA_RT_FORMAT_YUV420,
                                       std::move(release_cb));
  }

  std::optional<std::pair<const CodecBuffer*, uint32_t>> ProcessOutputSurface(
      scoped_refptr<VASurface> va_surface) override {
    VAStatus status = vaSyncSurface(VADisplayWrapper::GetSingleton()->display(), va_surface->id());
    if (status != VA_STATUS_SUCCESS) {
      FX_SLOG(ERROR, "SyncSurface failed", FX_KV("error_str", vaErrorStr(status)));
      return std::nullopt;
    }

    const CodecBuffer* buffer = nullptr;

    {
      std::lock_guard<std::mutex> guard(surface_lock_);
      ZX_DEBUG_ASSERT(surface_to_buffer_.count(va_surface->id()) != 0);
      buffer = surface_to_buffer_[va_surface->id()];
    }

    if (!buffer) {
      return {};
    }

    const auto& [y_plane_checked, uv_plane_checked] = GetSurfacePlaneSizes(va_surface->size());
    const auto pic_size_checked = (y_plane_checked + uv_plane_checked).Cast<uint32_t>();
    if (!pic_size_checked.IsValid()) {
      FX_SLOG(WARNING, "Output picture size overflowed");
      return {};
    }

    // We are about to lend out the surface to the client so store the surface in in_use_by_client_
    // multimap so it increments the refcount until the client recycles it
    {
      std::lock_guard<std::mutex> guard(codec_lock_);
      in_use_by_client_.insert(std::make_pair(buffer, va_surface));
    }

    return std::make_pair(buffer, pic_size_checked.ValueOrDie());
  }

  void Reset() override { output_buffer_pool_.Reset(true); }

  void StopAllWaits() override { output_buffer_pool_.StopAllWaits(); }

  gfx::Size GetRequiredSurfaceSize(const gfx::Size& picture_size) override {
    std::lock_guard<std::mutex> guard(surface_lock_);
    return GetRequiredSurfaceSizeLocked(picture_size);
  }

  bool NeedsKeyframeForBufferAllocation() const override { return true; }

 protected:
  gfx::Size GetRequiredSurfaceSizeLocked(const gfx::Size& picture_size) FXL_REQUIRE(surface_lock_) {
    // Given the new picture size and the current surface size, create a surface size that will
    // allow us to hold decoded picture without shrinking the dimensions of the current DPB surface.
    // Since media-driver does not allow the surfaces to become smaller, ensure that the surface
    // dimensions are always at least equal to what they were before this function call.
    uint32_t unaligned_surface_width =
        safemath::checked_cast<uint32_t>(std::max(picture_size.width(), dpb_surface_size_.width()));
    uint32_t unaligned_surface_height = safemath::checked_cast<uint32_t>(
        std::max(picture_size.height(), dpb_surface_size_.height()));

    uint32_t aligned_surface_width = fbl::round_up(
        unaligned_surface_width, CodecAdapterVaApiDecoder::kTileSurfaceWidthAlignment);
    uint32_t aligned_surface_height = fbl::round_up(
        unaligned_surface_height, CodecAdapterVaApiDecoder::kTileSurfaceHeightAlignment);

    return {safemath::checked_cast<int>(aligned_surface_width),
            safemath::checked_cast<int>(aligned_surface_height)};
  }

  void OnSurfaceGenerationUpdatedLocked(size_t num_of_surfaces)
      FXL_REQUIRE(surface_lock_) override {
    // This will call vaDestroySurface on all surfaces held by this data structure. Don't need to
    // reconstruct the surfaces here. They will be reconstructed once GetDPBSurface() is called and
    // the buffer has no linked surface.
    allocated_free_surfaces_.clear();

    // Given the new picture size and the current surface size, create a surface size that will
    // allow us to hold decoded picture without shrinking the dimensions of the current DPB surface.
    // Since media-driver does not allow the surfaces to become smaller, ensure that the surface
    // dimensions are always at least equal to what they were before this function call.
    dpb_surface_size_ = GetRequiredSurfaceSizeLocked(coded_picture_size_);
  }

 private:
  static safemath::internal::CheckedNumeric<uint32_t> GetAlignedStride(const gfx::Size& size) {
    auto aligned_stride = fbl::round_up(static_cast<uint64_t>(size.width()),
                                        CodecAdapterVaApiDecoder::kTileSurfaceWidthAlignment);
    return safemath::MakeCheckedNum(aligned_stride).Cast<uint32_t>();
  }

  static std::pair<safemath::internal::CheckedNumeric<uint32_t>,
                   safemath::internal::CheckedNumeric<uint32_t>>
  GetSurfacePlaneSizes(const gfx::Size& size) {
    // Depending on if the output is tiled or not we have to align our planes on tile boundaries
    // for both width and height
    auto aligned_stride = GetAlignedStride(size);
    auto aligned_y_height = static_cast<uint32_t>(size.height());
    auto aligned_uv_height = static_cast<uint32_t>(size.height()) / 2u;

    aligned_y_height =
        fbl::round_up(aligned_y_height, CodecAdapterVaApiDecoder::kTileSurfaceHeightAlignment);
    aligned_uv_height =
        fbl::round_up(aligned_uv_height, CodecAdapterVaApiDecoder::kTileSurfaceHeightAlignment);

    auto y_plane_size = safemath::CheckMul(aligned_stride, aligned_y_height);
    auto uv_plane_size = safemath::CheckMul(aligned_stride, aligned_uv_height);

    return std::make_pair(y_plane_size, uv_plane_size);
  }

  // Structure that maps allocated buffers shared with the client. Once the buffer is no longer in
  // use by the client and the decoder it should be removed from this map and marked as free in the
  // output_buffer_pool_.
  std::unordered_map<VASurfaceID, const CodecBuffer*> surface_to_buffer_
      FXL_GUARDED_BY(surface_lock_);

  // Once a surface is allocated it is stored in this map which maps the codec buffer that backs
  // the surface. If a resize event happens this structure will have to be invalidated and the
  // surfaces will have to be regenerated to match the new surface_size_
  std::unordered_map<const CodecBuffer*, ScopedSurfaceID> allocated_free_surfaces_
      FXL_GUARDED_BY(surface_lock_);

  // Maps the codec buffer to the VA surface being shared to the client. In addition to the
  // mapping this data structure holds a reference to the surface being used by the client,
  // preventing it from being destructed prior to it being recycled.
  // This has to be a multimap because it is possible to lend out the same surface concurrently to
  // the client and we don't want the destructor of the VASurface to be called when only one of the
  // lent out surfaces is recycled. For example on VP9 if show_existing_frame is marked true, we can
  // lend out the same surface concurrently.
  std::unordered_multimap<const CodecBuffer*, scoped_refptr<VASurface>> in_use_by_client_
      FXL_GUARDED_BY(codec_lock_);
};

void CodecAdapterVaApiDecoder::CoreCodecInit(
    const fuchsia::media::FormatDetails& initial_input_format_details) {
  if (!initial_input_format_details.has_format_details_version_ordinal()) {
    SetCodecFailure("CoreCodecInit(): Initial input format details missing version ordinal.");
    return;
  }
  // Will always be 0 for now.
  input_format_details_version_ordinal_ =
      initial_input_format_details.format_details_version_ordinal();

  const std::string& mime_type = initial_input_format_details.mime_type();
  auto maybe_media_codec = CodecTypeFromMime(mime_type);
  if (!maybe_media_codec.has_value()) {
    SetCodecFailure("CodecCodecInit(): Unknown mime_type %s\n", mime_type.c_str());
    return;
  }

  ZX_ASSERT(maybe_media_codec.has_value());
  media_codec_ = maybe_media_codec.value();

  ZX_ASSERT(media_codec_.has_value());
  ConstructDecoder();

  if (codec_diagnostics_) {
    codec_instance_diagnostics_ =
        codec_diagnostics_->CreateComponentCodec(CodecTypeName(media_codec_.value()));
  }

  VAConfigAttrib attribs[2] = {
      {.type = VAConfigAttribRTFormat, .value = VA_RT_FORMAT_YUV420},
      {.type = VAConfigAttribDecSliceMode, .value = VA_DEC_SLICE_MODE_NORMAL}};
  VAConfigID config_id;
  VAEntrypoint va_entrypoint = VAEntrypointVLD;
  VAStatus va_status;
  VAProfile va_profile;

  switch (media_codec_.value()) {
    case CodecType::kMJPEG:
      if (initial_input_format_details.has_profile() &&
          (initial_input_format_details.profile() !=
           fuchsia::media::CodecProfile::MJPEG_BASELINE)) {
        SetCodecFailure("CodecCodecInit(): MJPEG decoder only supports BASELINE profile");
        return;
      }
      va_profile = VAProfileJPEGBaseline;
      break;
    case CodecType::kH264:
      if (initial_input_format_details.has_profile() &&
          (initial_input_format_details.profile() !=
           fuchsia::media::CodecProfile::H264PROFILE_HIGH)) {
        SetCodecFailure("CodecCodecInit(): H.264 decoder only supports HIGH profile");
        return;
      }
      va_profile = VAProfileH264High;
      break;
    case CodecType::kVP9:
      if (initial_input_format_details.has_profile() &&
          (initial_input_format_details.profile() !=
           fuchsia::media::CodecProfile::VP9PROFILE_PROFILE0)) {
        SetCodecFailure("CodecCodecInit(): VP9 decoder only supports PROFILE0 profile");
        return;
      }
      va_profile = VAProfileVP9Profile0;
      break;
    default:
      SetCodecFailure("CodecCodecInit(): Unknown codec\n");
      return;
  }

  va_status = vaCreateConfig(VADisplayWrapper::GetSingleton()->display(), va_profile, va_entrypoint,
                             attribs, std::size(attribs), &config_id);
  if (va_status != VA_STATUS_SUCCESS) {
    SetCodecFailure("CodecCodecInit(): Failed to create config: %s", vaErrorStr(va_status));
    return;
  }
  config_.emplace(config_id);

  int max_config_attributes = vaMaxNumConfigAttributes(VADisplayWrapper::GetSingleton()->display());
  std::vector<VAConfigAttrib> config_attributes(max_config_attributes);

  int num_config_attributes;
  va_status = vaQueryConfigAttributes(VADisplayWrapper::GetSingleton()->display(), config_->id(),
                                      &va_profile, &va_entrypoint, config_attributes.data(),
                                      &num_config_attributes);

  if (va_status != VA_STATUS_SUCCESS) {
    SetCodecFailure("CodecCodecInit(): Failed to query attributes: %s", vaErrorStr(va_status));
    return;
  }

  std::optional<uint32_t> max_height = std::nullopt;
  std::optional<uint32_t> max_width = std::nullopt;

  for (int i = 0; i < num_config_attributes; i += 1) {
    const VAConfigAttrib& attrib = config_attributes[i];
    switch (attrib.type) {
      case VAConfigAttribMaxPictureHeight:
        max_height = attrib.value;
        break;
      case VAConfigAttribMaxPictureWidth:
        max_width = attrib.value;
        break;
      default:
        break;
    }
  }

  if (!max_height) {
    FX_SLOG(WARNING, "Could not query hardware for max picture height supported. Setting default.");
  } else {
    max_picture_height_ = max_height.value();
  }

  if (!max_width) {
    FX_SLOG(WARNING, "Could not query hardware for max picture width supported. Setting default.");
  } else {
    max_picture_width_ = max_width.value();
  }

  zx_status_t result =
      input_processing_loop_.StartThread("input_processing_thread_", &input_processing_thread_);
  if (result != ZX_OK) {
    SetCodecFailure(
        "CodecCodecInit(): Failed to start input processing thread with "
        "zx_status_t: %d",
        result);
    return;
  }
}

void CodecAdapterVaApiDecoder::CoreCodecStartStream() {
  // It's ok for RecycleInputPacket to make a packet free anywhere in this
  // sequence. Nothing else ought to be happening during CoreCodecStartStream
  // (in this or any other thread).
  input_queue_.Reset();
  free_output_packets_.Reset(/*keep_data=*/true);

  {
    std::lock_guard<std::mutex> guard(lock_);
    is_stream_stopped_ = false;
  }

  // If the stream has initialized then reset
  if (surface_buffer_manager_) {
    surface_buffer_manager_->Reset();
  }

  LaunchInputProcessingLoop();

  TRACE_INSTANT("codec_runner", "Media:Start", TRACE_SCOPE_THREAD);
}

void CodecAdapterVaApiDecoder::CoreCodecResetStreamAfterCurrentFrame() {
  // Before we reset the decoder we must ensure that ProcessInputLoop() has exited and has no
  // outstanding tasks
  WaitForInputProcessingLoopToEnd();

  // Reconstruct |media_decoder_|
  media_decoder_.reset();
  ConstructDecoder();

  input_queue_.Reset(/*keep_data=*/true);
  LaunchInputProcessingLoop();
}

void CodecAdapterVaApiDecoder::DecodeAnnexBBuffer(media::DecoderBuffer buffer) {
  media_decoder_->SetStream(next_stream_id_++, buffer);

  while (true) {
    state_ = DecoderState::kDecoding;
    auto result = media_decoder_->Decode();
    state_ = DecoderState::kIdle;

    if (result == media::AcceleratedVideoDecoder::kConfigChange) {
      gfx::Size pic_size = media_decoder_->GetPicSize();
      gfx::Rect render_size = media_decoder_->GetVisibleRect();
      std::string profile = GetProfileName(media_decoder_->GetProfile());
      FX_SLOG(INFO, "Detected a configuration change in bitstream",
              FX_KV("pic_width", pic_size.width()), FX_KV("pic_height", pic_size.height()),
              FX_KV("render_width", render_size.width()),
              FX_KV("render_height", render_size.height()), FX_KV("profile", profile.c_str()),
              FX_KV("bit_depth", media_decoder_->GetBitDepth()),
              FX_KV("required_num_pics", media_decoder_->GetRequiredNumOfPictures()),
              FX_KV("num_reference_frames", media_decoder_->GetNumReferenceFrames()));

      // We only need to request a output buffer reconfiguration if the current buffers are not able
      // to handle the new picture size. If they are able to handle the new picture size then the
      // new output format will be sent to the client and the current buffers will be kept. Since
      // linear and tiled format modifier effects how the planes are stored on the surface, the
      // surface manager is responsible for doing the calculation on how big the buffer needs to be
      // in order to store the output.
      auto output_re_config_required_result = IsBufferReconfigurationNeeded();

      if (output_re_config_required_result.is_error()) {
        SetCodecFailure(output_re_config_required_result.error_value().c_str());
        break;
      }

      ZX_ASSERT(output_re_config_required_result.is_ok());
      bool output_re_config_required = output_re_config_required_result.value();

      FX_SLOG(INFO, "Are new buffers required for bitstream change?",
              FX_KV("output_re_config_required", output_re_config_required ? "yes" : "no"));

      // TODO(https://fxbug.dev/42060469): This is a temporary workaround until the new media APIs
      // are adopted
      if (surface_buffer_manager_ &&
          (surface_buffer_manager_->NeedsKeyframeForBufferAllocation() &&
           !media_decoder_->IsCurrentFrameKeyframe() && output_re_config_required)) {
        SetCodecFailure(
            "SurfaceManager implementation does not support buffer allocation on non-keyframes");
        break;
      }

      // If buffer reconfiguration is needed, reset mid_stream_output_buffer_reconfig_finish_ since
      // we are going to block the input_processing thread until either the stream is stopped or
      // CoreCodecMidStreamOutputBufferReConfigFinish() is called.
      if (output_re_config_required) {
        std::lock_guard<std::mutex> guard(lock_);
        mid_stream_output_buffer_reconfig_finish_ = false;
      }

      if (output_re_config_required) {
        // TODO(https://fxbug.dev/42073231): Calling onCoreCodecMidStreamOutputConstraintsChange()
        // with false is now deprecated. Remove the |output_re_config_buffer| parameter.
        events_->onCoreCodecMidStreamOutputConstraintsChange(true);
      } else {
        // If an output reconfiguration was not needed, we still need to inform the client that the
        // output codec format has changed before the next output packet is sent to the client.
        events_->onCoreCodecOutputFormatChange();
      }

      if (!context_id_) {
        // vaCreateContext's |picture_width| and |picture_height| parameters are only used to ensure
        // that they are not negative and do not exceed the maximum size allowed by the hardware.
        // Once vaRenderPicture() is called with a VADecPictureParameterBuffer struct as a
        // parameter, |picture_width| and |picture_height| parameters provided to vaCreateContext()
        // will be overridden.
        VAContextID context_id;
        VAStatus va_res = vaCreateContext(VADisplayWrapper::GetSingleton()->display(),
                                          config_->id(), pic_size.width(), pic_size.height(),
                                          VA_PROGRESSIVE, nullptr, 0, &context_id);
        if (va_res != VA_STATUS_SUCCESS) {
          SetCodecFailure("vaCreateContext failed: %s", vaErrorStr(va_res));
          break;
        }
        context_id_.emplace(context_id);
      }

      // Only wait if an output reconfiguration was required since sysmem will be required to add
      // the new buffers before preceding with the stream. Otherwise the buffers will be kept and
      // the new output constraints and format will be sent.
      if (output_re_config_required) {
        // Wait for the stream reconfiguration to finish before continuing to increment the
        // surface generation value
        std::unique_lock<std::mutex> lock(lock_);
        surface_buffer_manager_cv_.wait(lock, [this]() FXL_REQUIRE(lock_) {
          return mid_stream_output_buffer_reconfig_finish_ || is_stream_stopped_;
        });

        // If the stream is stopped, exit immediately
        if (is_stream_stopped_) {
          return;
        }
      }

      // Inform |surface_buffer_manager_| of what the current picture size. It is also possible for
      // the participants of sysmem to specify more than the min buffer count required by the
      // decoder, so use the buffer_count returned for the output buffer collection.
      ZX_ASSERT(buffer_counts_[kOutputPort]);
      ZX_DEBUG_ASSERT_MSG(
          buffer_counts_[kOutputPort].value() >= media_decoder_->GetRequiredNumOfPictures(),
          "buffer_count (%u) < Required Number of Pictures (%zu)",
          buffer_counts_[kOutputPort].value(), media_decoder_->GetRequiredNumOfPictures());
      surface_buffer_manager_->UpdatePictureSize(pic_size, buffer_counts_[kOutputPort].value());

      TRACE_INSTANT("codec_runner", "Configuration Change", TRACE_SCOPE_PROCESS, "pic_width",
                    TA_INT32(pic_size.width()), "pic_height", TA_INT32(pic_size.height()));

      continue;
    } else if (result == media::AcceleratedVideoDecoder::kRanOutOfStreamData) {
      // Reset decoder failures on successful decode
      decoder_failures_ = 0;
      break;
    } else {
      decoder_failures_ += 1;
      if (decoder_failures_ >= kMaxDecoderFailures) {
        SetCodecFailure(
            "Decoder exceeded the number of allowed failures. media_decoder::Decode result: "
            "%d",
            result);
      } else {
        // We allow the decoder to fail a set amount of times, reset the decoder after the current
        // frame. We need to stop the input_queue_ from processing any further items before the
        // stream reset. The stream control thread is responsible starting the stream once is has
        // been successfully reset.
        input_queue_.StopAllWaits();
        events_->onCoreCodecResetStreamAfterCurrentFrame();
      }

      break;
    }
  }
}  // ~buffer

std::string_view CodecAdapterVaApiDecoder::CodecTypeName(CodecType codec_type) {
  switch (codec_type) {
    case CodecType::kMJPEG:
      return "MJPEG";
    case CodecType::kH264:
      return "H264";
    case CodecType::kVP9:
      return "VP9";
    default:
      FX_NOTREACHED();
  }
}

std::optional<std::string_view> CodecAdapterVaApiDecoder::CodecMimeFromType(CodecType codec_type) {
  switch (codec_type) {
    case CodecType::kMJPEG:
      return kMjpegMimeType;
    case CodecType::kH264:
      return kH264MimeType;
    case CodecType::kVP9:
      return kVp9MimeType;
    default:
      FX_NOTREACHED();
      return std::nullopt;
  }
}

std::optional<CodecAdapterVaApiDecoder::CodecType> CodecAdapterVaApiDecoder::CodecTypeFromMime(
    std::string_view mime_type) {
  if (mime_type == kMjpegMimeType) {
    return CodecType::kMJPEG;
  } else if (mime_type == kVp9MimeType) {
    return CodecType::kVP9;
  } else if (mime_type == kH264MimeType) {
    return CodecType::kH264;
  } else {
    return std::nullopt;
  }
}

const char* CodecAdapterVaApiDecoder::DecoderStateName(DecoderState state) {
  switch (state) {
    case DecoderState::kIdle:
      return "Idle";
    case DecoderState::kDecoding:
      return "Decoding";
    case DecoderState::kError:
      return "Error";
    default:
      FX_NOTREACHED();
  }
}

template <class... Args>
void CodecAdapterVaApiDecoder::SetCodecFailure(const char* format, Args&&... args) {
  state_ = DecoderState::kError;
  events_->onCoreCodecFailCodec(format, std::forward<Args>(args)...);

  // Calling |onCoreCodecFailCodec()| will result in the closing of the StreamProcessor channel.
  // This task will be posted on the stream control thread, so it is possible that the channel will
  // not immediately be closed and therefore the call to |CoreCodecStopStream()| might have a slight
  // delay. The caller is expecting |SetCodecFailure()| to prevent further processing to be done
  // since it is possible the reason why the caller is failing is because it has detected an
  // unrecoverable error and wants to stops all video decoding processing. To handle this
  // gracefully, we will stop all waits on |input_queue_|. This will exit the |ProcessInputLoop()|
  // task which will cancel all pending and future operations. While it does not prevent the
  // enqueuing of new data, the call to |CoreCodecStopStream()| will happen in the near future,
  // which will clear out any operations that were enqueued in that time.
  input_queue_.StopAllWaits();
}

void CodecAdapterVaApiDecoder::ConstructDecoder() {
  ZX_ASSERT(!static_cast<bool>(media_decoder_));
  ZX_ASSERT(media_codec_.has_value());

  switch (media_codec_.value()) {
    case CodecType::kMJPEG:
      media_decoder_ =
          std::make_unique<media::MJPEGDecoder>(std::make_unique<MJPEGAccelerator>(this));
      break;
    case CodecType::kH264:
      media_decoder_ = std::make_unique<media::H264Decoder>(std::make_unique<H264Accelerator>(this),
                                                            media::H264PROFILE_HIGH);
      break;
    case CodecType::kVP9:
      media_decoder_ = std::make_unique<media::VP9Decoder>(std::make_unique<VP9Accelerator>(this),
                                                           media::VP9PROFILE_PROFILE0);
      break;
    default:
      ZX_ASSERT(false);
      break;
  }
}

fit::result<std::string, bool> CodecAdapterVaApiDecoder::IsBufferReconfigurationNeeded() const {
  // After issuing a kConfigChange, the media decoder picture size will now reflect what size
  // the current stream needs in order to proceed
  gfx::Size pic_size = media_decoder_->GetPicSize();
  gfx::Rect visible_rect = media_decoder_->GetVisibleRect();

  uint32_t coded_width = safemath::checked_cast<uint32_t>(pic_size.width());
  uint32_t coded_height = safemath::checked_cast<uint32_t>(pic_size.height());
  uint32_t display_width = safemath::checked_cast<uint32_t>(visible_rect.width());
  uint32_t display_height = safemath::checked_cast<uint32_t>(visible_rect.height());

  // Ensure that the new picture size is within the allowed hardware requirements
  if (coded_height > max_picture_height_) {
    FX_SLOG(ERROR, "coded_height exceeds max_picture_height_", FX_KV("coded_height", coded_height),
            FX_KV("max_picture_height_", max_picture_height_));
    std::ostringstream oss;
    oss << "Requested picture height " << coded_height
        << " exceeds max hardware supported height of " << max_picture_height_;
    return fit::error(oss.str());
  }
  if (coded_width > max_picture_width_) {
    FX_SLOG(ERROR, "coded_width exceeds max_picture_width_", FX_KV("coded_width", coded_width),
            FX_KV("max_picture_width_", max_picture_width_));
    std::ostringstream oss;
    oss << "Requested picture width " << coded_width << " exceeds max hardware supported width of "
        << max_picture_width_;
    return fit::error(oss.str());
  }

  // Ensure that we have buffers already configured, if not then a reconfiguration is always needed
  if (!surface_buffer_manager_ || !buffer_settings_[kOutputPort].has_value()) {
    return fit::ok(true);
  }

  ZX_ASSERT(buffer_settings_[kOutputPort]->image_format_constraints().has_value());
  auto surface_size = surface_buffer_manager_->GetRequiredSurfaceSize(pic_size);

  // TODO(https://fxbug.dev/42073232): This isn't the correct calculation as it does not factor in
  // alignment for tiled surfaces
  auto total_plane_size_checked =
      ((safemath::MakeCheckedNum(surface_size.GetArea()) * 3) / 2).Cast<uint32_t>();

  // The check above should ensure that we never get to an unsupported hardware size, but
  // better safe than sorry when calling ValueOrDie()
  if (!total_plane_size_checked.IsValid()) {
    FX_SLOG(ERROR, "Surface size exceeds the max hardware supported size");
    return fit::error("Surface size exceeds the max hardware supported size");
  }
  uint32_t total_plane_size = total_plane_size_checked.ValueOrDie();

  // Ensure the size of the buffers can hold the new plane size
  if (total_plane_size > *buffer_settings_[kOutputPort]->buffer_settings()->size_bytes()) {
    FX_SLOG(DEBUG, "total_plane_size > buffer_size_bytes",
            FX_KV("total_plane_size", total_plane_size),
            FX_KV("buffer_size_bytes",
                  *buffer_settings_[kOutputPort]->buffer_settings()->size_bytes()));
    return fit::ok(true);
  }

  const auto& image_constraints = *buffer_settings_[kOutputPort]->image_format_constraints();

  if (display_width % image_constraints.display_rect_alignment()->width() != 0u) {
    FX_SLOG(DEBUG, "display_width not divisible by display_width_divisor",
            FX_KV("display_width", display_width),
            FX_KV("display_width_divisor", image_constraints.display_rect_alignment()->width()));
    // These will fail, but let them fail when trying to re-negotiate sysmem buffers.
    return fit::ok(true);
  }

  if (display_height % image_constraints.display_rect_alignment()->height() != 0u) {
    FX_SLOG(DEBUG, "display_height not divisible by display_height_divisor",
            FX_KV("display_height", display_height),
            FX_KV("display_height_divisor", image_constraints.display_rect_alignment()->height()));
    // These will fail, but let them fail when trying to re-negotiate sysmem buffers.
    return fit::ok(true);
  }

  auto coded_area_checked = safemath::CheckMul(coded_width, coded_height).Cast<uint32_t>();
  if (!coded_area_checked.IsValid()) {
    FX_SLOG(ERROR, "Surface size exceeds uint32_t", FX_KV("coded_width", coded_width),
            FX_KV("coded_height", coded_height));
    return fit::error("Surface size exceeds uint32_t");
  }
  uint32_t coded_area = coded_area_checked.ValueOrDie();
  if (coded_area > *image_constraints.max_width_times_height()) {
    FX_SLOG(
        DEBUG, "coded_area > max_coded_width_times_coded_height", FX_KV("coded_area", coded_area),
        FX_KV("max_coded_width_times_coded_height", *image_constraints.max_width_times_height()));
    // These will very likely fail, but let them fail when trying to re-negotiate sysmem buffers.
    return fit::ok(true);
  }

  if (coded_width % image_constraints.size_alignment()->width() != 0u) {
    FX_SLOG(DEBUG, "coded_width not divisible by coded_width_divisor",
            FX_KV("coded_width", coded_width),
            FX_KV("coded_width_divisor", image_constraints.size_alignment()->width()));
    // These will fail, but let them fail when trying to re-negotiate sysmem buffers.
    return fit::ok(true);
  }

  if (coded_height % image_constraints.size_alignment()->height() != 0u) {
    FX_SLOG(DEBUG, "coded_height not divisible by coded_height_divisor",
            FX_KV("coded_height", coded_height),
            FX_KV("coded_height_divisor", image_constraints.size_alignment()->height()));
    // These will fail, but let them fail when trying to re-negotiate sysmem buffers.
    return fit::ok(true);
  }

  if (coded_width < image_constraints.min_size()->width()) {
    FX_SLOG(DEBUG, "coded_width < min_coded_width", FX_KV("coded_width", coded_width),
            FX_KV("min_coded_width", image_constraints.min_size()->width()));
    return fit::ok(true);
  }

  if (coded_width > image_constraints.max_size()->width()) {
    FX_SLOG(DEBUG, "coded_width > max_coded_width", FX_KV("coded_width", coded_width),
            FX_KV("max_coded_width", image_constraints.max_size()->width()));
    return fit::ok(true);
  }

  if (coded_height < image_constraints.min_size()->height()) {
    FX_SLOG(DEBUG, "coded_height < min_coded_height", FX_KV("coded_height", coded_height),
            FX_KV("min_coded_height", image_constraints.min_size()->height()));
    return fit::ok(true);
  }

  if (coded_height > image_constraints.max_size()->height()) {
    FX_SLOG(DEBUG, "coded_height > max_coded_height", FX_KV("coded_height", coded_height),
            FX_KV("max_coded_height", image_constraints.max_size()->height()));
    return fit::ok(true);
  }

  uint32_t stride = safemath::checked_cast<uint32_t>(surface_size.width());
  if (stride < *image_constraints.min_bytes_per_row()) {
    FX_SLOG(DEBUG, "stride < min_bytes_per_row", FX_KV("stride", stride),
            FX_KV("min_bytes_per_row", *image_constraints.min_bytes_per_row()));
    return fit::ok(true);
  }

  if (stride > *image_constraints.max_bytes_per_row()) {
    FX_SLOG(DEBUG, "stride > max_bytes_per_row", FX_KV("stride", stride),
            FX_KV("max_bytes_per_row", *image_constraints.max_bytes_per_row()));
    return fit::ok(true);
  }

  // This check only makes sense if the output is linear since tiled formats don't really have a
  // concept of bytes per row divisor
  if (!IsOutputTiled()) {
    if (stride % *image_constraints.bytes_per_row_divisor() != 0u) {
      FX_SLOG(DEBUG, "stride not divisible by bytes_per_row_divisor", FX_KV("stride", stride),
              FX_KV("bytes_per_row_divisor", *image_constraints.bytes_per_row_divisor()));
      // These will fail, but let them fail when trying to re-negotiate sysmem buffers.
      return fit::ok(true);
    }
  }

  // The current buffers meet all conditions, output reconfiguration is not needed
  return fit::ok(false);
}

void CodecAdapterVaApiDecoder::ProcessInputLoop() {
  std::optional<CodecInputItem> maybe_input_item;
  while ((maybe_input_item = input_queue_.WaitForElement())) {
    CodecInputItem input_item = std::move(maybe_input_item.value());
    if (input_item.is_format_details()) {
      ZX_ASSERT(media_codec_.has_value());
      const std::string& mime_type = input_item.format_details().mime_type();
      const auto allow_mime_type = CodecMimeFromType(media_codec_.value());
      if (!allow_mime_type.has_value() || (allow_mime_type.value() != mime_type)) {
        SetCodecFailure(
            "CodecCodecInit(): Can not switch codec type after setting it in CoreCodecInit(). "
            "Attempting to switch it to %s\n",
            mime_type.c_str());
        return;
      }

      if (media_codec_.value() == CodecType::kH264) {
        avcc_processor_.ProcessOobBytes(input_item.format_details());
      }
    } else if (input_item.is_end_of_stream()) {
      ZX_ASSERT(media_codec_.has_value());
      if (media_codec_.value() == CodecType::kH264) {
        constexpr uint8_t kEndOfStreamNalUnitType = 11;
        // Force frames to be processed.
        std::vector<uint8_t> end_of_stream_delimiter{0, 0, 1, kEndOfStreamNalUnitType};

        media::DecoderBuffer buffer(end_of_stream_delimiter);
        media_decoder_->SetStream(next_stream_id_++, buffer);
        state_ = DecoderState::kDecoding;
        auto result = media_decoder_->Decode();
        state_ = DecoderState::kIdle;
        if (result != media::AcceleratedVideoDecoder::kRanOutOfStreamData) {
          SetCodecFailure("Unexpected media_decoder::Decode result for end of stream: %d", result);
          return;
        }
      }

      bool res = media_decoder_->Flush();
      if (!res) {
        FX_SLOG(WARNING, "media decoder flush failed");
      }
      events_->onCoreCodecOutputEndOfStream(/*error_detected_before=*/!res);
    } else if (input_item.is_packet()) {
      auto* packet = input_item.packet();
      ZX_DEBUG_ASSERT(packet->has_start_offset());
      if (packet->has_timestamp_ish()) {
        stream_to_pts_map_.emplace_back(next_stream_id_, packet->timestamp_ish());
        constexpr size_t kMaxPtsMapSize = 64;
        if (stream_to_pts_map_.size() > kMaxPtsMapSize)
          stream_to_pts_map_.pop_front();
      }

      const uint8_t* buffer_start = packet->buffer()->base() + packet->start_offset();
      size_t buffer_size = packet->valid_length_bytes();

      bool returned_buffer = false;
      auto return_input_packet =
          fit::defer_callback(fit::closure([this, &input_item, &returned_buffer] {
            events_->onCoreCodecInputPacketDone(input_item.packet());
            returned_buffer = true;
          }));

      ZX_ASSERT(media_codec_.has_value());
      if ((media_codec_.value() == CodecType::kH264) && avcc_processor_.is_avcc()) {
        // TODO(https://fxbug.dev/42176001): Remove this copy.
        auto output_avcc_vec = avcc_processor_.ParseVideoAvcc(buffer_start, buffer_size);
        media::DecoderBuffer buffer(output_avcc_vec, packet->buffer(), packet->start_offset(),
                                    std::move(return_input_packet));
        DecodeAnnexBBuffer(std::move(buffer));
      } else {
        media::DecoderBuffer buffer({buffer_start, buffer_size}, packet->buffer(),
                                    packet->start_offset(), std::move(return_input_packet));
        DecodeAnnexBBuffer(std::move(buffer));
      }

      // Ensure that the decode buffer has been destroyed and the input packet has been returned
      ZX_ASSERT(returned_buffer);

      if (media_codec_.value() == CodecType::kH264) {
        constexpr uint8_t kAccessUnitDelimiterNalUnitType = 9;
        constexpr uint8_t kPrimaryPicType = 1 << (7 - 3);
        // Force frames to be processed. TODO(https://fxbug.dev/42073233): Key on
        // known_end_access_unit.
        std::vector<uint8_t> access_unit_delimiter{0, 0, 1, kAccessUnitDelimiterNalUnitType,
                                                   kPrimaryPicType};

        media::DecoderBuffer buffer(access_unit_delimiter);
        media_decoder_->SetStream(next_stream_id_++, buffer);
        state_ = DecoderState::kDecoding;
        auto result = media_decoder_->Decode();
        state_ = DecoderState::kIdle;
        if (result != media::AcceleratedVideoDecoder::kRanOutOfStreamData) {
          SetCodecFailure("Unexpected media_decoder::Decode result for delimiter: %d", result);
          return;
        }
      }
    }
  }
}

void CodecAdapterVaApiDecoder::CleanUpAfterStream() {
  ZX_ASSERT(media_codec_.has_value());
  if (media_codec_.value() == CodecType::kH264) {
    // Force frames to be processed.
    std::vector<uint8_t> end_of_stream_delimiter{0, 0, 1, 11};

    media::DecoderBuffer buffer(end_of_stream_delimiter);
    media_decoder_->SetStream(next_stream_id_++, buffer);
    auto result = media_decoder_->Decode();
    if (result != media::AcceleratedVideoDecoder::kRanOutOfStreamData) {
      SetCodecFailure("Unexpected media_decoder::Decode result for end of stream: %d", result);
      return;
    }
  }

  bool res = media_decoder_->Flush();
  if (!res) {
    FX_SLOG(WARNING, "media decoder flush failed");
  }

  // Given that there are no more operations pending on this stream, we should reset the media
  // decoder. This will also release any DPB surfaces under the decoder's ownership. This is
  // specifically useful for the tiling case since the decoder references surfaces that are backed
  // by buffers from sysmem. |CodecImpl| can call |CoreCodecEnsureBuffersNotConfigured()| for
  // the output buffers and will expect that since |CoreCodecStopStream()| was called the buffers
  // can be deconfigured.
  media_decoder_.reset();
  ConstructDecoder();
}

void CodecAdapterVaApiDecoder::CoreCodecMidStreamOutputBufferReConfigFinish() {
  // Currently once the surface_buffer_manager_ has been constructed, it can not be destructed until
  // the end of the stream. This means once the client have chosen a format modifier, it can not be
  // changed
  if (!surface_buffer_manager_) {
    auto failure_callback = SurfaceBufferManager::CodecFailureCallback(
        [this](const std::string& failure_message) { SetCodecFailure(failure_message.c_str()); });

    if (IsOutputTiled()) {
      surface_buffer_manager_ =
          std::make_unique<TiledBufferManager>(lock_, std::move(failure_callback));
    } else {
      surface_buffer_manager_ =
          std::make_unique<LinearBufferManager>(lock_, std::move(failure_callback));
    }
  }

  LoadStagedOutputBuffers();

  // Signal that we are done with the mid stream output buffer configuration to other threads
  {
    std::lock_guard<std::mutex> guard(lock_);
    mid_stream_output_buffer_reconfig_finish_ = true;
    surface_buffer_manager_cv_.notify_all();
  }
}

bool CodecAdapterVaApiDecoder::ProcessOutput(scoped_refptr<VASurface> va_surface,
                                             int bitstream_id) {
  auto maybe_processed_surface =
      surface_buffer_manager_->ProcessOutputSurface(std::move(va_surface));

  if (!maybe_processed_surface) {
    return true;
  }

  auto& [codec_buffer, pic_size_bytes] = maybe_processed_surface.value();

  auto release_buffer = fit::defer([this, codec_buffer = codec_buffer]() {
    surface_buffer_manager_->RecycleBuffer(codec_buffer);
  });

  std::optional<CodecPacket*> maybe_output_packet = free_output_packets_.WaitForElement();
  if (!maybe_output_packet) {
    // Wait will succeed unless we're dropping all remaining frames of a stream.
    return true;
  }

  auto output_packet = maybe_output_packet.value();
  output_packet->SetBuffer(codec_buffer);
  output_packet->SetStartOffset(0);
  output_packet->SetValidLengthBytes(pic_size_bytes);
  {
    auto pts_it =
        std::find_if(stream_to_pts_map_.begin(), stream_to_pts_map_.end(),
                     [bitstream_id](const auto& pair) { return pair.first == bitstream_id; });
    if (pts_it != stream_to_pts_map_.end()) {
      output_packet->SetTimstampIsh(pts_it->second);
    } else {
      output_packet->ClearTimestampIsh();
    }
  }

  release_buffer.cancel();
  events_->onCoreCodecOutputPacket(output_packet,
                                   /*error_detected_before=*/false,
                                   /*error_detected_during=*/false);
  return true;
}

scoped_refptr<VASurface> CodecAdapterVaApiDecoder::GetVASurface() {
  return surface_buffer_manager_->GetDPBSurface();
}
