// services/video_capture/public/mojom/video_frame_handler.mojom.cc is auto generated by mojom_bindings_generator.py, do not edit

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

#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
#endif

#include "services/video_capture/public/mojom/video_frame_handler.mojom.h"

#include <math.h>
#include <stdint.h>
#include <utility>

#include "base/debug/alias.h"
#include "base/hash/md5_constexpr.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/typed_macros.h"
#include "mojo/public/cpp/bindings/lib/generated_code_util.h"
#include "mojo/public/cpp/bindings/lib/message_internal.h"
#include "mojo/public/cpp/bindings/lib/send_message_helper.h"
#include "mojo/public/cpp/bindings/lib/proxy_to_responder.h"
#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/cpp/bindings/lib/unserialized_message_context.h"
#include "mojo/public/cpp/bindings/lib/validate_params.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/cpp/bindings/mojo_buildflags.h"
#include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"

#include "services/video_capture/public/mojom/video_frame_handler.mojom-params-data.h"
#include "services/video_capture/public/mojom/video_frame_handler.mojom-shared-message-ids.h"

#include "services/video_capture/public/mojom/video_frame_handler.mojom-import-headers.h"
#include "services/video_capture/public/mojom/video_frame_handler.mojom-test-utils.h"


#ifndef SERVICES_VIDEO_CAPTURE_PUBLIC_MOJOM_VIDEO_FRAME_HANDLER_MOJOM_JUMBO_H_
#define SERVICES_VIDEO_CAPTURE_PUBLIC_MOJOM_VIDEO_FRAME_HANDLER_MOJOM_JUMBO_H_
#endif



namespace video_capture {
namespace mojom {
ReadyFrameInBuffer::ReadyFrameInBuffer()
    : buffer_id(),
      frame_feedback_id(),
      frame_info() {}

ReadyFrameInBuffer::ReadyFrameInBuffer(
    int32_t buffer_id_in,
    int32_t frame_feedback_id_in,
    ::media::mojom::VideoFrameInfoPtr frame_info_in)
    : buffer_id(std::move(buffer_id_in)),
      frame_feedback_id(std::move(frame_feedback_id_in)),
      frame_info(std::move(frame_info_in)) {}

ReadyFrameInBuffer::~ReadyFrameInBuffer() = default;

void ReadyFrameInBuffer::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "buffer_id"), this->buffer_id,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type int32_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "frame_feedback_id"), this->frame_feedback_id,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type int32_t>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "frame_info"), this->frame_info,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type ::media::mojom::VideoFrameInfoPtr>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool ReadyFrameInBuffer::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
const char VideoFrameAccessHandler::Name_[] = "video_capture.mojom.VideoFrameAccessHandler";

std::pair<uint32_t, const void*> VideoFrameAccessHandler::MessageToMethodInfo_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kVideoFrameAccessHandler_OnFinishedConsumingBuffer_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameAccessHandler::OnFinishedConsumingBuffer");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameAccessHandler::OnFinishedConsumingBuffer_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
  }
  return std::make_pair(0, nullptr);
}


const char* VideoFrameAccessHandler::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (!is_response) {
    switch (message.name()) {
      case internal::kVideoFrameAccessHandler_OnFinishedConsumingBuffer_Name:
            return "Receive video_capture::mojom::VideoFrameAccessHandler::OnFinishedConsumingBuffer";
    }
  } else {
    switch (message.name()) {
      case internal::kVideoFrameAccessHandler_OnFinishedConsumingBuffer_Name:
            return "Receive reply video_capture::mojom::VideoFrameAccessHandler::OnFinishedConsumingBuffer";
    }
  }
  return "Receive unknown mojo message";
#else
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (is_response) {
    return "Receive mojo reply";
  } else {
    return "Receive mojo message";
  }
#endif // BUILDFLAG(MOJO_TRACE_ENABLED)
}

#if !BUILDFLAG(IS_FUCHSIA)
void VideoFrameAccessHandler::OnFinishedConsumingBuffer_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
# endif // !BUILDFLAG(IS_FUCHSIA)

VideoFrameAccessHandlerProxy::VideoFrameAccessHandlerProxy(mojo::MessageReceiverWithResponder* receiver)
    : receiver_(receiver) {
}

