chromium/media/media_options.gni

# Copyright 2014 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/cast.gni")
import("//build/config/chrome_build.gni")
import("//build/config/chromeos/args.gni")
import("//build/config/chromeos/ui_mode.gni")
import("//build/config/features.gni")
import("//build/config/ui.gni")
import("//media/gpu/args.gni")
import("//testing/libfuzzer/fuzzer_test.gni")
import("//third_party/libaom/options.gni")

# This flag sets defaults for the current generation of cast devices.
is_cast_media_device = is_castos || is_cast_android

# Out-of-process video decoding is a feature specific to Linux and ChromeOS
# which makes the interaction with platform drivers (for the purposes of
# hardware accelerated video decoding) happen on utility processes for stability
# and security purposes. When |allow_oop_video_decoder| is true, code to
# use this feature is compiled. Note that even if |allow_oop_video_decoder| is
# true, the feature may be disabled by a runtime flag.
#
# When |allow_hosting_oop_video_decoder| is true, code to host the video decoder
# utility processes is compiled. Note that even if
# |allow_hosting_oop_video_decoder| is true, the hosting of these utility
# processes may be disabled by a runtime flag.
#
# TODO(b/195769334): finish replacing usages of (is_linux || is_chromeos) with
# allow_oop_video_decoder where appropriate. Also, finish replacing usages of
# (is_linux || is_chromeos_ash) with allow_hosting_oop_video_decoder where
# appropriate.
allow_hosting_oop_video_decoder =
    (is_chromeos_ash || is_linux) && (use_vaapi || use_v4l2_codec)
allow_oop_video_decoder = is_chromeos_lacros || allow_hosting_oop_video_decoder

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

  # non-blink builds doesn't use ffmpeg, libvpx.
  if (!use_blink) {
    media_use_ffmpeg = false
    media_use_libvpx = false
  }

  # Enable usage of OpenH264 within the media library. Used for software based
  # encoding of H264 content.
  media_use_openh264 = true
  if (is_ios || is_android || !proprietary_codecs) {
    media_use_openh264 = false
  }

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

  # Enables AC3/EAC3 audio handling in chromium. This includes demuxing,
  # on-device decoding and bitstream passthrough as supported by device.
  enable_platform_ac3_eac3_audio = proprietary_codecs && is_cast_media_device

  # Enables AC4 audio handling in chromium. This includes demuxing,
  # on-device decoding and bitstream passthrough as supported by device.
  enable_platform_ac4_audio = false

  enable_platform_mpeg_h_audio = proprietary_codecs && is_cast_media_device

  # Enables DTS/DTSX audio handling in chromium. This includes demuxing,
  # on-device decoding and bitstream passthrough as supported by device.
  enable_platform_dts_audio = false

  # Enables IAMF audio handling in chromium. This includes demuxing,
  # on-device decoding and bitstream passthrough as supported by device.
  enable_platform_iamf_audio = false

  # Enable Dolby Vision demuxing. Enabled by default for Chromecast and Windows.
  # Actual decoding must be provided by the platform. Since most Dolby Vision
  # profiles use HEVC, `enable_platform_hevc` is required to enable this.
  #
  # TODO(crbug.com/1336055): Revisit the default value for this setting as it
  # applies to video-capable devices.
  enable_platform_dolby_vision =
      proprietary_codecs && (is_cast_media_device || is_win)

  # Enable platform support of encrypted Dolby Vision. The actual support
  # depends on platform capability and is controlled by the run time feature
  # kPlatformEncryptedDolbyVision. Clear Dolby Vision is not supported by
  # default, unless overwritten by the run time feature
  # kAllowClearDolbyVisionInMseWhenPlatformEncryptedDvEnabled.
  enable_platform_encrypted_dolby_vision = proprietary_codecs && is_win

  # Enable logging override, e.g. enable DVLOGs through level 2 at build time.
  # On Cast devices, these are logged as INFO.
  # When enabled on Fuchsia, these are logged as VLOGs.
  enable_logging_override = is_cast_media_device

  enable_dav1d_decoder = use_blink

  # Enable browser managed persistent metadata storage for EME persistent
  # session and persistent usage record session.
  enable_media_drm_storage = is_android || is_castos

  # Enable HLS manifest parser and demuxer.
  enable_hls_demuxer = proprietary_codecs && is_android

  # Enable inclusion of the HEVC/H265 parser and also enable HEVC/H265 decoding
  # with hardware acceleration assist. Enabled by default for fuzzer builds,
  # Windows, Mac, and Android.
  enable_hevc_parser_and_hw_decoder =
      proprietary_codecs &&
      (use_fuzzing_engine || is_win || is_apple || is_android || is_linux)

  # Enable inclusion of VVC/H.266 parser/demuxer, and also enable VVC/H.266 decoding
  # with hardware acceleration provided by platform. Disabled by default for all builds.
  enable_platform_vvc = false
}

