# Copyright 2014 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.

import("//build/config/chromecast_build.gni")
import("//build/config/features.gni")
import("//testing/libfuzzer/fuzzer_test.gni")

declare_args() {
  # Allows distributions to link pulseaudio directly (DT_NEEDED) instead of
  # using dlopen. This helps with automated detection of ABI mismatches and
  # prevents silent errors.
  link_pulseaudio = false

  # Enable usage of FFmpeg within the media library. Used for most software
  # based decoding, demuxing, and sometimes optimized FFTs. If disabled,
  # implementors must provide their own demuxers and decoders.
  media_use_ffmpeg = true

  # Enable usage of libvpx within the media library. Used for software based
  # decoding of VP9 and VP8A type content.
  media_use_libvpx = true

  # iOS doesn't use ffmpeg, libvpx.
  if (is_ios) {
    media_use_ffmpeg = false
    media_use_libvpx = false
  }

  # Override to dynamically link the cras (ChromeOS audio) library.
  use_cras = false

  # Use low-memory buffers on non-Android builds of Chromecast.
  use_low_memory_buffer = is_chromecast && !is_android

  # Enables AC3/EAC3 audio demuxing. This is enabled only on Chromecast, since
  # it only provides demuxing, and is only useful for AC3/EAC3 audio
  # pass-through to HDMI sink on Chromecast.
  enable_ac3_eac3_audio_demuxing = proprietary_codecs && is_chromecast

  enable_mse_mpeg2ts_stream_parser =
      (proprietary_codecs && is_chromecast) || use_libfuzzer || use_afl

  # Enable support for the 'cbcs' encryption scheme added by MPEG Common
  # Encryption 3rd Edition (ISO/IEC 23001-7), published 02/15/2016.
  enable_cbcs_encryption_scheme = is_chromecast

  # Enable HEVC/H265 demuxing. Actual decoding must be provided by the
  # platform. Enable by default for Chromecast.
  enable_hevc_demuxing = proprietary_codecs && is_chromecast

  enable_webrtc = !is_ios

  # Enable HLS with SAMPLE-AES decryption.
  # Enabled by default on the cast desktop implementation to allow unit tests of
  # MP2TS parsing support.
  enable_hls_sample_aes = proprietary_codecs && is_cast_desktop_build
}

# enable_hls_sample_aes can only be true if enable_mse_mpeg2ts_stream_parser is.
assert(enable_mse_mpeg2ts_stream_parser || !enable_hls_sample_aes)

# Use a second declare_args() to pick up possible overrides of |use_cras|.
declare_args() {
  # Enables runtime selection of PulseAudio library.
  use_pulseaudio = false

  # Enables runtime selection of ALSA library for audio.
  use_alsa = false

  # Alsa should be used on non-Android, non-Mac POSIX systems.
  # Alsa should be used on desktop Chromecast and audio-only Chromecast builds.
  if (is_posix && !is_android && !is_mac &&
      (!is_chromecast || is_cast_desktop_build || is_cast_audio_only)) {
    use_alsa = true

    # Pulse is not supported on Chromecast platforms.
    if (!use_cras && !is_chromecast) {
      use_pulseaudio = true
    }
  }
}

# Use another declare_args() to pick up possible overrides of media_use_ffmpeg
# from --args command line flags. See "gn help declare_args".
declare_args() {
  # On Android, FFMpeg is built without video decoders by default.
  # This flag gives the option to override that decision in case there are no
  # hardware decoders. To do so, you will also need to update ffmpeg build files
  # in order to define which decoders to build in.
  disable_ffmpeg_video_decoders = !media_use_ffmpeg || is_android
}

declare_args() {
  # Experiment to enable mojo media services (e.g. "renderer", "cdm", see
  # |mojo_media_services|). When enabled, selected mojo paths will be enabled in
  # the media pipeline and corresponding services will hosted in the selected
  # remote process (e.g. "utility" process, see |mojo_media_host|).
  enable_mojo_media = is_android || is_chromecast

  # Enable the TestMojoMediaClient to be used in mojo MediaService. This is for
  # testing only and will override the default platform MojoMediaClient, if any.
  enable_test_mojo_media_client = false

  # When enabled, this feature allows developers to use a runtime flag to
  # choose the implementation of the renderer that is used. On a build which
  # enables the mojo renderer, if --disable-mojo-renderer is passed at start-up,
  # the "default" renderer will be used instead. Both renderer implementations
  # will be linked if this feature is enabled, increasing the binary size. This
  # feature does not make sense if the mojo renderer is not enabled.
  enable_runtime_media_renderer_selection = is_cast_desktop_build
}

# This feature can only be enabled when using Mojo media. Furthermore, the
# "renderer" service must be enabled, which is asserted in
# //media/mojo/services/BUILD.gn
assert(
    !enable_runtime_media_renderer_selection || enable_mojo_media,
    "Runtime media renderer selection only applies when mojo media is enabled.")

# Use another declare_args() to pick up possible overrides of enable_mojo_media
# from --args command line flags. See "gn help declare_args".
declare_args() {
  # A list of mojo media services that should be used in the media pipeline.
  # Must not be empty if |enable_mojo_media| is true.
  # Valid entries in the list are:
  # - "renderer": Use mojo-based media Renderer service.
  # - "cdm": Use mojo-based Content Decryption Module.
  # - "audio_decoder": Use mojo-based audio decoder in the default media
  #                    Renderer. Cannot be used with the mojo Renderer above.
  # - "video_decoder": Use mojo-based video decoder in the default media
  #                    Renderer. Cannot be used with the mojo Renderer above.
  mojo_media_services = []

  # The process to host the mojo media service.
  # Valid options are:
  # - "none": Do not use mojo media service.
  # - "browser": Use mojo media service hosted in the browser process.
  # - "gpu": Use mojo media service hosted in the gpu process.
  # - "utility": Use mojo media service hosted in the utility process.
  mojo_media_host = "none"

  # Default mojo_media_services and mojo_media_host on various platforms.
  # Can be overridden by gn build arguments from the --args command line flag
  # for local testing.
  if (enable_mojo_media) {
    if (is_android) {
      mojo_media_services = [
        "cdm",
        "audio_decoder",
      ]
      mojo_media_host = "gpu"
    } else if (is_chromecast) {
      mojo_media_services = [
        "cdm",
        "renderer",
      ]
      mojo_media_host = "browser"
    } else {
      mojo_media_services = [ "video_decoder" ]
      mojo_media_host = "gpu"
    }
  }
}

declare_args() {
  # This switch defines whether the Media Remoting implementation will be built.
  # When enabled, media is allowed to be renderer and played back on remote
  # devices when the tab is being casted and other conditions are met.
  enable_media_remoting = !is_chromecast && !is_ios && !is_android
}