void VideoFrameAccessHandlerProxy::OnFinishedConsumingBuffer(
    int32_t in_buffer_id) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send video_capture::mojom::VideoFrameAccessHandler::OnFinishedConsumingBuffer", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("buffer_id"), in_buffer_id,
                        "<value of type int32_t>");
   });
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameAccessHandler_OnFinishedConsumingBuffer_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameAccessHandler_OnFinishedConsumingBuffer_Params_Data> params(
          message);
  params.Allocate();
  params->buffer_id = in_buffer_id;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameAccessHandler::Name_);
  message.set_method_name("OnFinishedConsumingBuffer");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

// static
bool VideoFrameAccessHandlerStubDispatch::Accept(
    VideoFrameAccessHandler* impl,
    mojo::Message* message) {
  switch (message->header()->name) {
    case internal::kVideoFrameAccessHandler_OnFinishedConsumingBuffer_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameAccessHandler_OnFinishedConsumingBuffer_Params_Data* params =
          reinterpret_cast<internal::VideoFrameAccessHandler_OnFinishedConsumingBuffer_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      int32_t p_buffer_id{};
      VideoFrameAccessHandler_OnFinishedConsumingBuffer_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_buffer_id = input_data_view.buffer_id();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameAccessHandler::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnFinishedConsumingBuffer(
std::move(p_buffer_id));
      return true;
    }
  }
  return false;
}

// static
bool VideoFrameAccessHandlerStubDispatch::AcceptWithResponder(
    VideoFrameAccessHandler* impl,
    mojo::Message* message,
    std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
  [[maybe_unused]] const bool message_is_sync =
      message->has_flag(mojo::Message::kFlagIsSync);
  [[maybe_unused]] const uint64_t request_id = message->request_id();
  switch (message->header()->name) {
    case internal::kVideoFrameAccessHandler_OnFinishedConsumingBuffer_Name: {
      break;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kVideoFrameAccessHandlerValidationInfo[] = {
    {&internal::VideoFrameAccessHandler_OnFinishedConsumingBuffer_Params_Data::Validate,
     nullptr /* no response */},
};

bool VideoFrameAccessHandlerRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::video_capture::mojom::VideoFrameAccessHandler::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kVideoFrameAccessHandlerValidationInfo);
}

const char VideoFrameHandler::Name_[] = "video_capture.mojom.VideoFrameHandler";

std::pair<uint32_t, const void*> VideoFrameHandler::MessageToMethodInfo_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kVideoFrameHandler_OnNewBuffer_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameHandler::OnNewBuffer");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameHandler::OnNewBuffer_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kVideoFrameHandler_OnFrameAccessHandlerReady_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameHandler::OnFrameAccessHandlerReady");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameHandler::OnFrameAccessHandlerReady_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kVideoFrameHandler_OnFrameReadyInBuffer_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameHandler::OnFrameReadyInBuffer");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameHandler::OnFrameReadyInBuffer_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kVideoFrameHandler_OnBufferRetired_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameHandler::OnBufferRetired");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameHandler::OnBufferRetired_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kVideoFrameHandler_OnError_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameHandler::OnError");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameHandler::OnError_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kVideoFrameHandler_OnFrameDropped_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameHandler::OnFrameDropped");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameHandler::OnFrameDropped_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kVideoFrameHandler_OnNewCropVersion_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameHandler::OnNewCropVersion");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameHandler::OnNewCropVersion_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kVideoFrameHandler_OnFrameWithEmptyRegionCapture_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameHandler::OnFrameWithEmptyRegionCapture");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameHandler::OnFrameWithEmptyRegionCapture_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kVideoFrameHandler_OnLog_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameHandler::OnLog");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameHandler::OnLog_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kVideoFrameHandler_OnStarted_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameHandler::OnStarted");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameHandler::OnStarted_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kVideoFrameHandler_OnStartedUsingGpuDecode_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameHandler::OnStartedUsingGpuDecode");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameHandler::OnStartedUsingGpuDecode_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kVideoFrameHandler_OnStopped_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)video_capture::mojom::VideoFrameHandler::OnStopped");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&VideoFrameHandler::OnStopped_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
  }
  return std::make_pair(0, nullptr);
}