# Use another declare_args() to allow dependence on args defined above.
declare_args() {
  # If overriding this to false, possibly via its component values,
  # `enable_libaom` should likely also be overriddent to false.
  enable_av1_decoder = enable_dav1d_decoder

  # Enable HEVC/H265 demuxing. Actual decoding must be provided by the
  # platform. Always enable this for Lacros, it determines support at runtime.
  # TODO(crbug.com/1336055): Revisit the default value for this setting as it
  # applies to video-capable devices.
  enable_platform_hevc =
      proprietary_codecs && (enable_hevc_parser_and_hw_decoder ||
                             is_cast_media_device || is_chromeos_lacros)

  enable_mse_mpeg2ts_stream_parser =
      proprietary_codecs &&
      (enable_hls_demuxer || enable_cast_receiver || use_fuzzing_engine)
}

declare_args() {
  platform_has_optional_hevc_support =
      enable_platform_hevc &&
      (is_win || is_chromeos || is_linux || is_apple || is_android)
}

assert(!enable_hls_demuxer || enable_mse_mpeg2ts_stream_parser,
       "enable_mse_mpeg2ts_stream_parser required for enable_hls_demuxer")
assert(!enable_hls_demuxer || proprietary_codecs,
       "proprietary_codecs required for enable_hls_demuxer")
assert(!enable_platform_ac3_eac3_audio || proprietary_codecs,
       "proprietary_codecs required for enable_platform_ac3_eac3_audio")
assert(!enable_platform_ac4_audio || proprietary_codecs,
       "proprietary_codecs required for enable_platform_ac4_audio")
assert(!enable_platform_mpeg_h_audio || proprietary_codecs,
       "proprietary_codecs required for enable_platform_mpeg_h_audio")
assert(!enable_mse_mpeg2ts_stream_parser || proprietary_codecs,
       "proprietary_codecs required for enable_mse_mpeg2ts_stream_parser")
assert(!enable_platform_dolby_vision || proprietary_codecs,
       "proprietary_codecs required for enable_platform_dolby_vision")
assert(
    !enable_platform_encrypted_dolby_vision || enable_platform_dolby_vision,
    "enable_platform_dolby_vision required for enable_platform_encrypted_dolby_vision")
assert(!enable_platform_dts_audio || proprietary_codecs,
       "proprietary_codecs required for enable_platform_dts_audio")
assert(!enable_platform_hevc || proprietary_codecs,
       "proprietary_codecs required for enable_platform_hevc")
assert(!enable_hevc_parser_and_hw_decoder || enable_platform_hevc,
       "enable_platform_hevc required for enable_hevc_parser_and_hw_decoder")

# Most DolbyVision profiles (4, 5, 7, 8, not 9) require HEVC support. It's very
# unlikely that we support DolbyVision on a new platform without requiring HEVC
# support. See for details:
# https://professionalsupport.dolby.com/s/article/What-is-Dolby-Vision-Profile
assert(!enable_platform_dolby_vision || enable_platform_hevc,
       "enable_platform_hevc required for enable_platform_dolby_vision")

# Use another 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 all non-Android, non-Mac POSIX systems - with the
  # exception of CastOS desktop builds.
  #
  # TODO(crbug.com/1336055): Remove legacy target_cpu hack used for targeting
  # desktop Chromecast builds.
  if (is_posix && !is_android && !is_apple &&
      (!is_castos || (target_cpu == "x86" || target_cpu == "x64") ||
       is_cast_audio_only)) {
    use_alsa = true

    # Pulse is not supported on Chromecast platforms.
    #
    # ASAN and TSAN will occasionally hang during pa_context_connect(), so we
    # disable PulseAudio when these configurations are enabled.
    #
    # TODO(crbug.com/40636948): We shouldn't have to do this, but it's unclear why
    # our test bots are hanging and all of the ones that don't hang just fall
    # back to ALSA after a connection error anyways.
    if (!use_cras && !is_castos && !is_asan && !is_tsan) {
      use_pulseaudio = true
    }
  }
}

# Use another declare_args() to include possible overrides of media_use_ffmpeg
# from --args command line flags in the evaluation. 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.
  enable_ffmpeg_video_decoders =
      media_use_ffmpeg && (!is_android || current_cpu != "arm")
}

declare_args() {
  # Enables the use of library CDMs that implements the interface defined at
  # media/cdm/api/content_decryption_module.h. If true, the actually library CDM
  # will be hosted in the mojo CDM service running in the CDM (utility) process.
  # Used for all desktop platforms.
  enable_library_cdms = toolkit_views && !is_castos
}

