chromium/ash/webui/camera_app_ui/resources/js/lib/build_ffmpeg.sh

#!/bin/bash

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

# We are using unquoted '=' in array as intended.
# shellcheck disable=SC2191

set -ex

die() {
  echo -e "\e[1;31merror: $*\e[0m" 1>&2
  exit 1
}

do_copy_ffmpeg() {
  # locate ffmpeg directory in chromium source tree
  local ffmpeg_dir
  ffmpeg_dir=$(realpath ../../../../../../third_party/ffmpeg)
  [[ -d "$ffmpeg_dir" ]] || die "ffmpeg not found"

  # checkout specific commit to keep code base consistent to the patch
  # TODO(b/199980849): Fix pthread issue to be able to use latest FFMpeg update.
  # TODO(b/199980849): Remove video_size patch once the PR is sent upstream.
  local build_commit=90810bb
  (
    cd $ffmpeg_dir;
    git archive --format=tar "$build_commit" | (cd "$1" && tar xf -)
  )
}

do_patch() {
  git apply -- "$1"
}

do_configure() {
  local WASM_LDFLAGS=(
    -s ASYNCIFY_IMPORTS='["wait_readable"]'
    -s EXTRA_EXPORTED_RUNTIME_METHODS='["FS"]'
    -s ALLOW_MEMORY_GROWTH=1
    -s ASYNCIFY
    -s EXIT_RUNTIME=1
    -s ENVIRONMENT=web
    -s EXPORT_ES6=1
    -s MODULARIZE=1
    -s TOTAL_MEMORY=33554432
    -s USE_ES6_IMPORT_META=0
    -s WASM=1
    -v
    -Os
    --llvm-lto 3
    --js-library ./lib.js
  )
  local args=(
    # emscripten toolchain
    --ar=emar
    --cc=emcc
    --cxx="em++"
    --ranlib=emranlib
    # generic architecture
    --arch=c
    --cpu=generic
    --extra-ldflags="$LDFLAGS"
    --disable-asm
    --disable-stripping
    --enable-cross-compile
    --target-os=none
    # smaller binary
    --disable-all
    --disable-autodetect
    --disable-debug
    --disable-everything
    --disable-iconv
    --disable-network
    --disable-pthreads
    --disable-runtime-cpudetect
    --enable-lto
    --enable-small
    # enable selective features
    --enable-avcodec
    --enable-avfilter
    --enable-avformat
    --enable-ffmpeg
    --enable-swresample
    --enable-swscale
    --enable-protocol=file
    --enable-protocol=pipe
    --enable-demuxer=h264
    --enable-demuxer=matroska
    --enable-demuxer=rawvideo
    --enable-muxer=gif
    --enable-muxer=mov
    --enable-muxer=mp4
    --enable-parser=h264
    --enable-decoder=pcm_f32le
    --enable-decoder=rawvideo
    --enable-encoder=aac
    --enable-encoder=gif
    --enable-filter=aresample
    --enable-filter=scale
    --enable-bsf=extract_extradata
  )

  LDFLAGS="${WASM_LDFLAGS[@]}" emconfigure ./configure "${args[@]}"
}

do_make() {
  emmake make -j "$(nproc)"
}

do_cleanup_name() {
  mv ffmpeg_g.wasm ffmpeg.wasm
  mv ffmpeg_g ffmpeg.js
  sed -i -e 's/ffmpeg_g.wasm/ffmpeg.wasm/g' ffmpeg.js
}

do_add_header() {
  mv ffmpeg.js ffmpeg.orig.js
  cat <<'EOF' > ffmpeg.js
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
/* eslint-disable */
// @ts-nocheck
EOF
  cat ffmpeg.orig.js >> ffmpeg.js
  echo >> ffmpeg.js
}

main() {
  [[ -z "$EMSDK" ]] && die "emsdk is not setup properly"

  # change working directory to the script location
  cd -- "$(dirname -- "$(realpath -- "${BASH_SOURCE[0]}")")"

  # locate patch file
  local patch_file
  patch_file=$(realpath ffmpeg.patch)
  [[ -f "$patch_file" ]] || die "patch not found"

  # copy ffmpeg/ into a temporary directory to patch and build
  local build_dir
  build_dir=$(mktemp -d -t ffmpeg_build_XXXXXX)
  do_copy_ffmpeg "$build_dir"
  pushd -- "$build_dir" > /dev/null
  do_patch "$patch_file"

  # configure + build
  do_configure
  do_make
  do_cleanup_name
  do_add_header

  popd

  cp --interactive -- "$build_dir"/ffmpeg.{js,wasm} .
}

main "$@"