const char* VideoFrameHandler::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (!is_response) {
    switch (message.name()) {
      case internal::kVideoFrameHandler_OnNewBuffer_Name:
            return "Receive video_capture::mojom::VideoFrameHandler::OnNewBuffer";
      case internal::kVideoFrameHandler_OnFrameAccessHandlerReady_Name:
            return "Receive video_capture::mojom::VideoFrameHandler::OnFrameAccessHandlerReady";
      case internal::kVideoFrameHandler_OnFrameReadyInBuffer_Name:
            return "Receive video_capture::mojom::VideoFrameHandler::OnFrameReadyInBuffer";
      case internal::kVideoFrameHandler_OnBufferRetired_Name:
            return "Receive video_capture::mojom::VideoFrameHandler::OnBufferRetired";
      case internal::kVideoFrameHandler_OnError_Name:
            return "Receive video_capture::mojom::VideoFrameHandler::OnError";
      case internal::kVideoFrameHandler_OnFrameDropped_Name:
            return "Receive video_capture::mojom::VideoFrameHandler::OnFrameDropped";
      case internal::kVideoFrameHandler_OnNewCropVersion_Name:
            return "Receive video_capture::mojom::VideoFrameHandler::OnNewCropVersion";
      case internal::kVideoFrameHandler_OnFrameWithEmptyRegionCapture_Name:
            return "Receive video_capture::mojom::VideoFrameHandler::OnFrameWithEmptyRegionCapture";
      case internal::kVideoFrameHandler_OnLog_Name:
            return "Receive video_capture::mojom::VideoFrameHandler::OnLog";
      case internal::kVideoFrameHandler_OnStarted_Name:
            return "Receive video_capture::mojom::VideoFrameHandler::OnStarted";
      case internal::kVideoFrameHandler_OnStartedUsingGpuDecode_Name:
            return "Receive video_capture::mojom::VideoFrameHandler::OnStartedUsingGpuDecode";
      case internal::kVideoFrameHandler_OnStopped_Name:
            return "Receive video_capture::mojom::VideoFrameHandler::OnStopped";
    }
  } else {
    switch (message.name()) {
      case internal::kVideoFrameHandler_OnNewBuffer_Name:
            return "Receive reply video_capture::mojom::VideoFrameHandler::OnNewBuffer";
      case internal::kVideoFrameHandler_OnFrameAccessHandlerReady_Name:
            return "Receive reply video_capture::mojom::VideoFrameHandler::OnFrameAccessHandlerReady";
      case internal::kVideoFrameHandler_OnFrameReadyInBuffer_Name:
            return "Receive reply video_capture::mojom::VideoFrameHandler::OnFrameReadyInBuffer";
      case internal::kVideoFrameHandler_OnBufferRetired_Name:
            return "Receive reply video_capture::mojom::VideoFrameHandler::OnBufferRetired";
      case internal::kVideoFrameHandler_OnError_Name:
            return "Receive reply video_capture::mojom::VideoFrameHandler::OnError";
      case internal::kVideoFrameHandler_OnFrameDropped_Name:
            return "Receive reply video_capture::mojom::VideoFrameHandler::OnFrameDropped";
      case internal::kVideoFrameHandler_OnNewCropVersion_Name:
            return "Receive reply video_capture::mojom::VideoFrameHandler::OnNewCropVersion";
      case internal::kVideoFrameHandler_OnFrameWithEmptyRegionCapture_Name:
            return "Receive reply video_capture::mojom::VideoFrameHandler::OnFrameWithEmptyRegionCapture";
      case internal::kVideoFrameHandler_OnLog_Name:
            return "Receive reply video_capture::mojom::VideoFrameHandler::OnLog";
      case internal::kVideoFrameHandler_OnStarted_Name:
            return "Receive reply video_capture::mojom::VideoFrameHandler::OnStarted";
      case internal::kVideoFrameHandler_OnStartedUsingGpuDecode_Name:
            return "Receive reply video_capture::mojom::VideoFrameHandler::OnStartedUsingGpuDecode";
      case internal::kVideoFrameHandler_OnStopped_Name:
            return "Receive reply video_capture::mojom::VideoFrameHandler::OnStopped";
    }
  }
  return "Receive unknown mojo message";
#else
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (is_response) {
    return "Receive mojo reply";
  } else {
    return "Receive mojo message";
  }
#endif // BUILDFLAG(MOJO_TRACE_ENABLED)
}