# Use another declare_args() to allow dependence on `enable_library_cdms`.
declare_args() {
  # Enables host verification for CDMs.
  # Windows and Mac.
  enable_cdm_host_verification =
      enable_library_cdms && (is_mac || is_win) && is_chrome_branded &&
      !is_chrome_for_testing_branded

  # Enable Storage ID which is used by CDMs. This is only available with chrome
  # branding, but may be overridden by other embedders.
  enable_cdm_storage_id = enable_library_cdms && is_chrome_branded &&
                          (is_win || is_mac || is_chromeos)

  # If |enable_cdm_storage_id| is set, then an implementation specific key
  # must also be provided. It can be provided by defining CDM_STORAGE_ID_KEY
  # (which takes precedence), or by setting |alternate_cdm_storage_id_key|.
  # The key must be a string of at least 32 characters.
  alternate_cdm_storage_id_key = ""
}

assert(!enable_cdm_host_verification || is_mac || is_win,
       "CDM host verification is only supported on Mac and Windows.")

# https://crbug.com/1475137#c37
assert(!is_chrome_for_testing_branded || !enable_cdm_host_verification,
       "Chrome for Testing is incompatible with CDM Host Verification.")

# Default |mojo_media_services| and |mojo_media_host| on various platforms. See
# comments below for valid values. Can be overridden by gn build arguments from
# the --args command line flag.
_default_mojo_media_services = []
_default_mojo_media_host = ""

if (is_cast_media_device) {
  _default_mojo_media_services = cast_mojo_media_services
  _default_mojo_media_host = cast_mojo_media_host
} else if (is_android) {
  _default_mojo_media_services = [
    "cdm",
    "audio_decoder",
    "audio_encoder",
    "video_decoder",
  ]
  _default_mojo_media_host = "gpu"
} else if (is_apple || is_win) {
  _default_mojo_media_services = [
    "audio_decoder",
    "audio_encoder",
    "video_decoder",
  ]
  _default_mojo_media_host = "gpu"
} else if (is_chromeos_ash || ((is_linux || is_chromeos_lacros) &&
                               (use_vaapi || use_v4l2_codec))) {
  _default_mojo_media_services = [ "video_decoder" ]
  _default_mojo_media_host = "gpu"
}

# When |enable_library_cdms| is true, the "cdm" service will run in a separate
# CdmService in the CDM (utility) process. Therefore there's no need to specify
# |_default_mojo_media_host| which controls where the MediaService runs in.
if (enable_library_cdms) {
  _default_mojo_media_services += [ "cdm" ]
}

declare_args() {
  # A list of mojo media services that should be used in the media pipeline.
  # 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 = _default_mojo_media_services

  # The process that the mojo MediaService runs in. By default, all services
  # registered in |mojo_media_services| are hosted in the MediaService, with the
  # exception that when |enable_library_cdms| is true, the "cdm" service will
  # run in a separate CdmService in the CDM (utility) process, while other
  # |mojo_media_services| still run in the MediaService in the process specified
  # by "mojo_media_host".
  # Valid options are:
  # - "browser": Use mojo media service hosted in the browser process.
  # - "gpu": Use mojo media service hosted in the gpu process.
  # - "": Do not use mojo media service.
  mojo_media_host = _default_mojo_media_host
}

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_cast_media_device && !is_ios
}

declare_args() {
  # Media Remoting RPC is disabled on Android since it's unused but increases
  # the native binary size by ~70Kb.
  enable_media_remoting_rpc = enable_media_remoting && !is_android
}

declare_args() {
  # Currently it is available on Win, Mac and Linux, since it requires the audio
  # service to run in a separate process.
  chrome_wide_echo_cancellation_supported = is_win || is_mac || is_linux
}

# Do not expand this list without double-checking with OWNERS, this is a list of
# all targets which roll up into the //media component. It controls visibility
# of subcomponent targets and public_deps for //media.
media_subcomponent_deps = [
  "//media/audio",
  "//media/base",

  # TODO(crbug.com/41237623): These files should not be in //media/base.
  "//media/base/android",
  "//media/capabilities",
  "//media/cdm",
  "//media/device_monitors",
  "//media/filters",
  "//media/formats",
  "//media/muxers",
  "//media/parsers",
  "//media/renderers",
  "//media/video",
]

if (is_fuchsia) {
  media_subcomponent_deps += [ "//media/fuchsia/common" ]
}

if (media_use_ffmpeg) {
  media_subcomponent_deps += [ "//media/ffmpeg" ]
}

if (enable_library_cdms || is_win) {
  media_subcomponent_deps += [ "//media/cdm:cdm_type_conversion" ]
}

if (is_win) {
  media_subcomponent_deps += [ "//media/base/win:media_foundation_util" ]
}