#if !BUILDFLAG(IS_FUCHSIA)
void VideoFrameHandler::OnNewBuffer_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void VideoFrameHandler::OnFrameAccessHandlerReady_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void VideoFrameHandler::OnFrameReadyInBuffer_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void VideoFrameHandler::OnBufferRetired_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void VideoFrameHandler::OnError_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void VideoFrameHandler::OnFrameDropped_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void VideoFrameHandler::OnNewCropVersion_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void VideoFrameHandler::OnFrameWithEmptyRegionCapture_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void VideoFrameHandler::OnLog_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void VideoFrameHandler::OnStarted_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void VideoFrameHandler::OnStartedUsingGpuDecode_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void VideoFrameHandler::OnStopped_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
# endif // !BUILDFLAG(IS_FUCHSIA)

VideoFrameHandlerProxy::VideoFrameHandlerProxy(mojo::MessageReceiverWithResponder* receiver)
    : receiver_(receiver) {
}

void VideoFrameHandlerProxy::OnNewBuffer(
    int32_t in_buffer_id, ::media::mojom::VideoBufferHandlePtr in_buffer_handle) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send video_capture::mojom::VideoFrameHandler::OnNewBuffer", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("buffer_id"), in_buffer_id,
                        "<value of type int32_t>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("buffer_handle"), in_buffer_handle,
                        "<value of type ::media::mojom::VideoBufferHandlePtr>");
   });
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameHandler_OnNewBuffer_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameHandler_OnNewBuffer_Params_Data> params(
          message);
  params.Allocate();
  params->buffer_id = in_buffer_id;
  mojo::internal::MessageFragment<decltype(params->buffer_handle)>
      buffer_handle_fragment(params.message());
  buffer_handle_fragment.Claim(&params->buffer_handle);
  mojo::internal::Serialize<::media::mojom::VideoBufferHandleDataView>(
      in_buffer_handle, buffer_handle_fragment, true);
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->buffer_handle.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null buffer_handle in VideoFrameHandler.OnNewBuffer request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameHandler::Name_);
  message.set_method_name("OnNewBuffer");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void VideoFrameHandlerProxy::OnFrameAccessHandlerReady(
    ::mojo::PendingRemote<VideoFrameAccessHandler> in_frame_access_handler) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send video_capture::mojom::VideoFrameHandler::OnFrameAccessHandlerReady", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("frame_access_handler"), in_frame_access_handler,
                        "<value of type ::mojo::PendingRemote<VideoFrameAccessHandler>>");
   });
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameHandler_OnFrameAccessHandlerReady_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameHandler_OnFrameAccessHandlerReady_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<mojo::InterfacePtrDataView<::video_capture::mojom::VideoFrameAccessHandlerInterfaceBase>>(
      in_frame_access_handler, &params->frame_access_handler, &params.message());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      !mojo::internal::IsHandleOrInterfaceValid(params->frame_access_handler),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
      "invalid frame_access_handler in VideoFrameHandler.OnFrameAccessHandlerReady request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameHandler::Name_);
  message.set_method_name("OnFrameAccessHandlerReady");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void VideoFrameHandlerProxy::OnFrameReadyInBuffer(
    ReadyFrameInBufferPtr in_buffer, std::vector<ReadyFrameInBufferPtr> in_scaled_buffers) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send video_capture::mojom::VideoFrameHandler::OnFrameReadyInBuffer", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("buffer"), in_buffer,
                        "<value of type ReadyFrameInBufferPtr>");
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("scaled_buffers"), in_scaled_buffers,
                        "<value of type std::vector<ReadyFrameInBufferPtr>>");
   });
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameHandler_OnFrameReadyInBuffer_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameHandler_OnFrameReadyInBuffer_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->buffer)::BaseType> buffer_fragment(
          params.message());
  mojo::internal::Serialize<::video_capture::mojom::ReadyFrameInBufferDataView>(
      in_buffer, buffer_fragment);
  params->buffer.Set(
      buffer_fragment.is_null() ? nullptr : buffer_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->buffer.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null buffer in VideoFrameHandler.OnFrameReadyInBuffer request");
  mojo::internal::MessageFragment<
      typename decltype(params->scaled_buffers)::BaseType>
      scaled_buffers_fragment(params.message());
  const mojo::internal::ContainerValidateParams scaled_buffers_validate_params(
      0, false, nullptr);
  mojo::internal::Serialize<mojo::ArrayDataView<::video_capture::mojom::ReadyFrameInBufferDataView>>(
      in_scaled_buffers, scaled_buffers_fragment, &scaled_buffers_validate_params);
  params->scaled_buffers.Set(
      scaled_buffers_fragment.is_null() ? nullptr : scaled_buffers_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->scaled_buffers.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null scaled_buffers in VideoFrameHandler.OnFrameReadyInBuffer request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameHandler::Name_);
  message.set_method_name("OnFrameReadyInBuffer");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void VideoFrameHandlerProxy::OnBufferRetired(
    int32_t in_buffer_id) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send video_capture::mojom::VideoFrameHandler::OnBufferRetired", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("buffer_id"), in_buffer_id,
                        "<value of type int32_t>");
   });
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameHandler_OnBufferRetired_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameHandler_OnBufferRetired_Params_Data> params(
          message);
  params.Allocate();
  params->buffer_id = in_buffer_id;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameHandler::Name_);
  message.set_method_name("OnBufferRetired");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void VideoFrameHandlerProxy::OnError(
    ::media::VideoCaptureError in_error) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send video_capture::mojom::VideoFrameHandler::OnError", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("error"), in_error,
                        "<value of type ::media::VideoCaptureError>");
   });
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameHandler_OnError_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameHandler_OnError_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::media::mojom::VideoCaptureError>(
      in_error, &params->error);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameHandler::Name_);
  message.set_method_name("OnError");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void VideoFrameHandlerProxy::OnFrameDropped(
    ::media::VideoCaptureFrameDropReason in_reason) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send video_capture::mojom::VideoFrameHandler::OnFrameDropped", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("reason"), in_reason,
                        "<value of type ::media::VideoCaptureFrameDropReason>");
   });
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameHandler_OnFrameDropped_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameHandler_OnFrameDropped_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::media::mojom::VideoCaptureFrameDropReason>(
      in_reason, &params->reason);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameHandler::Name_);
  message.set_method_name("OnFrameDropped");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void VideoFrameHandlerProxy::OnNewCropVersion(
    uint32_t in_crop_version) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send video_capture::mojom::VideoFrameHandler::OnNewCropVersion", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("crop_version"), in_crop_version,
                        "<value of type uint32_t>");
   });
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameHandler_OnNewCropVersion_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameHandler_OnNewCropVersion_Params_Data> params(
          message);
  params.Allocate();
  params->crop_version = in_crop_version;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameHandler::Name_);
  message.set_method_name("OnNewCropVersion");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void VideoFrameHandlerProxy::OnFrameWithEmptyRegionCapture(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send video_capture::mojom::VideoFrameHandler::OnFrameWithEmptyRegionCapture");
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameHandler_OnFrameWithEmptyRegionCapture_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameHandler_OnFrameWithEmptyRegionCapture_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameHandler::Name_);
  message.set_method_name("OnFrameWithEmptyRegionCapture");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void VideoFrameHandlerProxy::OnLog(
    const std::string& in_message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send video_capture::mojom::VideoFrameHandler::OnLog", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("message"), in_message,
                        "<value of type const std::string&>");
   });
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameHandler_OnLog_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameHandler_OnLog_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->message)::BaseType> message_fragment(
          params.message());
  mojo::internal::Serialize<mojo::StringDataView>(
      in_message, message_fragment);
  params->message.Set(
      message_fragment.is_null() ? nullptr : message_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->message.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null message in VideoFrameHandler.OnLog request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameHandler::Name_);
  message.set_method_name("OnLog");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void VideoFrameHandlerProxy::OnStarted(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send video_capture::mojom::VideoFrameHandler::OnStarted");
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameHandler_OnStarted_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameHandler_OnStarted_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameHandler::Name_);
  message.set_method_name("OnStarted");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void VideoFrameHandlerProxy::OnStartedUsingGpuDecode(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send video_capture::mojom::VideoFrameHandler::OnStartedUsingGpuDecode");
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameHandler_OnStartedUsingGpuDecode_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameHandler_OnStartedUsingGpuDecode_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameHandler::Name_);
  message.set_method_name("OnStartedUsingGpuDecode");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void VideoFrameHandlerProxy::OnStopped(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send video_capture::mojom::VideoFrameHandler::OnStopped");
#endif
  const bool kExpectsResponse = false;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kVideoFrameHandler_OnStopped_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::video_capture::mojom::internal::VideoFrameHandler_OnStopped_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(VideoFrameHandler::Name_);
  message.set_method_name("OnStopped");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

// static
bool VideoFrameHandlerStubDispatch::Accept(
    VideoFrameHandler* impl,
    mojo::Message* message) {
  switch (message->header()->name) {
    case internal::kVideoFrameHandler_OnNewBuffer_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameHandler_OnNewBuffer_Params_Data* params =
          reinterpret_cast<internal::VideoFrameHandler_OnNewBuffer_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      int32_t p_buffer_id{};
      ::media::mojom::VideoBufferHandlePtr p_buffer_handle{};
      VideoFrameHandler_OnNewBuffer_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_buffer_id = input_data_view.buffer_id();
      if (success && !input_data_view.ReadBufferHandle(&p_buffer_handle))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameHandler::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnNewBuffer(
std::move(p_buffer_id), 
std::move(p_buffer_handle));
      return true;
    }
    case internal::kVideoFrameHandler_OnFrameAccessHandlerReady_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameHandler_OnFrameAccessHandlerReady_Params_Data* params =
          reinterpret_cast<internal::VideoFrameHandler_OnFrameAccessHandlerReady_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::mojo::PendingRemote<VideoFrameAccessHandler> p_frame_access_handler{};
      VideoFrameHandler_OnFrameAccessHandlerReady_ParamsDataView input_data_view(params, message);
      
      if (success) {
        p_frame_access_handler =
            input_data_view.TakeFrameAccessHandler<decltype(p_frame_access_handler)>();
      }
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameHandler::Name_, 1, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnFrameAccessHandlerReady(
std::move(p_frame_access_handler));
      return true;
    }
    case internal::kVideoFrameHandler_OnFrameReadyInBuffer_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameHandler_OnFrameReadyInBuffer_Params_Data* params =
          reinterpret_cast<internal::VideoFrameHandler_OnFrameReadyInBuffer_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ReadyFrameInBufferPtr p_buffer{};
      std::vector<ReadyFrameInBufferPtr> p_scaled_buffers{};
      VideoFrameHandler_OnFrameReadyInBuffer_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadBuffer(&p_buffer))
        success = false;
      if (success && !input_data_view.ReadScaledBuffers(&p_scaled_buffers))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameHandler::Name_, 2, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnFrameReadyInBuffer(
std::move(p_buffer), 
std::move(p_scaled_buffers));
      return true;
    }
    case internal::kVideoFrameHandler_OnBufferRetired_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameHandler_OnBufferRetired_Params_Data* params =
          reinterpret_cast<internal::VideoFrameHandler_OnBufferRetired_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      int32_t p_buffer_id{};
      VideoFrameHandler_OnBufferRetired_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_buffer_id = input_data_view.buffer_id();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameHandler::Name_, 3, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnBufferRetired(
std::move(p_buffer_id));
      return true;
    }
    case internal::kVideoFrameHandler_OnError_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameHandler_OnError_Params_Data* params =
          reinterpret_cast<internal::VideoFrameHandler_OnError_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::media::VideoCaptureError p_error{};
      VideoFrameHandler_OnError_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadError(&p_error))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameHandler::Name_, 4, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnError(
std::move(p_error));
      return true;
    }
    case internal::kVideoFrameHandler_OnFrameDropped_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameHandler_OnFrameDropped_Params_Data* params =
          reinterpret_cast<internal::VideoFrameHandler_OnFrameDropped_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      ::media::VideoCaptureFrameDropReason p_reason{};
      VideoFrameHandler_OnFrameDropped_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadReason(&p_reason))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameHandler::Name_, 5, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnFrameDropped(
std::move(p_reason));
      return true;
    }
    case internal::kVideoFrameHandler_OnNewCropVersion_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameHandler_OnNewCropVersion_Params_Data* params =
          reinterpret_cast<internal::VideoFrameHandler_OnNewCropVersion_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      uint32_t p_crop_version{};
      VideoFrameHandler_OnNewCropVersion_ParamsDataView input_data_view(params, message);
      
      if (success)
        p_crop_version = input_data_view.crop_version();
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameHandler::Name_, 6, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnNewCropVersion(
std::move(p_crop_version));
      return true;
    }
    case internal::kVideoFrameHandler_OnFrameWithEmptyRegionCapture_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameHandler_OnFrameWithEmptyRegionCapture_Params_Data* params =
          reinterpret_cast<internal::VideoFrameHandler_OnFrameWithEmptyRegionCapture_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      VideoFrameHandler_OnFrameWithEmptyRegionCapture_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameHandler::Name_, 7, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnFrameWithEmptyRegionCapture();
      return true;
    }
    case internal::kVideoFrameHandler_OnLog_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameHandler_OnLog_Params_Data* params =
          reinterpret_cast<internal::VideoFrameHandler_OnLog_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      std::string p_message{};
      VideoFrameHandler_OnLog_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadMessage(&p_message))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameHandler::Name_, 8, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnLog(
std::move(p_message));
      return true;
    }
    case internal::kVideoFrameHandler_OnStarted_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameHandler_OnStarted_Params_Data* params =
          reinterpret_cast<internal::VideoFrameHandler_OnStarted_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      VideoFrameHandler_OnStarted_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameHandler::Name_, 9, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnStarted();
      return true;
    }
    case internal::kVideoFrameHandler_OnStartedUsingGpuDecode_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameHandler_OnStartedUsingGpuDecode_Params_Data* params =
          reinterpret_cast<internal::VideoFrameHandler_OnStartedUsingGpuDecode_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      VideoFrameHandler_OnStartedUsingGpuDecode_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameHandler::Name_, 10, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnStartedUsingGpuDecode();
      return true;
    }
    case internal::kVideoFrameHandler_OnStopped_Name: {

      DCHECK(message->is_serialized());
      internal::VideoFrameHandler_OnStopped_Params_Data* params =
          reinterpret_cast<internal::VideoFrameHandler_OnStopped_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      VideoFrameHandler_OnStopped_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            VideoFrameHandler::Name_, 11, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OnStopped();
      return true;
    }
  }
  return false;
}

// static
bool VideoFrameHandlerStubDispatch::AcceptWithResponder(
    VideoFrameHandler* impl,
    mojo::Message* message,
    std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
  [[maybe_unused]] const bool message_is_sync =
      message->has_flag(mojo::Message::kFlagIsSync);
  [[maybe_unused]] const uint64_t request_id = message->request_id();
  switch (message->header()->name) {
    case internal::kVideoFrameHandler_OnNewBuffer_Name: {
      break;
    }
    case internal::kVideoFrameHandler_OnFrameAccessHandlerReady_Name: {
      break;
    }
    case internal::kVideoFrameHandler_OnFrameReadyInBuffer_Name: {
      break;
    }
    case internal::kVideoFrameHandler_OnBufferRetired_Name: {
      break;
    }
    case internal::kVideoFrameHandler_OnError_Name: {
      break;
    }
    case internal::kVideoFrameHandler_OnFrameDropped_Name: {
      break;
    }
    case internal::kVideoFrameHandler_OnNewCropVersion_Name: {
      break;
    }
    case internal::kVideoFrameHandler_OnFrameWithEmptyRegionCapture_Name: {
      break;
    }
    case internal::kVideoFrameHandler_OnLog_Name: {
      break;
    }
    case internal::kVideoFrameHandler_OnStarted_Name: {
      break;
    }
    case internal::kVideoFrameHandler_OnStartedUsingGpuDecode_Name: {
      break;
    }
    case internal::kVideoFrameHandler_OnStopped_Name: {
      break;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kVideoFrameHandlerValidationInfo[] = {
    {&internal::VideoFrameHandler_OnNewBuffer_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::VideoFrameHandler_OnFrameAccessHandlerReady_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::VideoFrameHandler_OnFrameReadyInBuffer_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::VideoFrameHandler_OnBufferRetired_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::VideoFrameHandler_OnError_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::VideoFrameHandler_OnFrameDropped_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::VideoFrameHandler_OnNewCropVersion_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::VideoFrameHandler_OnFrameWithEmptyRegionCapture_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::VideoFrameHandler_OnLog_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::VideoFrameHandler_OnStarted_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::VideoFrameHandler_OnStartedUsingGpuDecode_Params_Data::Validate,
     nullptr /* no response */},
    {&internal::VideoFrameHandler_OnStopped_Params_Data::Validate,
     nullptr /* no response */},
};

bool VideoFrameHandlerRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::video_capture::mojom::VideoFrameHandler::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kVideoFrameHandlerValidationInfo);
}



}  // namespace mojom
}  // namespace video_capture


namespace mojo {


// static
bool StructTraits<::video_capture::mojom::ReadyFrameInBuffer::DataView, ::video_capture::mojom::ReadyFrameInBufferPtr>::Read(
    ::video_capture::mojom::ReadyFrameInBuffer::DataView input,
    ::video_capture::mojom::ReadyFrameInBufferPtr* output) {
  bool success = true;
  ::video_capture::mojom::ReadyFrameInBufferPtr result(::video_capture::mojom::ReadyFrameInBuffer::New());
  
      if (success)
        result->buffer_id = input.buffer_id();
      if (success)
        result->frame_feedback_id = input.frame_feedback_id();
      if (success && !input.ReadFrameInfo(&result->frame_info))
        success = false;
  *output = std::move(result);
  return success;
}

}  // namespace mojo


// Symbols declared in the -test-utils.h header are defined here instead of a
// separate .cc file to save compile time.


namespace video_capture {
namespace mojom {


void VideoFrameAccessHandlerInterceptorForTesting::OnFinishedConsumingBuffer(int32_t buffer_id) {
  GetForwardingInterface()->OnFinishedConsumingBuffer(std::move(buffer_id));
}
VideoFrameAccessHandlerAsyncWaiter::VideoFrameAccessHandlerAsyncWaiter(
    VideoFrameAccessHandler* proxy) : proxy_(proxy) {}

VideoFrameAccessHandlerAsyncWaiter::~VideoFrameAccessHandlerAsyncWaiter() = default;




void VideoFrameHandlerInterceptorForTesting::OnNewBuffer(int32_t buffer_id, ::media::mojom::VideoBufferHandlePtr buffer_handle) {
  GetForwardingInterface()->OnNewBuffer(std::move(buffer_id), std::move(buffer_handle));
}
void VideoFrameHandlerInterceptorForTesting::OnFrameAccessHandlerReady(::mojo::PendingRemote<VideoFrameAccessHandler> frame_access_handler) {
  GetForwardingInterface()->OnFrameAccessHandlerReady(std::move(frame_access_handler));
}
void VideoFrameHandlerInterceptorForTesting::OnFrameReadyInBuffer(ReadyFrameInBufferPtr buffer, std::vector<ReadyFrameInBufferPtr> scaled_buffers) {
  GetForwardingInterface()->OnFrameReadyInBuffer(std::move(buffer), std::move(scaled_buffers));
}
void VideoFrameHandlerInterceptorForTesting::OnBufferRetired(int32_t buffer_id) {
  GetForwardingInterface()->OnBufferRetired(std::move(buffer_id));
}
void VideoFrameHandlerInterceptorForTesting::OnError(::media::VideoCaptureError error) {
  GetForwardingInterface()->OnError(std::move(error));
}
void VideoFrameHandlerInterceptorForTesting::OnFrameDropped(::media::VideoCaptureFrameDropReason reason) {
  GetForwardingInterface()->OnFrameDropped(std::move(reason));
}
void VideoFrameHandlerInterceptorForTesting::OnNewCropVersion(uint32_t crop_version) {
  GetForwardingInterface()->OnNewCropVersion(std::move(crop_version));
}
void VideoFrameHandlerInterceptorForTesting::OnFrameWithEmptyRegionCapture() {
  GetForwardingInterface()->OnFrameWithEmptyRegionCapture();
}
void VideoFrameHandlerInterceptorForTesting::OnLog(const std::string& message) {
  GetForwardingInterface()->OnLog(std::move(message));
}
void VideoFrameHandlerInterceptorForTesting::OnStarted() {
  GetForwardingInterface()->OnStarted();
}
void VideoFrameHandlerInterceptorForTesting::OnStartedUsingGpuDecode() {
  GetForwardingInterface()->OnStartedUsingGpuDecode();
}
void VideoFrameHandlerInterceptorForTesting::OnStopped() {
  GetForwardingInterface()->OnStopped();
}
VideoFrameHandlerAsyncWaiter::VideoFrameHandlerAsyncWaiter(
    VideoFrameHandler* proxy) : proxy_(proxy) {}

VideoFrameHandlerAsyncWaiter::~VideoFrameHandlerAsyncWaiter() = default;






}  // namespace mojom
}  // namespace video_capture


#if defined(__clang__)
#pragma clang diagnostic pop
#endif