diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 6bbbbacb70..b1a14076ea 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -22,23 +22,11 @@ body: validations: required: true - - type: dropdown - id: hw - attributes: - label: What hardware does this issue affect? - multiple: true - options: - - comma three - - comma two - - EON Gold - validations: - required: true - - type: input id: route attributes: label: Provide a route where the issue occurs - description: Ensure the route is fully uploaded at https://useradmin.comma.ai + description: Ensure the route is fully uploaded at https://useradmin.comma.ai. We cannot look into issues without routes, or at least a Dongle ID. placeholder: 77611a1fac303767|2020-05-11--16-37-07 validations: required: true diff --git a/.github/ISSUE_TEMPLATE/car_bug_report.yml b/.github/ISSUE_TEMPLATE/car_bug_report.yml index a48f984192..23527c3a43 100644 --- a/.github/ISSUE_TEMPLATE/car_bug_report.yml +++ b/.github/ISSUE_TEMPLATE/car_bug_report.yml @@ -21,18 +21,6 @@ body: validations: required: true - - type: dropdown - id: hw - attributes: - label: What hardware does this issue affect? - multiple: true - options: - - comma three - - comma two - - EON Gold - validations: - required: true - - type: input id: car attributes: diff --git a/.github/workflows/prebuilt.yaml b/.github/workflows/prebuilt.yaml index 80942b3bc5..7acc8a2254 100644 --- a/.github/workflows/prebuilt.yaml +++ b/.github/workflows/prebuilt.yaml @@ -3,6 +3,8 @@ on: schedule: - cron: '0 * * * *' + workflow_dispatch: + env: BASE_IMAGE: openpilot-base DOCKER_REGISTRY: ghcr.io/commaai @@ -23,12 +25,13 @@ jobs: IMAGE_NAME: openpilot-prebuilt steps: - name: Wait for green check mark - uses: lewagon/wait-on-check-action@v0.2 + uses: commaai/wait-on-check-action@f16fc3bb6cd4886520b4e9328db1d42104d5cadc with: ref: master wait-interval: 30 running-workflow-name: 'build prebuilt' - - uses: actions/checkout@v2 + check-regexp: ^((?!.*(build master-ci).*).)*$ + - uses: actions/checkout@v3 with: submodules: true - name: Build Docker image diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000000..fb5a37eeef --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,29 @@ +name: release +on: + schedule: + - cron: '0 * * * *' + workflow_dispatch: + +jobs: + build_masterci: + name: build master-ci + runs-on: ubuntu-20.04 + timeout-minutes: 60 + if: github.repository == 'commaai/openpilot' + steps: + - name: Wait for green check mark + uses: commaai/wait-on-check-action@f16fc3bb6cd4886520b4e9328db1d42104d5cadc + with: + ref: master + wait-interval: 30 + running-workflow-name: 'build master-ci' + check-regexp: ^((?!.*(build prebuilt).*).)*$ + - uses: actions/checkout@v3 + with: + submodules: true + fetch-depth: 0 + - name: Pull LFS + run: git lfs pull + - name: Build master-ci + run: | + BRANCH=master-ci release/build_devel.sh diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 752a5ec357..5bd9acc200 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -7,7 +7,9 @@ on: env: BASE_IMAGE: openpilot-base + CL_BASE_IMAGE: openpilot-base-cl DOCKER_REGISTRY: ghcr.io/commaai + AZURE_TOKEN: ${{ secrets.AZURE_COMMADATACI_OPENPILOTCI_TOKEN }} DOCKER_LOGIN: docker login ghcr.io -u adeebshihadeh -p ${{ secrets.CONTAINER_TOKEN }} BUILD: | @@ -16,6 +18,12 @@ env: docker build --cache-from $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $BASE_IMAGE:latest -f Dockerfile.openpilot_base . RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache $BASE_IMAGE /bin/sh -c + + BUILD_CL: | + docker pull $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest || true + docker build --cache-from $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest -t $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest -t $CL_BASE_IMAGE:latest -f Dockerfile.openpilot_base_cl . + RUN_CL: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache $CL_BASE_IMAGE /bin/sh -c + UNIT_TEST: coverage run --append -m unittest discover jobs: @@ -25,10 +33,11 @@ jobs: runs-on: ubuntu-20.04 timeout-minutes: 50 env: - STRIPPED_DIR: tmppilot + STRIPPED_DIR: /tmp/releasepilot steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: + fetch-depth: 0 submodules: true - name: Check submodules if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot' @@ -45,16 +54,10 @@ jobs: restore-keys: | scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- scons- - - name: Strip non-release files + - name: Build devel run: | - mkdir $STRIPPED_DIR - cp -pR --parents $(cat release/files_common) $STRIPPED_DIR - cp -pR --parents $(cat release/files_tici) $STRIPPED_DIR - cp -pR --parents $(cat release/files_pc) $STRIPPED_DIR + TARGET_DIR=$STRIPPED_DIR release/build_devel.sh cp Dockerfile.openpilot_base $STRIPPED_DIR - - # need this to build on x86 - cp -pR --parents third_party/libyuv third_party/snpe selfdrive/modeld/runners $STRIPPED_DIR - name: Build Docker image run: eval "$BUILD" - name: Build openpilot and run checks @@ -62,32 +65,43 @@ jobs: cd $STRIPPED_DIR ${{ env.RUN }} "CI=1 python selfdrive/manager/build.py && \ python -m unittest discover selfdrive/car" - - name: Cleanup scons cache - run: | - cd $STRIPPED_DIR - ${{ env.RUN }} "scons -j$(nproc) && \ - rm -rf /tmp/scons_cache/* && \ - scons -j$(nproc) --cache-populate" build_all: name: build all runs-on: ubuntu-20.04 timeout-minutes: 50 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true + - name: Cache scons + id: scons-cache + # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. + uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b + env: + CACHE_SKIP_SAVE: ${{ github.ref != 'refs/heads/master' || github.repository != 'commaai/openpilot' }} + with: + path: /tmp/scons_cache + key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}-${{ steps.date.outputs.time }} + restore-keys: | + scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- + scons- - name: Build Docker image run: eval "$BUILD" - name: Build openpilot with all flags run: ${{ env.RUN }} "scons -j$(nproc) --extras --test" + - name: Cleanup scons cache + run: | + ${{ env.RUN }} "scons -j$(nproc) --extras --test && \ + rm -rf /tmp/scons_cache/* && \ + scons -j$(nproc) --extras --test --cache-populate" #build_mac: # name: build macos # runs-on: macos-latest # timeout-minutes: 60 # steps: - # - uses: actions/checkout@v2 + # - uses: actions/checkout@v3 # with: # submodules: true # - name: Determine pre-existing Homebrew packages @@ -146,9 +160,21 @@ jobs: env: IMAGE_NAME: openpilotwebcamci steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true + - name: Cache scons + id: scons-cache + # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. + uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b + env: + CACHE_SKIP_SAVE: true + with: + path: /tmp/scons_cache + key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- + restore-keys: | + scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- + scons- - name: Build Docker image run: | eval "$BUILD" @@ -169,7 +195,7 @@ jobs: if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/openpilot' needs: static_analysis # hack to ensure slow tests run first since this and static_analysis are fast steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true - name: Build Docker image @@ -178,26 +204,32 @@ jobs: run: | $DOCKER_LOGIN docker push $DOCKER_REGISTRY/$BASE_IMAGE:latest + - name: Build CL Docker image + run: eval "$BUILD_CL" + - name: Push to container registry + run: | + $DOCKER_LOGIN + docker push $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest static_analysis: name: static analysis runs-on: ubuntu-20.04 timeout-minutes: 50 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true - name: Build Docker image run: eval "$BUILD" - name: pre-commit - run: ${{ env.RUN }} "git init && git add -A && pre-commit run --all" + run: ${{ env.RUN }} "pre-commit run --all" valgrind: name: valgrind runs-on: ubuntu-20.04 timeout-minutes: 50 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true - name: Cache dependencies @@ -240,7 +272,7 @@ jobs: run: echo $TIMESTAMP env: TIMESTAMP: ${{ steps.date.outputs.time }} - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true - name: Cache scons @@ -272,11 +304,11 @@ jobs: $UNIT_TEST selfdrive/hardware/tici && \ $UNIT_TEST selfdrive/modeld && \ $UNIT_TEST tools/lib/tests && \ + ./common/tests/test_util && \ + ./common/tests/test_swaglog && \ ./selfdrive/boardd/tests/test_boardd_usbprotocol && \ - ./selfdrive/common/tests/test_util && \ - ./selfdrive/common/tests/test_swaglog && \ ./selfdrive/loggerd/tests/test_logger &&\ - ./selfdrive/proclogd/tests/test_proclog && \ + ./system/proclogd/tests/test_proclog && \ ./selfdrive/ui/replay/tests/test_replay && \ ./selfdrive/camerad/test/ae_gray_test && \ coverage xml" @@ -288,7 +320,7 @@ jobs: runs-on: ubuntu-20.04 timeout-minutes: 50 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true - name: Cache dependencies @@ -314,10 +346,8 @@ jobs: - name: Run replay run: | ${{ env.RUN }} "scons -j$(nproc) && \ - FILEREADER_CACHE=1 CI=1 coverage run selfdrive/test/process_replay/test_processes.py && \ + FILEREADER_CACHE=1 CI=1 coverage run selfdrive/test/process_replay/test_processes.py -j$(nproc) && \ coverage xml" - - name: "Upload coverage to Codecov" - uses: codecov/codecov-action@v2 - name: Print diff if: always() run: cat selfdrive/test/process_replay/diff.txt @@ -327,28 +357,58 @@ jobs: with: name: process_replay_diff.txt path: selfdrive/test/process_replay/diff.txt - - #model_replay: - # name: model replay - # runs-on: ubuntu-20.04 - # timeout-minutes: 50 - # steps: - # - uses: actions/checkout@v2 - # with: - # submodules: true - # - name: Build Docker image - # run: eval "$BUILD" - # - name: Run replay - # run: | - # ${{ env.RUN }} "scons -j$(nproc) && \ - # selfdrive/test/process_replay/model_replay.py" + - name: Upload reference logs + if: ${{ failure() && github.event_name == 'pull_request' && github.repository == 'commaai/openpilot' && env.AZURE_TOKEN != '' }} + run: | + ${{ env.RUN }} "scons -j$(nproc) && \ + CI=1 AZURE_TOKEN='$AZURE_TOKEN' python selfdrive/test/process_replay/test_processes.py -j$(nproc) --upload-only" + - name: "Upload coverage to Codecov" + uses: codecov/codecov-action@v2 + + model_replay_onnx: + name: model replay onnx + runs-on: ubuntu-20.04 + timeout-minutes: 50 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Pull LFS + run: git lfs pull + - name: Cache dependencies + id: dependency-cache + uses: actions/cache@v2 + with: + path: /tmp/comma_download_cache + key: ${{ hashFiles('.github/workflows/selfdrive_tests.yaml', 'selfdrive/test/process_replay/model_replay.py') }} + - name: Cache scons + id: scons-cache + # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. + uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b + env: + CACHE_SKIP_SAVE: true + with: + path: /tmp/scons_cache + key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- + restore-keys: | + scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- + scons- + - name: Build Docker image + # Sim docker is needed to get the intel OPENCL drivers + run: eval "$BUILD_CL" + - name: Run replay + run: | + ${{ env.RUN_CL }} "scons -j$(nproc) && \ + ONNXCPU=1 FILEREADER_CACHE=1 CI=1 coverage run \ + selfdrive/test/process_replay/model_replay.py -j$(nproc) && \ + coverage xml" test_longitudinal: name: longitudinal runs-on: ubuntu-20.04 timeout-minutes: 50 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true - name: Cache scons @@ -388,9 +448,9 @@ jobs: strategy: fail-fast: false matrix: - job: [0, 1, 2, 3] + job: [0, 1, 2, 3, 4] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true - name: Cache dependencies @@ -420,7 +480,7 @@ jobs: coverage xml && \ chmod -R 777 /tmp/comma_download_cache" env: - NUM_JOBS: 4 + NUM_JOBS: 5 JOB_ID: ${{ matrix.job }} - name: "Upload coverage to Codecov" uses: codecov/codecov-action@v2 @@ -430,7 +490,7 @@ jobs: runs-on: ubuntu-20.04 timeout-minutes: 50 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true - name: Build docker container diff --git a/.github/workflows/tools_tests.yaml b/.github/workflows/tools_tests.yaml index 0b0df4c516..b2433fba8f 100644 --- a/.github/workflows/tools_tests.yaml +++ b/.github/workflows/tools_tests.yaml @@ -5,6 +5,7 @@ on: env: BASE_IMAGE: openpilot-base + CL_BASE_IMAGE: openpilot-base-cl DOCKER_REGISTRY: ghcr.io/commaai DOCKER_LOGIN: docker login ghcr.io -u adeebshihadeh -p ${{ secrets.CONTAINER_TOKEN }} @@ -12,16 +13,60 @@ env: docker pull $(grep -iohP '(?<=^from)\s+\S+' Dockerfile.openpilot_base) || true docker pull $DOCKER_REGISTRY/$BASE_IMAGE:latest || true docker build --cache-from $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $BASE_IMAGE:latest -f Dockerfile.openpilot_base . + BUILD_CL: | + docker pull $(grep -iohP '(?<=^from)\s+\S+' Dockerfile.openpilot_base_cl) || true + docker pull $DOCKER_REGISTRY/$BASE_IMAGE:latest || true + docker build --cache-from $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest -t $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest -t $CL_BASE_IMAGE:latest -f Dockerfile.openpilot_base_cl . RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e \ GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/comma_download_cache:/tmp/comma_download_cache $BASE_IMAGE /bin/sh -c jobs: + build_latest_ubuntu: + name: build latest ubuntu + runs-on: ubuntu-20.04 + timeout-minutes: 60 + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Cache pyenv + id: ubuntu-latest-pyenv + uses: actions/cache@v3 + with: + path: | + ~/.pyenv + ~/.local/share/virtualenvs/ + key: ubuntu-latest-python-${{ hashFiles('tools/ubuntu_setup.sh') }}- + - name: Cache scons + id: ubuntu-latest-scons + uses: actions/cache@v3 + with: + path: /tmp/scons_cache + key: ubuntu-latest-scons-${{ hashFiles('.github/workflows/tools_test.yaml') }}- + restore-keys: | + ubuntu-latest-scons-${{ hashFiles('.github/workflows/tools_test.yaml') }}- + ubuntu-latest-scons- + + - name: tools/ubuntu_setup.sh + run: | + source tools/openpilot_env.sh + tools/ubuntu_setup.sh + - name: Build openpilot + run: | + source tools/openpilot_env.sh + pipenv run scons -j$(nproc) --extras --test + - name: Cleanup scons cache + run: | + source tools/openpilot_env.sh + rm -rf /tmp/scons_cache/* + pipenv run scons -j$(nproc) --extras --test --cache-populate + plotjuggler: name: plotjuggler runs-on: ubuntu-20.04 timeout-minutes: 30 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true - name: Build Docker image @@ -42,28 +87,19 @@ jobs: IMAGE_NAME: openpilot-sim if: github.repository == 'commaai/openpilot' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true - - # HACK: cache LFS objects since they count against our quota - # https://github.com/actions/checkout/issues/165#issuecomment-657673315 - - name: Create LFS file list - run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id - - name: Restore LFS cache - uses: actions/cache@v2 - id: lfs-cache - with: - path: .git/lfs - key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }} - - name: Git LFS Pull + - name: Pull LFS run: git lfs pull - - - name: Build Docker image - run: | - eval "$BUILD" - docker pull $DOCKER_REGISTRY/$IMAGE_NAME:latest || true - docker build --cache-from $DOCKER_REGISTRY/$IMAGE_NAME:latest -t $DOCKER_REGISTRY/$IMAGE_NAME:latest -f tools/sim/Dockerfile.sim . + - name: Build base image + run: eval "$BUILD" + - name: Build base cl image + run: eval "$BUILD_CL" + - name: Pull latest simulator image + run: docker pull $DOCKER_REGISTRY/$IMAGE_NAME:latest || true + - name: Build simulator image + run: docker build --cache-from $DOCKER_REGISTRY/$IMAGE_NAME:latest -t $DOCKER_REGISTRY/$IMAGE_NAME:latest -f tools/sim/Dockerfile.sim . - name: Push to container registry if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot' run: | diff --git a/.gitignore b/.gitignore index 06c6117b18..334b1b4fed 100644 --- a/.gitignore +++ b/.gitignore @@ -41,7 +41,7 @@ board/obj/ selfdrive/boardd/boardd selfdrive/logcatd/logcatd selfdrive/mapd/default_speeds_by_region.json -selfdrive/proclogd/proclogd +system/proclogd/proclogd selfdrive/ui/_ui selfdrive/test/longitudinal_maneuvers/out selfdrive/visiond/visiond @@ -56,6 +56,7 @@ selfdrive/modeld/_dmonitoringmodeld /src/ one +/body/ openpilot notebooks xx @@ -76,7 +77,7 @@ cppcheck_report.txt comma*.sh selfdrive/modeld/thneed/compile -models/*.thneed +selfdrive/modeld/models/*.thneed *.bz2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cf41b28a90..81ce927f65 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,12 +20,13 @@ repos: hooks: - id: mypy exclude: '^(pyextra/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(opendbc/)|(laika_repo/)|(rednose_repo/)/' - additional_dependencies: ['git+https://github.com/numpy/numpy-stubs', 'types-requests', 'types-atomicwrites', - 'types-pycurl', 'types-certifi'] + additional_dependencies: ['lxml', 'numpy', 'types-atomicwrites', 'types-pycurl', 'types-requests', 'types-certifi'] args: - - --warn-unused-ignores - --warn-redundant-casts + - --warn-return-any - --warn-unreachable + - --warn-unused-ignores + #- --html-report=/home/batman/openpilot - repo: https://github.com/PyCQA/flake8 rev: 4.0.1 hooks: diff --git a/.pylintrc b/.pylintrc index 73035360ca..58988c5d74 100644 --- a/.pylintrc +++ b/.pylintrc @@ -3,7 +3,7 @@ # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code -extension-pkg-whitelist=scipy cereal.messaging.messaging_pyx +extension-pkg-whitelist=scipy,cereal.messaging.messaging_pyx,PyQt5,av # Add files or directories to the blacklist. They should be base names, not # paths. @@ -250,13 +250,6 @@ max-line-length=100 # Maximum number of lines in a module max-module-lines=1000 -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma, - dict-separator - # Allow the body of a class to be on the same line as the declaration if body # contains single statement. single-line-class-stmt=no diff --git a/Dockerfile.openpilot b/Dockerfile.openpilot index daf85f8183..102da78d7d 100644 --- a/Dockerfile.openpilot +++ b/Dockerfile.openpilot @@ -8,11 +8,6 @@ ENV PYTHONPATH ${OPENPILOT_PATH}:${PYTHONPATH} RUN mkdir -p ${OPENPILOT_PATH} WORKDIR ${OPENPILOT_PATH} -COPY Pipfile Pipfile.lock $OPENPILOT_PATH -RUN pip install --no-cache-dir pipenv==2021.5.29 pip==21.3.1 && \ - pipenv install --system --deploy --dev --clear && \ - pip uninstall -y pipenv - COPY SConstruct ${OPENPILOT_PATH} COPY ./pyextra ${OPENPILOT_PATH}/pyextra @@ -28,5 +23,6 @@ COPY ./opendbc ${OPENPILOT_PATH}/opendbc COPY ./cereal ${OPENPILOT_PATH}/cereal COPY ./panda ${OPENPILOT_PATH}/panda COPY ./selfdrive ${OPENPILOT_PATH}/selfdrive +COPY ./system ${OPENPILOT_PATH}/system -RUN scons -j$(nproc) +RUN scons --cache-readonly -j$(nproc) diff --git a/Dockerfile.openpilot_base b/Dockerfile.openpilot_base index c5a024db82..0de3008baf 100644 --- a/Dockerfile.openpilot_base +++ b/Dockerfile.openpilot_base @@ -4,7 +4,7 @@ ENV PYTHONUNBUFFERED 1 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ - apt-get install -y --no-install-recommends sudo tzdata locales && \ + apt-get install -y --no-install-recommends sudo tzdata locales ssh && \ rm -rf /var/lib/apt/lists/* RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen @@ -29,5 +29,5 @@ RUN cd /tmp && \ cd /usr/lib/gcc/arm-none-eabi/9.2.1 && \ rm -rf arm/ && \ rm -rf thumb/nofp thumb/v6* thumb/v8* thumb/v7+fp thumb/v7-r+fp.sp -RUN sudo git config --global --add safe.directory /tmp/openpilot +RUN sudo git config --global --add safe.directory /tmp/openpilot diff --git a/Dockerfile.openpilot_base_cl b/Dockerfile.openpilot_base_cl new file mode 100644 index 0000000000..7652b7e4e6 --- /dev/null +++ b/Dockerfile.openpilot_base_cl @@ -0,0 +1,37 @@ +FROM ghcr.io/commaai/openpilot-base:latest + +RUN apt-get update && apt-get install -y --no-install-recommends\ + apt-utils \ + alien \ + unzip \ + tar \ + curl \ + xz-utils \ + dbus \ + gcc-arm-none-eabi \ + tmux \ + vim \ + lsb-core \ + libx11-6 \ + && rm -rf /var/lib/apt/lists/* + +# Intel OpenCL driver +ARG INTEL_DRIVER=l_opencl_p_18.1.0.015.tgz +ARG INTEL_DRIVER_URL=http://registrationcenter-download.intel.com/akdlm/irc_nas/vcp/15532 +RUN mkdir -p /tmp/opencl-driver-intel +WORKDIR /tmp/opencl-driver-intel +RUN echo INTEL_DRIVER is $INTEL_DRIVER && \ + curl -O $INTEL_DRIVER_URL/$INTEL_DRIVER && \ + tar -xzf $INTEL_DRIVER && \ + for i in $(basename $INTEL_DRIVER .tgz)/rpm/*.rpm; do alien --to-deb $i; done && \ + dpkg -i *.deb && \ + rm -rf $INTEL_DRIVER $(basename $INTEL_DRIVER .tgz) *.deb && \ + mkdir -p /etc/OpenCL/vendors && \ + echo /opt/intel/opencl_compilers_and_libraries_18.1.0.015/linux/compiler/lib/intel64_lin/libintelocl.so > /etc/OpenCL/vendors/intel.icd && \ + rm -rf /tmp/opencl-driver-intel +ENV NVIDIA_VISIBLE_DEVICES all +ENV NVIDIA_DRIVER_CAPABILITIES graphics,utility,compute +ENV QTWEBENGINE_DISABLE_SANDBOX 1 + +RUN dbus-uuidgen > /etc/machine-id + diff --git a/Jenkinsfile b/Jenkinsfile index c5edda56fd..ebc26a5920 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -42,6 +42,7 @@ def phone_steps(String device_type, steps) { pipeline { agent none environment { + CI = "1" TEST_DIR = "/data/openpilot" SOURCE_DIR = "/data/openpilot_source/" } @@ -74,105 +75,87 @@ pipeline { } } - stages { - stage('On-device Tests') { - agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } } - stages { - stage('parallel tests') { - parallel { - /* - stage('Power Consumption Tests') { - steps { - lock(resource: "", label: "c2-zookeeper", inversePrecedence: true, variable: 'device_ip', quantity: 1) { - timeout(time: 90, unit: 'MINUTES') { - sh script: "/home/batman/tools/zookeeper/enable_and_wait.py $device_ip 120", label: "turn on device" - phone(device_ip, "git checkout", readFile("selfdrive/test/setup_device_ci.sh"),) - phone(device_ip, "build", "scons -j4 && sync") - sh script: "/home/batman/tools/zookeeper/disable.py $device_ip", label: "turn off device" - sh script: "/home/batman/tools/zookeeper/enable_and_wait.py $device_ip 120", label: "turn on device" - sh script: "/home/batman/tools/zookeeper/check_consumption.py 60 3", label: "idle power consumption after boot" - sh script: "/home/batman/tools/zookeeper/ignition.py 1", label: "go onroad" - sh script: "/home/batman/tools/zookeeper/check_consumption.py 60 10", label: "onroad power consumption" - sh script: "/home/batman/tools/zookeeper/ignition.py 0", label: "go offroad" - sh script: "/home/batman/tools/zookeeper/check_consumption.py 60 2", label: "idle power consumption offroad" - } - } - } - } - */ - - stage('build') { - environment { - R3_PUSH = "${env.BRANCH_NAME == 'master' ? '1' : ' '}" - } - steps { - phone_steps("tici", [ - ["build master-ci", "cd $SOURCE_DIR/release && EXTRA_FILES='tools/' ./build_devel.sh"], - ["build openpilot", "cd selfdrive/manager && ./build.py"], - ["test manager", "python selfdrive/manager/test/test_manager.py"], - ["onroad tests", "cd selfdrive/test/ && ./test_onroad.py"], - ["test car interfaces", "cd selfdrive/car/tests/ && ./test_car_interfaces.py"], - ]) - } - } - - stage('HW + Unit Tests') { - steps { - phone_steps("tici2", [ - ["build", "cd selfdrive/manager && ./build.py"], - ["test power draw", "python selfdrive/hardware/tici/test_power_draw.py"], - ["test boardd loopback", "python selfdrive/boardd/tests/test_boardd_loopback.py"], - ["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"], - ["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python selfdrive/loggerd/tests/test_encoder.py"], - ]) - } - } - - stage('camerad') { - steps { - phone_steps("tici-party", [ - ["build", "cd selfdrive/manager && ./build.py"], - ["test camerad", "python selfdrive/camerad/test/test_camerad.py"], - ["test exposure", "python selfdrive/camerad/test/test_exposure.py"], - ]) - } - } - - stage('replay') { - steps { - phone_steps("tici3", [ - ["build", "cd selfdrive/manager && ./build.py"], - ["model replay", "cd selfdrive/test/process_replay && ./model_replay.py"], - ]) - } - } - - } - } + parallel { - stage('Push master-ci') { - when { - branch 'master' - } - steps { - phone_steps("tici-build", [ - ["push devel", "cd $SOURCE_DIR/release && PUSH='master-ci' ./build_devel.sh"], - ]) - } + stage('simulator') { + agent { + dockerfile { + filename 'Dockerfile.sim_nvidia' + dir 'tools/sim' + args '--user=root' + } + } + steps { + sh "git config --global --add safe.directory ${WORKSPACE}" + sh "git lfs pull" + sh "${WORKSPACE}/tools/sim/build_container.sh" + lock(resource: "", label: "simulator", inversePrecedence: true, quantity: 1) { + sh "DETACH=1 ${WORKSPACE}/tools/sim/start_carla.sh" + sh "${WORKSPACE}/tools/sim/start_openpilot_docker.sh" } - } post { always { - cleanWs() + sh "docker kill carla_sim || true" + sh "rm -rf ${WORKSPACE}/* || true" + sh "rm -rf .* || true" } } + } + + stage('build') { + agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } } + environment { + R3_PUSH = "${env.BRANCH_NAME == 'master' ? '1' : ' '}" + } + steps { + phone_steps("tici", [ + ["build master-ci", "cd $SOURCE_DIR/release && TARGET_DIR=$TEST_DIR EXTRA_FILES='tools/' ./build_devel.sh"], + ["build openpilot", "cd selfdrive/manager && ./build.py"], + ["test manager", "python selfdrive/manager/test/test_manager.py"], + ["onroad tests", "cd selfdrive/test/ && ./test_onroad.py"], + ["test car interfaces", "cd selfdrive/car/tests/ && ./test_car_interfaces.py"], + ]) + } + } + + stage('HW + Unit Tests') { + agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } } + steps { + phone_steps("tici2", [ + ["build", "cd selfdrive/manager && ./build.py"], + ["test power draw", "python system/hardware/tici/test_power_draw.py"], + ["test boardd loopback", "python selfdrive/boardd/tests/test_boardd_loopback.py"], + ["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"], + ["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python selfdrive/loggerd/tests/test_encoder.py"], + ["test sensord", "python selfdrive/sensord/test/test_sensord.py"], + ]) + } + } + stage('camerad') { + agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } } + steps { + phone_steps("tici-party", [ + ["build", "cd selfdrive/manager && ./build.py"], + ["test camerad", "python selfdrive/camerad/test/test_camerad.py"], + ["test exposure", "python selfdrive/camerad/test/test_exposure.py"], + ]) + } } + stage('replay') { + agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } } + steps { + phone_steps("tici3", [ + ["build", "cd selfdrive/manager && ./build.py"], + ["model replay", "cd selfdrive/test/process_replay && ./model_replay.py"], + ]) + } + } } + } } } - diff --git a/Pipfile b/Pipfile index 6d30179b9d..b8545b1a21 100644 --- a/Pipfile +++ b/Pipfile @@ -4,12 +4,14 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] +av = "*" +azure-storage-blob = "~=2.1" control = "*" coverage = "*" dictdiffer = "*" fastcluster = "*" hexdump = "*" -hypothesis = "*" +hypothesis = "==6.46.7" inputs = "*" lru-dict = "*" markdown-it-py = "*" @@ -37,7 +39,8 @@ breathe = "*" subprocess32 = "*" tenacity = "*" mpld3 = "*" -carla = "==0.9.12" +carla = {version = "==0.9.13", markers="platform_system != 'Darwin'"} +ft4222 = "*" [packages] atomicwrites = "*" @@ -56,6 +59,7 @@ json-rpc = "*" libusb1 = "*" nose = "*" numpy = "*" +protobuf = "==3.20.1" onnx = "*" onnxruntime-gpu = {version = "*", markers="platform_system != 'Darwin'"} pillow = "*" @@ -81,6 +85,9 @@ tqdm = "*" urllib3 = "*" utm = "*" websocket_client = "*" +hatanaka = "==2.4" +PyQt5 = "==5.15.4" +PyQt5-sip = "==12.9.0" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 2c62e13dfa..cc347a60f4 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "41e285b10b9b5a353b3eb9c202886e52d22403c369784877aaa35e099aa203a8" + "sha256": "d2629168f477b3a14f68f26e3b63ea9797b20599c066b2aa23a027bcee2ca40a" }, "pipfile-spec": 6, "requires": { @@ -18,11 +18,11 @@ "default": { "astroid": { "hashes": [ - "sha256:8d0a30fe6481ce919f56690076eafbb2fb649142a89dc874f1ec0e7a011492d0", - "sha256:cc8cc0d2d916c42d0a7c476c57550a4557a083081976bf42a73414322a6411d9" + "sha256:4f933d0bf5e408b03a6feb5d23793740c27e07340605f236496cd6ce552043d6", + "sha256:ba33a82a9a9c06a5ceed98180c5aab16e29c285b828d94696bf32d6015ea82a9" ], "markers": "python_full_version >= '3.6.2'", - "version": "==2.11.2" + "version": "==2.11.6" }, "atomicwrites": { "hashes": [ @@ -79,10 +79,11 @@ }, "certifi": { "hashes": [ - "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", - "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" + "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7", + "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a" ], - "version": "==2021.10.8" + "markers": "python_version >= '3.6'", + "version": "==2022.5.18.1" }, "cffi": { "hashes": [ @@ -145,16 +146,16 @@ "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df" ], - "markers": "python_version >= '3'", + "markers": "python_full_version >= '3.5.0'", "version": "==2.0.12" }, "click": { "hashes": [ - "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e", - "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72" + "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", + "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" ], "markers": "python_version >= '3.7'", - "version": "==8.1.2" + "version": "==8.1.3" }, "crcmod": { "hashes": [ @@ -168,79 +169,85 @@ }, "cryptography": { "hashes": [ - "sha256:0a3bf09bb0b7a2c93ce7b98cb107e9170a90c51a0162a20af1c61c765b90e60b", - "sha256:1f64a62b3b75e4005df19d3b5235abd43fa6358d5516cfc43d87aeba8d08dd51", - "sha256:32db5cc49c73f39aac27574522cecd0a4bb7384e71198bc65a0d23f901e89bb7", - "sha256:4881d09298cd0b669bb15b9cfe6166f16fc1277b4ed0d04a22f3d6430cb30f1d", - "sha256:4e2dddd38a5ba733be6a025a1475a9f45e4e41139d1321f412c6b360b19070b6", - "sha256:53e0285b49fd0ab6e604f4c5d9c5ddd98de77018542e88366923f152dbeb3c29", - "sha256:70f8f4f7bb2ac9f340655cbac89d68c527af5bb4387522a8413e841e3e6628c9", - "sha256:7b2d54e787a884ffc6e187262823b6feb06c338084bbe80d45166a1cb1c6c5bf", - "sha256:7be666cc4599b415f320839e36367b273db8501127b38316f3b9f22f17a0b815", - "sha256:8241cac0aae90b82d6b5c443b853723bcc66963970c67e56e71a2609dc4b5eaf", - "sha256:82740818f2f240a5da8dfb8943b360e4f24022b093207160c77cadade47d7c85", - "sha256:8897b7b7ec077c819187a123174b645eb680c13df68354ed99f9b40a50898f77", - "sha256:c2c5250ff0d36fd58550252f54915776940e4e866f38f3a7866d92b32a654b86", - "sha256:ca9f686517ec2c4a4ce930207f75c00bf03d94e5063cbc00a1dc42531511b7eb", - "sha256:d2b3d199647468d410994dbeb8cec5816fb74feb9368aedf300af709ef507e3e", - "sha256:da73d095f8590ad437cd5e9faf6628a218aa7c387e1fdf67b888b47ba56a17f0", - "sha256:e167b6b710c7f7bc54e67ef593f8731e1f45aa35f8a8a7b72d6e42ec76afd4b3", - "sha256:ea634401ca02367c1567f012317502ef3437522e2fc44a3ea1844de028fa4b84", - "sha256:ec6597aa85ce03f3e507566b8bcdf9da2227ec86c4266bd5e6ab4d9e0cc8dab2", - "sha256:f64b232348ee82f13aac22856515ce0195837f6968aeaa94a3d0353ea2ec06a6" - ], - "index": "pypi", - "version": "==36.0.2" + "sha256:093cb351031656d3ee2f4fa1be579a8c69c754cf874206be1d4cf3b542042804", + "sha256:0cc20f655157d4cfc7bada909dc5cc228211b075ba8407c46467f63597c78178", + "sha256:1b9362d34363f2c71b7853f6251219298124aa4cc2075ae2932e64c91a3e2717", + "sha256:1f3bfbd611db5cb58ca82f3deb35e83af34bb8cf06043fa61500157d50a70982", + "sha256:2bd1096476aaac820426239ab534b636c77d71af66c547b9ddcd76eb9c79e004", + "sha256:31fe38d14d2e5f787e0aecef831457da6cec68e0bb09a35835b0b44ae8b988fe", + "sha256:3b8398b3d0efc420e777c40c16764d6870bcef2eb383df9c6dbb9ffe12c64452", + "sha256:3c81599befb4d4f3d7648ed3217e00d21a9341a9a688ecdd615ff72ffbed7336", + "sha256:419c57d7b63f5ec38b1199a9521d77d7d1754eb97827bbb773162073ccd8c8d4", + "sha256:46f4c544f6557a2fefa7ac8ac7d1b17bf9b647bd20b16decc8fbcab7117fbc15", + "sha256:471e0d70201c069f74c837983189949aa0d24bb2d751b57e26e3761f2f782b8d", + "sha256:59b281eab51e1b6b6afa525af2bd93c16d49358404f814fe2c2410058623928c", + "sha256:731c8abd27693323b348518ed0e0705713a36d79fdbd969ad968fbef0979a7e0", + "sha256:95e590dd70642eb2079d280420a888190aa040ad20f19ec8c6e097e38aa29e06", + "sha256:a68254dd88021f24a68b613d8c51d5c5e74d735878b9e32cc0adf19d1f10aaf9", + "sha256:a7d5137e556cc0ea418dca6186deabe9129cee318618eb1ffecbd35bee55ddc1", + "sha256:aeaba7b5e756ea52c8861c133c596afe93dd716cbcacae23b80bc238202dc023", + "sha256:dc26bb134452081859aa21d4990474ddb7e863aa39e60d1592800a8865a702de", + "sha256:e53258e69874a306fcecb88b7534d61820db8a98655662a3dd2ec7f1afd9132f", + "sha256:ef15c2df7656763b4ff20a9bc4381d8352e6640cfeb95c2972c38ef508e75181", + "sha256:f224ad253cc9cea7568f49077007d2263efa57396a2f2f78114066fd54b5c68e", + "sha256:f8ec91983e638a9bcd75b39f1396e5c0dc2330cbd9ce4accefe68717e6779e0a" + ], + "index": "pypi", + "version": "==37.0.2" }, "cython": { "hashes": [ - "sha256:004387d8b94c64681ee05660d6a234e125396097726cf2f419c0fa2ac38034d6", - "sha256:0378a14d2580dcea234d7a2dc8d75f60c091105885096e6dd5b032be97542c16", - "sha256:03b749e4f0bbf631cee472add2806d338a7d496f8383f6fb28cc5fdc34b7fdb8", - "sha256:05edfa51c0ff31a8df3cb291b90ca93ab499686d023b9b81c216cd3509f73def", - "sha256:076aa8da83383e2bed0ca5f92c13a7e76e684bc41fe8e438bbed735f5b1c2731", - "sha256:09448aadb818387160ca4d1e1b82dbb7001526b6d0bed7529c4e8ac12e3b6f4c", - "sha256:1612d7439590ba3b8de5f907bf0e54bd8e024eafb8c59261531a7988030c182d", - "sha256:16f2e74fcac223c53e298ecead62c353d3cffa107bea5d8232e4b2ba40781634", - "sha256:26d8d0ededca42be50e0ac377c08408e18802b1391caa3aea045a72c1bff47ac", - "sha256:31465dce7fd3f058d02afb98b13af962848cc607052388814428dc801cc26f57", - "sha256:33b69ac9bbf2b93d8cae336cfe48889397a857e6ceeb5cef0b2f0b31b6c54f2b", - "sha256:341917bdb2c95bcf8322aacfe50bbe6b4794880b16fa8b2300330520e123a5e5", - "sha256:43eca77169f855dd04be11921a585c8854a174f30bc925257e92bc7b9197fbd2", - "sha256:49076747b731ed78acf203666c3b3c5d664754ea01ca4527f62f6d8675703688", - "sha256:4b3089255b6b1cc69e4b854626a41193e6acae5332263d24707976b3cb8ca644", - "sha256:5658fa477e80d96c49d5ff011938dd4b62da9aa428f771b91f1a7c49af45aad8", - "sha256:59f4e86b415620a097cf0ec602adf5a7ee3cc33e8220567ded96566f753483f8", - "sha256:5e82f6b3dc2133b2e0e2c5c63d352d40a695e40cc7ed99f4cbe83334bcf9ab39", - "sha256:6626f9691ce2093ccbcc9932f449efe3b6e1c893b556910881d177c61612e8ff", - "sha256:75686c586e37b1fed0fe4a2c053474f96fc07da0063bbfc98023454540515d31", - "sha256:7962a78ceb80cdec21345fb5088e675060fa65982030d446069f2d675d30e3cd", - "sha256:9d39ee7ddef6856413f950b8959e852d83376d9db1c509505e3f4873df32aa70", - "sha256:9f2b7c86a73db0d8dbbd885fe67f04c7b787df37a3848b9867270d3484101fbd", - "sha256:a0ed39c63ba52edd03a39ea9d6da6f5326aaee5d333c317feba543270a1b3af5", - "sha256:a3b27812ac9e9737026bfbb1dd47434f3e84013f430bafe1c6cbaf1cd51b5518", - "sha256:b6c77cc24861a33714e74212abfab4e54bf42e1ad602623f193b8e369389af2f", - "sha256:c9848a423a14e8f51bd4bbf8e2ff37031764ce66bdc7c6bc06c70d4084eb23c7", - "sha256:d6036f6a5a0c7fb1af88889872268b15bf20dd9cefe33a6602d79ba18b8db20f", - "sha256:d6fac2342802c30e51426828fe084ff4deb1b3387367cf98976bb2e64b6f8e45", - "sha256:d7c98727397c2547a56aa0c3c98140f1873c69a0642edc9446c6c870d0d8a5b5", - "sha256:d7d7beb600d5dd551e9322e1393b74286f4a3d4aa387f7bfbaccc1495a98603b", - "sha256:ded4fd3da4dee2f4414c35214244e29befa7f6fede3e9be317e765169df2cbc7", - "sha256:e24bd94946ffa37f30fcb865f2340fb6d429a3c7bf87b47b22f7d22e0e68a15c", - "sha256:e9cc6af0c9c477c5e175e807dce439509934efefc24ea2da9fced7fbc8170591", - "sha256:ed32c206e1d68056a34b21d2ec0cf0f23d338d6531476a68c73e21e20bd7bb63", - "sha256:fdcef7abb09fd827691e3abe6fd42c6c34beaccfa0bc2df6074f0a49949df6a8" - ], - "index": "pypi", - "version": "==0.29.28" + "sha256:019d330ac580b2ca4a457c464ac0b8c35009d820ef5d09f328d6e31a10e1ce89", + "sha256:0b83a342a071c4f14e7410568e0c0bd95e2f20c0b32944e3a721649a1357fda4", + "sha256:0cd6c932e945af15ae4ddcf8fdc0532bda48784c92ed0a53cf4fae897067ccd1", + "sha256:1e078943bbde703ca08d43e719480eb8b187d9023cbd91798619f5b5e18d0d71", + "sha256:20778297c8bcba201ca122a2f792a9899d6e64c68a92363dd7eb24306d54d7ce", + "sha256:2235b62da8fe6fa8b99422c8e583f2fb95e143867d337b5c75e4b9a1a865f9e3", + "sha256:28db751e2d8365b39664d9cb62dc1668688b8fcc5b954e9ca9d20e0b8e03d8b0", + "sha256:3993aafd68a7311ef94e00e44a137f6a50a69af0575ebcc8a0a074ad4152a2b2", + "sha256:3d0239c7a22a0f3fb1deec75cab0078eba4dd17868aa992a54a178851e0c8684", + "sha256:5183356c756b56c2df12d96300d602e47ffb89943c5a0bded66faca5d3da7be0", + "sha256:58d2b734250c1093bc69c1c3a6f5736493b9f8b34eb765f0a28a4a09468c0b00", + "sha256:5a8a3709ad9343a1dc02b8ec9cf6bb284be248d2c64af85464d9c3525eec74a5", + "sha256:5c7cfd908efc77306ddd41ef07f5a7a352c9205ced5c1e00a0e5ece4391707c4", + "sha256:5f2dae7dd56860018d5fd5032a71f11fdc224020932b463d0511a1536f27df85", + "sha256:60d370c33d56077d30e5f425026e58c2559e93b4784106f61581cf54071f6270", + "sha256:6b389a94b42909ff56d3491fde7c44802053a103701a7d210dcdd449a5b4f7b4", + "sha256:71fd1d910aced510c001936667fc7f2901c49b2ca7a2ad67358979c94a7f42ac", + "sha256:786ee7b0cdb508b6de64c0f1f9c74f207186dfafad1ef938f25b7494cc481a80", + "sha256:7eff71c39b98078deaad1d1bdbf10864d234e2ab5d5257e980a6926a8523f697", + "sha256:80a7255ad84620f53235c0720cdee2bc7431d9e3db7b3742823a606c329eb539", + "sha256:88c5e2f92f16cd999ddfc43d572639679e8a057587088e627e98118e46a803e6", + "sha256:8e08f18d249b9b65e272a5a60f3360a8922c4c149036b98fc821fe1afad5bdae", + "sha256:9462e9cf284d9b1d2c5b53d62188e3c09cc5c7a0018ba349d99b73cf930238de", + "sha256:9826981308802c61a76f967875b31b7c683b7fc369eabaa6cbc22efeb12c90e8", + "sha256:9f1fe924c920b699af27aefebd722df4cfbb85206291623cd37d1a7ddfd57792", + "sha256:a30092c6e2d24255fbfe0525f9a750554f96a263ed986d12ac3c9f7d9a85a424", + "sha256:abcaf99f90cddc0f53600613eaafc81d27c4ac0671f0df8bce5466d4e86d54a1", + "sha256:acb72e0b42079862cf2f894964b41f261e941e75677e902c5f4304b3eb00af33", + "sha256:b17639b6a155abaa61a89f6f1323fb57b138d0529911ca03978d594945d062ba", + "sha256:c299c5b250ae9f81c38200441b6f1d023aeee9d8e7f61c04001c7437181ccb06", + "sha256:c79685dd4631a188e2385dc6a232896c7b67ea2e3e5f8b5555b4b743f475d6d7", + "sha256:d0859a958e0155b6ae4dee04170ccfac2c3d613a7e3bee8749614530b9e3b4a4", + "sha256:d0f34b44078e3e0b2f1be2b99044619b37127128e7d55c54bbd2438adcaf31d3", + "sha256:d166d9f853db436f5e10733a9bd615699ddb4238feadcbdf5ae50dc0b18b18f5", + "sha256:d52d5733dcb144deca8985f0a197c19cf71e6bd6bd9d8034f3f67b2dea68d12b", + "sha256:e29d3487f357108b711f2f29319811d92166643d29aec1b8e063aad46a346775", + "sha256:e36755e71fd20eceb410cc441b7f2586654c2edb013f4663842fdaf60b96c1ca", + "sha256:e5cb144728a335d7a7fd0a61dff6abb7a9aeff9acd46d50b886b7d9a95bb7311", + "sha256:e605635a92ae862cb46d84d1d6883324518f9aaff4a71cede6d61df20b6a410c", + "sha256:ffa8c09617833ff0824aa7926fa4fa9d2ec3929c67168e89105f276b7f36a63e" + ], + "index": "pypi", + "version": "==0.29.30" }, "dill": { "hashes": [ - "sha256:7e40e4a70304fd9ceab3535d36e58791d9c4a776b38ec7f7ec9afc8d3dca4d4f", - "sha256:9f9734205146b2b353ab3fec9af0070237b6ddae78452af83d2fca84d739e675" + "sha256:33501d03270bbe410c72639b350e941882a8b0fd55357580fbc873fba0c59302", + "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86" ], - "markers": "python_version >= '2.7' and python_version != '3.0'", - "version": "==0.3.4" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", + "version": "==0.3.5.1" }, "flake8": { "hashes": [ @@ -252,11 +259,11 @@ }, "flask": { "hashes": [ - "sha256:8a4cf32d904cf5621db9f0c9fbcd7efabf3003f22a04e4d0ce790c7137ec5264", - "sha256:a8c9bd3e558ec99646d177a9739c41df1ded0629480b4c8d2975412f3c9519c8" + "sha256:315ded2ddf8a6281567edb27393010fe3406188bafbfe65a3339d5787d89e477", + "sha256:fad5b446feb0d6db6aec0c3184d16a8c1f6c3e464b511649c8918a9be100b4fe" ], "index": "pypi", - "version": "==2.1.1" + "version": "==2.1.2" }, "flatbuffers": { "hashes": [ @@ -281,6 +288,53 @@ "index": "pypi", "version": "==20.1.0" }, + "h3": { + "hashes": [ + "sha256:08a09f7a43ed142573c602ef487a058da54ab4d86c173082b29a5057805fe2d3", + "sha256:0a96ea1844182bd0511cdcdc89e38e3026d9a3d4139fd0c5e899709edd798ffa", + "sha256:1387166f453816f91d624c6ce70876a3c20356cd28a3a759920dee23c78684cf", + "sha256:25f0c22f4802ab71c45b86d206bd30fa0a6c7fbc3b630398b60c22907e9742e6", + "sha256:2bf4d75fe42a260ac23bf4cb9f9de6e6f2aa37279b2719387711f3e0727c4653", + "sha256:2faf304020493c5ffede34264bd28ed529b8b7238103e0904c0f3e9ca880bcfd", + "sha256:33b147ecc0e19ab1f27303d0e3ae28e5a457f3347ce18ca9a58b694a8b0cdd0a", + "sha256:38a084d74b234d48aafc01e4329cd9a92966e3f45b8cf21224118643b6eaa1c0", + "sha256:3b1642085939c597a9c723ae3b187f80527ffc79cad0ded0e55be9c9bac69c6c", + "sha256:4469fdf90034b1a67e155cac4f46b077fdc404b6182ab33abcb7081c9bfbf411", + "sha256:46a1284521d86cab414981056390be944dca780fe74c6c9e463a16d1c8d24871", + "sha256:585f375ba2a95ceb16b115a378e9118159c912c26703cf1627f57a004818c3b3", + "sha256:62057c1c3d1c7fe492841e42fa360825d66fafd55ac37dc4e90b2292af21cb47", + "sha256:68227df989274b0da54de9101a50741c70c48197ba3beacfb97c88170445c18e", + "sha256:7b0ddfdd02920996d7c6672c91e83efb5432c67ff83f89a03f774e84bcfe19f8", + "sha256:7c5366d24c2c01ef3bae68547c15f1965fac6053b2596c0073766bf7544ecaf0", + "sha256:8155b2de1938eb56128fe4fd96e4f6d2022d4c34d8137bc95d73cbf329f8f89e", + "sha256:83c2b0cd8259541f95b0493a620fb781b6a18c7c1e8fac1bda4fb234ae23ab43", + "sha256:8d03622433da1a2761574311af378ff1ff841f5956db25927837c6aee9d1c13c", + "sha256:960cd005b8817314d95fbaff3e848a72385df4e3c6c9703ff99b08581c8def69", + "sha256:9b0277d82578b3ed3220167ef5c5acd8b4e0ef2fcd6c2fd69dbf29e0c4e03765", + "sha256:a33fae02a54c63acb3c30fe49388715d658d76d42858a6ad4563e7e6859a9e57", + "sha256:a59d7d10597a2da9e9729637a625ae8dff2ed4e7c6c0b4952f0a5b2db6ef7152", + "sha256:ad21cfa8d97a62984ce30692a7ddf71a32a0c744cc247c43cbdbac1536aec4de", + "sha256:be63482de86bbb91db7f3f3b7dd452b9e08a11dacbda2088386831fb0e7de59c", + "sha256:c1108a9acb755310dce50a6e3c58ae1a2460ef60901d40e1155d633c7392f858", + "sha256:c644ab3f221c7faaab2d1ccd11bc3b1106f172e9bb1c85a863b0a097f6b71cce", + "sha256:c95c0818c163b69989c9e876dd82005e60edfbaabfd45429abebfc26f9a357e8", + "sha256:cdd68e684f0c6e18604d46ee04dbcfe5c79de62238b2c29f1db0f3a5d8dfa47b", + "sha256:ce86c6dce2c923bfb16e26586bc5f0443a8be61d4f43227be8587ccb95588a46", + "sha256:e61d3c6b1b66072f5b74d46dbee7df29daac6ce9738b9a6223a67dc577114515", + "sha256:f8edf5a546b31afdcd801b60448ea890ce1ff418fb784335e1329519f13aa85e" + ], + "version": "==3.7.4" + }, + "hatanaka": { + "hashes": [ + "sha256:5a0624f6812b13abb4c996398a60338566885c1786841c4c04de9b1b91da28d2", + "sha256:8fda4aa56f27313de75a806a2f5aa83ed5bb2dc7561bebab856a774d06cf1ee7", + "sha256:c22970b99169bddaf22e5239672e856a6bc9602c435f8793d26ad49619a70a99", + "sha256:ef594d63473782fac46df5b0c92a59211a3efea1d47c1a964244a0abffc9f3f6" + ], + "index": "pypi", + "version": "==2.4" + }, "hexdump": { "hashes": [ "sha256:d781a43b0c16ace3f9366aade73e8ad3a7bd5137d58f0b45ab2d3f54876f20db" @@ -293,16 +347,24 @@ "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], - "markers": "python_version >= '3'", + "markers": "python_full_version >= '3.5.0'", "version": "==3.3" }, "importlib-metadata": { "hashes": [ - "sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6", - "sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539" + "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700", + "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec" ], "markers": "python_version < '3.10'", - "version": "==4.11.3" + "version": "==4.11.4" + }, + "importlib-resources": { + "hashes": [ + "sha256:b6062987dfc51f0fcb809187cffbd60f35df7acb4589091f154214af6d0d49d3", + "sha256:e447dc01619b1e951286f3929be820029d48c75eb25d265c28b92a16548212b8" + ], + "markers": "python_version >= '3.7'", + "version": "==5.7.1" }, "isort": { "hashes": [ @@ -322,11 +384,11 @@ }, "jinja2": { "hashes": [ - "sha256:539835f51a74a69f41b848a9645dbdc35b4f20a3b601e2d9a7e22947b15ff119", - "sha256:640bed4bb501cbd17194b3cace1dc2126f5b619cf068a726b98192a0fde74ae9" + "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", + "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" ], "index": "pypi", - "version": "==3.1.1" + "version": "==3.1.2" }, "json-rpc": { "hashes": [ @@ -449,6 +511,47 @@ ], "version": "==1.2.1" }, + "ncompress": { + "hashes": [ + "sha256:0349d7de11edd70a7efea9ce9dc67f0e47b5774832dd063f7ae68a9e3e36ea31", + "sha256:070044eab19586a45d1855c3e50e000ce86d6075b122a5ec8cffd480713dffac", + "sha256:13fa26ec8000d786a8079bb265508b5df4b445a4f460481a13549b4bd3c83824", + "sha256:15f10fbfa11345ff0af090e3e6ae13a1fe2b52a2bb39d4f2373c2d6aeac75e5d", + "sha256:2a104803fbe3ab0a96edb14927fa22c8142be838aabe7e938b4a52a4e82db56e", + "sha256:34754041d9bac2d6908ae0d07ba541e4d6d606cca222ddd53f3a57e15f386b0a", + "sha256:34c6496168fd4dbc13f1fc0c0fcbadded1957639956f8cbc6894c39999817e36", + "sha256:3590e66313041721ae81e72ece06b7048c9293321bb30900358638673608e264", + "sha256:393cc3c126b9451fb32fe2bc07773264c90e73afbd37da0df472ac23bfd1a2d5", + "sha256:5336a8831a7e587829ce54e9e27d1fb2e04ddbc7d2d983693e35a3a03ac3ce79", + "sha256:5a2ae8a9170fa1f45df7efa292eb8c437b18c225b63d4adca4f50f9da0e8e0c7", + "sha256:6540556d47670a8fb93878a44d0206bbdc87f32e4c5b57d6fe63691efafbb982", + "sha256:66d991155a1655ccd98e8433c4a7e811d63eb649adb55f47d8f9528a30cc4b7a", + "sha256:736dbae078107742cf6ac7ccc11ae9c5eab77ef2c02aab3ef64802877bb01cab", + "sha256:7608fbda43d04d9f476be2dbf4ef3c96e72d83b9557a48b07fbc9ff3ad29cdd2", + "sha256:78674f246878938387b6f82b10d1aa2192e02544d214541943d12ef1a45e66c6", + "sha256:8322482e72ac2802d1dca1007ec06aa281a4d5cf1cf9f8c75bb51e917382b756", + "sha256:8b9acc46cf36bb998ed215d6e76a94e2bd1e827b9a4cb5362982b7004b5a7620", + "sha256:8eb4a55cbeaeb238a3b412952077be6b3f37b3416cd0211cc22776391ff2fef7", + "sha256:916671d62167191af58d6b4a17b1c09c647e349dcff1fc0b7d764aa64c3773ee", + "sha256:94b3f4e851f5b37e1d4cf2d8da911fa10783a59cba3d7f1f2ae5bd2842558077", + "sha256:9cd040ad73a3b0e917e01cdfba507e10e0bb56849daaac3ac3d86382d4d7ad82", + "sha256:9d89acf209858e7940223cf35324e1b2effec119bb009a41f039e2ea4db22177", + "sha256:9da7c81313aed4b6c6e8020442ed8d03d04bff72947f9380ea1ce2c63ffb8ad1", + "sha256:aaa18a509d9fc173b4b47d53c834e43ced1eda63d2aa7d4613dc59b2f802a31a", + "sha256:ab9fc62baaa55faf8ed8ac67f2c64a7295fec91d7c1f306ac46aa894ca4edf91", + "sha256:af0011bae90e44121f4e4edbff3dccdce7e4c5fc5e354db7eb48410d71f496df", + "sha256:b031e06b42037b181e3514261e1e85a9eae4af990c12b9348a9f22b8042201ff", + "sha256:d11df815d280985dfa660974df11dbe051a1a18dca2f91f9d30fbd6548237b8f", + "sha256:d45ec59a8a3ce00613df0c81e5567854574dbbbf01ecd1a5a0929cd8fb04844d", + "sha256:da216a53db7cd4c0247376f87367dd71df457443567e55310f6d3d23a9aff2f2", + "sha256:e0ebd71990ef7909b6627b5341a2fe1977dcce61dd3760a29e19e3f9e4c6a275", + "sha256:e6f5bf381412e9d3847b76e8b6bd1f84dfadcd3d9c25903c8592facb437909a0", + "sha256:e7bbf10cca1376f4f17ae2c447e33a9d4067525abb0c71d488c9a5ced50552f1", + "sha256:f9ba6ab2aadd6fd90365fdad5219e4dc7bc2459b94f1e900a733dddaf4e9b2e6", + "sha256:fe0a671a2f7dc1ee0438d278ef30ab425a969536100c4352b5cb6bc0b6210818" + ], + "version": "==1.0.0" + }, "nose": { "hashes": [ "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac", @@ -460,29 +563,31 @@ }, "numpy": { "hashes": [ - "sha256:07a8c89a04997625236c5ecb7afe35a02af3896c8aa01890a849913a2309c676", - "sha256:08d9b008d0156c70dc392bb3ab3abb6e7a711383c3247b410b39962263576cd4", - "sha256:201b4d0552831f7250a08d3b38de0d989d6f6e4658b709a02a73c524ccc6ffce", - "sha256:2c10a93606e0b4b95c9b04b77dc349b398fdfbda382d2a39ba5a822f669a0123", - "sha256:3ca688e1b9b95d80250bca34b11a05e389b1420d00e87a0d12dc45f131f704a1", - "sha256:48a3aecd3b997bf452a2dedb11f4e79bc5bfd21a1d4cc760e703c31d57c84b3e", - "sha256:568dfd16224abddafb1cbcce2ff14f522abe037268514dd7e42c6776a1c3f8e5", - "sha256:5bfb1bb598e8229c2d5d48db1860bcf4311337864ea3efdbe1171fb0c5da515d", - "sha256:639b54cdf6aa4f82fe37ebf70401bbb74b8508fddcf4797f9fe59615b8c5813a", - "sha256:8251ed96f38b47b4295b1ae51631de7ffa8260b5b087808ef09a39a9d66c97ab", - "sha256:92bfa69cfbdf7dfc3040978ad09a48091143cffb778ec3b03fa170c494118d75", - "sha256:97098b95aa4e418529099c26558eeb8486e66bd1e53a6b606d684d0c3616b168", - "sha256:a3bae1a2ed00e90b3ba5f7bd0a7c7999b55d609e0c54ceb2b076a25e345fa9f4", - "sha256:c34ea7e9d13a70bf2ab64a2532fe149a9aced424cd05a2c4ba662fd989e3e45f", - "sha256:dbc7601a3b7472d559dc7b933b18b4b66f9aa7452c120e87dfb33d02008c8a18", - "sha256:e7927a589df200c5e23c57970bafbd0cd322459aa7b1ff73b7c2e84d6e3eae62", - "sha256:f8c1f39caad2c896bc0018f699882b345b2a63708008be29b1f355ebf6f933fe", - "sha256:f950f8845b480cffe522913d35567e29dd381b0dc7e4ce6a4a9f9156417d2430", - "sha256:fade0d4f4d292b6f39951b6836d7a3c7ef5b2347f3c420cd9820a1d90d794802", - "sha256:fdf3c08bce27132395d3c3ba1503cac12e17282358cb4bddc25cc46b0aca07aa" - ], - "index": "pypi", - "version": "==1.22.3" + "sha256:0791fbd1e43bf74b3502133207e378901272f3c156c4df4954cad833b1380207", + "sha256:1ce7ab2053e36c0a71e7a13a7475bd3b1f54750b4b433adc96313e127b870887", + "sha256:2d487e06ecbf1dc2f18e7efce82ded4f705f4bd0cd02677ffccfb39e5c284c7e", + "sha256:37431a77ceb9307c28382c9773da9f306435135fae6b80b62a11c53cfedd8802", + "sha256:3e1ffa4748168e1cc8d3cde93f006fe92b5421396221a02f2274aab6ac83b077", + "sha256:425b390e4619f58d8526b3dcf656dde069133ae5c240229821f01b5f44ea07af", + "sha256:43a8ca7391b626b4c4fe20aefe79fec683279e31e7c79716863b4b25021e0e74", + "sha256:4c6036521f11a731ce0648f10c18ae66d7143865f19f7299943c985cdc95afb5", + "sha256:59d55e634968b8f77d3fd674a3cf0b96e85147cd6556ec64ade018f27e9479e1", + "sha256:64f56fc53a2d18b1924abd15745e30d82a5782b2cab3429aceecc6875bd5add0", + "sha256:7228ad13744f63575b3a972d7ee4fd61815b2879998e70930d4ccf9ec721dce0", + "sha256:9ce7df0abeabe7fbd8ccbf343dc0db72f68549856b863ae3dd580255d009648e", + "sha256:a911e317e8c826ea632205e63ed8507e0dc877dcdc49744584dfc363df9ca08c", + "sha256:b89bf9b94b3d624e7bb480344e91f68c1c6c75f026ed6755955117de00917a7c", + "sha256:ba9ead61dfb5d971d77b6c131a9dbee62294a932bf6a356e48c75ae684e635b3", + "sha256:c1d937820db6e43bec43e8d016b9b3165dcb42892ea9f106c70fb13d430ffe72", + "sha256:cc7f00008eb7d3f2489fca6f334ec19ca63e31371be28fd5dad955b16ec285bd", + "sha256:d4c5d5eb2ec8da0b4f50c9a843393971f31f1d60be87e0fb0917a49133d257d6", + "sha256:e96d7f3096a36c8754207ab89d4b3282ba7b49ea140e4973591852c77d09eb76", + "sha256:f0725df166cf4785c0bc4cbfb320203182b1ecd30fee6e541c8752a92df6aa32", + "sha256:f3eb268dbd5cfaffd9448113539e44e2dd1c5ca9ce25576f7c04a5453edc26fa", + "sha256:fb7a980c81dd932381f8228a426df8aeb70d59bbcda2af075b627bbc50207cba" + ], + "index": "pypi", + "version": "==1.22.4" }, "onnx": { "hashes": [ @@ -517,136 +622,150 @@ }, "onnxruntime-gpu": { "hashes": [ - "sha256:2886a84a0e64f7ec594f787c0c941c05af230e5e3df342dd05d86382722dd78a", - "sha256:2db2bdcb23b6b4fa08a03009bf057f42cebf6828cb418f4f5ab890cc6d1bb8ff", - "sha256:58e9a3487820728e2140523787f0c413518f7f8ca137a7c3e015044b65d159f4", - "sha256:63f8b8e48f33b61f7bdec9a561770a6bea5ec3c905ef088e70cb5909c88e7515", - "sha256:766c1249c6a2fc422022348a04f747008cf171edd00c9a452454f7c35899ae88", - "sha256:fe00066d2d350806c1099761d856ec2934ff9843c192dee6d41cbe074ad5a1a9" + "sha256:3f1363e9ba30051cc3d649beefbd12047e1c41b5c47bcacfbfb23b74a7d68f7b", + "sha256:3fad0d3df58815c11160714433ca3bcff6d9a06f721bcc97ade46abce30aea72", + "sha256:a4f5317838f4816a9b21fcb43d551ac95f9d35ca8ecd5c959419b3b94d458342", + "sha256:be1766a9d60ec774e1a7a0279ade5ec001c5d528f2f2dbe9f8d02133e49d1d68", + "sha256:c79f42cbdee18e059c0ba43f0efeb7117539dfb76d6ed0e4a9ecc34093ed97b3", + "sha256:dc34be44224aa855d7ab17f61942b665788a2136ae4f71ee857fa47b38d1fdb8" ], "index": "pypi", "markers": "platform_system != 'Darwin'", - "version": "==1.11.0" + "version": "==1.11.1" }, "pillow": { "hashes": [ - "sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e", - "sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595", - "sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512", - "sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c", - "sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477", - "sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a", - "sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4", - "sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e", - "sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5", - "sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378", - "sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a", - "sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652", - "sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7", - "sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a", - "sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a", - "sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6", - "sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165", - "sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160", - "sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331", - "sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b", - "sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458", - "sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033", - "sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8", - "sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481", - "sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58", - "sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7", - "sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3", - "sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea", - "sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34", - "sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3", - "sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8", - "sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581", - "sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244", - "sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef", - "sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0", - "sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2", - "sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97", - "sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717" - ], - "index": "pypi", - "version": "==9.1.0" + "sha256:088df396b047477dd1bbc7de6e22f58400dae2f21310d9e2ec2933b2ef7dfa4f", + "sha256:09e67ef6e430f90caa093528bd758b0616f8165e57ed8d8ce014ae32df6a831d", + "sha256:0b4d5ad2cd3a1f0d1df882d926b37dbb2ab6c823ae21d041b46910c8f8cd844b", + "sha256:0b525a356680022b0af53385944026d3486fc8c013638cf9900eb87c866afb4c", + "sha256:1d4331aeb12f6b3791911a6da82de72257a99ad99726ed6b63f481c0184b6fb9", + "sha256:20d514c989fa28e73a5adbddd7a171afa5824710d0ab06d4e1234195d2a2e546", + "sha256:2b291cab8a888658d72b575a03e340509b6b050b62db1f5539dd5cd18fd50578", + "sha256:3f6c1716c473ebd1649663bf3b42702d0d53e27af8b64642be0dd3598c761fb1", + "sha256:42dfefbef90eb67c10c45a73a9bc1599d4dac920f7dfcbf4ec6b80cb620757fe", + "sha256:488f3383cf5159907d48d32957ac6f9ea85ccdcc296c14eca1a4e396ecc32098", + "sha256:4d45dbe4b21a9679c3e8b3f7f4f42a45a7d3ddff8a4a16109dff0e1da30a35b2", + "sha256:53c27bd452e0f1bc4bfed07ceb235663a1df7c74df08e37fd6b03eb89454946a", + "sha256:55e74faf8359ddda43fee01bffbc5bd99d96ea508d8a08c527099e84eb708f45", + "sha256:59789a7d06c742e9d13b883d5e3569188c16acb02eeed2510fd3bfdbc1bd1530", + "sha256:5b650dbbc0969a4e226d98a0b440c2f07a850896aed9266b6fedc0f7e7834108", + "sha256:66daa16952d5bf0c9d5389c5e9df562922a59bd16d77e2a276e575d32e38afd1", + "sha256:6e760cf01259a1c0a50f3c845f9cad1af30577fd8b670339b1659c6d0e7a41dd", + "sha256:7502539939b53d7565f3d11d87c78e7ec900d3c72945d4ee0e2f250d598309a0", + "sha256:769a7f131a2f43752455cc72f9f7a093c3ff3856bf976c5fb53a59d0ccc704f6", + "sha256:7c150dbbb4a94ea4825d1e5f2c5501af7141ea95825fadd7829f9b11c97aaf6c", + "sha256:8844217cdf66eabe39567118f229e275f0727e9195635a15e0e4b9227458daaf", + "sha256:8a66fe50386162df2da701b3722781cbe90ce043e7d53c1fd6bd801bca6b48d4", + "sha256:9370d6744d379f2de5d7fa95cdbd3a4d92f0b0ef29609b4b1687f16bc197063d", + "sha256:937a54e5694684f74dcbf6e24cc453bfc5b33940216ddd8f4cd8f0f79167f765", + "sha256:9c857532c719fb30fafabd2371ce9b7031812ff3889d75273827633bca0c4602", + "sha256:a4165205a13b16a29e1ac57efeee6be2dfd5b5408122d59ef2145bc3239fa340", + "sha256:b3fe2ff1e1715d4475d7e2c3e8dabd7c025f4410f79513b4ff2de3d51ce0fa9c", + "sha256:b6617221ff08fbd3b7a811950b5c3f9367f6e941b86259843eab77c8e3d2b56b", + "sha256:b761727ed7d593e49671d1827044b942dd2f4caae6e51bab144d4accf8244a84", + "sha256:baf3be0b9446a4083cc0c5bb9f9c964034be5374b5bc09757be89f5d2fa247b8", + "sha256:c17770a62a71718a74b7548098a74cd6880be16bcfff5f937f900ead90ca8e92", + "sha256:c67db410508b9de9c4694c57ed754b65a460e4812126e87f5052ecf23a011a54", + "sha256:d78ca526a559fb84faaaf84da2dd4addef5edb109db8b81677c0bb1aad342601", + "sha256:e9ed59d1b6ee837f4515b9584f3d26cf0388b742a11ecdae0d9237a94505d03a", + "sha256:f054b020c4d7e9786ae0404278ea318768eb123403b18453e28e47cdb7a0a4bf", + "sha256:f372d0f08eff1475ef426344efe42493f71f377ec52237bf153c5713de987251", + "sha256:f3f6a6034140e9e17e9abc175fc7a266a6e63652028e157750bd98e804a8ed9a", + "sha256:ffde4c6fabb52891d81606411cbfaf77756e3b561b566efd270b3ed3791fde4e" + ], + "index": "pypi", + "version": "==9.1.1" }, "platformdirs": { "hashes": [ - "sha256:7535e70dfa32e84d4b34996ea99c5e432fa29a708d0f4e394bbcb2a8faa4f16d", - "sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227" + "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788", + "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19" ], "markers": "python_version >= '3.7'", - "version": "==2.5.1" + "version": "==2.5.2" }, "protobuf": { "hashes": [ - "sha256:001c2160c03b6349c04de39cf1a58e342750da3632f6978a1634a3dcca1ec10e", - "sha256:0b250c60256c8824219352dc2a228a6b49987e5bf94d3ffcf4c46585efcbd499", - "sha256:1d24c81c2310f0063b8fc1c20c8ed01f3331be9374b4b5c2de846f69e11e21fb", - "sha256:1eb13f5a5a59ca4973bcfa2fc8fff644bd39f2109c3f7a60bd5860cb6a49b679", - "sha256:25d2fcd6eef340082718ec9ad2c58d734429f2b1f7335d989523852f2bba220b", - "sha256:32bf4a90c207a0b4e70ca6dd09d43de3cb9898f7d5b69c2e9e3b966a7f342820", - "sha256:38fd9eb74b852e4ee14b16e9670cd401d147ee3f3ec0d4f7652e0c921d6227f8", - "sha256:47257d932de14a7b6c4ae1b7dbf592388153ee35ec7cae216b87ae6490ed39a3", - "sha256:4eda68bd9e2a4879385e6b1ea528c976f59cd9728382005cc54c28bcce8db983", - "sha256:52bae32a147c375522ce09bd6af4d2949aca32a0415bc62df1456b3ad17c6001", - "sha256:542f25a4adf3691a306dcc00bf9a73176554938ec9b98f20f929a044f80acf1b", - "sha256:5b5860b790498f233cdc8d635a17fc08de62e59d4dcd8cdb6c6c0d38a31edf2b", - "sha256:6efe066a7135233f97ce51a1aa007d4fb0be28ef093b4f88dac4ad1b3a2b7b6f", - "sha256:71b2c3d1cd26ed1ec7c8196834143258b2ad7f444efff26fdc366c6f5e752702", - "sha256:7a53d4035427b9dbfbb397f46642754d294f131e93c661d056366f2a31438263", - "sha256:7dcd84dc31ebb35ade755e06d1561d1bd3b85e85dbdbf6278011fc97b22810db", - "sha256:88c8be0558bdfc35e68c42ae5bf785eb9390d25915d4863bbc7583d23da77074", - "sha256:8be43a91ab66fe995e85ccdbdd1046d9f0443d59e060c0840319290de25b7d33", - "sha256:8d84453422312f8275455d1cb52d850d6a4d7d714b784e41b573c6f5bfc2a029", - "sha256:9d0f3aca8ca51c8b5e204ab92bd8afdb2a8e3df46bd0ce0bd39065d79aabcaa4", - "sha256:a1eebb6eb0653e594cb86cd8e536b9b083373fca9aba761ade6cd412d46fb2ab", - "sha256:bc14037281db66aa60856cd4ce4541a942040686d290e3f3224dd3978f88f554", - "sha256:fbcbb068ebe67c4ff6483d2e2aa87079c325f8470b24b098d6bf7d4d21d57a69", - "sha256:fd7133b885e356fa4920ead8289bb45dc6f185a164e99e10279f33732ed5ce15" - ], - "markers": "python_version >= '3.7'", - "version": "==3.20.0" + "sha256:06059eb6953ff01e56a25cd02cca1a9649a75a7e65397b5b9b4e929ed71d10cf", + "sha256:097c5d8a9808302fb0da7e20edf0b8d4703274d140fd25c5edabddcde43e081f", + "sha256:0d4719e724472e296062ba8e82a36d64693fcfdb550d9dff98af70ca79eafe3d", + "sha256:284f86a6207c897542d7e956eb243a36bb8f9564c1742b253462386e96c6b78f", + "sha256:2b35602cb65d53c168c104469e714bf68670335044c38eee3c899d6a8af03ffc", + "sha256:32ca378605b41fd180dfe4e14d3226386d8d1b002ab31c969c366549e66a2bb7", + "sha256:32fff501b6df3050936d1839b80ea5899bf34db24792d223d7640611f67de15a", + "sha256:34400fd76f85bdae9a2e9c1444ea4699c0280962423eff4418765deceebd81b5", + "sha256:3767c64593a49c7ac0accd08ed39ce42744405f0989d468f0097a17496fdbe84", + "sha256:3cc797c9d15d7689ed507b165cd05913acb992d78b379f6014e013f9ecb20996", + "sha256:3f2ed842e8ca43b790cb4a101bcf577226e0ded98a6a6ba2d5e12095a08dc4da", + "sha256:52c1e44e25f2949be7ffa7c66acbfea940b0945dd416920231f7cb30ea5ac6db", + "sha256:5d9b5c8270461706973c3871c6fbdd236b51dfe9dab652f1fb6a36aa88287e47", + "sha256:62f1b5c4cd6c5402b4e2d63804ba49a327e0c386c99b1675c8a0fefda23b2067", + "sha256:69ccfdf3657ba59569c64295b7d51325f91af586f8d5793b734260dfe2e94e2c", + "sha256:6f50601512a3d23625d8a85b1638d914a0970f17920ff39cec63aaef80a93fb7", + "sha256:72d357cc4d834cc85bd957e8b8e1f4b64c2eac9ca1a942efeb8eb2e723fca852", + "sha256:7403941f6d0992d40161aa8bb23e12575637008a5a02283a930addc0508982f9", + "sha256:755f3aee41354ae395e104d62119cb223339a8f3276a0cd009ffabfcdd46bb0c", + "sha256:77053d28427a29987ca9caf7b72ccafee011257561259faba8dd308fda9a8739", + "sha256:79cd8d0a269b714f6b32641f86928c718e8d234466919b3f552bfb069dbb159b", + "sha256:7e371f10abe57cee5021797126c93479f59fccc9693dafd6bd5633ab67808a91", + "sha256:9016d01c91e8e625141d24ec1b20fed584703e527d28512aa8c8707f105a683c", + "sha256:9be73ad47579abc26c12024239d3540e6b765182a91dbc88e23658ab71767153", + "sha256:a4c0c6f2f95a559e59a0258d3e4b186f340cbdc5adec5ce1bc06d01972527c88", + "sha256:adc31566d027f45efe3f44eeb5b1f329da43891634d61c75a5944e9be6dd42c9", + "sha256:adfc6cf69c7f8c50fd24c793964eef18f0ac321315439d94945820612849c388", + "sha256:af0ebadc74e281a517141daad9d0f2c5d93ab78e9d455113719a45a49da9db4e", + "sha256:b309fda192850ac4184ca1777aab9655564bc8d10a9cc98f10e1c8bf11295c22", + "sha256:b3d7d4b4945fe3c001403b6c24442901a5e58c0a3059290f5a63523ed4435f82", + "sha256:c8829092c5aeb61619161269b2f8a2e36fd7cb26abbd9282d3bc453f02769146", + "sha256:cb29edb9eab15742d791e1025dd7b6a8f6fcb53802ad2f6e3adcb102051063ab", + "sha256:cd68be2559e2a3b84f517fb029ee611546f7812b1fdd0aa2ecc9bc6ec0e4fdde", + "sha256:cdee09140e1cd184ba9324ec1df410e7147242b94b5f8b0c64fc89e38a8ba531", + "sha256:db977c4ca738dd9ce508557d4fce0f5aebd105e158c725beec86feb1f6bc20d8", + "sha256:dd5789b2948ca702c17027c84c2accb552fc30f4622a98ab5c51fcfe8c50d3e7", + "sha256:e250a42f15bf9d5b09fe1b293bdba2801cd520a9f5ea2d7fb7536d4441811d20", + "sha256:ff8d8fa42675249bb456f5db06c00de6c2f4c27a065955917b28c4f15978b9c3" + ], + "index": "pypi", + "version": "==3.20.1" }, "psutil": { "hashes": [ - "sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5", - "sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a", - "sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4", - "sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841", - "sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d", - "sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d", - "sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0", - "sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845", - "sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf", - "sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b", - "sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07", - "sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618", - "sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2", - "sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd", - "sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666", - "sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce", - "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3", - "sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d", - "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25", - "sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492", - "sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b", - "sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d", - "sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2", - "sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203", - "sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2", - "sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94", - "sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9", - "sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64", - "sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56", - "sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3", - "sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c", - "sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3" - ], - "index": "pypi", - "version": "==5.9.0" + "sha256:068935df39055bf27a29824b95c801c7a5130f118b806eee663cad28dca97685", + "sha256:0904727e0b0a038830b019551cf3204dd48ef5c6868adc776e06e93d615fc5fc", + "sha256:0f15a19a05f39a09327345bc279c1ba4a8cfb0172cc0d3c7f7d16c813b2e7d36", + "sha256:19f36c16012ba9cfc742604df189f2f28d2720e23ff7d1e81602dbe066be9fd1", + "sha256:20b27771b077dcaa0de1de3ad52d22538fe101f9946d6dc7869e6f694f079329", + "sha256:28976df6c64ddd6320d281128817f32c29b539a52bdae5e192537bc338a9ec81", + "sha256:29a442e25fab1f4d05e2655bb1b8ab6887981838d22effa2396d584b740194de", + "sha256:3054e923204b8e9c23a55b23b6df73a8089ae1d075cb0bf711d3e9da1724ded4", + "sha256:32c52611756096ae91f5d1499fe6c53b86f4a9ada147ee42db4991ba1520e574", + "sha256:3a76ad658641172d9c6e593de6fe248ddde825b5866464c3b2ee26c35da9d237", + "sha256:44d1826150d49ffd62035785a9e2c56afcea66e55b43b8b630d7706276e87f22", + "sha256:4b6750a73a9c4a4e689490ccb862d53c7b976a2a35c4e1846d049dcc3f17d83b", + "sha256:56960b9e8edcca1456f8c86a196f0c3d8e3e361320071c93378d41445ffd28b0", + "sha256:57f1819b5d9e95cdfb0c881a8a5b7d542ed0b7c522d575706a80bedc848c8954", + "sha256:58678bbadae12e0db55186dc58f2888839228ac9f41cc7848853539b70490021", + "sha256:645bd4f7bb5b8633803e0b6746ff1628724668681a434482546887d22c7a9537", + "sha256:799759d809c31aab5fe4579e50addf84565e71c1dc9f1c31258f159ff70d3f87", + "sha256:79c9108d9aa7fa6fba6e668b61b82facc067a6b81517cab34d07a84aa89f3df0", + "sha256:91c7ff2a40c373d0cc9121d54bc5f31c4fa09c346528e6a08d1845bce5771ffc", + "sha256:9272167b5f5fbfe16945be3db475b3ce8d792386907e673a209da686176552af", + "sha256:944c4b4b82dc4a1b805329c980f270f170fdc9945464223f2ec8e57563139cf4", + "sha256:a6a11e48cb93a5fa606306493f439b4aa7c56cb03fc9ace7f6bfa21aaf07c453", + "sha256:a8746bfe4e8f659528c5c7e9af5090c5a7d252f32b2e859c584ef7d8efb1e689", + "sha256:abd9246e4cdd5b554a2ddd97c157e292ac11ef3e7af25ac56b08b455c829dca8", + "sha256:b14ee12da9338f5e5b3a3ef7ca58b3cba30f5b66f7662159762932e6d0b8f680", + "sha256:b88f75005586131276634027f4219d06e0561292be8bd6bc7f2f00bdabd63c4e", + "sha256:c7be9d7f5b0d206f0bbc3794b8e16fb7dbc53ec9e40bbe8787c6f2d38efcf6c9", + "sha256:d2d006286fbcb60f0b391741f520862e9b69f4019b4d738a2a45728c7e952f1b", + "sha256:db417f0865f90bdc07fa30e1aadc69b6f4cad7f86324b02aa842034efe8d8c4d", + "sha256:e7e10454cb1ab62cc6ce776e1c135a64045a11ec4c6d254d3f7689c16eb3efd2", + "sha256:f65f9a46d984b8cd9b3750c2bdb419b2996895b005aefa6cbaba9a143b1ce2c5", + "sha256:fea896b54f3a4ae6f790ac1d017101252c93f6fe075d0e7571543510f11d2676" + ], + "index": "pypi", + "version": "==5.9.1" }, "pycapnp": { "hashes": [ @@ -728,32 +847,109 @@ }, "pyjwt": { "hashes": [ - "sha256:b888b4d56f06f6dcd777210c334e69c737be74755d3e5e9ee3fe67dc18a0ee41", - "sha256:e0c4bb8d9f0af0c7f5b1ec4c5036309617d03d56932877f2f7a0beeb5318322f" + "sha256:72d1d253f32dbd4f5c88eaf1fdc62f3a19f676ccbadb9dbc5d07e951b2b26daf", + "sha256:d42908208c699b3b973cbeb01a969ba6a96c821eefb1c5bfe4c390c01d67abba" ], "index": "pypi", - "version": "==2.3.0" + "version": "==2.4.0" }, "pylint": { "hashes": [ - "sha256:7cc6d0c4f61dff440f9ed8b657f4ecd615dcfe35345953eb7b1dc74afe901d7a", - "sha256:8672cf7441b81410f5de7defdf56e2d559c956fd0579652f2e0a0a35bea2d546" + "sha256:549261e0762c3466cc001024c4419c08252cb8c8d40f5c2c6966fea690e7fe2a", + "sha256:bb71e6d169506de585edea997e48d9ff20c0dc0e2fbc1d166bad6b640120326b" ], "index": "pypi", - "version": "==2.13.4" + "version": "==2.14.1" }, "pyopencl": { "hashes": [ - "sha256:1ab792ff11a7ff271b1ba39686bd7aae271168e813a7e771bff6aa611ada383b", - "sha256:24c6d9a0a1ff7609f3d7365ebd8778616a5433c426566c2c8e35ffab00ef22c4", - "sha256:3b3f0d8b69923064f6d64b520c594aa2506e96ab398a0f1ed4895c4fceb20ff4", - "sha256:4bea0e965252f477204a87cc73eca492de5c30252198bc6679ef4968880a2443", - "sha256:7d9ec6c8daf283666dd577d6bcc49ab3d5b44c9532c2f642daf7e9c85b73606f", - "sha256:d8af9c4ea375f51237059124f7bab1fd32e32a8893997ffa05dff88efc4d9274", - "sha256:dee72b29c4e47a99f5ecc7fc7ba70bfc3d85e3cc9734765d6992380f5296787b" - ], - "index": "pypi", - "version": "==2022.1" + "sha256:01030054c201b021715deb3d6f1355844f9795429dfa0591b59b6f8000ec2d38", + "sha256:02997935ac164f519be65c371f9dd2267a2b7532247dc0a2ef43f435cf76cf4b", + "sha256:07482df440e1246cba6dc46ef70d3ebf1a6c8157a3c6456091026c7f9e4d18d2", + "sha256:0b179591c60b4446846fbea035cb3d1acd2685b0226ba91724109882dc59af2c", + "sha256:15ebc3f3eb2df1d196a7dcefd68d0e9ffa11e275f8a6c57a1145a1d0ff36c382", + "sha256:1a5fb7dc32cf24cdeab1205bc075710d7112656720c2bf9972bebe906e28ec4b", + "sha256:1b649637d608e8dabdec0e0f85392f727fdf622463b425cf7587bdd313b4d9eb", + "sha256:22eed49903178bc686287192a8319ce763129b4e5d42a9dfb5d8f763ba5d6bd6", + "sha256:2deef59d73d0bdd11ba40613ab0798c767214a669a1a5a672500787fb7da63d3", + "sha256:3736bfdc946068be66fe4b5c680926c84366b724b3c4b649b2a1940f7bd6afde", + "sha256:3dd0b5ff24d12ad4c13446d8e5439e63914496dfcf9e23a26baeaa65ec3c7039", + "sha256:5430b938e9391309be2ffaefb6269a0a3c016af5d729121cf8a5fce62a5146c2", + "sha256:5e89596e7f18824fc1f84e2cb0ae059fbfe187d1e2e3919ab0cd701cc634eb03", + "sha256:65e406603fbe47ca72298e022a3c3855b2e1732cb9d04ecbb411025050d0bc57", + "sha256:6f9f91594358af6a9728908c31c5ed4bec3fe1a0d25c6292e37e40c92903fe36", + "sha256:77a70b76789aac85566cb0e3ff6b60c4c00729bbd7f0edd24ac4b3b43e4627e2", + "sha256:799355c27463bf801260e3398643c3c9359627fa9e6ac621cfb5dc1d6e77d859", + "sha256:7ae4825562f7c5956b8926cb99882df1631c5e28aa1310d896c22a8471cf8f56", + "sha256:7b17906a4821a30aa1ce7a9d783bba2564230ea6a55ff31eb3f0e2a4aa5b80af", + "sha256:7d4bf4c858554e9e3af9e7f18b06e8d6c39b25d7a80c28db6e5dd412dc457aee", + "sha256:8981a9274796272508158b08a3cb1a5711318cf32b5f0e4829edecb1a9efcf93", + "sha256:8da3ef5a03cfd0a9859a5ebe623f3c43037e9f0dffd2b658e944bbc381beb529", + "sha256:94c744997f4aff86e68fa3a5d383dc8b5f1e529a360156b82c7583a757eddaa5", + "sha256:9a7fb5769bce7ec09a2d264a233ec9c730b15b391c830d04a381df3fc85bdaca", + "sha256:a6ce276a42caedd3a9a7be00031cfe6bf5d1796efdac40e47f1b707846c96d86", + "sha256:a84310ae508f998ed31825b6e3ab888098cb69a2c627bf5970706620a8d4b127", + "sha256:ad08e37cdeda5d38ac3ca9820400da62ce3a67aab76a5eefa5d089ef3a4877c9", + "sha256:b6e426b5fdce61051b112825da20df4cb78429967e491223bfedaf95c025273a", + "sha256:bb363f9993013b04c0b146e269a73b3d5ebef30f78d5fa542f317cc2440e15b6", + "sha256:c58f05b050ae4ac3b0584d97738ae7ac4381e611567b9d67fe7cf4210c0a7b62", + "sha256:c84ef85cf6b83dbcef4e034390fc1ed6bd8eadf5260b5ae89515d3b9744ef207", + "sha256:c9a841b80ef4c332a6133377fc295fe5376f90f8f2e7c63d36903b07b8ea7262", + "sha256:cd5871aff617d3c9d338fd94c9187382390db82452be0868055b8c519a73445d", + "sha256:cf45c232bf818ef54ee831eb41f4edbd5dfe4c67d894b1e65fc17a690a63c81e", + "sha256:e90bd1ed69cca2a750ffabafc70b4f9eb4d109299e986c3c8fdc4c40fee36ef2", + "sha256:ea5b6ef0e4ad23a3ccbdb382f7cccadbb200a47ceb6ff3e965a3c6c46360b4c2", + "sha256:f433ddd7bfd688b591ea95b6971e5e6cb00f8d5f2dc5db833e528e5ede6909d6" + ], + "index": "pypi", + "version": "==2022.1.5" + }, + "pyqt5": { + "hashes": [ + "sha256:213bebd51821ed89b4d5b35bb10dbe67564228b3568f463a351a08e8b1677025", + "sha256:2a69597e0dd11caabe75fae133feca66387819fc9bc050f547e5551bce97e5be", + "sha256:883a549382fc22d29a0568f3ef20b38c8e7ab633a59498ac4eb63a3bf36d3fd3", + "sha256:8c0848ba790a895801d5bfd171da31cad3e551dbcc4e59677a3b622de2ceca98", + "sha256:a88526a271e846e44779bb9ad7a738c6d3c4a9d01e15a128ecfc6dd4696393b7" + ], + "index": "pypi", + "version": "==5.15.4" + }, + "pyqt5-qt5": { + "hashes": [ + "sha256:1988f364ec8caf87a6ee5d5a3a5210d57539988bf8e84714c7d60972692e2f4a", + "sha256:750b78e4dba6bdf1607febedc08738e318ea09e9b10aea9ff0d73073f11f6962", + "sha256:76980cd3d7ae87e3c7a33bfebfaee84448fd650bad6840471d6cae199b56e154", + "sha256:9cc7a768b1921f4b982ebc00a318ccb38578e44e45316c7a4a850e953e1dd327" + ], + "version": "==5.15.2" + }, + "pyqt5-sip": { + "hashes": [ + "sha256:055581c6fed44ba4302b70eeb82e979ff70400037358908f251cd85cbb3dbd93", + "sha256:0fc9aefacf502696710b36cdc9fa2a61487f55ee883dbcf2c2a6477e261546f7", + "sha256:42274a501ab4806d2c31659170db14c282b8313d2255458064666d9e70d96206", + "sha256:4347bd81d30c8e3181e553b3734f91658cfbdd8f1a19f254777f906870974e6d", + "sha256:485972daff2fb0311013f471998f8ec8262ea381bded244f9d14edaad5f54271", + "sha256:4f8e05fe01d54275877c59018d8e82dcdd0bc5696053a8b830eecea3ce806121", + "sha256:69a3ad4259172e2b1aa9060de211efac39ddd734a517b1924d9c6c0cc4f55f96", + "sha256:6a8701892a01a5a2a4720872361197cc80fdd5f49c8482d488ddf38c9c84f055", + "sha256:6d5bca2fc222d58e8093ee8a81a6e3437067bb22bc3f86d06ec8be721e15e90a", + "sha256:83c3220b1ca36eb8623ba2eb3766637b19eb0ce9f42336ad8253656d32750c0a", + "sha256:a25b9843c7da6a1608f310879c38e6434331aab1dc2fe6cb65c14f1ecf33780e", + "sha256:ac57d796c78117eb39edd1d1d1aea90354651efac9d3590aac67fa4983f99f1f", + "sha256:b09f4cd36a4831229fb77c424d89635fa937d97765ec90685e2f257e56a2685a", + "sha256:c446971c360a0a1030282a69375a08c78e8a61d568bfd6dab3dcc5cf8817f644", + "sha256:c5216403d4d8d857ec4a61f631d3945e44fa248aa2415e9ee9369ab7c8a4d0c7", + "sha256:d3e4489d7c2b0ece9d203ae66e573939f7f60d4d29e089c9f11daa17cfeaae32", + "sha256:d59af63120d1475b2bf94fe8062610720a9be1e8940ea146c7f42bb449d49067", + "sha256:d85002238b5180bce4b245c13d6face848faa1a7a9e5c6e292025004f2fd619a", + "sha256:d8b2bdff7bbf45bc975c113a03b14fd669dc0c73e1327f02706666a7dd51a197", + "sha256:dd05c768c2b55ffe56a9d49ce6cc77cdf3d53dbfad935258a9e347cbfd9a5850", + "sha256:fc43f2d7c438517ee33e929e8ae77132749c15909afab6aeece5fcf4147ffdb5" + ], + "index": "pypi", + "version": "==12.9.0" }, "pyserial": { "hashes": [ @@ -773,10 +969,10 @@ }, "pytools": { "hashes": [ - "sha256:5e824101880a246354756365880a65bb416f6a8cab6513b68fcbb48fba090fcb" + "sha256:3393d25029982080e3fb94c47bf627a1e553ccd174fe2edef6c1c5ec723918ff" ], "markers": "python_version ~= '3.6'", - "version": "==2022.1.2" + "version": "==2022.1.9" }, "pyyaml": { "hashes": [ @@ -819,64 +1015,74 @@ }, "pyzmq": { "hashes": [ - "sha256:08c4e315a76ef26eb833511ebf3fa87d182152adf43dedee8d79f998a2162a0b", - "sha256:0ca6cd58f62a2751728016d40082008d3b3412a7f28ddfb4a2f0d3c130f69e74", - "sha256:1621e7a2af72cced1f6ec8ca8ca91d0f76ac236ab2e8828ac8fe909512d566cb", - "sha256:18cd854b423fce44951c3a4d3e686bac8f1243d954f579e120a1714096637cc0", - "sha256:2841997a0d85b998cbafecb4183caf51fd19c4357075dfd33eb7efea57e4c149", - "sha256:2b97502c16a5ec611cd52410bdfaab264997c627a46b0f98d3f666227fd1ea2d", - "sha256:3a4c9886d61d386b2b493377d980f502186cd71d501fffdba52bd2a0880cef4f", - "sha256:3c1895c95be92600233e476fe283f042e71cf8f0b938aabf21b7aafa62a8dac9", - "sha256:42abddebe2c6a35180ca549fadc7228d23c1e1f76167c5ebc8a936b5804ea2df", - "sha256:468bd59a588e276961a918a3060948ae68f6ff5a7fa10bb2f9160c18fe341067", - "sha256:480b9931bfb08bf8b094edd4836271d4d6b44150da051547d8c7113bf947a8b0", - "sha256:53f4fd13976789ffafedd4d46f954c7bb01146121812b72b4ddca286034df966", - "sha256:62bcade20813796c426409a3e7423862d50ff0639f5a2a95be4b85b09a618666", - "sha256:67db33bea0a29d03e6eeec55a8190e033318cee3cbc732ba8fd939617cbf762d", - "sha256:6b217b8f9dfb6628f74b94bdaf9f7408708cb02167d644edca33f38746ca12dd", - "sha256:7661fc1d5cb73481cf710a1418a4e1e301ed7d5d924f91c67ba84b2a1b89defd", - "sha256:76c532fd68b93998aab92356be280deec5de8f8fe59cd28763d2cc8a58747b7f", - "sha256:79244b9e97948eaf38695f4b8e6fc63b14b78cc37f403c6642ba555517ac1268", - "sha256:7c58f598d9fcc52772b89a92d72bf8829c12d09746a6d2c724c5b30076c1f11d", - "sha256:7dc09198e4073e6015d9a8ea093fc348d4e59de49382476940c3dd9ae156fba8", - "sha256:80e043a89c6cadefd3a0712f8a1322038e819ebe9dbac7eca3bce1721bcb63bf", - "sha256:851977788b9caa8ed011f5f643d3ee8653af02c5fc723fa350db5125abf2be7b", - "sha256:8eddc033e716f8c91c6a2112f0a8ebc5e00532b4a6ae1eb0ccc48e027f9c671c", - "sha256:902319cfe23366595d3fa769b5b751e6ee6750a0a64c5d9f757d624b2ac3519e", - "sha256:954e73c9cd4d6ae319f1c936ad159072b6d356a92dcbbabfd6e6204b9a79d356", - "sha256:ab888624ed68930442a3f3b0b921ad7439c51ba122dbc8c386e6487a658e4a4e", - "sha256:acebba1a23fb9d72b42471c3771b6f2f18dcd46df77482612054bd45c07dfa36", - "sha256:b4ebed0977f92320f6686c96e9e8dd29eed199eb8d066936bac991afc37cbb70", - "sha256:badb868fff14cfd0e200eaa845887b1011146a7d26d579aaa7f966c203736b92", - "sha256:be4e0f229cf3a71f9ecd633566bd6f80d9fa6afaaff5489492be63fe459ef98c", - "sha256:c0f84360dcca3481e8674393bdf931f9f10470988f87311b19d23cda869bb6b7", - "sha256:c1e41b32d6f7f9c26bc731a8b529ff592f31fc8b6ef2be9fa74abd05c8a342d7", - "sha256:c88fa7410e9fc471e0858638f403739ee869924dd8e4ae26748496466e27ac59", - "sha256:cf98fd7a6c8aaa08dbc699ffae33fd71175696d78028281bc7b832b26f00ca57", - "sha256:d072f7dfbdb184f0786d63bda26e8a0882041b1e393fbe98940395f7fab4c5e2", - "sha256:d1b5d457acbadcf8b27561deeaa386b0217f47626b29672fa7bd31deb6e91e1b", - "sha256:d3dcb5548ead4f1123851a5ced467791f6986d68c656bc63bfff1bf9e36671e2", - "sha256:d6157793719de168b199194f6b6173f0ccd3bf3499e6870fac17086072e39115", - "sha256:d728b08448e5ac3e4d886b165385a262883c34b84a7fe1166277fe675e1c197a", - "sha256:de8df0684398bd74ad160afdc2a118ca28384ac6f5e234eb0508858d8d2d9364", - "sha256:e6a02cf7271ee94674a44f4e62aa061d2d049001c844657740e156596298b70b", - "sha256:ea12133df25e3a6918718fbb9a510c6ee5d3fdd5a346320421aac3882f4feeea", - "sha256:ea5a79e808baef98c48c884effce05c31a0698c1057de8fc1c688891043c1ce1", - "sha256:f43b4a2e6218371dd4f41e547bd919ceeb6ebf4abf31a7a0669cd11cd91ea973", - "sha256:f762442bab706fd874064ca218b33a1d8e40d4938e96c24dafd9b12e28017f45", - "sha256:f89468059ebc519a7acde1ee50b779019535db8dcf9b8c162ef669257fef7a93", - "sha256:f907c7359ce8bf7f7e63c82f75ad0223384105f5126f313400b7e8004d9b33c3" - ], - "index": "pypi", - "version": "==22.3.0" + "sha256:057176dd3f5ccf5aad4abd662d76b6a39bbf799baaf2f39cd4fdaf2eab326e43", + "sha256:05ec90a8da618f2398f9d1aa20b18a9ef332992c6ac23e8c866099faad6ef0d6", + "sha256:154de02b15422af28b53d29a02de72121ba503634955017255573fc1f995143d", + "sha256:16b832adb5d8716f46051da5533c480250bf126984ce86804db6137a3a7f931b", + "sha256:1df26aa854bdd3a8341bf199064dd6aa6e240f2eaa3c9fa8d217e5d8b868c73e", + "sha256:28f9164fb2658b7b414fa0894c75b1a9c61375774cdc1bdb7298beb042a2cd87", + "sha256:2951c29b8649f3672af9dca8ff61d86310d3664d9629788b1c66422fb13b1239", + "sha256:2b08774057ae7ce8a2eb4e7d54db05358234440706ce43a85814500c5d7bd22e", + "sha256:2e2ac40f7a91c740ec68d6db07ae19ea9259c959333c68bee56ab2c799a67d66", + "sha256:312e56799410c34797417a4060a8bd37d4db1f06d1ec0c54f7c8fd81e0d90376", + "sha256:38f778a74e3889392e949326cfd0e9b2eb37dcbb2980d98fad2c51703d523db2", + "sha256:3955dd5bbbe02f454655296ee36a66c334c7102a29b8458223d168c0380edfd5", + "sha256:425ba851a6f9892bde1da2024d82e2fe6796bd77e3391fb96665c50fe9d4c6a5", + "sha256:48bbc2db041ab28eeee4a3e8ada0ed336640946dd5a8e53dbd3805f9dbdcf0dc", + "sha256:4fbcd657cda75574fd1315a4c44bd322bc2e219039fb09f146bbe6f8aef039e9", + "sha256:523ba7fd4d8fe75ad09c1e574a648892b75a97d0cfc8005727681053ac19555b", + "sha256:53b2c1326c2e484d450932d2be739f064b7cb572faabec38386098a28516a529", + "sha256:540d7146c3cdc9bbffab039ea067f494eba24d1abe5bd33eb9f963c01e3305d4", + "sha256:563d4281c4dbdf647d93114420151d33f895afc4c46b7115a67a0aa5347e6624", + "sha256:67a049bcf967a39993858beed873ed3405536019820922d4efacfe35ab3da51a", + "sha256:67ec63ae3c9c1fa2e077fcb42e77035e2121a04f987464bdf9945a28535d30ad", + "sha256:68e22c5d3be451e87d47f956b397a7823bfbde2176341bc902fba30f96831d7e", + "sha256:6ab4b6108e69f63c917cd7ef7217c5727955b1ac90600e44a13ed5312019a014", + "sha256:6bd7f18bd4cf51ea8d7e54825902cf36f9d2f35cc51ef618373988d5398b8dd0", + "sha256:6cd53e861bccc0bdc4620f68fb4a91d5bcfe9f4213cf8e200fa498044d33a6dc", + "sha256:6d346e551fa64b89d57a4ac74b9bc66703413f02f50093e089e861999ec5cccc", + "sha256:6ff8708fabc9f9bc2949f457d39b4088c9656c4c9ac15fbbbbaafce8f6d07833", + "sha256:7626e8384275a7dea6f3d1f749fb5e00299042e9c895fc3dbe24cb154909c242", + "sha256:7e7346b2b33dcd4a2171dd8a9870ae283eec8f6231dcbcf237a0f41e74751a50", + "sha256:81623c67cb71b93b5f7e06c9107f3781738ae86866db830c950223d87af2a235", + "sha256:83f1c76068faf62c32a36dd62dc4db642c2027bbbd960f8f6345b59e9d4dc472", + "sha256:8679bb1dd723ecbea03b1f96c98972815775fd8ec756c440a14f289c436c472e", + "sha256:86fb683cb9a9c0bb7476988b7957393ecdd22777d87d804442c66e62c99197f9", + "sha256:8757c62f7960cd26122f7aaaf86eda1e016fa85734c3777b8054dd334d7dea4d", + "sha256:894be7d17228e7328cc188096c0162697211ec91761f6812fff12790cbe11c66", + "sha256:8a0f240bf43c29be1bd82d77e602a61c798e9de02e5f8bb7bb414cb814f43236", + "sha256:8c3abf7eab5b76ae162c4fbb16d514a947fc57fd995b64e5ea8ef8ba3b888a69", + "sha256:93332c6972e4c91522c4810e907f3aea067424338071161b39cacded022559df", + "sha256:97d6c676dc97d593625d9fc48154f2ffeabb619a1e6fe8d2a5b53f97e3e9bdee", + "sha256:99dd85f0ca1db8d17a01a25c2bbb7784d25a2d39497c6beddbe96bff74194e04", + "sha256:9c7fb691fb07ec7ab99fd173bb0e7e0248d31bf83d484a87b917a342f63812c9", + "sha256:b3bc3cf200aab74f3d758586ac50295214eda496ac6a6636e0c881c5958d9123", + "sha256:bba54f97578943f48f621b4a7afb8eb022370da26a88b88ccc9fee9f3ef7ce45", + "sha256:bd2a13a0f8367e50347cbac87ae230ae1953935443240238f956bf10668bead6", + "sha256:cbc1184349ca6e5112898aa7fc3efa1b1bbae24ab1edc774cfd09cbfd3b091d7", + "sha256:cd82cca9c489e441574804dbda2dd8e114cf3be7935b03de11dade2c9478aea6", + "sha256:ce8ba5ed8b0a7a203922d61cff45ee6001a41a9359f04f00d055a4e988755569", + "sha256:cfee22e072a382b92ee0709dbb8203dabd52d54258051e770d9d2a81b162530b", + "sha256:d977df6f7c4109ed1d96ffb6795f6af77114be606ae4556efbfc9cac725db65d", + "sha256:da72a384a1d7e87490ca71182f3ab469ed21d847adc16b70c34faac5a3b12801", + "sha256:ddf4ad1d651e6c9234945061e1a31fe27a4be0dea21c498b87b186fadf8f5919", + "sha256:eb0ae5dfda83bbce660179d7b41c1c38fd833a54d2e6d9b258c644f3b75ef94d", + "sha256:f4c7d370badc60ac94a554bc571a46d03e39d8aacfba8006b334512e184aed59", + "sha256:f6c378b435a26fda8996579c0e324b108d2ca0d01b4661503a75634e5155559f", + "sha256:f6c9d30888503f2f5f87d6d41f016301352dd98da4a861bd10663c3a2d99d3b5", + "sha256:fab8a7877275060f7b303e1f91c218069a2814a616b6a5ee2d8a3737deb15915", + "sha256:fc32e7d7f98cac3d8d5153ed2cb583158ae3d446a6efb8e28ccb1c54a09f4169" + ], + "index": "pypi", + "version": "==23.1.0" }, "requests": { "hashes": [ - "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61", - "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d" + "sha256:bc7861137fbce630f17b03d3ad02ad0bf978c844f3536d0edda6499dafce2b6f", + "sha256:d568723a7ebd25875d8d1eaf5dfa068cd2fc8194b2e483d7b1f7c81918dbec6b" ], "index": "pypi", - "version": "==2.27.1" + "version": "==2.28.0" }, "scons": { "hashes": [ @@ -888,46 +1094,96 @@ }, "sentry-sdk": { "hashes": [ - "sha256:32af1a57954576709242beb8c373b3dbde346ac6bd616921def29d68846fb8c3", - "sha256:38fd16a92b5ef94203db3ece10e03bdaa291481dd7e00e77a148aa0302267d47" + "sha256:259535ba66933eacf85ab46524188c84dcb4c39f40348455ce15e2c0aca68863", + "sha256:778b53f0a6c83b1ee43d3b7886318ba86d975e686cb2c7906ccc35b334360be1" ], "index": "pypi", - "version": "==1.5.8" + "version": "==1.5.12" }, "setproctitle": { "hashes": [ - "sha256:077943272d0490b3f43d17379432d5e49c263f608fdf4cf624b419db762ca72b", - "sha256:0d160d46c8f3567e0aa27b26b1f36e03122e3de475aacacc14a92b8fe45b648a", - "sha256:0df728d0d350e6b1ad8436cc7add052faebca6f4d03257182d427d86d4422065", - "sha256:17598f38be9ef499d74f2380bf76b558be72e87da75d66b153350e586649171b", - "sha256:249526a06f16d493a2cb632abc1b1fdfaaa05776339a50dd9f27c941f6ff1383", - "sha256:28b884e1cb9a53974e15838864283f9bad774b5c7db98c9609416bd123cb9fd1", - "sha256:30bc7a769a4451639a0adcbc97bdf7a6e9ac0ef3ddad8d63eb1e338edb3ebeda", - "sha256:3f6136966c81daaf5b4b010613fe33240a045a4036132ef040b623e35772d998", - "sha256:4fc5bebd34f451dc87d2772ae6093adea1ea1dc29afc24641b250140decd23bb", - "sha256:5260e8700c5793d48e79c5e607e8e552e795b698491a4b9bb9111eb74366a450", - "sha256:7dfb472c8852403d34007e01d6e3c68c57eb66433fb8a5c77b13b89a160d97df", - "sha256:9106bcbacae534b6f82955b176723f1b2ca6514518aab44dffec05a583f8dca8", - "sha256:970798d948f0c90a3eb0f8750f08cb215b89dcbee1b55ffb353ad62d9361daeb", - "sha256:a11d329f33221443317e2aeaee9442f22fcae25be3aa4fb8489e4f7b1f65cdd2", - "sha256:ba1fb32e7267330bd9f72e69e076777a877f1cb9be5beac5e62d1279e305f37f", - "sha256:bc4393576ed3ac87ddac7d1bd0faaa2fab24840a025cc5f3c21d14cf0c9c8a12", - "sha256:c611f65bc9de5391a1514de556f71101e6531bb0715d240efd3e9732626d5c9e", - "sha256:e13a5c1d9c369cb11cdfc4b75be432b83eb3205c95a69006008ffd4366f87b9e", - "sha256:e696c93d93c23f377ccd2d72e38908d3dbfc90e45561602b805f53f2627d42ea", - "sha256:e8ef655eab26e83ec105ce79036bb87e5f2bf8ba2d6f48afdd9595ef7647fcf4", - "sha256:fbf914179dc4540ee6bfd8228b4cc1f1f6fb12dad66b72b5c9b955b222403220" - ], - "index": "pypi", - "version": "==1.2.2" + "sha256:01cef383afc7ea7a3b1696818c8712029bf2f1d64f5d4777dbaf0166becf2c00", + "sha256:0670f2130a7ca0e167d3d5a7c8e3c707340b8693d6af7416ff55c18ab2a0a43f", + "sha256:06aab65e68163ead9d046b452dd9ad1fc6834ce6bde490f63fdce3be53e9cc73", + "sha256:0a668acec8b61a971de54bc4c733869ea7b0eb1348eae5a32b9477f788908e5c", + "sha256:0b207de9e4f4aa5265b36dd826a1f6ef6566b064a042033bd7447efb7e9a7664", + "sha256:0b444ed4051161a3b0a85dec2bb9b50922f37c75f5fb86f7784b235cf6754336", + "sha256:138bfa853e607f06d95b0f253e9152b32a00af3d0dbec96abf0871236a483932", + "sha256:14641a4ec2f2110cf4afc666eaecc82ba67814e927e02647fa1f4cf74476e752", + "sha256:21d6e064b8fee4e58eb00cdd8771c638de1bc30bb6c02d0208af9ca0a1c00898", + "sha256:25538341e56f9e75e9759229ff674282dccb5b1ce79a974f968d36208d465674", + "sha256:28e0df80d5069586a08a3cb463fb23503a37cbb805826ef93164bc4bfb5f35b9", + "sha256:2c0be45535e934deab3aa72ed1a8487174af4ea12cec124478c68a312e1c8b13", + "sha256:2c8c245e08f6a296fdaa1b36894ec40e20464a4fc6458e6178c8d55a2f83457a", + "sha256:2d083cae02e344e760bd21c28d591ac5f7ddbd6e1a0ecba62092ae724abd5c28", + "sha256:32a84cc309b9e595f06a55bec2fa335a23c307a55d2989864b60ecd71ea87897", + "sha256:335750c9eb5b18326a138a09266862a52b4f474277c3e410b419bea9a1df8bee", + "sha256:35b869e416a105c59133a48b569c6e808159485d916f55e80c7394a42667a386", + "sha256:38855b06a124361dc73c198853dee3f2b775531c4f4b7472f0e3d441192b3d8a", + "sha256:3b1883ccdbee624386dc046cfbcd80c4e75e24c478f35627984a79892e088b88", + "sha256:3dbe87e76197f9a303451512088c18c96f09a6fc4f871a92e5bd695f46f94a26", + "sha256:3f55493c987935fa540ef9ffb7ee7db03b4a18a9d5cc103681e2e6a6dfbd7054", + "sha256:4051c3a3b07f8a4cca205cd45366a22f322da2f26491c0d6b313a10f8c77b734", + "sha256:409a39f92e123be061626fdfd3e76625b04db103479bb4ba1c85b587db0b9498", + "sha256:423f8a6d8116acf975ebf93d6b5c4a752f7d2039fa9aafe175a62de86e17016e", + "sha256:47f97f591ea2335b7d35f5e9ad7d806385338182dc6de5732d091e9c70ed1cc0", + "sha256:48ac48a94040ef21be37366cbc8270fcba2ca103d6c64da6099d5a7b034f72d0", + "sha256:4eed53c12146de5df959d84384ffc2774651cab406ee4854e12728cf0eee5297", + "sha256:501c084cf3df7d848e91c97d4f8c44d799ba545858a79c6960326ce6f285b4e4", + "sha256:52265182fe5ac237d179d8e949248d307882a2e6ec7f189c8dac1c9d1b3631fa", + "sha256:5464e6812d050c986e6e9b97d54ab88c23dbe9d81151a2fa10b48bb5133a1e2c", + "sha256:54c7315e53b49ef2227d47a75c3d28c4c51ea9ee46a066460732c0d0f8e605a7", + "sha256:60f7a2f5da36a3075dda7edbee2173be5b765b0460b8d401ee01a11f68dee1d2", + "sha256:65a9384cafdfed98f91416e93705ad08f049c298afcb9c515882beba23153bd0", + "sha256:71d00ef63a1f78e13c236895badac77b6c8503377467b9c1a4f81fe729d16e03", + "sha256:76f59444a25fb42ca07f53a4474b1545d97a06f016e6c6b8246eee5b146820b5", + "sha256:791bed39e4ecbdd008b64999a60c9cc560d17b3836ca0c27cd4708e8e1bcf495", + "sha256:7a72bbe53191fbe574c94c0f8b9451dce535b398b7c47ce2e26e21d55eaa1d7e", + "sha256:97accd117392b1e57e09888792750c403d7729b7e4b193005178b3736b325ea0", + "sha256:9a92978030616f5e20617b7b832efee398df82072b7239c53db41c8026f5fe55", + "sha256:9fb5d2e66f94eebc3d06cda9e71a3fffef24c5273971180a4b5628a37fae05a5", + "sha256:a39b30d7400c0d50941fe19e1fe0b7d35676186fec4d9c010129ac91b883fd26", + "sha256:a4a3cb19346a0cd680617742f5e39fdd14596f6fd91d6c9038272663e37441b4", + "sha256:a546cd2dfaecb227d24122257b98b2e062762871888835c7b608f1c41c3a77ad", + "sha256:a81067bdc015fee1cc148c79b346f24fdad1224a8898b4239c7cbdee1add8a60", + "sha256:a912df3f065572cef211e9ed9f157a0dd2bd73d150281f18f00728afa1b1e5d2", + "sha256:a993610383028f093112dce7f77b262e88fce9d70127535fcdc78953179857e8", + "sha256:b213376fc779c0e1a4b60008f3fd03f74e9baa9665db37fa6646e98d31baa6d8", + "sha256:b2fa9f4b382a6cf88f2f345044d0916a92f37cac21355585bd14bc7ee91af187", + "sha256:b9d905ac84dde5227de6516ec08639759f99684148bb88ba05f4cbdaebff5d69", + "sha256:be0b46beeb1c92450079a7f30a025d69b63fd6a5de040ebc478fd6e6bf3b63fc", + "sha256:c93a2272740e60cddf59d3e1d35dbb89fcc3676f5ca9618bb4e6ae9633fdf13c", + "sha256:ccb0b5334dbf248f7504d88b5e9e9a09a0da119eeafacd6f7247f7c055443522", + "sha256:d312a170f539895c8093b5e68ba126aa131c9f0d00f6360410db27ec50bf7afa", + "sha256:d45dbe4171f8c27a515ecb4562f4cd9ef67d98474bea18e0c14dfbdc2b225050", + "sha256:d8e4da68d4d4ba46d4c5db6ae5eb61b11de9c520f25ae8334570f4d0018a8611", + "sha256:e24fa9251cc22ddb88ef183070063fdca826c9636381f1c4fb9d2a1dccb7c2a4", + "sha256:e2ac0ebd9c63c3d19f768966be2f771bf088bc7373c63ed6fcbb3444a30d0f62", + "sha256:e40c35564081983eab6a07f9eb5693867bc447b0edf9c61b69446223d6593814", + "sha256:e80fc59739a738b5c67afbbb9d1c238aa47b6d290c2ada872b15c819350ec5f8", + "sha256:eb06c1086cf8c8cf12ce45a02450befcb408dfd646d0ccb47d388fd6e73c333a", + "sha256:eb82a49aaf440232c762539ab3737b5174d31aba0141fd4bf4d8739c28d18624", + "sha256:ec7c3a27460ae7811e868e5494e3d8aee5012912744c48fa2d80b5e614b1b972", + "sha256:ecf28b1c07a799d76f4326e508157b71aeda07b84b90368ea451c0710dbd32c0", + "sha256:efb3001fd9e71d3ae939d826bf436f0446fd30a6ac01e0ce08cd7eb55ee5ac57", + "sha256:f06ff922254023eaabef6af6631f89e5f2f420cf0112865d57d7703f933d4e9f", + "sha256:f272b84d79bbe15af26ecf6f7c129bbe642f628866c9253659cdb519216f138f", + "sha256:f2a137984d3436f13e4bf7c8ca6f6f292df119c009c5e39556cabba4f4bfbf92", + "sha256:f47f6704880869d8e8f52efac2f2f60f5ed4cb9662b98fc1c7e916eefe76e61d", + "sha256:f9cf1098205c23fbcaaaef798afaff714fa9ffadf24166f5e85e6d16b9ef82a1", + "sha256:fc586f002fd5dd8695718e22a83771fd9f744f081a2b8e614bf6b5f44135964a", + "sha256:fdb2231db176e0848b757fc5d9bed08bc8a498b5b9abb8b640f39e9720f309fc" + ], + "index": "pypi", + "version": "==1.2.3" }, "setuptools": { "hashes": [ - "sha256:7999cbd87f1b6e1f33bf47efa368b224bed5e27b5ef2c4d46580186cbcb1a86a", - "sha256:a65e3802053e99fc64c6b3b29c11132943d5b8c8facbcc461157511546510967" + "sha256:5a844ad6e190dccc67d6d7411d119c5152ce01f7c76be4d8a1eaa314501bba77", + "sha256:bf8a748ac98b09d32c9a64a995a6b25921c96cc5743c1efa82763ba80ff54e91" ], "markers": "python_version >= '3.7'", - "version": "==62.0.0" + "version": "==62.4.0" }, "six": { "hashes": [ @@ -939,11 +1195,11 @@ }, "smbus2": { "hashes": [ - "sha256:6276eb599b76c4e74372f2582d2282f03b4398f0da16bc996608e4f21557ca9b", - "sha256:8b1e70cda011b6fb3caf8377a1084f73a5aa99392b78529f140b0a3f06468f6c" + "sha256:50f3c78e436b42a9583948be06961a8104cf020ebad5edfaaf2657528bef0818", + "sha256:634541ed794068a822fe7499f1577468b9d4641b68dd9bfb6d0eb7270f4d2a32" ], "index": "pypi", - "version": "==0.4.1" + "version": "==0.4.2" }, "sympy": { "hashes": [ @@ -955,11 +1211,11 @@ }, "timezonefinder": { "hashes": [ - "sha256:4545533086eb25cd7ba10b97785059acbababf4577ab1b4d5c2ab56642eadfea", - "sha256:a374570295a8dbd923630ce85f754e52578e288cb0a9cf575834415e84758352" + "sha256:0471463083b5fef7a656c7e31a7376fa1941bf6a41a0750c6e0ca151e43646e7", + "sha256:2e8e958814f21fa809b16e98bd2f99082b69a0f88b864a4a1f2944d5a7e61827" ], "index": "pypi", - "version": "==5.2.0" + "version": "==6.0.1" }, "tomli": { "hashes": [ @@ -969,6 +1225,14 @@ "markers": "python_version < '3.11'", "version": "==2.0.1" }, + "tomlkit": { + "hashes": [ + "sha256:0f4050db66fd445b885778900ce4dd9aea8c90c4721141fde0d6ade893820ef1", + "sha256:71ceb10c0eefd8b8f11fe34e8a51ad07812cb1dc3de23247425fbc9ddc47b9dd" + ], + "markers": "python_version >= '3.6' and python_version < '4.0'", + "version": "==0.11.0" + }, "tqdm": { "hashes": [ "sha256:40be55d30e200777a307a7585aee69e4eabb46b4ec6a4b4a5f2d9f11e7d5408d", @@ -979,11 +1243,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42", - "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2" + "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", + "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" ], - "markers": "python_version >= '3.6'", - "version": "==4.1.1" + "markers": "python_version < '3.10'", + "version": "==4.2.0" }, "urllib3": { "hashes": [ @@ -1010,81 +1274,81 @@ }, "werkzeug": { "hashes": [ - "sha256:3c5493ece8268fecdcdc9c0b112211acd006354723b280d643ec732b6d4063d6", - "sha256:f8e89a20aeabbe8a893c24a461d3ee5dad2123b05cc6abd73ceed01d39c3ae74" + "sha256:1ce08e8093ed67d638d63879fd1ba3735817f7a80de3674d293f5984f25fb6e6", + "sha256:72a4b735692dd3135217911cbeaa1be5fa3f62bffb8745c5215420a03dc55255" ], "markers": "python_version >= '3.7'", - "version": "==2.1.1" + "version": "==2.1.2" }, "wrapt": { "hashes": [ - "sha256:00108411e0f34c52ce16f81f1d308a571df7784932cc7491d1e94be2ee93374b", - "sha256:01f799def9b96a8ec1ef6b9c1bbaf2bbc859b87545efbecc4a78faea13d0e3a0", - "sha256:09d16ae7a13cff43660155383a2372b4aa09109c7127aa3f24c3cf99b891c330", - "sha256:14e7e2c5f5fca67e9a6d5f753d21f138398cad2b1159913ec9e9a67745f09ba3", - "sha256:167e4793dc987f77fd476862d32fa404d42b71f6a85d3b38cbce711dba5e6b68", - "sha256:1807054aa7b61ad8d8103b3b30c9764de2e9d0c0978e9d3fc337e4e74bf25faa", - "sha256:1f83e9c21cd5275991076b2ba1cd35418af3504667affb4745b48937e214bafe", - "sha256:21b1106bff6ece8cb203ef45b4f5778d7226c941c83aaaa1e1f0f4f32cc148cd", - "sha256:22626dca56fd7f55a0733e604f1027277eb0f4f3d95ff28f15d27ac25a45f71b", - "sha256:23f96134a3aa24cc50614920cc087e22f87439053d886e474638c68c8d15dc80", - "sha256:2498762814dd7dd2a1d0248eda2afbc3dd9c11537bc8200a4b21789b6df6cd38", - "sha256:28c659878f684365d53cf59dc9a1929ea2eecd7ac65da762be8b1ba193f7e84f", - "sha256:2eca15d6b947cfff51ed76b2d60fd172c6ecd418ddab1c5126032d27f74bc350", - "sha256:354d9fc6b1e44750e2a67b4b108841f5f5ea08853453ecbf44c81fdc2e0d50bd", - "sha256:36a76a7527df8583112b24adc01748cd51a2d14e905b337a6fefa8b96fc708fb", - "sha256:3a0a4ca02752ced5f37498827e49c414d694ad7cf451ee850e3ff160f2bee9d3", - "sha256:3a71dbd792cc7a3d772ef8cd08d3048593f13d6f40a11f3427c000cf0a5b36a0", - "sha256:3a88254881e8a8c4784ecc9cb2249ff757fd94b911d5df9a5984961b96113fff", - "sha256:47045ed35481e857918ae78b54891fac0c1d197f22c95778e66302668309336c", - "sha256:4775a574e9d84e0212f5b18886cace049a42e13e12009bb0491562a48bb2b758", - "sha256:493da1f8b1bb8a623c16552fb4a1e164c0200447eb83d3f68b44315ead3f9036", - "sha256:4b847029e2d5e11fd536c9ac3136ddc3f54bc9488a75ef7d040a3900406a91eb", - "sha256:59d7d92cee84a547d91267f0fea381c363121d70fe90b12cd88241bd9b0e1763", - "sha256:5a0898a640559dec00f3614ffb11d97a2666ee9a2a6bad1259c9facd01a1d4d9", - "sha256:5a9a1889cc01ed2ed5f34574c90745fab1dd06ec2eee663e8ebeefe363e8efd7", - "sha256:5b835b86bd5a1bdbe257d610eecab07bf685b1af2a7563093e0e69180c1d4af1", - "sha256:5f24ca7953f2643d59a9c87d6e272d8adddd4a53bb62b9208f36db408d7aafc7", - "sha256:61e1a064906ccba038aa3c4a5a82f6199749efbbb3cef0804ae5c37f550eded0", - "sha256:65bf3eb34721bf18b5a021a1ad7aa05947a1767d1aa272b725728014475ea7d5", - "sha256:6807bcee549a8cb2f38f73f469703a1d8d5d990815c3004f21ddb68a567385ce", - "sha256:68aeefac31c1f73949662ba8affaf9950b9938b712fb9d428fa2a07e40ee57f8", - "sha256:6915682f9a9bc4cf2908e83caf5895a685da1fbd20b6d485dafb8e218a338279", - "sha256:6d9810d4f697d58fd66039ab959e6d37e63ab377008ef1d63904df25956c7db0", - "sha256:729d5e96566f44fccac6c4447ec2332636b4fe273f03da128fff8d5559782b06", - "sha256:748df39ed634851350efa87690c2237a678ed794fe9ede3f0d79f071ee042561", - "sha256:763a73ab377390e2af26042f685a26787c402390f682443727b847e9496e4a2a", - "sha256:8323a43bd9c91f62bb7d4be74cc9ff10090e7ef820e27bfe8815c57e68261311", - "sha256:8529b07b49b2d89d6917cfa157d3ea1dfb4d319d51e23030664a827fe5fd2131", - "sha256:87fa943e8bbe40c8c1ba4086971a6fefbf75e9991217c55ed1bcb2f1985bd3d4", - "sha256:88236b90dda77f0394f878324cfbae05ae6fde8a84d548cfe73a75278d760291", - "sha256:891c353e95bb11abb548ca95c8b98050f3620a7378332eb90d6acdef35b401d4", - "sha256:89ba3d548ee1e6291a20f3c7380c92f71e358ce8b9e48161401e087e0bc740f8", - "sha256:8c6be72eac3c14baa473620e04f74186c5d8f45d80f8f2b4eda6e1d18af808e8", - "sha256:9a242871b3d8eecc56d350e5e03ea1854de47b17f040446da0e47dc3e0b9ad4d", - "sha256:9a3ff5fb015f6feb78340143584d9f8a0b91b6293d6b5cf4295b3e95d179b88c", - "sha256:9a5a544861b21e0e7575b6023adebe7a8c6321127bb1d238eb40d99803a0e8bd", - "sha256:9d57677238a0c5411c76097b8b93bdebb02eb845814c90f0b01727527a179e4d", - "sha256:9d8c68c4145041b4eeae96239802cfdfd9ef927754a5be3f50505f09f309d8c6", - "sha256:9d9fcd06c952efa4b6b95f3d788a819b7f33d11bea377be6b8980c95e7d10775", - "sha256:a0057b5435a65b933cbf5d859cd4956624df37b8bf0917c71756e4b3d9958b9e", - "sha256:a65bffd24409454b889af33b6c49d0d9bcd1a219b972fba975ac935f17bdf627", - "sha256:b0ed6ad6c9640671689c2dbe6244680fe8b897c08fd1fab2228429b66c518e5e", - "sha256:b21650fa6907e523869e0396c5bd591cc326e5c1dd594dcdccac089561cacfb8", - "sha256:b3f7e671fb19734c872566e57ce7fc235fa953d7c181bb4ef138e17d607dc8a1", - "sha256:b77159d9862374da213f741af0c361720200ab7ad21b9f12556e0eb95912cd48", - "sha256:bb36fbb48b22985d13a6b496ea5fb9bb2a076fea943831643836c9f6febbcfdc", - "sha256:d066ffc5ed0be00cd0352c95800a519cf9e4b5dd34a028d301bdc7177c72daf3", - "sha256:d332eecf307fca852d02b63f35a7872de32d5ba8b4ec32da82f45df986b39ff6", - "sha256:d808a5a5411982a09fef6b49aac62986274ab050e9d3e9817ad65b2791ed1425", - "sha256:d9bdfa74d369256e4218000a629978590fd7cb6cf6893251dad13d051090436d", - "sha256:db6a0ddc1282ceb9032e41853e659c9b638789be38e5b8ad7498caac00231c23", - "sha256:debaf04f813ada978d7d16c7dfa16f3c9c2ec9adf4656efdc4defdf841fc2f0c", - "sha256:f0408e2dbad9e82b4c960274214af533f856a199c9274bd4aff55d4634dedc33", - "sha256:f2f3bc7cd9c9fcd39143f11342eb5963317bd54ecc98e3650ca22704b69d9653" + "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3", + "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b", + "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4", + "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2", + "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656", + "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3", + "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff", + "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310", + "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a", + "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57", + "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069", + "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383", + "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe", + "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87", + "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d", + "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b", + "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907", + "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f", + "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0", + "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28", + "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1", + "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853", + "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc", + "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3", + "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3", + "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164", + "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1", + "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c", + "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1", + "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7", + "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1", + "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320", + "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed", + "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1", + "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248", + "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c", + "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456", + "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77", + "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef", + "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1", + "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7", + "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86", + "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4", + "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d", + "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d", + "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8", + "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5", + "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471", + "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00", + "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68", + "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3", + "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d", + "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735", + "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d", + "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569", + "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7", + "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59", + "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5", + "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb", + "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b", + "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f", + "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462", + "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015", + "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.14.0" + "version": "==1.14.1" }, "zipp": { "hashes": [ @@ -1111,29 +1375,96 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==21.4.0" }, + "av": { + "hashes": [ + "sha256:0340cc68f3d222bc9438b4fde12e3d68f949eeb5de9e090db182f2cb06e23d53", + "sha256:0d9cad890e6eccf2697b1c932761bee6f5e1e7faf9b8c03cf10f18f697d29ba3", + "sha256:109526152e658921731018c50a05db802e7c9f3eb04a7a5fcbd8321fb3b73134", + "sha256:17a7b6617d4201214f3dd5f628041b4fe56f4244dcd48399ed8d0cf324ca24d1", + "sha256:1cbf031f650f89943023eef80e8b2c99588bf9ba26ffef8b3b54bef7102ea3dc", + "sha256:1e2a50a146b3f33a24ea059af913ad368dbb61ed494234debe140a09f1076950", + "sha256:24dac414eafcc20423f2ec7e873706489433648f0e9af08a537996880aa55979", + "sha256:28d85b8476f7d8fb18e3af9bd6d22bb292f1d810a20f8910fe481f648372e798", + "sha256:29373aa86a055a07eebb14d253cb202033f63ba98c5a4b0233d6d4c07fc7a292", + "sha256:2b46b54ddf64409d4455f408b5970f8494c27c0273181b81c2f7d5072c9afb55", + "sha256:343b11d9b03e71da29f3ce56bc0a6c2d40aba448225dcf8296ab53c10527fff0", + "sha256:3ea180bfd89bc0a9e392c32de204cf4e51648aefe2f375d430ce39c04e3ed625", + "sha256:3facfe8dc5ba7f9ec7fd7e4c0466e577b84d5f2a1671428f7e28ebcd2cb0ccd3", + "sha256:45816a39255b39e514a72125e0b6e29eb24fe0994bef3f4f87f3b9d9960b3fa8", + "sha256:48819e401cea5be57bd03299d8e5f700082c411746d1ac23eb5e5a931d3d3ced", + "sha256:49481c2d5bc296f451ccd3f93b1cb692d7f58a804b794b99c8b7743e058cae71", + "sha256:587dd492a2ef3eb20324a0a8d67e6a2e686845d8c1dfdcad058377ac84268d67", + "sha256:6a1c2c1dcc1947473ea1e2cbbf50549e2655e49e08bdd2a6427a97276d7a92c8", + "sha256:6b01fbe8047da81892f8bd2aee5690f00465bf5215e3f6b6372863ac9408d75f", + "sha256:7a5dc26b9df656bed5e1bdeaf8bcc4ff4a2e009ee90b3b3024a86cf8476b2cbf", + "sha256:8671fa01648ce7aac76e71816c2421ddb1939bf706e2e14684608ab1ce9dbbbb", + "sha256:9b0f124e335561cf4de6b7cdc461283c5eba5f05cccb1a5e1b8ceb1cd15393d8", + "sha256:a616a6eb46b62f41ff69569cafe12b0005a6dd14389f597dee115340336a910f", + "sha256:a6a35e6028dec677caed97d19bfab3b66182690d43b0ec3c355778d740ce0509", + "sha256:a9983bc45dab65d2416d2f8a63785caa076a751590823fc8c199617d0dbad390", + "sha256:ab90aa3ac2cbdf1f22087fc0fa439f643e96979f169ecfa1d496e114c3c3a8b3", + "sha256:af951271d998f736a20e54fbc0d944f263db7b17592f11cd489947957bf46aa8", + "sha256:b07b91f534ee7a096068149404c67c3c0e5b4c373580b016151de0fcb440cd3f", + "sha256:b6be9388618af978304b56d1cf6b74c811db4f220dd320da5bd79640aa443358", + "sha256:ba3d9e3fe23fd8a14e810f291386225acbdef1c7e5376cc10c8e85c2d4280771", + "sha256:bf941896b4c800ee707211c802f94c6e0b4642d3000e25d1974d0b6032af4f66", + "sha256:d080f34ddfde551de3a5f2d0d06d7518718e3115af81e56182e158cc03111662", + "sha256:d380925732e7497c1c11545107eabe1f498cab214f49f32d1b5d6abe01a2b36b", + "sha256:d6a3c9126d658029b151484b48c656b73af1b145b143c50de5b8b983ac60e095", + "sha256:d730f3ed30eda46d06849bd71ad87d480cf0cad9fd064f33a0386dee95461e31", + "sha256:e3e4a28fa0eabd3ab5b0915e9c005e9155039f9e1a4466212434c40eb69a33fb", + "sha256:e59e4ab0e8832bf87707e5024283b3a24cc01784604f0b0e96fbfbadbd8d9fc0", + "sha256:f2a7c226724d7f7745b376b459c500d9d17bd8d0473b7ea6bf8ddb4f7957c69d" + ], + "index": "pypi", + "version": "==9.2.0" + }, + "azure-common": { + "hashes": [ + "sha256:4ac0cd3214e36b6a1b6a442686722a5d8cc449603aa833f3f0f40bda836704a3", + "sha256:5c12d3dcf4ec20599ca6b0d3e09e86e146353d443e7fcc050c9a19c1f9df20ad" + ], + "version": "==1.1.28" + }, + "azure-storage-blob": { + "hashes": [ + "sha256:a8e91a51d4f62d11127c7fd8ba0077385c5b11022f0269f8a2a71b9fc36bef31", + "sha256:b90323aad60f207f9f90a0c4cf94c10acc313c20b39403398dfba51f25f7b454" + ], + "index": "pypi", + "version": "==2.1.0" + }, + "azure-storage-common": { + "hashes": [ + "sha256:b01a491a18839b9d05a4fe3421458a0ddb5ab9443c14e487f40d16f9a1dc2fbe", + "sha256:ccedef5c67227bc4d6670ffd37cec18fb529a1b7c3a5e53e4096eb0cf23dc73f" + ], + "version": "==2.1.0" + }, "babel": { "hashes": [ - "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9", - "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0" + "sha256:7aed055f0c04c9e7f51a2f75261e41e1c804efa724cb65b60a970dd4448d469d", + "sha256:81a3beca4d0cd40a9cfb9e2adb2cf39261c2f959b92e7a74750befe5d79afd7b" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.9.1" + "markers": "python_version >= '3.6'", + "version": "==2.10.2" }, "bcrypt": { "hashes": [ - "sha256:56e5da069a76470679f312a7d3d23deb3ac4519991a0361abc11da837087b61d", - "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29", - "sha256:63d4e3ff96188e5898779b6057878fecf3f11cfe6ec3b313ea09955d587ec7a7", - "sha256:81fec756feff5b6818ea7ab031205e1d323d8943d237303baca2c5f9c7846f34", - "sha256:a0584a92329210fcd75eb8a3250c5a941633f8bfaf2a18f81009b097732839b7", - "sha256:a67fb841b35c28a59cebed05fbd3e80eea26e6d75851f0574a9273c80f3e9b55", - "sha256:b589229207630484aefe5899122fb938a5b017b0f4349f769b8c13e78d99a8fd", - "sha256:c95d4cbebffafcdd28bd28bb4e25b31c50f6da605c81ffd9ad8a3d1b2ab7b1b6", - "sha256:cd1ea2ff3038509ea95f687256c46b79f5fc382ad0aa3664d200047546d511d1", - "sha256:cdcdcb3972027f83fe24a48b1e90ea4b584d35f1cc279d76de6fc4b13376239d" + "sha256:2b02d6bfc6336d1094276f3f588aa1225a598e27f8e3388f4db9948cb707b521", + "sha256:433c410c2177057705da2a9f2cd01dd157493b2a7ac14c8593a16b3dab6b6bfb", + "sha256:4e029cef560967fb0cf4a802bcf4d562d3d6b4b1bf81de5ec1abbe0f1adb027e", + "sha256:61bae49580dce88095d669226d5076d0b9d927754cedbdf76c6c9f5099ad6f26", + "sha256:6d2cb9d969bfca5bc08e45864137276e4c3d3d7de2b162171def3d188bf9d34a", + "sha256:7180d98a96f00b1050e93f5b0f556e658605dd9f524d0b0e68ae7944673f525e", + "sha256:7d9ba2e41e330d2af4af6b1b6ec9e6128e91343d0b4afb9282e54e5508f31baa", + "sha256:7ff2069240c6bbe49109fe84ca80508773a904f5a8cb960e02a977f7f519b129", + "sha256:88273d806ab3a50d06bc6a2fc7c87d737dd669b76ad955f449c43095389bc8fb", + "sha256:a2c46100e315c3a5b90fdc53e429c006c5f962529bc27e1dfd656292c20ccc40", + "sha256:cd43303d6b8a165c29ec6756afd169faba9396a9472cdff753fe9f19b96ce2fa" ], "markers": "python_version >= '3.6'", - "version": "==3.2.0" + "version": "==3.2.2" }, "breathe": { "hashes": [ @@ -1145,23 +1476,25 @@ }, "carla": { "hashes": [ - "sha256:1ed11b56c781cd15cbd540cacfb59ad348e0a021d898cfd0ff89a585f144da0b", - "sha256:20c1e1b72034175824d89b2d86b09ae72b4aca09ea25874dc6251f239297251d", - "sha256:6d1122c24af4f6375dc6858fbb0309b61c219b101d8c5a540def4c36c4563fe1", - "sha256:9c19ebf6cbbc535bde4baf9e18c72ab349657b34c4202b9751541e4c0d20b3cc", - "sha256:a69f6d84b59e2f805b2a417de98f977fe9efe0cfa733da8d75e20d28892da915", - "sha256:c3ae0dce3f1354b6311fee21a365947b0ff169249993a913904f676046d2d69f", - "sha256:dd392a267e14b785a8f65dafef86e05a92201253e9fb4a01e1e262834f20bed2" + "sha256:1210cce213e968a644effd4e2e48458a072481459d073424b05725056ba3d77d", + "sha256:339fcb1e392f3ade1be82b7258de19c533e2efae111e954a6eb174efb296903d", + "sha256:5f065825ce812343bf27a80a19d647b3200b31b44a9e80cea0340e3bd20cdf81", + "sha256:954ca34d5bdd4516ceca353db907fee8cec6630d6b31a732b17dd1554e0f0f94", + "sha256:a64ee78fe91137fa7d4828c7fc06d5824bd7312e29e4ea4f31a5d74dd28bff40", + "sha256:a95d2d4218ea388c863c66b7c2ab3fe49ffefe53999305cfcb6a8107042f79af", + "sha256:d2bfaea2d6824a2d758cbe813856c69420494f5c97d2a2dfb45653ccf976f1ce" ], "index": "pypi", - "version": "==0.9.12" + "markers": "platform_system != 'Darwin'", + "version": "==0.9.13" }, "certifi": { "hashes": [ - "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", - "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" + "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7", + "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a" ], - "version": "==2021.10.8" + "markers": "python_version >= '3.6'", + "version": "==2022.5.18.1" }, "cffi": { "hashes": [ @@ -1232,88 +1565,90 @@ "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df" ], - "markers": "python_version >= '3'", + "markers": "python_full_version >= '3.5.0'", "version": "==2.0.12" }, "control": { "hashes": [ - "sha256:8c9084bf386eafcf5d74008f780fae6dec68d243d18a380c866ac10a3549f8d3" + "sha256:0891d2d32d6006ac1faa4e238ed8223ca342a4721d202dfeccae24fb02563183" ], "index": "pypi", - "version": "==0.9.1" + "version": "==0.9.2" }, "coverage": { "hashes": [ - "sha256:03e2a7826086b91ef345ff18742ee9fc47a6839ccd517061ef8fa1976e652ce9", - "sha256:07e6db90cd9686c767dcc593dff16c8c09f9814f5e9c51034066cad3373b914d", - "sha256:18d520c6860515a771708937d2f78f63cc47ab3b80cb78e86573b0a760161faf", - "sha256:1ebf730d2381158ecf3dfd4453fbca0613e16eaa547b4170e2450c9707665ce7", - "sha256:21b7745788866028adeb1e0eca3bf1101109e2dc58456cb49d2d9b99a8c516e6", - "sha256:26e2deacd414fc2f97dd9f7676ee3eaecd299ca751412d89f40bc01557a6b1b4", - "sha256:2c6dbb42f3ad25760010c45191e9757e7dce981cbfb90e42feef301d71540059", - "sha256:2fea046bfb455510e05be95e879f0e768d45c10c11509e20e06d8fcaa31d9e39", - "sha256:34626a7eee2a3da12af0507780bb51eb52dca0e1751fd1471d0810539cefb536", - "sha256:37d1141ad6b2466a7b53a22e08fe76994c2d35a5b6b469590424a9953155afac", - "sha256:46191097ebc381fbf89bdce207a6c107ac4ec0890d8d20f3360345ff5976155c", - "sha256:4dd8bafa458b5c7d061540f1ee9f18025a68e2d8471b3e858a9dad47c8d41903", - "sha256:4e21876082ed887baed0146fe222f861b5815455ada3b33b890f4105d806128d", - "sha256:58303469e9a272b4abdb9e302a780072c0633cdcc0165db7eec0f9e32f901e05", - "sha256:5ca5aeb4344b30d0bec47481536b8ba1181d50dbe783b0e4ad03c95dc1296684", - "sha256:68353fe7cdf91f109fc7d474461b46e7f1f14e533e911a2a2cbb8b0fc8613cf1", - "sha256:6f89d05e028d274ce4fa1a86887b071ae1755082ef94a6740238cd7a8178804f", - "sha256:7a15dc0a14008f1da3d1ebd44bdda3e357dbabdf5a0b5034d38fcde0b5c234b7", - "sha256:8bdde1177f2311ee552f47ae6e5aa7750c0e3291ca6b75f71f7ffe1f1dab3dca", - "sha256:8ce257cac556cb03be4a248d92ed36904a59a4a5ff55a994e92214cde15c5bad", - "sha256:8cf5cfcb1521dc3255d845d9dca3ff204b3229401994ef8d1984b32746bb45ca", - "sha256:8fbbdc8d55990eac1b0919ca69eb5a988a802b854488c34b8f37f3e2025fa90d", - "sha256:9548f10d8be799551eb3a9c74bbf2b4934ddb330e08a73320123c07f95cc2d92", - "sha256:96f8a1cb43ca1422f36492bebe63312d396491a9165ed3b9231e778d43a7fca4", - "sha256:9b27d894748475fa858f9597c0ee1d4829f44683f3813633aaf94b19cb5453cf", - "sha256:9baff2a45ae1f17c8078452e9e5962e518eab705e50a0aa8083733ea7d45f3a6", - "sha256:a2a8b8bcc399edb4347a5ca8b9b87e7524c0967b335fbb08a83c8421489ddee1", - "sha256:acf53bc2cf7282ab9b8ba346746afe703474004d9e566ad164c91a7a59f188a4", - "sha256:b0be84e5a6209858a1d3e8d1806c46214e867ce1b0fd32e4ea03f4bd8b2e3359", - "sha256:b31651d018b23ec463e95cf10070d0b2c548aa950a03d0b559eaa11c7e5a6fa3", - "sha256:b78e5afb39941572209f71866aa0b206c12f0109835aa0d601e41552f9b3e620", - "sha256:c76aeef1b95aff3905fb2ae2d96e319caca5b76fa41d3470b19d4e4a3a313512", - "sha256:dd035edafefee4d573140a76fdc785dc38829fe5a455c4bb12bac8c20cfc3d69", - "sha256:dd6fe30bd519694b356cbfcaca9bd5c1737cddd20778c6a581ae20dc8c04def2", - "sha256:e5f4e1edcf57ce94e5475fe09e5afa3e3145081318e5fd1a43a6b4539a97e518", - "sha256:ec6bc7fe73a938933d4178c9b23c4e0568e43e220aef9472c4f6044bfc6dd0f0", - "sha256:f1555ea6d6da108e1999b2463ea1003fe03f29213e459145e70edbaf3e004aaa", - "sha256:f5fa5803f47e095d7ad8443d28b01d48c0359484fec1b9d8606d0e3282084bc4", - "sha256:f7331dbf301b7289013175087636bbaf5b2405e57259dd2c42fdcc9fcc47325e", - "sha256:f9987b0354b06d4df0f4d3e0ec1ae76d7ce7cbca9a2f98c25041eb79eec766f1", - "sha256:fd9e830e9d8d89b20ab1e5af09b32d33e1a08ef4c4e14411e559556fd788e6b2" - ], - "index": "pypi", - "version": "==6.3.2" + "sha256:01c5615d13f3dd3aa8543afc069e5319cfa0c7d712f6e04b920431e5c564a749", + "sha256:106c16dfe494de3193ec55cac9640dd039b66e196e4641fa8ac396181578b982", + "sha256:129cd05ba6f0d08a766d942a9ed4b29283aff7b2cccf5b7ce279d50796860bb3", + "sha256:145f296d00441ca703a659e8f3eb48ae39fb083baba2d7ce4482fb2723e050d9", + "sha256:1480ff858b4113db2718848d7b2d1b75bc79895a9c22e76a221b9d8d62496428", + "sha256:269eaa2c20a13a5bf17558d4dc91a8d078c4fa1872f25303dddcbba3a813085e", + "sha256:26dff09fb0d82693ba9e6231248641d60ba606150d02ed45110f9ec26404ed1c", + "sha256:2bd9a6fc18aab8d2e18f89b7ff91c0f34ff4d5e0ba0b33e989b3cd4194c81fd9", + "sha256:309ce4a522ed5fca432af4ebe0f32b21d6d7ccbb0f5fcc99290e71feba67c264", + "sha256:3384f2a3652cef289e38100f2d037956194a837221edd520a7ee5b42d00cc605", + "sha256:342d4aefd1c3e7f620a13f4fe563154d808b69cccef415415aece4c786665397", + "sha256:39ee53946bf009788108b4dd2894bf1349b4e0ca18c2016ffa7d26ce46b8f10d", + "sha256:4321f075095a096e70aff1d002030ee612b65a205a0a0f5b815280d5dc58100c", + "sha256:4803e7ccf93230accb928f3a68f00ffa80a88213af98ed338a57ad021ef06815", + "sha256:4ce1b258493cbf8aec43e9b50d89982346b98e9ffdfaae8ae5793bc112fb0068", + "sha256:664a47ce62fe4bef9e2d2c430306e1428ecea207ffd68649e3b942fa8ea83b0b", + "sha256:75ab269400706fab15981fd4bd5080c56bd5cc07c3bccb86aab5e1d5a88dc8f4", + "sha256:83c4e737f60c6936460c5be330d296dd5b48b3963f48634c53b3f7deb0f34ec4", + "sha256:84631e81dd053e8a0d4967cedab6db94345f1c36107c71698f746cb2636c63e3", + "sha256:84e65ef149028516c6d64461b95a8dbcfce95cfd5b9eb634320596173332ea84", + "sha256:865d69ae811a392f4d06bde506d531f6a28a00af36f5c8649684a9e5e4a85c83", + "sha256:87f4f3df85aa39da00fd3ec4b5abeb7407e82b68c7c5ad181308b0e2526da5d4", + "sha256:8c08da0bd238f2970230c2a0d28ff0e99961598cb2e810245d7fc5afcf1254e8", + "sha256:961e2fb0680b4f5ad63234e0bf55dfb90d302740ae9c7ed0120677a94a1590cb", + "sha256:9b3e07152b4563722be523e8cd0b209e0d1a373022cfbde395ebb6575bf6790d", + "sha256:a7f3049243783df2e6cc6deafc49ea123522b59f464831476d3d1448e30d72df", + "sha256:bf5601c33213d3cb19d17a796f8a14a9eaa5e87629a53979a5981e3e3ae166f6", + "sha256:cec3a0f75c8f1031825e19cd86ee787e87cf03e4fd2865c79c057092e69e3a3b", + "sha256:d42c549a8f41dc103a8004b9f0c433e2086add8a719da00e246e17cbe4056f72", + "sha256:d67d44996140af8b84284e5e7d398e589574b376fb4de8ccd28d82ad8e3bea13", + "sha256:d9c80df769f5ec05ad21ea34be7458d1dc51ff1fb4b2219e77fe24edf462d6df", + "sha256:e57816f8ffe46b1df8f12e1b348f06d164fd5219beba7d9433ba79608ef011cc", + "sha256:ee2ddcac99b2d2aec413e36d7a429ae9ebcadf912946b13ffa88e7d4c9b712d6", + "sha256:f02cbbf8119db68455b9d763f2f8737bb7db7e43720afa07d8eb1604e5c5ae28", + "sha256:f1d5aa2703e1dab4ae6cf416eb0095304f49d004c39e9db1d86f57924f43006b", + "sha256:f5b66caa62922531059bc5ac04f836860412f7f88d38a476eda0a6f11d4724f4", + "sha256:f69718750eaae75efe506406c490d6fc5a6161d047206cc63ce25527e8a3adad", + "sha256:fb73e0011b8793c053bfa85e53129ba5f0250fdc0392c1591fd35d915ec75c46", + "sha256:fd180ed867e289964404051a958f7cccabdeed423f91a899829264bb7974d3d3", + "sha256:fdb6f7bd51c2d1714cea40718f6149ad9be6a2ee7d93b19e9f00934c0f2a74d9", + "sha256:ffa9297c3a453fba4717d06df579af42ab9a28022444cae7fa605af4df612d54" + ], + "index": "pypi", + "version": "==6.4.1" }, "cryptography": { "hashes": [ - "sha256:0a3bf09bb0b7a2c93ce7b98cb107e9170a90c51a0162a20af1c61c765b90e60b", - "sha256:1f64a62b3b75e4005df19d3b5235abd43fa6358d5516cfc43d87aeba8d08dd51", - "sha256:32db5cc49c73f39aac27574522cecd0a4bb7384e71198bc65a0d23f901e89bb7", - "sha256:4881d09298cd0b669bb15b9cfe6166f16fc1277b4ed0d04a22f3d6430cb30f1d", - "sha256:4e2dddd38a5ba733be6a025a1475a9f45e4e41139d1321f412c6b360b19070b6", - "sha256:53e0285b49fd0ab6e604f4c5d9c5ddd98de77018542e88366923f152dbeb3c29", - "sha256:70f8f4f7bb2ac9f340655cbac89d68c527af5bb4387522a8413e841e3e6628c9", - "sha256:7b2d54e787a884ffc6e187262823b6feb06c338084bbe80d45166a1cb1c6c5bf", - "sha256:7be666cc4599b415f320839e36367b273db8501127b38316f3b9f22f17a0b815", - "sha256:8241cac0aae90b82d6b5c443b853723bcc66963970c67e56e71a2609dc4b5eaf", - "sha256:82740818f2f240a5da8dfb8943b360e4f24022b093207160c77cadade47d7c85", - "sha256:8897b7b7ec077c819187a123174b645eb680c13df68354ed99f9b40a50898f77", - "sha256:c2c5250ff0d36fd58550252f54915776940e4e866f38f3a7866d92b32a654b86", - "sha256:ca9f686517ec2c4a4ce930207f75c00bf03d94e5063cbc00a1dc42531511b7eb", - "sha256:d2b3d199647468d410994dbeb8cec5816fb74feb9368aedf300af709ef507e3e", - "sha256:da73d095f8590ad437cd5e9faf6628a218aa7c387e1fdf67b888b47ba56a17f0", - "sha256:e167b6b710c7f7bc54e67ef593f8731e1f45aa35f8a8a7b72d6e42ec76afd4b3", - "sha256:ea634401ca02367c1567f012317502ef3437522e2fc44a3ea1844de028fa4b84", - "sha256:ec6597aa85ce03f3e507566b8bcdf9da2227ec86c4266bd5e6ab4d9e0cc8dab2", - "sha256:f64b232348ee82f13aac22856515ce0195837f6968aeaa94a3d0353ea2ec06a6" - ], - "index": "pypi", - "version": "==36.0.2" + "sha256:093cb351031656d3ee2f4fa1be579a8c69c754cf874206be1d4cf3b542042804", + "sha256:0cc20f655157d4cfc7bada909dc5cc228211b075ba8407c46467f63597c78178", + "sha256:1b9362d34363f2c71b7853f6251219298124aa4cc2075ae2932e64c91a3e2717", + "sha256:1f3bfbd611db5cb58ca82f3deb35e83af34bb8cf06043fa61500157d50a70982", + "sha256:2bd1096476aaac820426239ab534b636c77d71af66c547b9ddcd76eb9c79e004", + "sha256:31fe38d14d2e5f787e0aecef831457da6cec68e0bb09a35835b0b44ae8b988fe", + "sha256:3b8398b3d0efc420e777c40c16764d6870bcef2eb383df9c6dbb9ffe12c64452", + "sha256:3c81599befb4d4f3d7648ed3217e00d21a9341a9a688ecdd615ff72ffbed7336", + "sha256:419c57d7b63f5ec38b1199a9521d77d7d1754eb97827bbb773162073ccd8c8d4", + "sha256:46f4c544f6557a2fefa7ac8ac7d1b17bf9b647bd20b16decc8fbcab7117fbc15", + "sha256:471e0d70201c069f74c837983189949aa0d24bb2d751b57e26e3761f2f782b8d", + "sha256:59b281eab51e1b6b6afa525af2bd93c16d49358404f814fe2c2410058623928c", + "sha256:731c8abd27693323b348518ed0e0705713a36d79fdbd969ad968fbef0979a7e0", + "sha256:95e590dd70642eb2079d280420a888190aa040ad20f19ec8c6e097e38aa29e06", + "sha256:a68254dd88021f24a68b613d8c51d5c5e74d735878b9e32cc0adf19d1f10aaf9", + "sha256:a7d5137e556cc0ea418dca6186deabe9129cee318618eb1ffecbd35bee55ddc1", + "sha256:aeaba7b5e756ea52c8861c133c596afe93dd716cbcacae23b80bc238202dc023", + "sha256:dc26bb134452081859aa21d4990474ddb7e863aa39e60d1592800a8865a702de", + "sha256:e53258e69874a306fcecb88b7534d61820db8a98655662a3dd2ec7f1afd9132f", + "sha256:ef15c2df7656763b4ff20a9bc4381d8352e6640cfeb95c2972c38ef508e75181", + "sha256:f224ad253cc9cea7568f49077007d2263efa57396a2f2f78114066fd54b5c68e", + "sha256:f8ec91983e638a9bcd75b39f1396e5c0dc2330cbd9ce4accefe68717e6779e0a" + ], + "index": "pypi", + "version": "==37.0.2" }, "cycler": { "hashes": [ @@ -1399,19 +1734,46 @@ }, "filelock": { "hashes": [ - "sha256:9cd540a9352e432c7246a48fe4e8712b10acb1df2ad1f30e8c070b82ae1fed85", - "sha256:f8314284bfffbdcfa0ff3d7992b023d4c628ced6feb957351d4c48d059f56bc0" + "sha256:37def7b658813cda163b56fc564cdc75e86d338246458c4c28ae84cabefa2404", + "sha256:3a0fd85166ad9dbab54c9aec96737b744106dc5f15c0b09a6744a445299fcf04" ], "markers": "python_version >= '3.7'", - "version": "==3.6.0" + "version": "==3.7.1" }, "fonttools": { "hashes": [ - "sha256:236b29aee6b113e8f7bee28779c1230a86ad2aac9a74a31b0aedf57e7dfb62a4", - "sha256:2df636a3f402ef14593c6811dac0609563b8c374bd7850e76919eb51ea205426" + "sha256:c0fdcfa8ceebd7c1b2021240bd46ef77aa8e7408cf10434be55df52384865f8e", + "sha256:f829c579a8678fa939a1d9e9894d01941db869de44390adb49ce67055a06cc2a" ], "markers": "python_version >= '3.7'", - "version": "==4.31.2" + "version": "==4.33.3" + }, + "ft4222": { + "hashes": [ + "sha256:1489b08e4042cb2b24894495c1c8514fa115122e9f8a739f665f0e4d8c53d3f4", + "sha256:1c71913f9fb862634fb77eb6efeea38b2b839e09f739aee5864b9549bcf1c4a9", + "sha256:1f9be0961bd7f3e0c1729c9692f602244e93898610611602ce1fa16059ac5bfa", + "sha256:208cde748fc2bf4a753e217ee2844e75d7d1b6d370a8937a2055f9de8906f933", + "sha256:372be3d7d04c0f6dfa62ff66b3d4be5c39d57c258ab562d9eb0d7cdd3a90ed0f", + "sha256:3ebf9380315c6af8f9f3bc5c5c7a5ae06498349c14a7b2e65d5067b20462d21b", + "sha256:422740efac86f3fdd971bb9a94d9974e56cfe062284a2be1a85db96dd0e77e5e", + "sha256:4414ef82a6321c5205ab0e3dab2bf072f14b4dd3262e5f392560adf107210d41", + "sha256:459894dcca7db71a0d58e6f3abb4c9dd67654c92ad9d934f1e32dc08bed87645", + "sha256:4b7e4c8b5e4a8fe769127d3db99b7b410468ffe2718a07f7b317e7dc1ad9ca4f", + "sha256:68e6b357ea2287fe0e8dac287efbac2f0ce9632d65e828d422d3a0604555c174", + "sha256:800a26a4a8fc854f41e4de41e45b6deafdeb78ae5eff48818f710bb2d94a8c11", + "sha256:8790e96b4c3f8d1fb768f689f1c437a59b20889e4726ed7457ff3d188f0a3274", + "sha256:9369b55393b2e1f58f8b8516bcf9cd6fd34c05e77377c4cc48be39a49cad7be5", + "sha256:a6236f05b8948cd9c113c7159e3fdde202a0f73dce6440da078fd2fc9e411123", + "sha256:b7f58cd16213a5c92503c530b301f071d67283c80c1e8cb43d6f3ec5c186df35", + "sha256:cc368b06b92529a11add37d14196d2e2aaae19c6ffc51b9457513a0d05ceae1a", + "sha256:d479c037b417ff289727112f1d4725563b78448d3765f457c8bf6884e4d83abd", + "sha256:dce00d513be811f738954c5593c52b533a02331e8a26983280dea3f4d864962f", + "sha256:eadcbc1dd20ed6d7d07dc53354ea137bcea30fb0889d74bedcd189cdb4f61c84", + "sha256:ec984bd7e9300e5f2e50823dcd5874d54aa3e7503e69afe7eb3b4cea77071084" + ], + "index": "pypi", + "version": "==1.4.1" }, "hexdump": { "hashes": [ @@ -1422,26 +1784,28 @@ }, "hypothesis": { "hashes": [ - "sha256:ca931c5a6414f3f9636fdaf978a216ee9b5c4a6b4415adf628e9d5e5003dcd99", - "sha256:de48abb676fc76e4397cd002926e5747cef518570d132221244d27e1075c0bec" + "sha256:2696cdb9005946bf1d2b215cc91d3fc01625e3342eb8743ddd04b667b2f1882b", + "sha256:4ad26c5d434171ffc02aba569dd52255573d615554c062bc30734dbe6f318c61", + "sha256:69978811f1d9c19710c7d2bf8233dc43c80efa964251b72efbe8274044e073b4", + "sha256:967009fa561b3a3f8363a73d71923357271c37dc7fa27b30c2d21a1b6092b240" ], "index": "pypi", - "version": "==6.41.0" + "version": "==6.46.7" }, "identify": { "hashes": [ - "sha256:3f3244a559290e7d3deb9e9adc7b33594c1bc85a9dd82e0f1be519bf12a1ec17", - "sha256:5f06b14366bd1facb88b00540a1de05b69b310cbc2654db3c7e07fa3a4339323" + "sha256:0dca2ea3e4381c435ef9c33ba100a78a9b40c0bab11189c7cf121f75815efeaa", + "sha256:3d11b16f3fe19f52039fb7e39c9c884b21cb1b586988114fbe42671f03de3e82" ], "markers": "python_version >= '3.7'", - "version": "==2.4.12" + "version": "==2.5.1" }, "idna": { "hashes": [ "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], - "markers": "python_version >= '3'", + "markers": "python_full_version >= '3.5.0'", "version": "==3.3" }, "imagesize": { @@ -1454,11 +1818,11 @@ }, "importlib-metadata": { "hashes": [ - "sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6", - "sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539" + "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700", + "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec" ], "markers": "python_version < '3.10'", - "version": "==4.11.3" + "version": "==4.11.4" }, "iniconfig": { "hashes": [ @@ -1477,60 +1841,60 @@ }, "jinja2": { "hashes": [ - "sha256:539835f51a74a69f41b848a9645dbdc35b4f20a3b601e2d9a7e22947b15ff119", - "sha256:640bed4bb501cbd17194b3cace1dc2126f5b619cf068a726b98192a0fde74ae9" + "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", + "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" ], "index": "pypi", - "version": "==3.1.1" + "version": "==3.1.2" }, "kiwisolver": { "hashes": [ - "sha256:0b7f50a1a25361da3440f07c58cd1d79957c2244209e4f166990e770256b6b0b", - "sha256:0c380bb5ae20d829c1a5473cfcae64267b73aaa4060adc091f6df1743784aae0", - "sha256:0d98dca86f77b851350c250f0149aa5852b36572514d20feeadd3c6b1efe38d0", - "sha256:0e45e780a74416ef2f173189ef4387e44b5494f45e290bcb1f03735faa6779bf", - "sha256:0e8afdf533b613122e4bbaf3c1e42c2a5e9e2d1dd3a0a017749a7658757cb377", - "sha256:1008346a7741620ab9cc6c96e8ad9b46f7a74ce839dbb8805ddf6b119d5fc6c2", - "sha256:1d1078ba770d6165abed3d9a1be1f9e79b61515de1dd00d942fa53bba79f01ae", - "sha256:1dcade8f6fe12a2bb4efe2cbe22116556e3b6899728d3b2a0d3b367db323eacc", - "sha256:240009fdf4fa87844f805e23f48995537a8cb8f8c361e35fda6b5ac97fcb906f", - "sha256:240c2d51d098395c012ddbcb9bd7b3ba5de412a1d11840698859f51d0e643c4f", - "sha256:262c248c60f22c2b547683ad521e8a3db5909c71f679b93876921549107a0c24", - "sha256:2e6cda72db409eefad6b021e8a4f964965a629f577812afc7860c69df7bdb84a", - "sha256:3c032c41ae4c3a321b43a3650e6ecc7406b99ff3e5279f24c9b310f41bc98479", - "sha256:42f6ef9b640deb6f7d438e0a371aedd8bef6ddfde30683491b2e6f568b4e884e", - "sha256:484f2a5f0307bc944bc79db235f41048bae4106ffa764168a068d88b644b305d", - "sha256:69b2d6c12f2ad5f55104a36a356192cfb680c049fe5e7c1f6620fc37f119cdc2", - "sha256:6e395ece147f0692ca7cdb05a028d31b83b72c369f7b4a2c1798f4b96af1e3d8", - "sha256:6ece2e12e4b57bc5646b354f436416cd2a6f090c1dadcd92b0ca4542190d7190", - "sha256:71469b5845b9876b8d3d252e201bef6f47bf7456804d2fbe9a1d6e19e78a1e65", - "sha256:7f606d91b8a8816be476513a77fd30abe66227039bd6f8b406c348cb0247dcc9", - "sha256:7f88c4b8e449908eeddb3bbd4242bd4dc2c7a15a7aa44bb33df893203f02dc2d", - "sha256:81237957b15469ea9151ec8ca08ce05656090ffabc476a752ef5ad7e2644c526", - "sha256:89b57c2984f4464840e4b768affeff6b6809c6150d1166938ade3e22fbe22db8", - "sha256:8a830a03970c462d1a2311c90e05679da56d3bd8e78a4ba9985cb78ef7836c9f", - "sha256:8ae5a071185f1a93777c79a9a1e67ac46544d4607f18d07131eece08d415083a", - "sha256:8b6086aa6936865962b2cee0e7aaecf01ab6778ce099288354a7229b4d9f1408", - "sha256:8ec2e55bf31b43aabe32089125dca3b46fdfe9f50afbf0756ae11e14c97b80ca", - "sha256:8ff3033e43e7ca1389ee59fb7ecb8303abb8713c008a1da49b00869e92e3dd7c", - "sha256:91eb4916271655dfe3a952249cb37a5c00b6ba68b4417ee15af9ba549b5ba61d", - "sha256:9d2bb56309fb75a811d81ed55fbe2208aa77a3a09ff5f546ca95e7bb5fac6eff", - "sha256:a4e8f072db1d6fb7a7cc05a6dbef8442c93001f4bb604f1081d8c2db3ca97159", - "sha256:b1605c7c38cc6a85212dfd6a641f3905a33412e49f7c003f35f9ac6d71f67720", - "sha256:b3e251e5c38ac623c5d786adb21477f018712f8c6fa54781bd38aa1c60b60fc2", - "sha256:b978afdb913ca953cf128d57181da2e8798e8b6153be866ae2a9c446c6162f40", - "sha256:be9a650890fb60393e60aacb65878c4a38bb334720aa5ecb1c13d0dac54dd73b", - "sha256:c222f91a45da9e01a9bc4f760727ae49050f8e8345c4ff6525495f7a164c8973", - "sha256:c839bf28e45d7ddad4ae8f986928dbf5a6d42ff79760d54ec8ada8fb263e097c", - "sha256:cbb5eb4a2ea1ffec26268d49766cafa8f957fe5c1b41ad00733763fae77f9436", - "sha256:e348f1904a4fab4153407f7ccc27e43b2a139752e8acf12e6640ba683093dd96", - "sha256:e677cc3626287f343de751e11b1e8a5b915a6ac897e8aecdbc996cd34de753a0", - "sha256:f74f2a13af201559e3d32b9ddfc303c94ae63d63d7f4326d06ce6fe67e7a8255", - "sha256:fa4d97d7d2b2c082e67907c0b8d9f31b85aa5d3ba0d33096b7116f03f8061261", - "sha256:ffbdb9a96c536f0405895b5e21ee39ec579cb0ed97bdbd169ae2b55f41d73219" + "sha256:007799c7fa934646318fc128b033bb6e6baabe7fbad521bfb2279aac26225cd7", + "sha256:130c6c35eded399d3967cf8a542c20b671f5ba85bd6f210f8b939f868360e9eb", + "sha256:1858ad3cb686eccc7c6b7c5eac846a1cfd45aacb5811b2cf575e80b208f5622a", + "sha256:1ae7aa0784aeadfbd693c27993727792fbe1455b84d49970bad5886b42976b18", + "sha256:1d2c744aeedce22c122bb42d176b4aa6d063202a05a4abdacb3e413c214b3694", + "sha256:21a3a98f0a21fc602663ca9bce2b12a4114891bdeba2dea1e9ad84db59892fca", + "sha256:22ccba48abae827a0f952a78a7b1a7ff01866131e5bbe1f826ce9bda406bf051", + "sha256:26b5a70bdab09e6a2f40babc4f8f992e3771751e144bda1938084c70d3001c09", + "sha256:2d76780d9c65c7529cedd49fa4802d713e60798d8dc3b0d5b12a0a8f38cca51c", + "sha256:325fa1b15098e44fe4590a6c5c09a212ca10c6ebb5d96f7447d675f6c8340e4e", + "sha256:3a297d77b3d6979693f5948df02b89431ae3645ec95865e351fb45578031bdae", + "sha256:3b1dcbc49923ac3c973184a82832e1f018dec643b1e054867d04a3a22255ec6a", + "sha256:40240da438c0ebfe2aa76dd04b844effac6679423df61adbe3437d32f23468d9", + "sha256:46c6e5018ba31d5ee7582f323d8661498a154dea1117486a571db4c244531f24", + "sha256:46fb56fde006b7ef5f8eaa3698299b0ea47444238b869ff3ced1426aa9fedcb5", + "sha256:4dc350cb65fe4e3f737d50f0465fa6ea0dcae0e5722b7edf5d5b0a0e3cd2c3c7", + "sha256:51078855a16b7a4984ed2067b54e35803d18bca9861cb60c60f6234b50869a56", + "sha256:547111ef7cf13d73546c2de97ce434935626c897bdec96a578ca100b5fcd694b", + "sha256:5fb73cc8a34baba1dfa546ae83b9c248ef6150c238b06fc53d2773685b67ec67", + "sha256:654280c5f41831ddcc5a331c0e3ce2e480bbc3d7c93c18ecf6236313aae2d61a", + "sha256:6b3136eecf7e1b4a4d23e4b19d6c4e7a8e0b42d55f30444e3c529700cdacaa0d", + "sha256:7118ca592d25b2957ff7b662bc0fe4f4c2b5d5b27814b9b1bc9f2fb249a970e7", + "sha256:71af5b43e4fa286a35110fc5bb740fdeae2b36ca79fbcf0a54237485baeee8be", + "sha256:747190fcdadc377263223f8f72b038381b3b549a8a3df5baf4d067da4749b046", + "sha256:8395064d63b26947fa2c9faeea9c3eee35e52148c5339c37987e1d96fbf009b3", + "sha256:84f85adfebd7d3c3db649efdf73659e1677a2cf3fa6e2556a3f373578af14bf7", + "sha256:86bcf0009f2012847a688f2f4f9b16203ca4c835979a02549aa0595d9f457cc8", + "sha256:ab8a15c2750ae8d53e31f77a94f846d0a00772240f1c12817411fa2344351f86", + "sha256:af24b21c2283ca69c416a8a42cde9764dc36c63d3389645d28c69b0e93db3cd7", + "sha256:afe173ac2646c2636305ab820cc0380b22a00a7bca4290452e7166b4f4fa49d0", + "sha256:b9eb88593159a53a5ee0b0159daee531ff7dd9c87fa78f5d807ca059c7eb1b2b", + "sha256:c16635f8dddbeb1b827977d0b00d07b644b040aeb9ff8607a9fc0997afa3e567", + "sha256:ca3eefb02ef17257fae8b8555c85e7c1efdfd777f671384b0e4ef27409b02720", + "sha256:caa59e2cae0e23b1e225447d7a9ddb0f982f42a6a22d497a484dfe62a06f7c0e", + "sha256:cb55258931448d61e2d50187de4ee66fc9d9f34908b524949b8b2b93d0c57136", + "sha256:d248c46c0aa406695bda2abf99632db991f8b3a6d46018721a2892312a99f069", + "sha256:d2578e5149ff49878934debfacf5c743fab49eca5ecdb983d0b218e1e554c498", + "sha256:dd22085446f3eca990d12a0878eeb5199dc9553b2e71716bfe7bed9915a472ab", + "sha256:e7cf940af5fee00a92e281eb157abe8770227a5255207818ea9a34e54a29f5b2", + "sha256:f70f3d028794e31cf9d1a822914efc935aadb2438ec4e8d4871d95eb1ce032d6", + "sha256:fd2842a0faed9ab9aba0922c951906132d9384be89690570f0ed18cd4f20e658", + "sha256:fd628e63ffdba0112e3ddf1b1e9f3db29dd8262345138e08f4938acbc6d0805a", + "sha256:ffd7cf165ff71afb202b3f36daafbf298932bee325aac9f58e1c9cd55838bef0" ], "markers": "python_version >= '3.7'", - "version": "==1.4.2" + "version": "==1.4.3" }, "lru-dict": { "hashes": [ @@ -1541,11 +1905,11 @@ }, "markdown-it-py": { "hashes": [ - "sha256:31974138ca8cafbcb62213f4974b29571b940e78364584729233f59b8dfdb8bd", - "sha256:7b5c153ae1ab2cde00a33938bce68f3ad5d68fbe363f946de7d28555bed4e08a" + "sha256:93de681e5c021a432c63147656fe21790bc01231e0cd2da73626f1aa3ac0fe27", + "sha256:cf7e59fed14b5ae17c0006eff14a2d9a00ed5f3a846148153899a0224e2c07da" ], "index": "pypi", - "version": "==2.0.1" + "version": "==2.1.0" }, "markupsafe": { "hashes": [ @@ -1595,44 +1959,44 @@ }, "matplotlib": { "hashes": [ - "sha256:14334b9902ec776461c4b8c6516e26b450f7ebe0b3ef8703bf5cdfbbaecf774a", - "sha256:2252bfac85cec7af4a67e494bfccf9080bcba8a0299701eab075f48847cca907", - "sha256:2e3484d8455af3fdb0424eae1789af61f6a79da0c80079125112fd5c1b604218", - "sha256:34a1fc29f8f96e78ec57a5eff5e8d8b53d3298c3be6df61e7aa9efba26929522", - "sha256:3e66497cd990b1a130e21919b004da2f1dc112132c01ac78011a90a0f9229778", - "sha256:40e0d7df05e8efe60397c69b467fc8f87a2affeb4d562fe92b72ff8937a2b511", - "sha256:456cc8334f6d1124e8ff856b42d2cc1c84335375a16448189999496549f7182b", - "sha256:506b210cc6e66a0d1c2bb765d055f4f6bc2745070fb1129203b67e85bbfa5c18", - "sha256:53273c5487d1c19c3bc03b9eb82adaf8456f243b97ed79d09dded747abaf1235", - "sha256:577ed20ec9a18d6bdedb4616f5e9e957b4c08563a9f985563a31fd5b10564d2a", - "sha256:6803299cbf4665eca14428d9e886de62e24f4223ac31ab9c5d6d5339a39782c7", - "sha256:68fa30cec89b6139dc559ed6ef226c53fd80396da1919a1b5ef672c911aaa767", - "sha256:6c094e4bfecd2fa7f9adffd03d8abceed7157c928c2976899de282f3600f0a3d", - "sha256:778d398c4866d8e36ee3bf833779c940b5f57192fa0a549b3ad67bc4c822771b", - "sha256:7a350ca685d9f594123f652ba796ee37219bf72c8e0fc4b471473d87121d6d34", - "sha256:87900c67c0f1728e6db17c6809ec05c025c6624dcf96a8020326ea15378fe8e7", - "sha256:8a77906dc2ef9b67407cec0bdbf08e3971141e535db888974a915be5e1e3efc6", - "sha256:8e70ae6475cfd0fad3816dcbf6cac536dc6f100f7474be58d59fa306e6e768a4", - "sha256:abf67e05a1b7f86583f6ebd01f69b693b9c535276f4e943292e444855870a1b8", - "sha256:b04fc29bcef04d4e2d626af28d9d892be6aba94856cb46ed52bcb219ceac8943", - "sha256:b19a761b948e939a9e20173aaae76070025f0024fc8f7ba08bef22a5c8573afc", - "sha256:b2e9810e09c3a47b73ce9cab5a72243a1258f61e7900969097a817232246ce1c", - "sha256:b71f3a7ca935fc759f2aed7cec06cfe10bc3100fadb5dbd9c435b04e557971e1", - "sha256:b8a4fb2a0c5afbe9604f8a91d7d0f27b1832c3e0b5e365f95a13015822b4cd65", - "sha256:bb1c613908f11bac270bc7494d68b1ef6e7c224b7a4204d5dacf3522a41e2bc3", - "sha256:d24e5bb8028541ce25e59390122f5e48c8506b7e35587e5135efcb6471b4ac6c", - "sha256:d70a32ee1f8b55eed3fd4e892f0286df8cccc7e0475c11d33b5d0a148f5c7599", - "sha256:e293b16cf303fe82995e41700d172a58a15efc5331125d08246b520843ef21ee", - "sha256:e2f28a07b4f82abb40267864ad7b3a4ed76f1b1663e81c7efc84a9b9248f672f", - "sha256:e3520a274a0e054e919f5b3279ee5dbccf5311833819ccf3399dab7c83e90a25", - "sha256:e3b6f3fd0d8ca37861c31e9a7cab71a0ef14c639b4c95654ea1dd153158bf0df", - "sha256:e486f60db0cd1c8d68464d9484fd2a94011c1ac8593d765d0211f9daba2bd535", - "sha256:e8c87cdaf06fd7b2477f68909838ff4176f105064a72ca9d24d3f2a29f73d393", - "sha256:edf5e4e1d5fb22c18820e8586fb867455de3b109c309cb4fce3aaed85d9468d1", - "sha256:fe8d40c434a8e2c68d64c6d6a04e77f21791a93ff6afe0dce169597c110d3079" - ], - "index": "pypi", - "version": "==3.5.1" + "sha256:03bbb3f5f78836855e127b5dab228d99551ad0642918ccbf3067fcd52ac7ac5e", + "sha256:24173c23d1bcbaed5bf47b8785d27933a1ac26a5d772200a0f3e0e38f471b001", + "sha256:2a0967d4156adbd0d46db06bc1a877f0370bce28d10206a5071f9ecd6dc60b79", + "sha256:2e8bda1088b941ead50caabd682601bece983cadb2283cafff56e8fcddbf7d7f", + "sha256:31fbc2af27ebb820763f077ec7adc79b5a031c2f3f7af446bd7909674cd59460", + "sha256:364e6bca34edc10a96aa3b1d7cd76eb2eea19a4097198c1b19e89bee47ed5781", + "sha256:3d8e129af95b156b41cb3be0d9a7512cc6d73e2b2109f82108f566dbabdbf377", + "sha256:44c6436868186564450df8fd2fc20ed9daaef5caad699aa04069e87099f9b5a8", + "sha256:48cf850ce14fa18067f2d9e0d646763681948487a8080ec0af2686468b4607a2", + "sha256:49a5938ed6ef9dda560f26ea930a2baae11ea99e1c2080c8714341ecfda72a89", + "sha256:4a05f2b37222319753a5d43c0a4fd97ed4ff15ab502113e3f2625c26728040cf", + "sha256:4a44cdfdb9d1b2f18b1e7d315eb3843abb097869cd1ef89cfce6a488cd1b5182", + "sha256:4fa28ca76ac5c2b2d54bc058b3dad8e22ee85d26d1ee1b116a6fd4d2277b6a04", + "sha256:5844cea45d804174bf0fac219b4ab50774e504bef477fc10f8f730ce2d623441", + "sha256:5a32ea6e12e80dedaca2d4795d9ed40f97bfa56e6011e14f31502fdd528b9c89", + "sha256:6c623b355d605a81c661546af7f24414165a8a2022cddbe7380a31a4170fa2e9", + "sha256:751d3815b555dcd6187ad35b21736dc12ce6925fc3fa363bbc6dc0f86f16484f", + "sha256:75c406c527a3aa07638689586343f4b344fcc7ab1f79c396699eb550cd2b91f7", + "sha256:77157be0fc4469cbfb901270c205e7d8adb3607af23cef8bd11419600647ceed", + "sha256:7d7705022df2c42bb02937a2a824f4ec3cca915700dd80dc23916af47ff05f1a", + "sha256:7f409716119fa39b03da3d9602bd9b41142fab7a0568758cd136cd80b1bf36c8", + "sha256:9480842d5aadb6e754f0b8f4ebeb73065ac8be1855baa93cd082e46e770591e9", + "sha256:9776e1a10636ee5f06ca8efe0122c6de57ffe7e8c843e0fb6e001e9d9256ec95", + "sha256:a91426ae910819383d337ba0dc7971c7cefdaa38599868476d94389a329e599b", + "sha256:b4fedaa5a9aa9ce14001541812849ed1713112651295fdddd640ea6620e6cf98", + "sha256:b6c63cd01cad0ea8704f1fd586e9dc5777ccedcd42f63cbbaa3eae8dd41172a1", + "sha256:b8d3f4e71e26307e8c120b72c16671d70c5cd08ae412355c11254aa8254fb87f", + "sha256:c4b82c2ae6d305fcbeb0eb9c93df2602ebd2f174f6e8c8a5d92f9445baa0c1d3", + "sha256:c772264631e5ae61f0bd41313bbe48e1b9bcc95b974033e1118c9caa1a84d5c6", + "sha256:c87973ddec10812bddc6c286b88fdd654a666080fbe846a1f7a3b4ba7b11ab78", + "sha256:e2b696699386766ef171a259d72b203a3c75d99d03ec383b97fc2054f52e15cf", + "sha256:ea75df8e567743207e2b479ba3d8843537be1c146d4b1e3e395319a4e1a77fe9", + "sha256:ebc27ad11df3c1661f4677a7762e57a8a91dd41b466c3605e90717c9a5f90c82", + "sha256:ee0b8e586ac07f83bb2950717e66cb305e2859baf6f00a9c39cc576e0ce9629c", + "sha256:ee175a571e692fc8ae8e41ac353c0e07259113f4cb063b0ec769eff9717e84bb" + ], + "index": "pypi", + "version": "==3.5.2" }, "mdit-py-plugins": { "hashes": [ @@ -1644,49 +2008,48 @@ }, "mdurl": { "hashes": [ - "sha256:40654d6dcb8d21501ed13c21cc0bd6fc42ff07ceb8be30029e5ae63ebc2ecfda", - "sha256:94873a969008ee48880fb21bad7de0349fef529f3be178969af5817239e9b990" + "sha256:6a8f6804087b7128040b2fb2ebe242bdc2affaeaa034d5fc9feeed30b443651b", + "sha256:f79c9709944df218a4cdb0fcc0b0c7ead2f44594e3e84dc566606f04ad749c20" ], - "markers": "python_version >= '3.6'", - "version": "==0.1.0" + "markers": "python_version >= '3.7'", + "version": "==0.1.1" }, "mpld3": { "hashes": [ - "sha256:3626d37da7ac11d0fce4dd5ceb37d04ba618bf951129bf6ca3f94bf48da87d6f", - "sha256:b1290f6cca2d9515e32ee21a8b0c18b2ea361cefce58ba0f4df881e9eeb3f64c", - "sha256:c589db8b661aee25c93e198e2e18ed47b9a96951de41d96241345acec5f819ab" + "sha256:1a167dbef836dd7c66d8aa71c06a32d50bffa18725f304d93cb74fdb3545043b", + "sha256:41938e65de4ba41a1b53d92e7c8609e7172e09b33ef5db42bb6f73701106c8b7" ], "index": "pypi", - "version": "==0.5.7" + "version": "==0.5.8" }, "mypy": { "hashes": [ - "sha256:0e2dd88410937423fba18e57147dd07cd8381291b93d5b1984626f173a26543e", - "sha256:10daab80bc40f84e3f087d896cdb53dc811a9f04eae4b3f95779c26edee89d16", - "sha256:17e44649fec92e9f82102b48a3bf7b4a5510ad0cd22fa21a104826b5db4903e2", - "sha256:1a0459c333f00e6a11cbf6b468b870c2b99a906cb72d6eadf3d1d95d38c9352c", - "sha256:246e1aa127d5b78488a4a0594bd95f6d6fb9d63cf08a66dafbff8595d8891f67", - "sha256:2b184db8c618c43c3a31b32ff00cd28195d39e9c24e7c3b401f3db7f6e5767f5", - "sha256:2bc249409a7168d37c658e062e1ab5173300984a2dada2589638568ddc1db02b", - "sha256:3841b5433ff936bff2f4dc8d54cf2cdbfea5d8e88cedfac45c161368e5770ba6", - "sha256:4c3e497588afccfa4334a9986b56f703e75793133c4be3a02d06a3df16b67a58", - "sha256:5bf44840fb43ac4074636fd47ee476d73f0039f4f54e86d7265077dc199be24d", - "sha256:64235137edc16bee6f095aba73be5334677d6f6bdb7fa03cfab90164fa294a17", - "sha256:6776e5fa22381cc761df53e7496a805801c1a751b27b99a9ff2f0ca848c7eca0", - "sha256:6ce34a118d1a898f47def970a2042b8af6bdcc01546454726c7dd2171aa6dfca", - "sha256:6f6ad963172152e112b87cc7ec103ba0f2db2f1cd8997237827c052a3903eaa6", - "sha256:6f7106cbf9cc2f403693bf50ed7c9fa5bb3dfa9007b240db3c910929abe2a322", - "sha256:7742d2c4e46bb5017b51c810283a6a389296cda03df805a4f7869a6f41246534", - "sha256:9521c1265ccaaa1791d2c13582f06facf815f426cd8b07c3a485f486a8ffc1f3", - "sha256:a1b383fe99678d7402754fe90448d4037f9512ce70c21f8aee3b8bf48ffc51db", - "sha256:b840cfe89c4ab6386c40300689cd8645fc8d2d5f20101c7f8bd23d15fca14904", - "sha256:d8d3ba77e56b84cd47a8ee45b62c84b6d80d32383928fe2548c9a124ea0a725c", - "sha256:dcd955f36e0180258a96f880348fbca54ce092b40fbb4b37372ae3b25a0b0a46", - "sha256:e865fec858d75b78b4d63266c9aff770ecb6a39dfb6d6b56c47f7f8aba6baba8", - "sha256:edf7237137a1a9330046dbb14796963d734dd740a98d5e144a3eb1d267f5f9ee" - ], - "index": "pypi", - "version": "==0.942" + "sha256:006be38474216b833eca29ff6b73e143386f352e10e9c2fbe76aa8549e5554f5", + "sha256:03c6cc893e7563e7b2949b969e63f02c000b32502a1b4d1314cabe391aa87d66", + "sha256:0e9f70df36405c25cc530a86eeda1e0867863d9471fe76d1273c783df3d35c2e", + "sha256:1ece702f29270ec6af25db8cf6185c04c02311c6bb21a69f423d40e527b75c56", + "sha256:3e09f1f983a71d0672bbc97ae33ee3709d10c779beb613febc36805a6e28bb4e", + "sha256:439c726a3b3da7ca84a0199a8ab444cd8896d95012c4a6c4a0d808e3147abf5d", + "sha256:5a0b53747f713f490affdceef835d8f0cb7285187a6a44c33821b6d1f46ed813", + "sha256:5f1332964963d4832a94bebc10f13d3279be3ce8f6c64da563d6ee6e2eeda932", + "sha256:63e85a03770ebf403291ec50097954cc5caf2a9205c888ce3a61bd3f82e17569", + "sha256:64759a273d590040a592e0f4186539858c948302c653c2eac840c7a3cd29e51b", + "sha256:697540876638ce349b01b6786bc6094ccdaba88af446a9abb967293ce6eaa2b0", + "sha256:9940e6916ed9371809b35b2154baf1f684acba935cd09928952310fbddaba648", + "sha256:9f5f5a74085d9a81a1f9c78081d60a0040c3efb3f28e5c9912b900adf59a16e6", + "sha256:a5ea0875a049de1b63b972456542f04643daf320d27dc592d7c3d9cd5d9bf950", + "sha256:b117650592e1782819829605a193360a08aa99f1fc23d1d71e1a75a142dc7e15", + "sha256:b24be97351084b11582fef18d79004b3e4db572219deee0212078f7cf6352723", + "sha256:b88f784e9e35dcaa075519096dc947a388319cb86811b6af621e3523980f1c8a", + "sha256:bdd5ca340beffb8c44cb9dc26697628d1b88c6bddf5c2f6eb308c46f269bb6f3", + "sha256:d5aaf1edaa7692490f72bdb9fbd941fbf2e201713523bdb3f4038be0af8846c6", + "sha256:e999229b9f3198c0c880d5e269f9f8129c8862451ce53a011326cad38b9ccd24", + "sha256:f4a21d01fc0ba4e31d82f0fff195682e29f9401a8bdb7173891070eb260aeb3b", + "sha256:f4b794db44168a4fc886e3450201365c9526a522c46ba089b55e1f11c163750d", + "sha256:f730d56cb924d371c26b8eaddeea3cc07d78ff51c521c6d04899ac6904b75492" + ], + "index": "pypi", + "version": "==0.961" }, "mypy-extensions": { "hashes": [ @@ -1697,11 +2060,11 @@ }, "myst-parser": { "hashes": [ - "sha256:555ec2950aba5ae5dac5c162c7e9a43ad4a7291cfac644d8f5f84da8efa6f356", - "sha256:d412347a5cacb77ebc03d7f7ffef050cd61957d46f234313d350e84e24972260" + "sha256:4965e51918837c13bf1c6f6fe2c6bddddf193148360fbdaefe743a4981358f6a", + "sha256:739a4d96773a8e55a2cacd3941ce46a446ee23dcd6b37e06f73f551ad7821d86" ], "index": "pypi", - "version": "==0.17.0" + "version": "==0.18.0" }, "natsort": { "hashes": [ @@ -1720,42 +2083,44 @@ }, "numpy": { "hashes": [ - "sha256:07a8c89a04997625236c5ecb7afe35a02af3896c8aa01890a849913a2309c676", - "sha256:08d9b008d0156c70dc392bb3ab3abb6e7a711383c3247b410b39962263576cd4", - "sha256:201b4d0552831f7250a08d3b38de0d989d6f6e4658b709a02a73c524ccc6ffce", - "sha256:2c10a93606e0b4b95c9b04b77dc349b398fdfbda382d2a39ba5a822f669a0123", - "sha256:3ca688e1b9b95d80250bca34b11a05e389b1420d00e87a0d12dc45f131f704a1", - "sha256:48a3aecd3b997bf452a2dedb11f4e79bc5bfd21a1d4cc760e703c31d57c84b3e", - "sha256:568dfd16224abddafb1cbcce2ff14f522abe037268514dd7e42c6776a1c3f8e5", - "sha256:5bfb1bb598e8229c2d5d48db1860bcf4311337864ea3efdbe1171fb0c5da515d", - "sha256:639b54cdf6aa4f82fe37ebf70401bbb74b8508fddcf4797f9fe59615b8c5813a", - "sha256:8251ed96f38b47b4295b1ae51631de7ffa8260b5b087808ef09a39a9d66c97ab", - "sha256:92bfa69cfbdf7dfc3040978ad09a48091143cffb778ec3b03fa170c494118d75", - "sha256:97098b95aa4e418529099c26558eeb8486e66bd1e53a6b606d684d0c3616b168", - "sha256:a3bae1a2ed00e90b3ba5f7bd0a7c7999b55d609e0c54ceb2b076a25e345fa9f4", - "sha256:c34ea7e9d13a70bf2ab64a2532fe149a9aced424cd05a2c4ba662fd989e3e45f", - "sha256:dbc7601a3b7472d559dc7b933b18b4b66f9aa7452c120e87dfb33d02008c8a18", - "sha256:e7927a589df200c5e23c57970bafbd0cd322459aa7b1ff73b7c2e84d6e3eae62", - "sha256:f8c1f39caad2c896bc0018f699882b345b2a63708008be29b1f355ebf6f933fe", - "sha256:f950f8845b480cffe522913d35567e29dd381b0dc7e4ce6a4a9f9156417d2430", - "sha256:fade0d4f4d292b6f39951b6836d7a3c7ef5b2347f3c420cd9820a1d90d794802", - "sha256:fdf3c08bce27132395d3c3ba1503cac12e17282358cb4bddc25cc46b0aca07aa" - ], - "index": "pypi", - "version": "==1.22.3" + "sha256:0791fbd1e43bf74b3502133207e378901272f3c156c4df4954cad833b1380207", + "sha256:1ce7ab2053e36c0a71e7a13a7475bd3b1f54750b4b433adc96313e127b870887", + "sha256:2d487e06ecbf1dc2f18e7efce82ded4f705f4bd0cd02677ffccfb39e5c284c7e", + "sha256:37431a77ceb9307c28382c9773da9f306435135fae6b80b62a11c53cfedd8802", + "sha256:3e1ffa4748168e1cc8d3cde93f006fe92b5421396221a02f2274aab6ac83b077", + "sha256:425b390e4619f58d8526b3dcf656dde069133ae5c240229821f01b5f44ea07af", + "sha256:43a8ca7391b626b4c4fe20aefe79fec683279e31e7c79716863b4b25021e0e74", + "sha256:4c6036521f11a731ce0648f10c18ae66d7143865f19f7299943c985cdc95afb5", + "sha256:59d55e634968b8f77d3fd674a3cf0b96e85147cd6556ec64ade018f27e9479e1", + "sha256:64f56fc53a2d18b1924abd15745e30d82a5782b2cab3429aceecc6875bd5add0", + "sha256:7228ad13744f63575b3a972d7ee4fd61815b2879998e70930d4ccf9ec721dce0", + "sha256:9ce7df0abeabe7fbd8ccbf343dc0db72f68549856b863ae3dd580255d009648e", + "sha256:a911e317e8c826ea632205e63ed8507e0dc877dcdc49744584dfc363df9ca08c", + "sha256:b89bf9b94b3d624e7bb480344e91f68c1c6c75f026ed6755955117de00917a7c", + "sha256:ba9ead61dfb5d971d77b6c131a9dbee62294a932bf6a356e48c75ae684e635b3", + "sha256:c1d937820db6e43bec43e8d016b9b3165dcb42892ea9f106c70fb13d430ffe72", + "sha256:cc7f00008eb7d3f2489fca6f334ec19ca63e31371be28fd5dad955b16ec285bd", + "sha256:d4c5d5eb2ec8da0b4f50c9a843393971f31f1d60be87e0fb0917a49133d257d6", + "sha256:e96d7f3096a36c8754207ab89d4b3282ba7b49ea140e4973591852c77d09eb76", + "sha256:f0725df166cf4785c0bc4cbfb320203182b1ecd30fee6e541c8752a92df6aa32", + "sha256:f3eb268dbd5cfaffd9448113539e44e2dd1c5ca9ce25576f7c04a5453edc26fa", + "sha256:fb7a980c81dd932381f8228a426df8aeb70d59bbcda2af075b627bbc50207cba" + ], + "index": "pypi", + "version": "==1.22.4" }, "opencv-python-headless": { "hashes": [ - "sha256:3f330468c29882dbbec5af25695c5e575572c6b855cb0f9fe53e14116fd46bfc", - "sha256:4bdf982574bf2fefc5f82c86df7cb42e56ad627874c7c0f4d94ecf4ae8885304", - "sha256:567a54c1919bcf5b3d20a9830e3c511e57134de8def286ce137c3544a892f98c", - "sha256:62e31878641a8f96e773118d1eea9f34bdda87c9990a0faab04ebaafb5ae015c", - "sha256:a60e9ff48854ec37be391e19dd634883cc26c2f0f814e5325b3deca33420912c", - "sha256:c3c2dda44d601757a508b07d628537c49f31223ad4edd0f747a70d4c852a7b98", - "sha256:ca4f013fa958f60fb2327fe87e6127c1ac0ab536890b1d4b00847f417b7af1ba" + "sha256:21e70f8b0c04098cdf466d27184fe6c3820aaef944a22548db95099959c95889", + "sha256:2c032c373e447c3fc2a670bca20e2918a1205a6e72854df60425fd3f82c78c32", + "sha256:3bacd806cce1f1988e58f3d6f761538e0215d6621d316de94c009dc0acbd6ad3", + "sha256:d5291d7e10aa2c19cab6fd86f0d61af8617290ecd2d7ffcb051e446868d04cc5", + "sha256:e6c069bc963d7e8fcec21b3e33e594d35948badd63eccb2e80f88b0a12102c03", + "sha256:eec6281054346103d6af93f173b7c6a206beb2663d3adc04aa3ddc66e85093df", + "sha256:ffbf26fcd697af996408440a93bc69c49c05a36845771f984156dfbeaa95d497" ], "index": "pypi", - "version": "==4.5.5.64" + "version": "==4.6.0.66" }, "packaging": { "hashes": [ @@ -1775,63 +2140,63 @@ }, "paramiko": { "hashes": [ - "sha256:ac6593479f2b47a9422eca076b22cff9f795495e6733a64723efc75dd8c92101", - "sha256:ddb1977853aef82804b35d72a0e597b244fa326c404c350bd00c5b01dbfee71a" + "sha256:003e6bee7c034c21fbb051bf83dc0a9ee4106204dd3c53054c71452cc4ec3938", + "sha256:655f25dc8baf763277b933dfcea101d636581df8d6b9774d1fb653426b72c270" ], "index": "pypi", - "version": "==2.10.3" + "version": "==2.11.0" }, "pillow": { "hashes": [ - "sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e", - "sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595", - "sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512", - "sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c", - "sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477", - "sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a", - "sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4", - "sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e", - "sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5", - "sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378", - "sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a", - "sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652", - "sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7", - "sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a", - "sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a", - "sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6", - "sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165", - "sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160", - "sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331", - "sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b", - "sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458", - "sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033", - "sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8", - "sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481", - "sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58", - "sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7", - "sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3", - "sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea", - "sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34", - "sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3", - "sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8", - "sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581", - "sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244", - "sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef", - "sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0", - "sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2", - "sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97", - "sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717" - ], - "index": "pypi", - "version": "==9.1.0" + "sha256:088df396b047477dd1bbc7de6e22f58400dae2f21310d9e2ec2933b2ef7dfa4f", + "sha256:09e67ef6e430f90caa093528bd758b0616f8165e57ed8d8ce014ae32df6a831d", + "sha256:0b4d5ad2cd3a1f0d1df882d926b37dbb2ab6c823ae21d041b46910c8f8cd844b", + "sha256:0b525a356680022b0af53385944026d3486fc8c013638cf9900eb87c866afb4c", + "sha256:1d4331aeb12f6b3791911a6da82de72257a99ad99726ed6b63f481c0184b6fb9", + "sha256:20d514c989fa28e73a5adbddd7a171afa5824710d0ab06d4e1234195d2a2e546", + "sha256:2b291cab8a888658d72b575a03e340509b6b050b62db1f5539dd5cd18fd50578", + "sha256:3f6c1716c473ebd1649663bf3b42702d0d53e27af8b64642be0dd3598c761fb1", + "sha256:42dfefbef90eb67c10c45a73a9bc1599d4dac920f7dfcbf4ec6b80cb620757fe", + "sha256:488f3383cf5159907d48d32957ac6f9ea85ccdcc296c14eca1a4e396ecc32098", + "sha256:4d45dbe4b21a9679c3e8b3f7f4f42a45a7d3ddff8a4a16109dff0e1da30a35b2", + "sha256:53c27bd452e0f1bc4bfed07ceb235663a1df7c74df08e37fd6b03eb89454946a", + "sha256:55e74faf8359ddda43fee01bffbc5bd99d96ea508d8a08c527099e84eb708f45", + "sha256:59789a7d06c742e9d13b883d5e3569188c16acb02eeed2510fd3bfdbc1bd1530", + "sha256:5b650dbbc0969a4e226d98a0b440c2f07a850896aed9266b6fedc0f7e7834108", + "sha256:66daa16952d5bf0c9d5389c5e9df562922a59bd16d77e2a276e575d32e38afd1", + "sha256:6e760cf01259a1c0a50f3c845f9cad1af30577fd8b670339b1659c6d0e7a41dd", + "sha256:7502539939b53d7565f3d11d87c78e7ec900d3c72945d4ee0e2f250d598309a0", + "sha256:769a7f131a2f43752455cc72f9f7a093c3ff3856bf976c5fb53a59d0ccc704f6", + "sha256:7c150dbbb4a94ea4825d1e5f2c5501af7141ea95825fadd7829f9b11c97aaf6c", + "sha256:8844217cdf66eabe39567118f229e275f0727e9195635a15e0e4b9227458daaf", + "sha256:8a66fe50386162df2da701b3722781cbe90ce043e7d53c1fd6bd801bca6b48d4", + "sha256:9370d6744d379f2de5d7fa95cdbd3a4d92f0b0ef29609b4b1687f16bc197063d", + "sha256:937a54e5694684f74dcbf6e24cc453bfc5b33940216ddd8f4cd8f0f79167f765", + "sha256:9c857532c719fb30fafabd2371ce9b7031812ff3889d75273827633bca0c4602", + "sha256:a4165205a13b16a29e1ac57efeee6be2dfd5b5408122d59ef2145bc3239fa340", + "sha256:b3fe2ff1e1715d4475d7e2c3e8dabd7c025f4410f79513b4ff2de3d51ce0fa9c", + "sha256:b6617221ff08fbd3b7a811950b5c3f9367f6e941b86259843eab77c8e3d2b56b", + "sha256:b761727ed7d593e49671d1827044b942dd2f4caae6e51bab144d4accf8244a84", + "sha256:baf3be0b9446a4083cc0c5bb9f9c964034be5374b5bc09757be89f5d2fa247b8", + "sha256:c17770a62a71718a74b7548098a74cd6880be16bcfff5f937f900ead90ca8e92", + "sha256:c67db410508b9de9c4694c57ed754b65a460e4812126e87f5052ecf23a011a54", + "sha256:d78ca526a559fb84faaaf84da2dd4addef5edb109db8b81677c0bb1aad342601", + "sha256:e9ed59d1b6ee837f4515b9584f3d26cf0388b742a11ecdae0d9237a94505d03a", + "sha256:f054b020c4d7e9786ae0404278ea318768eb123403b18453e28e47cdb7a0a4bf", + "sha256:f372d0f08eff1475ef426344efe42493f71f377ec52237bf153c5713de987251", + "sha256:f3f6a6034140e9e17e9abc175fc7a266a6e63652028e157750bd98e804a8ed9a", + "sha256:ffde4c6fabb52891d81606411cbfaf77756e3b561b566efd270b3ed3791fde4e" + ], + "index": "pypi", + "version": "==9.1.1" }, "platformdirs": { "hashes": [ - "sha256:7535e70dfa32e84d4b34996ea99c5e432fa29a708d0f4e394bbcb2a8faa4f16d", - "sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227" + "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788", + "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19" ], "markers": "python_version >= '3.7'", - "version": "==2.5.1" + "version": "==2.5.2" }, "pluggy": { "hashes": [ @@ -1850,11 +2215,11 @@ }, "pre-commit": { "hashes": [ - "sha256:02226e69564ebca1a070bd1f046af866aa1c318dbc430027c50ab832ed2b73f2", - "sha256:5d445ee1fa8738d506881c5d84f83c62bb5be6b2838e32207433647e8e5ebe10" + "sha256:10c62741aa5704faea2ad69cb550ca78082efe5697d6f04e5710c3c229afdd10", + "sha256:4233a1e38621c87d9dda9808c6606d7e7ba0e087cd56d3fe03202a01d2919615" ], "index": "pypi", - "version": "==2.18.1" + "version": "==2.19.0" }, "py": { "hashes": [ @@ -1944,11 +2309,11 @@ }, "pygments": { "hashes": [ - "sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65", - "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a" + "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb", + "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519" ], - "markers": "python_version >= '3.5'", - "version": "==2.11.2" + "markers": "python_version >= '3.6'", + "version": "==2.12.0" }, "pynacl": { "hashes": [ @@ -1968,11 +2333,11 @@ }, "pyparsing": { "hashes": [ - "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea", - "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484" + "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", + "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" ], - "markers": "python_version >= '3.6'", - "version": "==3.0.7" + "markers": "python_full_version >= '3.6.8'", + "version": "==3.0.9" }, "pyprof2calltree": { "hashes": [ @@ -1983,11 +2348,11 @@ }, "pytest": { "hashes": [ - "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63", - "sha256:92f723789a8fdd7180b6b06483874feca4c48a5c76968e03bb3e7f806a1869ea" + "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c", + "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45" ], "index": "pypi", - "version": "==7.1.1" + "version": "==7.1.2" }, "pytest-forked": { "hashes": [ @@ -2061,11 +2426,11 @@ }, "requests": { "hashes": [ - "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61", - "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d" + "sha256:bc7861137fbce630f17b03d3ad02ad0bf978c844f3536d0edda6499dafce2b6f", + "sha256:d568723a7ebd25875d8d1eaf5dfa068cd2fc8194b2e483d7b1f7c81918dbec6b" ], "index": "pypi", - "version": "==2.27.1" + "version": "==2.28.0" }, "reverse-geocoder": { "hashes": [ @@ -2076,32 +2441,32 @@ }, "scipy": { "hashes": [ - "sha256:011d4386b53b933142f58a652aa0f149c9b9242abd4f900b9f4ea5fbafc86b89", - "sha256:16e09ef68b352d73befa8bcaf3ebe25d3941fe1a58c82909d5589856e6bc8174", - "sha256:31d4f2d6b724bc9a98e527b5849b8a7e589bf1ea630c33aa563eda912c9ff0bd", - "sha256:38aa39b6724cb65271e469013aeb6f2ce66fd44f093e241c28a9c6bc64fd79ed", - "sha256:3d573228c10a3a8c32b9037be982e6440e411b443a6267b067cac72f690b8d56", - "sha256:3d9dd6c8b93a22bf9a3a52d1327aca7e092b1299fb3afc4f89e8eba381be7b59", - "sha256:559a8a4c03a5ba9fe3232f39ed24f86457e4f3f6c0abbeae1fb945029f092720", - "sha256:5e73343c5e0d413c1f937302b2e04fb07872f5843041bcfd50699aef6e95e399", - "sha256:723b9f878095ed994756fa4ee3060c450e2db0139c5ba248ee3f9628bd64e735", - "sha256:87b01c7d5761e8a266a0fbdb9d88dcba0910d63c1c671bdb4d99d29f469e9e03", - "sha256:8f4d059a97b29c91afad46b1737274cb282357a305a80bdd9e8adf3b0ca6a3f0", - "sha256:92b2c2af4183ed09afb595709a8ef5783b2baf7f41e26ece24e1329c109691a7", - "sha256:937d28722f13302febde29847bbe554b89073fbb924a30475e5ed7b028898b5f", - "sha256:a279e27c7f4566ef18bab1b1e2c37d168e365080974758d107e7d237d3f0f484", - "sha256:ad5be4039147c808e64f99c0e8a9641eb5d2fa079ff5894dcd8240e94e347af4", - "sha256:ae3e327da323d82e918e593460e23babdce40d7ab21490ddf9fc06dec6b91a18", - "sha256:bb7088e89cd751acf66195d2f00cf009a1ea113f3019664032d9075b1e727b6c", - "sha256:c17a1878d00a5dd2797ccd73623ceca9d02375328f6218ee6d921e1325e61aff", - "sha256:c2bae431d127bf0b1da81fc24e4bba0a84d058e3a96b9dd6475dfcb3c5e8761e", - "sha256:de2e80ee1d925984c2504812a310841c241791c5279352be4707cdcd7c255039", - "sha256:e6f0cd9c0bd374ef834ee1e0f0999678d49dcc400ea6209113d81528958f97c7", - "sha256:f3720d0124aced49f6f2198a6900304411dbbeed12f56951d7c66ebef05e3df6", - "sha256:f4a6d3b9f9797eb2d43938ac2c5d96d02aed17ef170c8b38f11798717523ddba" - ], - "index": "pypi", - "version": "==1.8.0" + "sha256:02b567e722d62bddd4ac253dafb01ce7ed8742cf8031aea030a41414b86c1125", + "sha256:1166514aa3bbf04cb5941027c6e294a000bba0cf00f5cdac6c77f2dad479b434", + "sha256:1da52b45ce1a24a4a22db6c157c38b39885a990a566748fc904ec9f03ed8c6ba", + "sha256:23b22fbeef3807966ea42d8163322366dd89da9bebdc075da7034cee3a1441ca", + "sha256:28d2cab0c6ac5aa131cc5071a3a1d8e1366dad82288d9ec2ca44df78fb50e649", + "sha256:2ef0fbc8bcf102c1998c1f16f15befe7cffba90895d6e84861cd6c6a33fb54f6", + "sha256:3b69b90c9419884efeffaac2c38376d6ef566e6e730a231e15722b0ab58f0328", + "sha256:4b93ec6f4c3c4d041b26b5f179a6aab8f5045423117ae7a45ba9710301d7e462", + "sha256:4e53a55f6a4f22de01ffe1d2f016e30adedb67a699a310cdcac312806807ca81", + "sha256:6311e3ae9cc75f77c33076cb2794fb0606f14c8f1b1c9ff8ce6005ba2c283621", + "sha256:65b77f20202599c51eb2771d11a6b899b97989159b7975e9b5259594f1d35ef4", + "sha256:6cc6b33139eb63f30725d5f7fa175763dc2df6a8f38ddf8df971f7c345b652dc", + "sha256:70de2f11bf64ca9921fda018864c78af7147025e467ce9f4a11bc877266900a6", + "sha256:70ebc84134cf0c504ce6a5f12d6db92cb2a8a53a49437a6bb4edca0bc101f11c", + "sha256:83606129247e7610b58d0e1e93d2c5133959e9cf93555d3c27e536892f1ba1f2", + "sha256:93d07494a8900d55492401917a119948ed330b8c3f1d700e0b904a578f10ead4", + "sha256:9c4e3ae8a716c8b3151e16c05edb1daf4cb4d866caa385e861556aff41300c14", + "sha256:9dd4012ac599a1e7eb63c114d1eee1bcfc6dc75a29b589ff0ad0bb3d9412034f", + "sha256:9e3fb1b0e896f14a85aa9a28d5f755daaeeb54c897b746df7a55ccb02b340f33", + "sha256:a0aa8220b89b2e3748a2836fbfa116194378910f1a6e78e4675a095bcd2c762d", + "sha256:d3b3c8924252caaffc54d4a99f1360aeec001e61267595561089f8b5900821bb", + "sha256:e013aed00ed776d790be4cb32826adb72799c61e318676172495383ba4570aa4", + "sha256:f3e7a8867f307e3359cc0ed2c63b61a1e33a19080f92fe377bc7d49f646f2ec1" + ], + "index": "pypi", + "version": "==1.8.1" }, "six": { "hashes": [ @@ -2231,11 +2596,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42", - "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2" + "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", + "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" ], - "markers": "python_version >= '3.6'", - "version": "==4.1.1" + "markers": "python_version < '3.10'", + "version": "==4.2.0" }, "urllib3": { "hashes": [ @@ -2247,11 +2612,11 @@ }, "virtualenv": { "hashes": [ - "sha256:1e8588f35e8b42c6ec6841a13c5e88239de1e6e4e4cedfd3916b306dc826ec66", - "sha256:8e5b402037287126e81ccde9432b95a8be5b19d36584f64957060a3488c11ca8" + "sha256:e617f16e25b42eb4f6e74096b9c9e37713cf10bf30168fb4a739f3fa8f898a3a", + "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==20.14.0" + "version": "==20.14.1" }, "zipp": { "hashes": [ diff --git a/README.md b/README.md index 5af02de8d9..c426b839d5 100755 --- a/README.md +++ b/README.md @@ -35,16 +35,17 @@ What is openpilot? -Running in a car +Running on a dedicated device in a car ------ To use openpilot in a car, you need four things -* This software. It's free and available right here. +* A supported device to run this software: a [comma three](https://comma.ai/shop/products/three). +* This software. The setup procedure of the comma three allows the user to enter a url for custom software. +The url, openpilot.comma.ai will install the release version of openpilot. To install openpilot master, you can use installer.comma.ai/commaai/master, and replacing commaai with another github username can install a fork. * One of [the 150+ supported cars](docs/CARS.md). We support Honda, Toyota, Hyundai, Nissan, Kia, Chrysler, Lexus, Acura, Audi, VW, and more. If your car is not supported, but has adaptive cruise control and lane keeping assist, it's likely able to run openpilot. -* A supported device to run this software: a [comma three](https://comma.ai/shop/products/three), or if you like to experiment, a [Ubuntu computer with webcams](https://github.com/commaai/openpilot/tree/master/tools/webcam). -* A way to connect to your car. With a comma three, you need only a [car harness](https://comma.ai/shop/products/car-harness). With a PC, you also need a [black panda](https://comma.ai/shop/products/panda). +* A [car harness](https://comma.ai/shop/products/car-harness) to connect to your car. -We have detailed instructions for [how to install the device in a car](https://comma.ai/setup). +We have detailed instructions for [how to mount the device in a car](https://comma.ai/setup). Running on PC ------ @@ -55,6 +56,7 @@ With openpilot's tools you can plot logs, replay drives and watch the full-res c You can also run openpilot in simulation [with the CARLA simulator](tools/sim/README.md). This allows openpilot to drive around a virtual car on your Ubuntu machine. The whole setup should only take a few minutes, but does require a decent GPU. +A PC running openpilot can also control your vehicle if it is connected to a [a webcam](https://github.com/commaai/openpilot/tree/master/tools/webcam), a [black panda](https://comma.ai/shop/products/panda), and [a harness](https://comma.ai/shop/products/car-harness). Community and Contributing ------ @@ -102,6 +104,9 @@ Directory Structure ├── panda # Code used to communicate on CAN ├── third_party # External libraries ├── pyextra # Extra python packages + └── system # Generic services + ├── logcatd # systemd journal as a service + └── proclogd # Logs information from /proc └── selfdrive # Code needed to drive the car ├── assets # Fonts, images, and sounds for UI ├── athena # Allows communication with the app @@ -112,7 +117,6 @@ Directory Structure ├── controls # Planning and controls ├── debug # Tools to help you debug and do car ports ├── locationd # Precise localization and vehicle parameter estimation - ├── logcatd # Android logcat as a service ├── loggerd # Logger and uploader of car data ├── modeld # Driving and monitoring model runners ├── proclogd # Logs information from proc diff --git a/RELEASES.md b/RELEASES.md index 6a72f8989a..7f365e5cef 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,17 +1,30 @@ -Version 0.8.14 (2022-0X-XX) +Version 0.8.15 (2022-XX-XX) +======================== +* New driving model +* New lateral controller based on physical wheel torque model + * Much smoother control, consistent across the speed range + * Effective feedforward that uses road roll + * Simplified tuning, all car-specific parameters can be derived from data + * Significantly improved control on TSS-P Prius +* New driver monitoring model + * takes a larger input frame + * outputs a driver state for both driver and passenger + * automatically determines which side the driver is on (soon) +* Display speed limit while navigating +* Reduced power usage: device runs cooler and fan spins less +* AGNOS 5 +* Hyundai Tucson 2021 support thanks to bluesforte! +* Lexus NX Hybrid 2020 support thanks to AlexandreSato! + +Version 0.8.14 (2022-06-01) ======================== * New driving model * Bigger model, using both of comma three's road-facing cameras * Better at cut-in detection and tight turns * New driver monitoring model - * Tweaked network structure to improve output resolution for dsp + * Tweaked network structure to improve output resolution for DSP * Fixed bug in quantization aware training to reduce quantizing errors * Resulted in 7x less MSE and no more random biases at runtime - * New lateral controller based on physical wheel torque model - * Much smoother control, consistent across the speed range - * Effective feedforward that uses road roll - * Simplified tuning, all car-specific parameters can be derived from data - * Initially used on TSS2 Corolla and TSS-P RAV4 * Added toggle to disable disengaging on the accelerator pedal * comma body support * Audi RS3 support thanks to jyoung8607! @@ -19,6 +32,7 @@ Version 0.8.14 (2022-0X-XX) * Hyundai Tucson Diesel 2019 support thanks to sunnyhaibin! * Toyota Alphard Hybrid 2021 support * Toyota Avalon Hybrid 2022 support + * Toyota RAV4 2022 support * Toyota RAV4 Hybrid 2022 support Version 0.8.13 (2022-02-18) diff --git a/SConstruct b/SConstruct index 48a5e0e2af..b5c4edc99b 100644 --- a/SConstruct +++ b/SConstruct @@ -1,5 +1,4 @@ import os -import shutil import subprocess import sys import sysconfig @@ -7,6 +6,8 @@ import platform import numpy as np TICI = os.path.isfile('/TICI') +AGNOS = TICI + Decider('MD5-timestamp') AddOption('--test', @@ -56,7 +57,7 @@ real_arch = arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rst if platform.system() == "Darwin": arch = "Darwin" -if arch == "aarch64" and TICI: +if arch == "aarch64" and AGNOS: arch = "larch64" USE_WEBCAM = os.getenv("USE_WEBCAM") is not None @@ -130,7 +131,7 @@ else: "#third_party/libyuv/x64/lib", "#third_party/mapbox-gl-native-qt/x86_64", "#cereal", - "#selfdrive/common", + "#common", "/usr/lib", "/usr/local/lib", ] @@ -138,7 +139,7 @@ else: rpath += [ Dir("#third_party/snpe/x86_64-linux-clang").abspath, Dir("#cereal").abspath, - Dir("#selfdrive/common").abspath + Dir("#common").abspath ] if GetOption('asan'): @@ -156,8 +157,8 @@ if arch != "Darwin": ldflags += ["-Wl,--as-needed", "-Wl,--no-undefined"] # Enable swaglog include in submodules -cflags += ['-DSWAGLOG="\\"selfdrive/common/swaglog.h\\""'] -cxxflags += ['-DSWAGLOG="\\"selfdrive/common/swaglog.h\\""'] +cflags += ['-DSWAGLOG="\\"common/swaglog.h\\""'] +cxxflags += ['-DSWAGLOG="\\"common/swaglog.h\\""'] env = Environment( ENV=lenv, @@ -184,7 +185,6 @@ env = Environment( "#third_party/acados/include/hpipm/include", "#third_party/catch2/include", "#third_party/libyuv/include", - "#third_party/openmax/include", "#third_party/json11", "#third_party/curl/include", "#third_party/libgralloc/include", @@ -213,7 +213,7 @@ env = Environment( "#third_party", "#opendbc/can", "#selfdrive/boardd", - "#selfdrive/common", + "#common", ], CYTHONCFILESUFFIX=".cpp", COMPILATIONDB_USE_ABSPATH=True, @@ -227,7 +227,7 @@ if GetOption('compile_db'): env.CompilationDatabase('compile_commands.json') # Setup cache dir -cache_dir = '/data/scons_cache' if TICI else '/tmp/scons_cache' +cache_dir = '/data/scons_cache' if AGNOS else '/tmp/scons_cache' CacheDir(cache_dir) Clean(["."], cache_dir) @@ -331,14 +331,14 @@ if GetOption("clazy"): Export('env', 'qt_env', 'arch', 'real_arch', 'SHARED', 'USE_WEBCAM') -SConscript(['selfdrive/common/SConscript']) -Import('_common', '_gpucommon', '_gpu_libs') +SConscript(['common/SConscript']) +Import('_common', '_gpucommon') if SHARED: common, gpucommon = abspath(common), abspath(gpucommon) else: common = [_common, 'json11'] - gpucommon = [_gpucommon] + _gpu_libs + gpucommon = [_gpucommon] Export('common', 'gpucommon') @@ -359,6 +359,7 @@ Export('cereal', 'messaging', 'visionipc') rednose_config = { 'generated_folder': '#selfdrive/locationd/models/generated', 'to_build': { + 'gnss': ('#selfdrive/locationd/models/gnss_kf.py', True, []), 'live': ('#selfdrive/locationd/models/live_kf.py', True, ['live_kf_constants.h']), 'car': ('#selfdrive/locationd/models/car_kf.py', True, []), }, @@ -366,7 +367,6 @@ rednose_config = { if arch != "larch64": rednose_config['to_build'].update({ - 'gnss': ('#selfdrive/locationd/models/gnss_kf.py', True, []), 'loc_4': ('#selfdrive/locationd/models/loc_kf.py', True, []), 'pos_computer_4': ('#rednose/helpers/lst_sq_computer.py', False, []), 'pos_computer_5': ('#rednose/helpers/lst_sq_computer.py', False, []), @@ -377,6 +377,14 @@ if arch != "larch64": Export('rednose_config') SConscript(['rednose/SConscript']) +# Build system services +SConscript([ + 'system/clocksd/SConscript', + 'system/proclogd/SConscript', +]) +if arch != "Darwin": + SConscript(['system/logcatd/SConscript']) + # Build openpilot SConscript(['cereal/SConscript']) @@ -385,7 +393,6 @@ SConscript(['opendbc/can/SConscript']) SConscript(['third_party/SConscript']) -SConscript(['common/SConscript']) SConscript(['common/kalman/SConscript']) SConscript(['common/transformations/SConscript']) @@ -397,8 +404,6 @@ SConscript(['selfdrive/controls/lib/lateral_mpc_lib/SConscript']) SConscript(['selfdrive/controls/lib/longitudinal_mpc_lib/SConscript']) SConscript(['selfdrive/boardd/SConscript']) -SConscript(['selfdrive/proclogd/SConscript']) -SConscript(['selfdrive/clocksd/SConscript']) SConscript(['selfdrive/loggerd/SConscript']) @@ -406,9 +411,6 @@ SConscript(['selfdrive/locationd/SConscript']) SConscript(['selfdrive/sensord/SConscript']) SConscript(['selfdrive/ui/SConscript']) -if arch != "Darwin": - SConscript(['selfdrive/logcatd/SConscript']) - if GetOption('test'): SConscript('panda/tests/safety/SConscript') diff --git a/cereal b/cereal index a057aed167..6faf34064b 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit a057aed16747d0e414145d83d4861c50315781ad +Subproject commit 6faf34064b70ab98c241d4a1cd9006b09ecaadfc diff --git a/common/SConscript b/common/SConscript index a41fc8b7eb..8aee6f42a7 100644 --- a/common/SConscript +++ b/common/SConscript @@ -1,4 +1,33 @@ -Import('envCython', 'common') +Import('env', 'envCython', 'arch', 'SHARED') +if SHARED: + fxn = env.SharedLibrary +else: + fxn = env.Library + +common_libs = [ + 'params.cc', + 'statlog.cc', + 'swaglog.cc', + 'util.cc', + 'gpio.cc', + 'i2c.cc', + 'watchdog.cc', +] + +_common = fxn('common', common_libs, LIBS="json11") + +files = [ + 'clutil.cc', +] + +_gpucommon = fxn('gpucommon', files) +Export('_common', '_gpucommon') + +if GetOption('test'): + env.Program('tests/test_util', ['tests/test_util.cc'], LIBS=[_common]) + env.Program('tests/test_swaglog', ['tests/test_swaglog.cc'], LIBS=[_common, 'json11', 'zmq', 'pthread']) + +# Cython envCython.Program('clock.so', 'clock.pyx') -envCython.Program('params_pyx.so', 'params_pyx.pyx', LIBS=envCython['LIBS'] + [common, 'zmq']) +envCython.Program('params_pyx.so', 'params_pyx.pyx', LIBS=envCython['LIBS'] + [_common, 'zmq', 'json11']) diff --git a/common/api/__init__.py b/common/api/__init__.py index 8b83dfc641..c1fa635bd6 100644 --- a/common/api/__init__.py +++ b/common/api/__init__.py @@ -3,7 +3,7 @@ import os import requests from datetime import datetime, timedelta from common.basedir import PERSIST -from selfdrive.version import get_version +from system.version import get_version API_HOST = os.getenv('API_HOST', 'https://api.commadotai.com') @@ -22,13 +22,13 @@ class Api(): def request(self, method, endpoint, timeout=None, access_token=None, **params): return api_get(endpoint, method=method, timeout=timeout, access_token=access_token, **params) - def get_token(self): + def get_token(self, expiry_hours=1): now = datetime.utcnow() payload = { 'identity': self.dongle_id, 'nbf': now, 'iat': now, - 'exp': now + timedelta(hours=1) + 'exp': now + timedelta(hours=expiry_hours) } token = jwt.encode(payload, self.private_key, algorithm='RS256') if isinstance(token, bytes): diff --git a/common/basedir.py b/common/basedir.py index 8be1cf6afa..371b54d3ef 100644 --- a/common/basedir.py +++ b/common/basedir.py @@ -1,7 +1,7 @@ import os from pathlib import Path -from selfdrive.hardware import PC +from system.hardware import PC BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")) diff --git a/selfdrive/common/clutil.cc b/common/clutil.cc similarity index 99% rename from selfdrive/common/clutil.cc rename to common/clutil.cc index 4e952a2a88..b8f9fde4cf 100644 --- a/selfdrive/common/clutil.cc +++ b/common/clutil.cc @@ -1,10 +1,10 @@ -#include "selfdrive/common/clutil.h" +#include "common/clutil.h" #include #include #include -#include "selfdrive/common/util.h" +#include "common/util.h" namespace { // helper functions diff --git a/selfdrive/common/clutil.h b/common/clutil.h similarity index 100% rename from selfdrive/common/clutil.h rename to common/clutil.h diff --git a/selfdrive/common/gpio.cc b/common/gpio.cc similarity index 92% rename from selfdrive/common/gpio.cc rename to common/gpio.cc index 033d6da4f7..73ff1b3f52 100644 --- a/selfdrive/common/gpio.cc +++ b/common/gpio.cc @@ -1,11 +1,11 @@ -#include "selfdrive/common/gpio.h" +#include "common/gpio.h" #include #include #include -#include "selfdrive/common/util.h" +#include "common/util.h" // We assume that all pins have already been exported on boot, // and that we have permission to write to them. diff --git a/selfdrive/common/gpio.h b/common/gpio.h similarity index 100% rename from selfdrive/common/gpio.h rename to common/gpio.h diff --git a/selfdrive/common/i2c.cc b/common/i2c.cc similarity index 92% rename from selfdrive/common/i2c.cc rename to common/i2c.cc index 5e6488fabf..eb10cd64bb 100644 --- a/selfdrive/common/i2c.cc +++ b/common/i2c.cc @@ -1,4 +1,4 @@ -#include "selfdrive/common/i2c.h" +#include "common/i2c.h" #include #include @@ -8,9 +8,9 @@ #include #include -#include "selfdrive/common/util.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" +#include "common/util.h" +#include "common/swaglog.h" +#include "common/util.h" #define UNUSED(x) (void)(x) diff --git a/selfdrive/common/i2c.h b/common/i2c.h similarity index 100% rename from selfdrive/common/i2c.h rename to common/i2c.h diff --git a/common/markdown.py b/common/markdown.py deleted file mode 100755 index 30c5bc2c09..0000000000 --- a/common/markdown.py +++ /dev/null @@ -1,48 +0,0 @@ -from typing import List - -HTML_REPLACEMENTS = [ - (r'&', r'&'), - (r'"', r'"'), -] - - -def parse_markdown(text: str, tab_length: int = 2) -> str: - lines = text.split("\n") - output: List[str] = [] - list_level = 0 - - def end_outstanding_lists(level: int, end_level: int) -> int: - while level > end_level: - level -= 1 - output.append("") - if level > 0: - output.append("") - return end_level - - for i, line in enumerate(lines): - if i + 1 < len(lines) and lines[i + 1].startswith("==="): # heading - output.append(f"

{line}

") - elif line.startswith("==="): - pass - elif line.lstrip().startswith("* "): # list - line_level = 1 + line.count(" " * tab_length, 0, line.index("*")) - if list_level >= line_level: - list_level = end_outstanding_lists(list_level, line_level) - else: - list_level += 1 - if list_level > 1: - output[-1] = output[-1].replace("", "") - output.append("
    ") - output.append(f"
  • {line.replace('*', '', 1).lstrip()}
  • ") - else: - list_level = end_outstanding_lists(list_level, 0) - if len(line) > 0: - output.append(line) - - end_outstanding_lists(list_level, 0) - output_str = "\n".join(output) + "\n" - - for (fr, to) in HTML_REPLACEMENTS: - output_str = output_str.replace(fr, to) - - return output_str diff --git a/selfdrive/common/mat.h b/common/mat.h similarity index 100% rename from selfdrive/common/mat.h rename to common/mat.h diff --git a/selfdrive/common/modeldata.h b/common/modeldata.h similarity index 94% rename from selfdrive/common/modeldata.h rename to common/modeldata.h index 6b30e60506..aee9fdfd83 100644 --- a/selfdrive/common/modeldata.h +++ b/common/modeldata.h @@ -1,8 +1,8 @@ #pragma once #include -#include "selfdrive/common/mat.h" -#include "selfdrive/hardware/hw.h" +#include "common/mat.h" +#include "system/hardware/hw.h" const int TRAJECTORY_SIZE = 33; const int LAT_MPC_N = 16; @@ -24,8 +24,6 @@ constexpr auto T_IDXS_FLOAT = build_idxs(10.0); constexpr auto X_IDXS = build_idxs(192.0); constexpr auto X_IDXS_FLOAT = build_idxs(192.0); -const int TICI_CAM_WIDTH = 1928; - namespace tici_dm_crop { const int x_offset = -72; const int y_offset = -144; diff --git a/selfdrive/common/params.cc b/common/params.cc similarity index 93% rename from selfdrive/common/params.cc rename to common/params.cc index bea12aca11..8cf1baa6c8 100644 --- a/selfdrive/common/params.cc +++ b/common/params.cc @@ -1,4 +1,4 @@ -#include "selfdrive/common/params.h" +#include "common/params.h" #include #include @@ -6,9 +6,9 @@ #include #include -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" -#include "selfdrive/hardware/hw.h" +#include "common/swaglog.h" +#include "common/util.h" +#include "system/hardware/hw.h" namespace { @@ -60,9 +60,9 @@ bool create_params_path(const std::string ¶m_path, const std::string &key_pa return true; } -std::string ensure_params_path(const std::string &path = {}) { +std::string ensure_params_path(const std::string &prefix, const std::string &path = {}) { std::string params_path = path.empty() ? Path::params() : path; - if (!create_params_path(params_path, params_path + "/d")) { + if (!create_params_path(params_path, params_path + prefix)) { throw std::runtime_error(util::string_format("Failed to ensure params path, errno=%d", errno)); } return params_path; @@ -94,6 +94,7 @@ std::unordered_map keys = { {"CompletedTrainingVersion", PERSISTENT}, {"ControlsReady", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON}, {"CurrentRoute", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON}, + {"DisableLogging", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON}, {"DisablePowerDown", PERSISTENT}, {"DisableRadar_Allow", PERSISTENT}, {"DisableRadar", PERSISTENT}, // WARNING: THIS DISABLES AEB @@ -103,8 +104,6 @@ std::unordered_map keys = { {"DoReboot", CLEAR_ON_MANAGER_START}, {"DoShutdown", CLEAR_ON_MANAGER_START}, {"DoUninstall", CLEAR_ON_MANAGER_START}, - {"EnableWideCamera", CLEAR_ON_MANAGER_START}, - {"EndToEndToggle", PERSISTENT}, {"ForcePowerDown", CLEAR_ON_MANAGER_START}, {"GitBranch", PERSISTENT}, {"GitCommit", PERSISTENT}, @@ -128,10 +127,10 @@ std::unordered_map keys = { {"IsTakingSnapshot", CLEAR_ON_MANAGER_START}, {"IsUpdateAvailable", CLEAR_ON_MANAGER_START}, {"JoystickDebugMode", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF}, + {"LaikadEphemeris", PERSISTENT}, {"LastAthenaPingTime", CLEAR_ON_MANAGER_START}, {"LastGPSPosition", PERSISTENT}, {"LastManagerExitReason", CLEAR_ON_MANAGER_START}, - {"LastPeripheralPandaType", PERSISTENT}, {"LastPowerDropDetected", CLEAR_ON_MANAGER_START}, {"LastSystemShutdown", CLEAR_ON_MANAGER_START}, {"LastUpdateException", CLEAR_ON_MANAGER_START}, @@ -144,7 +143,6 @@ std::unordered_map keys = { {"PandaHeartbeatLost", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF}, {"PandaSignatures", CLEAR_ON_MANAGER_START}, {"Passive", PERSISTENT}, - {"PrimeRedirected", PERSISTENT}, {"PrimeType", PERSISTENT}, {"RecordFront", PERSISTENT}, {"RecordFrontLock", PERSISTENT}, // for the internal fleet @@ -160,6 +158,7 @@ std::unordered_map keys = { {"UpdateFailedCount", CLEAR_ON_MANAGER_START}, {"Version", PERSISTENT}, {"VisionRadarToggle", PERSISTENT}, + {"WideCameraOnly", PERSISTENT}, {"ApiCache_Device", PERSISTENT}, {"ApiCache_DriveStats", PERSISTENT}, {"ApiCache_NavDestinations", PERSISTENT}, @@ -180,9 +179,12 @@ std::unordered_map keys = { } // namespace + Params::Params(const std::string &path) { - static std::string default_param_path = ensure_params_path(); - params_path = path.empty() ? default_param_path : ensure_params_path(path); + const char* env = std::getenv("OPENPILOT_PREFIX"); + prefix = env ? "/" + std::string(env) : "/d"; + std::string default_param_path = ensure_params_path(prefix); + params_path = path.empty() ? default_param_path : ensure_params_path(prefix, path); } bool Params::checkKey(const std::string &key) { diff --git a/selfdrive/common/params.h b/common/params.h similarity index 92% rename from selfdrive/common/params.h rename to common/params.h index be09c63d54..aa4b1d7af3 100644 --- a/selfdrive/common/params.h +++ b/common/params.h @@ -18,7 +18,7 @@ public: bool checkKey(const std::string &key); ParamKeyType getKeyType(const std::string &key); inline std::string getParamPath(const std::string &key = {}) { - return key.empty() ? params_path + "/d" : params_path + "/d/" + key; + return params_path + prefix + (key.empty() ? "" : "/" + key); } // Delete a value @@ -43,4 +43,5 @@ public: private: std::string params_path; + std::string prefix; }; diff --git a/common/params_pyx.pyx b/common/params_pyx.pyx index a8c43c2f2f..b3b8248529 100755 --- a/common/params_pyx.pyx +++ b/common/params_pyx.pyx @@ -4,7 +4,7 @@ from libcpp cimport bool from libcpp.string cimport string import threading -cdef extern from "selfdrive/common/params.h": +cdef extern from "common/params.h": cpdef enum ParamKeyType: PERSISTENT CLEAR_ON_MANAGER_START @@ -20,6 +20,7 @@ cdef extern from "selfdrive/common/params.h": int put(string, string) nogil int putBool(string, bool) nogil bool checkKey(string) nogil + string getParamPath(string) nogil void clearAll(ParamKeyType) @@ -94,6 +95,10 @@ cdef class Params: with nogil: self.p.remove(k) + def get_param_path(self, key=""): + cdef string key_bytes = ensure_bytes(key) + return self.p.getParamPath(key_bytes).decode("utf-8") + def put_nonblocking(key, val, d=""): def f(key, val): params = Params(d) diff --git a/selfdrive/common/queue.h b/common/queue.h similarity index 100% rename from selfdrive/common/queue.h rename to common/queue.h diff --git a/common/realtime.py b/common/realtime.py index 6ef27ed3a3..8a79d8d39f 100644 --- a/common/realtime.py +++ b/common/realtime.py @@ -8,19 +8,14 @@ from typing import Optional, List, Union from setproctitle import getproctitle # pylint: disable=no-name-in-module from common.clock import sec_since_boot # pylint: disable=no-name-in-module, import-error -from selfdrive.hardware import PC, TICI +from system.hardware import PC # time step for each process DT_CTRL = 0.01 # controlsd DT_MDL = 0.05 # model DT_TRML = 0.5 # thermald and manager - -# driver monitoring -if TICI: - DT_DMON = 0.05 -else: - DT_DMON = 0.1 +DT_DMON = 0.05 # driver monitoring class Priority: @@ -36,12 +31,12 @@ class Priority: def set_realtime_priority(level: int) -> None: if not PC: - os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(level)) # type: ignore[attr-defined] + os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(level)) # type: ignore[attr-defined] # pylint: disable=no-member def set_core_affinity(cores: List[int]) -> None: if not PC: - os.sched_setaffinity(0, cores) + os.sched_setaffinity(0, cores) # pylint: disable=no-member def config_realtime_process(cores: Union[int, List[int]], priority: int) -> None: @@ -52,7 +47,7 @@ def config_realtime_process(cores: Union[int, List[int]], priority: int) -> None class Ratekeeper: - def __init__(self, rate: int, print_delay_threshold: Optional[float] = 0.0) -> None: + def __init__(self, rate: float, print_delay_threshold: Optional[float] = 0.0) -> None: """Rate in Hz for ratekeeping. print_delay_threshold must be nonnegative.""" self._interval = 1. / rate self._next_frame_time = sec_since_boot() + self._interval diff --git a/selfdrive/common/statlog.cc b/common/statlog.cc similarity index 93% rename from selfdrive/common/statlog.cc rename to common/statlog.cc index 54463e9816..26945882d9 100644 --- a/selfdrive/common/statlog.cc +++ b/common/statlog.cc @@ -2,8 +2,8 @@ #define _GNU_SOURCE #endif -#include "selfdrive/common/statlog.h" -#include "selfdrive/common/util.h" +#include "common/statlog.h" +#include "common/util.h" #include #include diff --git a/selfdrive/common/statlog.h b/common/statlog.h similarity index 100% rename from selfdrive/common/statlog.h rename to common/statlog.h diff --git a/common/string_helpers.py b/common/string_helpers.py deleted file mode 100644 index 3038605fbb..0000000000 --- a/common/string_helpers.py +++ /dev/null @@ -1,6 +0,0 @@ -def replace_right(s, old, new, occurrence): - # replace_right('1232425', '2', ' ', 1) -> '12324 5' - # replace_right('1232425', '2', ' ', 2) -> '123 4 5' - - split = s.rsplit(old, occurrence) - return new.join(split) diff --git a/selfdrive/common/swaglog.cc b/common/swaglog.cc similarity index 93% rename from selfdrive/common/swaglog.cc rename to common/swaglog.cc index 21115da10f..6b0028326a 100644 --- a/selfdrive/common/swaglog.cc +++ b/common/swaglog.cc @@ -2,7 +2,7 @@ #define _GNU_SOURCE #endif -#include "selfdrive/common/swaglog.h" +#include "common/swaglog.h" #include #include @@ -13,9 +13,9 @@ #include #include "json11.hpp" -#include "selfdrive/common/util.h" -#include "selfdrive/common/version.h" -#include "selfdrive/hardware/hw.h" +#include "common/util.h" +#include "common/version.h" +#include "system/hardware/hw.h" class SwaglogState : public LogState { public: @@ -50,11 +50,7 @@ class SwaglogState : public LogState { ctx_j["dirty"] = !getenv("CLEAN"); // device type - if (Hardware::TICI()) { - ctx_j["device"] = "tici"; - } else { - ctx_j["device"] = "pc"; - } + ctx_j["device"] = Hardware::get_name(); LogState::initialize(); } }; diff --git a/selfdrive/common/swaglog.h b/common/swaglog.h similarity index 98% rename from selfdrive/common/swaglog.h rename to common/swaglog.h index edae9fdc34..68b05ed2e9 100644 --- a/selfdrive/common/swaglog.h +++ b/common/swaglog.h @@ -1,6 +1,6 @@ #pragma once -#include "selfdrive/common/timing.h" +#include "common/timing.h" #define CLOUDLOG_DEBUG 10 #define CLOUDLOG_INFO 20 diff --git a/common/tests/.gitignore b/common/tests/.gitignore new file mode 100644 index 0000000000..1350b3b825 --- /dev/null +++ b/common/tests/.gitignore @@ -0,0 +1,2 @@ +test_util +test_swaglog diff --git a/common/tests/test_markdown.py b/common/tests/test_markdown.py deleted file mode 100755 index 9ac67f7e50..0000000000 --- a/common/tests/test_markdown.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -from markdown_it import MarkdownIt -import os -import unittest - -from common.basedir import BASEDIR -from common.markdown import parse_markdown - - -class TestMarkdown(unittest.TestCase): - # validate that our simple markdown parser produces the same output as `markdown_it` from pip - def test_current_release_notes(self): - self.maxDiff = None - - with open(os.path.join(BASEDIR, "RELEASES.md")) as f: - for r in f.read().split("\n\n"): - - # No hyperlink support is ok - if '[' in r: - continue - - self.assertEqual(MarkdownIt().render(r), parse_markdown(r)) - - -if __name__ == "__main__": - unittest.main() diff --git a/selfdrive/common/tests/test_swaglog.cc b/common/tests/test_swaglog.cc similarity index 91% rename from selfdrive/common/tests/test_swaglog.cc rename to common/tests/test_swaglog.cc index 47c5504638..20455ec74c 100644 --- a/selfdrive/common/tests/test_swaglog.cc +++ b/common/tests/test_swaglog.cc @@ -4,10 +4,10 @@ #include "catch2/catch.hpp" #include "json11.hpp" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" -#include "selfdrive/common/version.h" -#include "selfdrive/hardware/hw.h" +#include "common/swaglog.h" +#include "common/util.h" +#include "common/version.h" +#include "system/hardware/hw.h" const char *SWAGLOG_ADDR = "ipc:///tmp/logmessage"; std::string daemon_name = "testy"; @@ -56,10 +56,7 @@ void recv_log(int thread_cnt, int thread_msg_cnt) { REQUIRE(ctx["version"].string_value() == COMMA_VERSION); - std::string device = "pc"; - if (Hardware::TICI()) { - device = "tici"; - } + std::string device = Hardware::get_name(); REQUIRE(ctx["device"].string_value() == device); int thread_id = atoi(msg["msg"].string_value().c_str()); diff --git a/selfdrive/common/tests/test_util.cc b/common/tests/test_util.cc similarity index 99% rename from selfdrive/common/tests/test_util.cc rename to common/tests/test_util.cc index 06317accd0..62e73275d4 100644 --- a/selfdrive/common/tests/test_util.cc +++ b/common/tests/test_util.cc @@ -10,7 +10,7 @@ #define CATCH_CONFIG_MAIN #include "catch2/catch.hpp" -#include "selfdrive/common/util.h" +#include "common/util.h" std::string random_bytes(int size) { std::random_device rd; diff --git a/common/tests/test_xattr.py b/common/tests/test_xattr.py deleted file mode 100644 index 16f6d52977..0000000000 --- a/common/tests/test_xattr.py +++ /dev/null @@ -1,47 +0,0 @@ -import os -import tempfile -import shutil -import unittest - -from common.xattr import getxattr, setxattr, listxattr, removexattr - -class TestParams(unittest.TestCase): - USER_TEST='user.test' - def setUp(self): - self.tmpdir = tempfile.mkdtemp() - self.tmpfn = os.path.join(self.tmpdir, 'test.txt') - open(self.tmpfn, 'w').close() - #print("using", self.tmpfn) - - def tearDown(self): - shutil.rmtree(self.tmpdir) - - def test_getxattr_none(self): - a = getxattr(self.tmpfn, TestParams.USER_TEST) - assert a is None - - def test_listxattr_none(self): - l = listxattr(self.tmpfn) - assert l == [] - - def test_setxattr(self): - setxattr(self.tmpfn, TestParams.USER_TEST, b'123') - a = getxattr(self.tmpfn, TestParams.USER_TEST) - assert a == b'123' - - def test_listxattr(self): - setxattr(self.tmpfn, 'user.test1', b'123') - setxattr(self.tmpfn, 'user.test2', b'123') - l = listxattr(self.tmpfn) - assert l == ['user.test1', 'user.test2'] - - def test_removexattr(self): - setxattr(self.tmpfn, TestParams.USER_TEST, b'123') - a = getxattr(self.tmpfn, TestParams.USER_TEST) - assert a == b'123' - removexattr(self.tmpfn, TestParams.USER_TEST) - a = getxattr(self.tmpfn, TestParams.USER_TEST) - assert a is None - -if __name__ == "__main__": - unittest.main() diff --git a/selfdrive/common/timing.h b/common/timing.h similarity index 100% rename from selfdrive/common/timing.h rename to common/timing.h diff --git a/common/transformations/README.md b/common/transformations/README.md index 78fa6a31c4..13878cb99c 100644 --- a/common/transformations/README.md +++ b/common/transformations/README.md @@ -24,7 +24,7 @@ by generating a rotation matrix and multiplying. -Orientation Conventations +Orientation Conventions ------ Quaternions, rotation matrices and euler angles are three equivalent representations of orientation and all three are diff --git a/common/transformations/camera.py b/common/transformations/camera.py index 7573877a3e..5d100d1047 100644 --- a/common/transformations/camera.py +++ b/common/transformations/camera.py @@ -1,7 +1,6 @@ import numpy as np import common.transformations.orientation as orient -from selfdrive.hardware import TICI ## -- hardcoded hardware params -- eon_f_focal_length = 910.0 @@ -45,14 +44,9 @@ tici_fcam_intrinsics_inv = np.linalg.inv(tici_fcam_intrinsics) tici_ecam_intrinsics_inv = np.linalg.inv(tici_ecam_intrinsics) -if not TICI: - FULL_FRAME_SIZE = eon_f_frame_size - FOCAL = eon_f_focal_length - fcam_intrinsics = eon_fcam_intrinsics -else: - FULL_FRAME_SIZE = tici_f_frame_size - FOCAL = tici_f_focal_length - fcam_intrinsics = tici_fcam_intrinsics +FULL_FRAME_SIZE = tici_f_frame_size +FOCAL = tici_f_focal_length +fcam_intrinsics = tici_fcam_intrinsics W, H = FULL_FRAME_SIZE[0], FULL_FRAME_SIZE[1] diff --git a/common/transformations/orientation.py b/common/transformations/orientation.py index 415e247ab2..134442b624 100644 --- a/common/transformations/orientation.py +++ b/common/transformations/orientation.py @@ -1,5 +1,6 @@ # pylint: skip-file import numpy as np +from typing import Callable from common.transformations.transformations import (ecef_euler_from_ned_single, euler2quat_single, @@ -11,7 +12,7 @@ from common.transformations.transformations import (ecef_euler_from_ned_single, rot2quat_single) -def numpy_wrap(function, input_shape, output_shape): +def numpy_wrap(function, input_shape, output_shape) -> Callable[..., np.ndarray]: """Wrap a function to take either an input or list of inputs and return the correct shape""" def f(*inps): *args, inp = inps diff --git a/selfdrive/common/util.cc b/common/util.cc similarity index 99% rename from selfdrive/common/util.cc rename to common/util.cc index 534a7f4456..92add63997 100644 --- a/selfdrive/common/util.cc +++ b/common/util.cc @@ -1,4 +1,4 @@ -#include "selfdrive/common/util.h" +#include "common/util.h" #include #include diff --git a/selfdrive/common/util.h b/common/util.h similarity index 100% rename from selfdrive/common/util.h rename to common/util.h diff --git a/common/version.h b/common/version.h new file mode 100644 index 0000000000..de550d6be5 --- /dev/null +++ b/common/version.h @@ -0,0 +1 @@ +#define COMMA_VERSION "0.8.15" diff --git a/selfdrive/common/watchdog.cc b/common/watchdog.cc similarity index 71% rename from selfdrive/common/watchdog.cc rename to common/watchdog.cc index c937103a5d..5a10207828 100644 --- a/selfdrive/common/watchdog.cc +++ b/common/watchdog.cc @@ -1,6 +1,6 @@ -#include "selfdrive/common/watchdog.h" -#include "selfdrive/common/timing.h" -#include "selfdrive/common/util.h" +#include "common/watchdog.h" +#include "common/timing.h" +#include "common/util.h" const std::string watchdog_fn_prefix = "/dev/shm/wd_"; // + diff --git a/selfdrive/common/watchdog.h b/common/watchdog.h similarity index 100% rename from selfdrive/common/watchdog.h rename to common/watchdog.h diff --git a/common/window.py b/common/window.py index ce1eecb881..613b3b201b 100644 --- a/common/window.py +++ b/common/window.py @@ -2,7 +2,7 @@ import sys import pygame # pylint: disable=import-error import cv2 # pylint: disable=import-error -class Window(): +class Window: def __init__(self, w, h, caption="window", double=False, halve=False): self.w = w self.h = h @@ -54,7 +54,7 @@ class Window(): if __name__ == "__main__": import numpy as np win = Window(200, 200, double=True) - img = np.zeros((200, 200, 3), np.uint8) + img: np.ndarray = np.zeros((200, 200, 3), np.uint8) while 1: print("draw") img += 1 diff --git a/common/xattr.py b/common/xattr.py index fa61b9e0fc..26616fd638 100644 --- a/common/xattr.py +++ b/common/xattr.py @@ -1,5 +1,6 @@ import os from cffi import FFI +from typing import Any, List # Workaround for the EON/termux build of Python having os.*xattr removed. ffi = FFI() @@ -11,7 +12,7 @@ int removexattr(const char *path, const char *name); """) libc = ffi.dlopen(None) -def setxattr(path, name, value, flags=0): +def setxattr(path, name, value, flags=0) -> None: path = path.encode() name = name.encode() if libc.setxattr(path, name, value, len(value), flags) == -1: @@ -29,7 +30,7 @@ def getxattr(path, name, size=128): raise OSError(ffi.errno, f"{os.strerror(ffi.errno)}: getxattr({path}, {name}, {size})") return ffi.buffer(value)[:l] -def listxattr(path, size=128): +def listxattr(path, size=128) -> List[Any]: path = path.encode() attrs = ffi.new(f"char[{size}]") l = libc.listxattr(path, attrs, size) @@ -38,7 +39,7 @@ def listxattr(path, size=128): # attrs is b'\0' delimited values (so chop off trailing empty item) return [a.decode() for a in ffi.buffer(attrs)[:l].split(b"\0")[0:-1]] -def removexattr(path, name): +def removexattr(path, name) -> None: path = path.encode() name = name.encode() if libc.removexattr(path, name) == -1: diff --git a/docs/CARS.md b/docs/CARS.md index 14664d480c..c0bd62eb3f 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -12,207 +12,216 @@ How We Rate The Cars --- ### openpilot Adaptive Cruise Control (ACC) -- - openpilot is able to control the gas and brakes. -- - openpilot is able to control the gas and brakes with some restrictions. -- - The gas and brakes are controlled by the car's stock Adaptive Cruise Control (ACC) system. +- - openpilot is able to control the gas and brakes. +- - openpilot is able to control the gas and brakes with some restrictions. +- - The gas and brakes are controlled by the car's stock Adaptive Cruise Control (ACC) system. ### Stop and Go -- - Adaptive Cruise Control (ACC) operates down to 0 mph. -- - Adaptive Cruise Control (ACC) available only above certain speeds. See your car's manual for the minimum speed. +- - Adaptive Cruise Control (ACC) operates down to 0 mph. +- - Adaptive Cruise Control (ACC) available only above certain speeds. See your car's manual for the minimum speed. ### Steer to 0 -- - openpilot can control the steering wheel down to 0 mph. -- - No steering control below certain speeds. +- - openpilot can control the steering wheel down to 0 mph. +- - No steering control below certain speeds. ### Steering Torque -- - Car has enough steering torque for comfortable highway driving. -- - Limited ability to make turns. +- - Car has enough steering torque to take tighter turns. +- - Car has enough steering torque for comfortable highway driving. +- - Limited ability to make turns. ### Actively Maintained -- - Mainline software support, harness hardware sold by comma, lots of users, primary development target. -- - Low user count, community maintained, harness hardware not sold by comma. +- - Mainline software support, harness hardware sold by comma, lots of users, primary development target. +- - Low user count, community maintained, harness hardware not sold by comma. **All supported cars can move between the tiers as support changes.** -## Gold Cars +# Gold - 28 cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| |---|---|---|:---:|:---:|:---:|:---:|:---:| -|comma|body|All|||||| -|Genesis|G70 2020|All|||||| -|Hyundai|Palisade 2020-21|All|||||| -|Hyundai|Santa Fe 2019-20|All|||||| -|Hyundai|Sonata 2020-22|All|||||| -|Hyundai|Sonata Hybrid 2020-22|All|||||| -|Kia|Niro Electric 2019-22|All|||||| -|Kia|Telluride 2020|SCC + LKAS|||||| -|Lexus|ES 2019-21|All|||||| -|Lexus|ES Hybrid 2019-21|All|||||| -|Lexus|NX 2020|All|||||| -|Lexus|RX 2020-22|All|||||| -|Lexus|RX Hybrid 2020-21|All|||||| -|Lexus|UX Hybrid 2019-21|All|||||| -|Toyota|Alphard 2019-20|All|||||| -|Toyota|Alphard Hybrid 2021|All|||||| -|Toyota|Avalon 2022|All|||||| -|Toyota|Avalon Hybrid 2022|All|||||| -|Toyota|Camry 2021-22|All||[4](#footnotes)|||| -|Toyota|Camry Hybrid 2021-22|All|||||| -|Toyota|Corolla 2020-22|All|||||| -|Toyota|Corolla Hatchback 2019-22|All|||||| -|Toyota|Corolla Hybrid 2020-22|All|||||| -|Toyota|Highlander 2020-22|All|||||| -|Toyota|Highlander Hybrid 2020-22|All|||||| -|Toyota|Mirai 2021|All|||||| -|Toyota|Prius 2021-22|All|||||| -|Toyota|Prius Prime 2021-22|All|||||| -|Toyota|RAV4 2019-21|All|||||| -|Toyota|RAV4 Hybrid 2019-21|All|||||| - -## Silver Cars +|comma|body|All|||||| +|Genesis|G70 2020|All|||||| +|Hyundai|Palisade 2020-21|All|||||| +|Hyundai|Santa Fe 2019-20|All|||||| +|Hyundai|Sonata 2020-22|All|||||| +|Hyundai|Sonata Hybrid 2020-22|All|||||| +|Kia|Niro Electric 2019-20|All|||||| +|Kia|Niro Electric 2021|All|||||| +|Kia|Niro Electric 2022|All|||||| +|Kia|Telluride 2020|SCC + LKAS|||||| +|Lexus|ES 2019-21|All|||||| +|Lexus|ES Hybrid 2019-22|All|||||| +|Lexus|NX 2020|All|||||| +|Lexus|RX 2020-22|All|||||| +|Lexus|UX Hybrid 2019-21|All|||||| +|Toyota|Avalon 2022|All|||||| +|Toyota|Camry 2021-22|All||[4](#footnotes)|||| +|Toyota|Camry Hybrid 2021-22|All|||||| +|Toyota|Corolla 2020-22|All|||||| +|Toyota|Corolla Hatchback 2019-22|All|||||| +|Toyota|Corolla Hybrid 2020-22|All|||||| +|Toyota|Highlander 2020-22|All|||||| +|Toyota|Highlander Hybrid 2020-22|All|||||| +|Toyota|Mirai 2021|All|||||| +|Toyota|Prius 2021-22|All|||||| +|Toyota|Prius Prime 2021-22|All|||||| +|Toyota|RAV4 2019-21|All|||||| +|Toyota|RAV4 Hybrid 2019-21|All|||||| + +# Silver - 76 cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| |---|---|---|:---:|:---:|:---:|:---:|:---:| -|Audi|A3 2014-19|ACC + Lane Assist|||||| -|Audi|A3 Sportback e-tron 2017-18|ACC + Lane Assist|||||| -|Audi|Q2 2018|ACC + Lane Assist|||||| -|Audi|Q3 2020-21|ACC + Lane Assist|||||| -|Audi|RS3 2018|ACC + Lane Assist|||||| -|Audi|S3 2015-17|ACC + Lane Assist|||||| -|Genesis|G70 2018|All|||||| -|Genesis|G80 2018|All|||||| -|Hyundai|Elantra 2021-22|SCC + LKAS|||||| -|Hyundai|Elantra Hybrid 2021-22|SCC + LKAS|||||| -|Hyundai|Ioniq Electric 2020|SCC + LKAS|||||| -|Hyundai|Ioniq Hybrid 2020-22|SCC + LFA|||||| -|Hyundai|Ioniq Plug-in Hybrid 2020-21|SCC + LKAS|||||| -|Hyundai|Kona 2020|SCC + LKAS|||||| -|Hyundai|Kona Electric 2018-21|SCC + LKAS|||||| -|Hyundai|Kona Hybrid 2020|SCC + LKAS|||||| -|Hyundai|Santa Fe 2021-22|All|||||| -|Hyundai|Santa Fe Hybrid 2022|All|||||| -|Hyundai|Santa Fe Plug-in Hybrid 2022|All|||||| -|Hyundai|Sonata 2018-19|SCC + LKAS|||||| -|Hyundai|Tucson Diesel 2019|SCC + LKAS|||||| -|Kia|Ceed 2019|SCC + LKAS|||||| -|Kia|Forte 2018-21|SCC + LKAS|||||| -|Kia|K5 2021-22|SCC + LFA|||||| -|Kia|Niro Hybrid 2021-22|SCC + LKAS|||||| -|Kia|Optima 2019|SCC + LKAS|||||| -|Kia|Seltos 2021|SCC + LKAS|||||| -|Kia|Sorento 2018-19|SCC + LKAS|||||| -|Kia|Stinger 2018|SCC + LKAS|||||| -|Lexus|CT Hybrid 2017-18|LSS|[3](#footnotes)||||| -|Lexus|ES Hybrid 2017-18|LSS|[3](#footnotes)||||| -|Lexus|NX 2018-19|All|[3](#footnotes)||||| -|Lexus|NX Hybrid 2018-19|All|[3](#footnotes)||||| -|Lexus|RX 2016-18|All|[3](#footnotes)||||| -|Lexus|RX Hybrid 2016-19|All|[3](#footnotes)||||| -|Mazda|CX-5 2022|All|||||| -|SEAT|Ateca 2018|Driver Assistance|||||| -|SEAT|Leon 2014-20|Driver Assistance|||||| -|Subaru|Crosstrek 2018-19|EyeSight|||||| -|Subaru|Forester 2019-21|EyeSight|||||| -|Subaru|Impreza 2017-19|EyeSight|||||| -|Å koda|Kamiq 2021[6](#footnotes)|Driver Assistance|||||| -|Å koda|Karoq 2019|Driver Assistance|||||| -|Å koda|Kodiaq 2018-19|Driver Assistance|||||| -|Å koda|Octavia 2015, 2018-19|Driver Assistance|||||| -|Å koda|Octavia RS 2016|Driver Assistance|||||| -|Å koda|Scala 2020|Driver Assistance|||||| -|Å koda|Superb 2015-18|Driver Assistance|||||| -|Toyota|Avalon 2019-21|TSS-P|[3](#footnotes)||||| -|Toyota|Avalon Hybrid 2019-21|TSS-P|[3](#footnotes)||||| -|Toyota|C-HR 2017-21|All|||||| -|Toyota|C-HR Hybrid 2017-19|All|||||| -|Toyota|Camry 2018-20|All||[4](#footnotes)|||| -|Toyota|Camry Hybrid 2018-20|All||[4](#footnotes)|||| -|Toyota|Highlander 2017-19|All|[3](#footnotes)||||| -|Toyota|Highlander Hybrid 2017-19|All|[3](#footnotes)||||| -|Toyota|RAV4 Hybrid 2016-18|TSS-P|[3](#footnotes)||||| -|Toyota|RAV4 Hybrid 2022|All|||||| -|Toyota|Sienna 2018-20|All|[3](#footnotes)||||| -|Volkswagen|Arteon 2018, 2021[8](#footnotes)|Driver Assistance|||||| -|Volkswagen|Atlas 2018-19, 2022[8](#footnotes)|Driver Assistance|||||| -|Volkswagen|e-Golf 2014, 2018-20|Driver Assistance|||||| -|Volkswagen|Golf 2015-20|Driver Assistance|||||| -|Volkswagen|Golf Alltrack 2017-18|Driver Assistance|||||| -|Volkswagen|Golf GTE 2016|Driver Assistance|||||| -|Volkswagen|Golf GTI 2018-21|Driver Assistance|||||| -|Volkswagen|Golf R 2016-19|Driver Assistance|||||| -|Volkswagen|Golf SportsVan 2016|Driver Assistance|||||| -|Volkswagen|Golf SportWagen 2015|Driver Assistance|||||| -|Volkswagen|Jetta 2018-21|Driver Assistance|||||| -|Volkswagen|Jetta GLI 2021|Driver Assistance|||||| -|Volkswagen|Passat 2016-18[7](#footnotes)|Driver Assistance|||||| -|Volkswagen|Polo 2020|Driver Assistance|||||| -|Volkswagen|T-Cross 2021[8](#footnotes)|Driver Assistance|||||| -|Volkswagen|T-Roc 2021[8](#footnotes)|Driver Assistance|||||| -|Volkswagen|Taos 2022[8](#footnotes)|Driver Assistance|||||| -|Volkswagen|Tiguan 2019-22[8](#footnotes)|Driver Assistance|||||| -|Volkswagen|Touran 2017|Driver Assistance|||||| - -## Bronze Cars +|Audi|A3 2014-19|ACC + Lane Assist|||||| +|Audi|A3 Sportback e-tron 2017-18|ACC + Lane Assist|||||| +|Audi|Q2 2018|ACC + Lane Assist|||||| +|Audi|RS3 2018|ACC + Lane Assist|||||| +|Audi|S3 2015-17|ACC + Lane Assist|||||| +|Chevrolet|Volt 2017-18[1](#footnotes)|Adaptive Cruise|||||| +|Genesis|G70 2018|All|||||| +|Genesis|G80 2018|All|||||| +|Hyundai|Elantra 2021-22|SCC + LKAS|||||| +|Hyundai|Elantra Hybrid 2021-22|SCC + LKAS|||||| +|Hyundai|Ioniq Electric 2020|SCC + LKAS|||||| +|Hyundai|Ioniq Hybrid 2020-22|SCC + LFA|||||| +|Hyundai|Ioniq Plug-in Hybrid 2020-21|SCC + LKAS|||||| +|Hyundai|Kona 2020|SCC + LKAS|||||| +|Hyundai|Kona Electric 2018-21|SCC + LKAS|||||| +|Hyundai|Kona Hybrid 2020|SCC + LKAS|||||| +|Hyundai|Santa Fe 2021-22|All|||||| +|Hyundai|Santa Fe Hybrid 2022|All|||||| +|Hyundai|Santa Fe Plug-in Hybrid 2022|All|||||| +|Hyundai|Tucson Diesel 2019|SCC + LKAS|||||| +|Kia|Ceed 2019|SCC + LKAS|||||| +|Kia|Forte 2018|SCC + LKAS|||||| +|Kia|Forte 2019-21|SCC + LKAS|||||| +|Kia|K5 2021-22|SCC|||||| +|Kia|Niro Hybrid 2021|SCC + LKAS|||||| +|Kia|Niro Hybrid 2022|SCC + LKAS|||||| +|Kia|Optima 2019|SCC + LKAS|||||| +|Kia|Seltos 2021|SCC + LKAS|||||| +|Kia|Sorento 2018|SCC + LKAS|||||| +|Kia|Sorento 2019|SCC + LKAS|||||| +|Kia|Stinger 2018|SCC + LKAS|||||| +|Lexus|NX 2018-19|All|[3](#footnotes)||||| +|Lexus|NX Hybrid 2018-19|All|[3](#footnotes)||||| +|Lexus|NX Hybrid 2020|All|||||| +|Lexus|RX Hybrid 2020-21|All|||||| +|Mazda|CX-5 2022|All|||||| +|SEAT|Ateca 2018|Driver Assistance|||||| +|SEAT|Leon 2014-20|Driver Assistance|||||| +|Subaru|Crosstrek 2020-21|EyeSight|||||| +|Subaru|Forester 2019-21|All|||||| +|Subaru|Impreza 2020-21|EyeSight|||||| +|Å koda|Kamiq 2021[5](#footnotes)|Driver Assistance|||||| +|Å koda|Karoq 2019|Driver Assistance|||||| +|Å koda|Kodiaq 2018-19|Driver Assistance|||||| +|Å koda|Octavia 2015, 2018-19|Driver Assistance|||||| +|Å koda|Octavia RS 2016|Driver Assistance|||||| +|Å koda|Scala 2020|Driver Assistance|||||| +|Å koda|Superb 2015-18|Driver Assistance|||||| +|Toyota|Alphard 2019-20|All|||||| +|Toyota|Alphard Hybrid 2021|All|||||| +|Toyota|Avalon 2019-21|TSS-P|[3](#footnotes)||||| +|Toyota|Avalon Hybrid 2022|All|||||| +|Toyota|Camry 2018-20|All||[4](#footnotes)|||| +|Toyota|Camry Hybrid 2018-20|All||[4](#footnotes)|||| +|Toyota|Highlander 2017-19|All|[3](#footnotes)||||| +|Toyota|Highlander Hybrid 2017-19|All|[3](#footnotes)||||| +|Toyota|Prius 2016-20|TSS-P|[3](#footnotes)||||| +|Toyota|Prius Prime 2017-20|All|[3](#footnotes)||||| +|Toyota|RAV4 2022|All|||||| +|Toyota|RAV4 Hybrid 2016-18|TSS-P|[3](#footnotes)||||| +|Toyota|RAV4 Hybrid 2022|All|||||| +|Toyota|Sienna 2018-20|All|[3](#footnotes)||||| +|Volkswagen|Atlas 2018-19, 2022[7](#footnotes)|Driver Assistance|||||| +|Volkswagen|e-Golf 2014, 2018-20|Driver Assistance|||||| +|Volkswagen|Golf 2015-20|Driver Assistance|||||| +|Volkswagen|Golf Alltrack 2017-18|Driver Assistance|||||| +|Volkswagen|Golf GTE 2016|Driver Assistance|||||| +|Volkswagen|Golf GTI 2018-21|Driver Assistance|||||| +|Volkswagen|Golf R 2016-19|Driver Assistance|||||| +|Volkswagen|Golf SportsVan 2016|Driver Assistance|||||| +|Volkswagen|Golf SportWagen 2015|Driver Assistance|||||| +|Volkswagen|Polo 2020|Driver Assistance|||||| +|Volkswagen|T-Cross 2021[7](#footnotes)|Driver Assistance|||||| +|Volkswagen|T-Roc 2021[7](#footnotes)|Driver Assistance|||||| +|Volkswagen|Taos 2022[7](#footnotes)|Driver Assistance|||||| +|Volkswagen|Touran 2017|Driver Assistance|||||| + +# Bronze - 69 cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| |---|---|---|:---:|:---:|:---:|:---:|:---:| -|Acura|ILX 2016-19|AcuraWatch Plus|||||| -|Acura|RDX 2016-18|AcuraWatch Plus|||||| -|Acura|RDX 2019-21|All|||||| -|Cadillac|Escalade ESV 2016[1](#footnotes)|ACC + LKAS|||||| -|Chevrolet|Volt 2017-18[1](#footnotes)|Adaptive Cruise|||||| -|Chrysler|Pacifica 2017-18|Adaptive Cruise|||||| -|Chrysler|Pacifica 2020|Adaptive Cruise|||||| -|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise|||||| -|Chrysler|Pacifica Hybrid 2019-21|Adaptive Cruise|||||| -|Genesis|G90 2018|All|||||| -|GMC|Acadia 2018[1](#footnotes)|Adaptive Cruise|||||| -|Honda|Accord 2018-21|All|||||| -|Honda|Accord Hybrid 2018-21|All|||||| -|Honda|Civic 2016-18|Honda Sensing|||||| -|Honda|Civic 2019-20|All|||[2](#footnotes)||| -|Honda|Civic Hatchback 2017-21|Honda Sensing|||||| -|Honda|CR-V 2015-16|Touring|||||| -|Honda|CR-V 2017-21|Honda Sensing|||||| -|Honda|CR-V Hybrid 2017-19|Honda Sensing|||||| -|Honda|e 2020|All|||||| -|Honda|Fit 2018-19|Honda Sensing|||||| -|Honda|Freed 2020|Honda Sensing|||||| -|Honda|HR-V 2019-20|Honda Sensing|||||| -|Honda|Insight 2019-21|All|||||| -|Honda|Inspire 2018|All|||||| -|Honda|Odyssey 2018-20|Honda Sensing|||||| -|Honda|Passport 2019-21|All|||||| -|Honda|Pilot 2016-21|Honda Sensing|||||| -|Honda|Ridgeline 2017-21|Honda Sensing|||||| -|Hyundai|Elantra 2017-19|SCC + LKAS|||||| -|Hyundai|Genesis 2015-16|SCC + LKAS|||||| -|Hyundai|Ioniq Electric 2019|SCC + LKAS|||||| -|Hyundai|Ioniq Hybrid 2017-19|SCC + LKAS|||||| -|Hyundai|Ioniq Plug-in Hybrid 2019|SCC + LKAS|||||| -|Hyundai|Veloster 2019-20|SCC + LKAS|||||| -|Jeep|Grand Cherokee 2016-18|Adaptive Cruise|||||| -|Jeep|Grand Cherokee 2019-20|Adaptive Cruise|||||| -|Kia|Niro Plug-in Hybrid 2019|SCC + LKAS|||||| -|Kia|Optima 2017|SCC + LKAS|||||| -|Lexus|IS 2017-19|All|||||| -|Lexus|RC 2020|All|||||| -|Mazda|CX-9 2021|All|||||| -|Nissan|Altima 2019-20|ProPILOT|||||| -|Nissan|Leaf 2018-22|ProPILOT|||||| -|Nissan|Rogue 2018-20|ProPILOT|||||| -|Nissan|X-Trail 2017|ProPILOT|||||| -|Subaru|Ascent 2019-20|EyeSight|||||| -|Subaru|Crosstrek 2020-21|EyeSight|||||| -|Subaru|Impreza 2020-21|EyeSight|||||| -|Toyota|Avalon 2016-18|TSS-P|[3](#footnotes)||||| -|Toyota|Corolla 2017-19|All|[3](#footnotes)||||| -|Toyota|Prius 2016-20|TSS-P|[3](#footnotes)|||[5](#footnotes)|| -|Toyota|Prius Prime 2017-20|All|[3](#footnotes)|||[5](#footnotes)|| -|Toyota|Prius v 2017|TSS-P|[3](#footnotes)|||[5](#footnotes)|| -|Toyota|RAV4 2016-18|TSS-P|[3](#footnotes)||||| -|Volkswagen|California 2021[8](#footnotes)|Driver Assistance|||||| -|Volkswagen|Caravelle 2020[8](#footnotes)|Driver Assistance|||||| +|Acura|ILX 2016-19|AcuraWatch Plus|||||| +|Acura|RDX 2016-18|AcuraWatch Plus|||||| +|Acura|RDX 2019-21|All|||||| +|Audi|Q3 2020-21|ACC + Lane Assist|||||| +|Cadillac|Escalade ESV 2016[1](#footnotes)|ACC + LKAS|||||| +|Chrysler|Pacifica 2017-18|Adaptive Cruise|||||| +|Chrysler|Pacifica 2020|Adaptive Cruise|||||| +|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise|||||| +|Chrysler|Pacifica Hybrid 2019-21|Adaptive Cruise|||||| +|Genesis|G90 2018|All|||||| +|GMC|Acadia 2018[1](#footnotes)|Adaptive Cruise|||||| +|Honda|Accord 2018-21|All|||||| +|Honda|Accord Hybrid 2018-21|All|||||| +|Honda|Civic 2016-18|Honda Sensing|||||| +|Honda|Civic 2019-20|All|||[2](#footnotes)||| +|Honda|Civic Hatchback 2017-21|Honda Sensing|||||| +|Honda|CR-V 2015-16|Touring|||||| +|Honda|CR-V 2017-21|Honda Sensing|||||| +|Honda|CR-V Hybrid 2017-19|Honda Sensing|||||| +|Honda|e 2020|All|||||| +|Honda|Fit 2018-19|Honda Sensing|||||| +|Honda|Freed 2020|Honda Sensing|||||| +|Honda|HR-V 2019-20|Honda Sensing|||||| +|Honda|Insight 2019-21|All|||||| +|Honda|Inspire 2018|All|||||| +|Honda|Odyssey 2018-20|Honda Sensing|||||| +|Honda|Passport 2019-21|All|||||| +|Honda|Pilot 2016-21|Honda Sensing|||||| +|Honda|Ridgeline 2017-22|Honda Sensing|||||| +|Hyundai|Elantra 2017-19|SCC + LKAS|||||| +|Hyundai|Genesis 2015-16|SCC + LKAS|||||| +|Hyundai|Ioniq Electric 2019|SCC + LKAS|||||| +|Hyundai|Ioniq Hybrid 2017-19|SCC + LKAS|||||| +|Hyundai|Ioniq Plug-in Hybrid 2019|SCC + LKAS|||||| +|Hyundai|Sonata 2018-19|SCC + LKAS|||||| +|Hyundai|Tucson 2021|SCC + LKAS|||||| +|Hyundai|Veloster 2019-20|SCC + LKAS|||||| +|Jeep|Grand Cherokee 2016-18|Adaptive Cruise|||||| +|Jeep|Grand Cherokee 2019-20|Adaptive Cruise|||||| +|Kia|Niro Plug-in Hybrid 2019|SCC + LKAS|||||| +|Kia|Optima 2017|SCC + LKAS|||||| +|Lexus|CT Hybrid 2017-18|LSS|[3](#footnotes)||||| +|Lexus|ES Hybrid 2017-18|LSS|[3](#footnotes)||||| +|Lexus|IS 2017-19|All|||||| +|Lexus|RC 2020|All|||||| +|Lexus|RX 2016-18|All|[3](#footnotes)||||| +|Lexus|RX Hybrid 2016-19|All|[3](#footnotes)||||| +|Mazda|CX-9 2021|All|||||| +|Nissan|Altima 2019-20|ProPILOT|||||| +|Nissan|Leaf 2018-22|ProPILOT|||||| +|Nissan|Rogue 2018-20|ProPILOT|||||| +|Nissan|X-Trail 2017|ProPILOT|||||| +|Subaru|Ascent 2019-20|All|||||| +|Subaru|Crosstrek 2018-19|EyeSight|||||| +|Subaru|Impreza 2017-19|EyeSight|||||| +|Toyota|Avalon 2016-18|TSS-P|[3](#footnotes)||||| +|Toyota|Avalon Hybrid 2019-21|TSS-P|[3](#footnotes)||||| +|Toyota|C-HR 2017-21|All|||||| +|Toyota|C-HR Hybrid 2017-19|All|||||| +|Toyota|Corolla 2017-19|All|[3](#footnotes)||||| +|Toyota|Prius v 2017|TSS-P|[3](#footnotes)||||| +|Toyota|RAV4 2016-18|TSS-P|[3](#footnotes)||||| +|Volkswagen|Arteon 2018, 2021[7](#footnotes)|Driver Assistance|||||| +|Volkswagen|California 2021[7](#footnotes)|Driver Assistance|||||| +|Volkswagen|Caravelle 2020[7](#footnotes)|Driver Assistance|||||| +|Volkswagen|Jetta 2018-21|Driver Assistance|||||| +|Volkswagen|Jetta GLI 2021|Driver Assistance|||||| +|Volkswagen|Passat 2015-19[6](#footnotes)|Driver Assistance|||||| +|Volkswagen|Tiguan 2019-22[7](#footnotes)|Driver Assistance|||||| @@ -220,10 +229,9 @@ How We Rate The Cars 22019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph.
    3When disconnecting the Driver Support Unit (DSU), openpilot Adaptive Cruise Control (ACC) will replace stock Adaptive Cruise Control (ACC). NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).
    428mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.
    -5An inaccurate steering wheel angle sensor makes precise control difficult.
    -6Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform.
    -7Not including the USA/China market Passat, which is based on the (currently) unsupported PQ35/NMS platform.
    -8Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma store. Before ordering, remove the Lane Assist camera cover and check to see if the connector is black (older design) or light brown (newer design). For the newer design, in the interim, choose "VW J533 Development" from the vehicle drop-down for a harness that integrates at the CAN gateway inside the dashboard.
    +5Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform.
    +6Not including the USA/China market Passat, which is based on the (currently) unsupported PQ35/NMS platform.
    +7Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma store. Before ordering, remove the Lane Assist camera cover and check to see if the connector is black (older design) or light brown (newer design). For the newer design, in the interim, choose "VW J533 Development" from the vehicle drop-down for a harness that integrates at the CAN gateway inside the dashboard.
    ## Community Maintained Cars Although they're not upstream, the community has openpilot running on other makes and models. See the 'Community Supported Models' section of each make [on our wiki](https://wiki.comma.ai/). \ No newline at end of file diff --git a/docs/c_docs.rst b/docs/c_docs.rst index 6cf5f268c5..218cd5a7d9 100644 --- a/docs/c_docs.rst +++ b/docs/c_docs.rst @@ -50,10 +50,6 @@ soundd .. autodoxygenindex:: :project: selfdrive_ui_soundd -navd -"""" -.. autodoxygenindex:: - :project: selfdrive_ui_navd replay """""" @@ -70,7 +66,7 @@ qt proclogd ^^^^^^^^ .. autodoxygenindex:: - :project: selfdrive_proclogd + :project: system_proclogd modeld ^^^^^^ @@ -86,7 +82,7 @@ modeld common ^^^^^^ .. autodoxygenindex:: - :project: selfdrive_common + :project: common sensorsd ^^^^^^^^ diff --git a/docs/conf.py b/docs/conf.py index c11d17455d..fea921de1f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,10 +14,12 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os -from os.path import exists import sys -from selfdrive.version import get_version +from os.path import exists + from common.basedir import BASEDIR +from system.version import get_version + sys.path.insert(0, os.path.abspath('.')) sys.path.insert(0, os.path.abspath('..')) diff --git a/docs/docker/Dockerfile b/docs/docker/Dockerfile index 124feb1bfc..cefe9be855 100644 --- a/docs/docker/Dockerfile +++ b/docs/docker/Dockerfile @@ -30,6 +30,7 @@ COPY ./opendbc ${OPENPILOT_PATH}/opendbc COPY ./cereal ${OPENPILOT_PATH}/cereal COPY ./panda ${OPENPILOT_PATH}/panda COPY ./selfdrive ${OPENPILOT_PATH}/selfdrive +COPY ./system ${OPENPILOT_PATH}/system COPY ./*.md ${OPENPILOT_PATH}/ RUN scons -j$(nproc) diff --git a/laika_repo b/laika_repo index 226adc655e..44f048bc1f 160000 --- a/laika_repo +++ b/laika_repo @@ -1 +1 @@ -Subproject commit 226adc655e1488474468a97ab4a7705aad7e5837 +Subproject commit 44f048bc1f58ae9e28dfdeb98e40aea3e0f2b699 diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index 503ebb5d41..911774a4eb 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -8,7 +8,7 @@ source "$BASEDIR/launch_env.sh" DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -function tici_init { +function agnos_init { # wait longer for weston to come up if [ -f "$BASEDIR/prebuilt" ]; then sleep 3 @@ -22,12 +22,12 @@ function tici_init { # Check if AGNOS update is required if [ $(< /VERSION) != "$AGNOS_VERSION" ]; then - AGNOS_PY="$DIR/selfdrive/hardware/tici/agnos.py" - MANIFEST="$DIR/selfdrive/hardware/tici/agnos.json" + AGNOS_PY="$DIR/system/hardware/tici/agnos.py" + MANIFEST="$DIR/system/hardware/tici/agnos.json" if $AGNOS_PY --verify $MANIFEST; then sudo reboot fi - $DIR/selfdrive/hardware/tici/updater $AGNOS_PY $MANIFEST + $DIR/system/hardware/tici/updater $AGNOS_PY $MANIFEST fi } @@ -77,9 +77,7 @@ function launch { export PYTHONPATH="$PWD:$PWD/pyextra" # hardware specific init - if [ -f /TICI ]; then - tici_init - fi + agnos_init # write tmux scrollback to a file tmux capture-pane -pq -S-1000 > /tmp/launch_log diff --git a/launch_env.sh b/launch_env.sh index d4b57c909a..769613bc79 100755 --- a/launch_env.sh +++ b/launch_env.sh @@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1 export VECLIB_MAXIMUM_THREADS=1 if [ -z "$AGNOS_VERSION" ]; then - export AGNOS_VERSION="4" + export AGNOS_VERSION="5.1" fi if [ -z "$PASSIVE" ]; then diff --git a/models/README.md b/models/README.md deleted file mode 100644 index a0cdd7967e..0000000000 --- a/models/README.md +++ /dev/null @@ -1,115 +0,0 @@ -## Neural networks in openpilot -To view the architecture of the ONNX networks, you can use [netron](https://netron.app/) - -## Supercombo -### Supercombo input format (Full size: 393738 x float32) -* **image stream** - * Two consecutive images (256 * 512 * 3 in RGB) recorded at 20 Hz : 393216 = 2 * 6 * 128 * 256 - * Each 256 * 512 image is represented in YUV420 with 6 channels : 6 * 128 * 256 - * Channels 0,1,2,3 represent the full-res Y channel and are represented in numpy as Y[::2, ::2], Y[::2, 1::2], Y[1::2, ::2], and Y[1::2, 1::2] - * Channel 4 represents the half-res U channel - * Channel 5 represents the half-res V channel -* **wide image stream** - * Two consecutive images (256 * 512 * 3 in RGB) recorded at 20 Hz : 393216 = 2 * 6 * 128 * 256 - * Each 256 * 512 image is represented in YUV420 with 6 channels : 6 * 128 * 256 - * Channels 0,1,2,3 represent the full-res Y channel and are represented in numpy as Y[::2, ::2], Y[::2, 1::2], Y[1::2, ::2], and Y[1::2, 1::2] - * Channel 4 represents the half-res U channel - * Channel 5 represents the half-res V channel -* **desire** - * one-hot encoded vector to command model to execute certain actions, bit only needs to be sent for 1 frame : 8 -* **traffic convention** - * one-hot encoded vector to tell model whether traffic is right-hand or left-hand traffic : 2 -* **recurrent state** - * The recurrent state vector that is fed back into the GRU for temporal context : 512 - - -### Supercombo output format (Full size: 6472 x float32) -* **plan** - * 5 potential desired plan predictions : 4955 = 5 * 991 - * predicted mean and standard deviation of the following values at 33 timesteps : 990 = 2 * 33 * 15 - * x,y,z position in current frame (meters) - * x,y,z velocity in local frame (meters/s) - * x,y,z acceleration local frame (meters/(s*s)) - * roll, pitch , yaw in current frame (radians) - * roll, pitch , yaw rates in local frame (radians/s) - * probability[^1] of this plan hypothesis being the most likely: 1 -* **lanelines** - * 4 lanelines (outer left, left, right, and outer right): 528 = 4 * 132 - * predicted mean and standard deviation for the following values at 33 x positions : 132 = 2 * 33 * 2 - * y position in current frame (meters) - * z position in current frame (meters) -* **laneline probabilties** - * 2 probabilities[^1] that each of the 4 lanelines exists : 8 = 4 * 2 - * deprecated probability - * used probability -* **road-edges** - * 2 road-edges (left and right): 264 = 2 * 132 - * predicted mean and standard deviation for the following values at 33 x positions : 132 = 2 * 33 * 2 - * y position in current frame (meters) - * z position in current frame (meters) -* **leads** - * 2 hypotheses for potential lead cars : 102 = 2 * 51 - * predicted mean and stadard deviation for the following values at 0,2,4,6,8,10s : 48 = 2 * 6 * 4 - * x position of lead in current frame (meters) - * y position of lead in current frame (meters) - * speed of lead (meters/s) - * acceleration of lead(meters/(s*s)) - * probabilities[^1] this hypothesis is the most likely hypothesis at 0s, 2s or 4s from now : 3 -* **lead probabilities** - * probability[^1] that there is a lead car at 0s, 2s, 4s from now : 3 = 1 * 3 -* **desire state** - * probability[^1] that the model thinks it is executing each of the 8 potential desire actions : 8 -* **meta** [^2] - * Various metadata about the scene : 80 = 1 + 35 + 12 + 32 - * Probability[^1] that openpilot is engaged : 1 - * Probabilities[^1] of various things happening between now and 2,4,6,8,10s : 35 = 5 * 7 - * Disengage of openpilot with gas pedal - * Disengage of openpilot with brake pedal - * Override of openpilot steering - * 3m/(s*s) of deceleration - * 4m/(s*s) of deceleration - * 5m/(s*s) of deceleration - * Probabilities[^1] of left or right blinker being active at 0,2,4,6,8,10s : 12 = 6 * 2 - * Probabilities[^1] that each of the 8 desires is being executed at 0,2,4,6s : 32 = 4 * 8 - -* **pose** [^2] - * predicted mean and standard deviation of current translation and rotation rates : 12 = 2 * 6 - * x,y,z velocity in current frame (meters/s) - * roll, pitch , yaw rates in current frame (radians/s) -* **recurrent state** - * The recurrent state vector that is fed back into the GRU for temporal context : 512 - -[^1]: All probabilities are in logits, so you need to apply sigmoid or softmax functions to get actual probabilities -[^2]: These outputs come directly from the vision blocks, they do not have access to temporal state or the desire input - - -## Driver Monitoring Model -* .onnx model can be run with onnx runtimes -* .dlc file is a pre-quantized model and only runs on qualcomm DSPs - -### input format -* single image (640 * 320 * 3 in RGB): - * full input size is 6 * 640/2 * 320/2 = 307200 - * represented in YUV420 with 6 channels: - * Channels 0,1,2,3 represent the full-res Y channel and are represented in numpy as Y[::2, ::2], Y[::2, 1::2], Y[1::2, ::2], and Y[1::2, 1::2] - * Channel 4 represents the half-res U channel - * Channel 5 represents the half-res V channel - * normalized, ranging from -1.0 to 1.0 - -### output format -* 39 x float32 outputs ([parsing example](https://github.com/commaai/openpilot/blob/master/selfdrive/modeld/models/dmonitoring.cc#L165)) - * face pose: 12 = 6 + 6 - * face orientation [pitch, yaw, roll] in camera frame: 3 - * face position [dx, dy] relative to image center: 2 - * normalized face size: 1 - * standard deviations for above outputs: 6 - * face visible probability: 1 - * eyes: 20 = (8 + 1) + (8 + 1) + 1 + 1 - * eye position and size, and their standard deviations: 8 - * eye visible probability: 1 - * eye closed probability: 1 - * wearing sunglasses probability: 1 - * poor camera vision probability: 1 - * face partially out-of-frame probability: 1 - * (deprecated) distracted probabilities: 2 - * face covered probability: 1 diff --git a/models/supercombo.dlc b/models/supercombo.dlc deleted file mode 100644 index a27e3d1180..0000000000 --- a/models/supercombo.dlc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ba3fe3e61853cc1434e3e220f40c8e9d1f1b9bab8458196ba3bea6a10b82c6ed -size 72718099 diff --git a/models/supercombo.onnx b/models/supercombo.onnx deleted file mode 100644 index 3039035fbc..0000000000 --- a/models/supercombo.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bda57c1a66944f5a633ecd739a24d62702c717a234f2fdcc499dfa1d61c3c19e -size 73147489 diff --git a/mypy.ini b/mypy.ini index 66b82bd5df..e2da60f926 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,4 +1,4 @@ [mypy] python_version = 3.8 ignore_missing_imports = True - +plugins = numpy.typing.mypy_plugin diff --git a/opendbc b/opendbc index e19ba095c3..a7b391cce8 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit e19ba095c3ee288d629284e24ec7e0deaf645f3f +Subproject commit a7b391cce88908824f1417f0c7abd35e3ae16f96 diff --git a/panda b/panda index 7b5af92eda..391b83d0a7 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 7b5af92edaeeaaacabc713e7aee456aeb553e590 +Subproject commit 391b83d0a73e957e84383a9e04c1cad140ecada2 diff --git a/release/build_devel.sh b/release/build_devel.sh index db8c69bd7a..9d8b06451b 100755 --- a/release/build_devel.sh +++ b/release/build_devel.sh @@ -1,25 +1,30 @@ -#!/usr/bin/bash -e +#!/usr/bin/bash + +set -ex DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" -TARGET_DIR=/data/openpilot -SOURCE_DIR="$(git rev-parse --show-toplevel)" +SOURCE_DIR="$(git -C $DIR rev-parse --show-toplevel)" +if [ -z "$TARGET_DIR" ]; then + TARGET_DIR="$(mktemp -d)" +fi # set git identity source $DIR/identity.sh echo "[-] Setting up repo T=$SECONDS" -if [ ! -d "$TARGET_DIR" ]; then - mkdir -p $TARGET_DIR - cd $TARGET_DIR - git init - git remote add origin git@github.com:commaai/openpilot.git -fi + +cd $SOURCE_DIR +git fetch origin + +rm -rf $TARGET_DIR +mkdir -p $TARGET_DIR +cd $TARGET_DIR +cp -r $SOURCE_DIR/.git $TARGET_DIR +pre-commit uninstall || true echo "[-] bringing master-ci and devel in sync T=$SECONDS" cd $TARGET_DIR -git prune || true -git remote prune origin || true git fetch origin master-ci git fetch origin devel @@ -28,6 +33,7 @@ git reset --hard master-ci git checkout master-ci git reset --hard origin/devel git clean -xdf +git lfs uninstall # remove everything except .git echo "[-] erasing old openpilot T=$SECONDS" @@ -40,31 +46,32 @@ git clean -xdf # do the files copy echo "[-] copying files T=$SECONDS" cd $SOURCE_DIR -cp -pR --parents $(cat release/files_common) $TARGET_DIR/ -cp -pR --parents $(cat release/files_tici) $TARGET_DIR/ +cp -pR --parents $(cat release/files_*) $TARGET_DIR/ if [ ! -z "$EXTRA_FILES" ]; then cp -pR --parents $EXTRA_FILES $TARGET_DIR/ fi -# append source commit hash and build date to version -GIT_HASH=$(git --git-dir=$SOURCE_DIR/.git rev-parse --short HEAD) -DATETIME=$(date '+%Y-%m-%dT%H:%M:%S') -VERSION=$(cat selfdrive/common/version.h | awk -F\" '{print $2}') -echo "#define COMMA_VERSION \"$VERSION-$GIT_HASH-$DATETIME\"" > selfdrive/common/version.h - # in the directory cd $TARGET_DIR rm -f panda/board/obj/panda.bin.signed +# include source commit hash and build date in commit +GIT_HASH=$(git --git-dir=$SOURCE_DIR/.git rev-parse HEAD) +DATETIME=$(date '+%Y-%m-%dT%H:%M:%S') +VERSION=$(cat $SOURCE_DIR/common/version.h | awk -F\" '{print $2}') + echo "[-] committing version $VERSION T=$SECONDS" git add -f . git status -git commit -a -m "openpilot v$VERSION release" +git commit -a -m "openpilot v$VERSION release + +date: $DATETIME +master commit: $GIT_HASH +" -if [ ! -z "$PUSH" ]; then - echo "[-] Pushing to $PUSH T=$SECONDS" - git remote set-url origin git@github.com:commaai/openpilot.git - git push -f origin master-ci:$PUSH +if [ ! -z "$BRANCH" ]; then + echo "[-] Pushing to $BRANCH T=$SECONDS" + git push -f origin master-ci:$BRANCH fi -echo "[-] done T=$SECONDS" +echo "[-] done T=$SECONDS, ready at $TARGET_DIR" diff --git a/release/build_release.sh b/release/build_release.sh index 79ab4fb087..b5e15e05c6 100755 --- a/release/build_release.sh +++ b/release/build_release.sh @@ -19,6 +19,7 @@ fi # set git identity source $DIR/identity.sh +export GIT_SSH_COMMAND="ssh -i /data/gitkey" echo "[-] Setting up repo T=$SECONDS" rm -rf $BUILD_DIR @@ -40,8 +41,8 @@ cd $BUILD_DIR rm -f panda/board/obj/panda.bin.signed -VERSION=$(cat selfdrive/common/version.h | awk -F[\"-] '{print $2}') -echo "#define COMMA_VERSION \"$VERSION-release\"" > selfdrive/common/version.h +VERSION=$(cat common/version.h | awk -F[\"-] '{print $2}') +echo "#define COMMA_VERSION \"$VERSION-release\"" > common/version.h echo "[-] committing version $VERSION T=$SECONDS" git add -f . @@ -75,7 +76,7 @@ find . -name 'moc_*' -delete find . -name '__pycache__' -delete rm -rf panda/board panda/certs panda/crypto rm -rf .sconsign.dblite Jenkinsfile release/ -rm models/supercombo.dlc +rm selfdrive/modeld/models/supercombo.dlc # Move back signed panda fw mkdir -p panda/board/obj diff --git a/release/files_common b/release/files_common index 1592fcf8ad..b6cd4fa797 100644 --- a/release/files_common +++ b/release/files_common @@ -26,10 +26,8 @@ common/ffi_wrapper.py common/file_helpers.py common/logging_extra.py common/numpy_fast.py -common/markdown.py common/params.py common/params_pyx.pyx -common/xattr.py common/profiler.py common/basedir.py common/dict_helpers.py @@ -58,25 +56,22 @@ common/transformations/transformations.pyx common/api/__init__.py -models/supercombo.dlc -models/dmonitoring_model_q.dlc - release/* tools/lib/* tools/joystick/* -selfdrive/version.py - selfdrive/__init__.py selfdrive/sentry.py -selfdrive/swaglog.py -selfdrive/logmessaged.py selfdrive/tombstoned.py selfdrive/updated.py selfdrive/rtshield.py selfdrive/statsd.py +system/logmessaged.py +system/swaglog.py +system/version.py + selfdrive/athena/__init__.py selfdrive/athena/athenad.py selfdrive/athena/manage_athenad.py @@ -109,121 +104,53 @@ selfdrive/car/fw_versions.py selfdrive/car/isotp_parallel_query.py selfdrive/car/tests/__init__.py selfdrive/car/tests/test_car_interfaces.py -selfdrive/car/chrysler/__init__.py -selfdrive/car/chrysler/carstate.py -selfdrive/car/chrysler/interface.py -selfdrive/car/chrysler/radar_interface.py -selfdrive/car/chrysler/values.py -selfdrive/car/chrysler/carcontroller.py -selfdrive/car/chrysler/chryslercan.py -selfdrive/car/honda/__init__.py -selfdrive/car/honda/carstate.py -selfdrive/car/honda/interface.py -selfdrive/car/honda/radar_interface.py -selfdrive/car/honda/values.py -selfdrive/car/honda/carcontroller.py -selfdrive/car/honda/hondacan.py -selfdrive/car/hyundai/__init__.py -selfdrive/car/hyundai/carstate.py -selfdrive/car/hyundai/interface.py -selfdrive/car/hyundai/radar_interface.py -selfdrive/car/hyundai/values.py -selfdrive/car/hyundai/carcontroller.py -selfdrive/car/hyundai/hyundaican.py -selfdrive/car/toyota/__init__.py -selfdrive/car/toyota/carstate.py -selfdrive/car/toyota/tunes.py -selfdrive/car/toyota/interface.py -selfdrive/car/toyota/radar_interface.py -selfdrive/car/toyota/values.py -selfdrive/car/toyota/carcontroller.py -selfdrive/car/toyota/toyotacan.py -selfdrive/car/nissan/__init__.py -selfdrive/car/nissan/carcontroller.py -selfdrive/car/nissan/carstate.py -selfdrive/car/nissan/interface.py -selfdrive/car/nissan/nissancan.py -selfdrive/car/nissan/radar_interface.py -selfdrive/car/nissan/values.py -selfdrive/car/volkswagen/__init__.py -selfdrive/car/volkswagen/carstate.py -selfdrive/car/volkswagen/interface.py -selfdrive/car/volkswagen/radar_interface.py -selfdrive/car/volkswagen/values.py -selfdrive/car/volkswagen/carcontroller.py -selfdrive/car/volkswagen/volkswagencan.py -selfdrive/car/gm/__init__.py -selfdrive/car/gm/carstate.py -selfdrive/car/gm/interface.py -selfdrive/car/gm/radar_interface.py -selfdrive/car/gm/values.py -selfdrive/car/gm/carcontroller.py -selfdrive/car/gm/gmcan.py -selfdrive/car/ford/__init__.py -selfdrive/car/ford/carstate.py -selfdrive/car/ford/interface.py -selfdrive/car/ford/radar_interface.py -selfdrive/car/ford/values.py -selfdrive/car/ford/carcontroller.py -selfdrive/car/ford/fordcan.py -selfdrive/car/subaru/__init__.py -selfdrive/car/subaru/carstate.py -selfdrive/car/subaru/interface.py -selfdrive/car/subaru/radar_interface.py -selfdrive/car/subaru/values.py -selfdrive/car/subaru/carcontroller.py -selfdrive/car/subaru/subarucan.py -selfdrive/car/mazda/__init__.py -selfdrive/car/mazda/carstate.py -selfdrive/car/mazda/interface.py -selfdrive/car/mazda/radar_interface.py -selfdrive/car/mazda/values.py -selfdrive/car/mazda/carcontroller.py -selfdrive/car/mazda/mazdacan.py -selfdrive/car/tesla/__init__.py -selfdrive/car/tesla/teslacan.py -selfdrive/car/tesla/carcontroller.py -selfdrive/car/tesla/radar_interface.py -selfdrive/car/tesla/values.py -selfdrive/car/tesla/carstate.py -selfdrive/car/tesla/interface.py +selfdrive/car/torque_data.json + +selfdrive/car/body/*.py +selfdrive/car/chrysler/*.py +selfdrive/car/ford/*.py +selfdrive/car/gm/*.py +selfdrive/car/honda/*.py +selfdrive/car/hyundai/*.py +selfdrive/car/mazda/*.py selfdrive/car/mock/*.py +selfdrive/car/nissan/*.py +selfdrive/car/subaru/*.py +selfdrive/car/tesla/*.py +selfdrive/car/toyota/*.py +selfdrive/car/volkswagen/*.py -selfdrive/clocksd/.gitignore -selfdrive/clocksd/SConscript -selfdrive/clocksd/clocksd.cc +system/clocksd/.gitignore +system/clocksd/SConscript +system/clocksd/clocksd.cc selfdrive/debug/*.py -selfdrive/common/SConscript -selfdrive/common/version.h - -selfdrive/common/swaglog.h -selfdrive/common/swaglog.cc -selfdrive/common/statlog.h -selfdrive/common/statlog.cc -selfdrive/common/util.cc -selfdrive/common/util.h -selfdrive/common/queue.h -selfdrive/common/clutil.cc -selfdrive/common/clutil.h -selfdrive/common/params.h -selfdrive/common/params.cc -selfdrive/common/watchdog.cc -selfdrive/common/watchdog.h - -selfdrive/common/modeldata.h -selfdrive/common/mat.h -selfdrive/common/timing.h - -selfdrive/common/visionimg.cc -selfdrive/common/visionimg.h - -selfdrive/common/gpio.cc -selfdrive/common/gpio.h -selfdrive/common/i2c.cc -selfdrive/common/i2c.h - +common/SConscript +common/version.h + +common/swaglog.h +common/swaglog.cc +common/statlog.h +common/statlog.cc +common/util.cc +common/util.h +common/queue.h +common/clutil.cc +common/clutil.h +common/params.h +common/params.cc +common/watchdog.cc +common/watchdog.h + +common/modeldata.h +common/mat.h +common/timing.h + +common/gpio.cc +common/gpio.h +common/i2c.cc +common/i2c.h selfdrive/controls/__init__.py selfdrive/controls/controlsd.py @@ -255,16 +182,21 @@ selfdrive/controls/lib/longitudinal_mpc_lib/.gitignore selfdrive/controls/lib/lateral_mpc_lib/* selfdrive/controls/lib/longitudinal_mpc_lib/* -selfdrive/hardware/__init__.py -selfdrive/hardware/base.h -selfdrive/hardware/base.py -selfdrive/hardware/hw.h -selfdrive/hardware/tici/__init__.py -selfdrive/hardware/tici/hardware.py -selfdrive/hardware/tici/amplifier.py -selfdrive/hardware/tici/iwlist.py -selfdrive/hardware/pc/__init__.py -selfdrive/hardware/pc/hardware.py +system/hardware/__init__.py +system/hardware/base.h +system/hardware/base.py +system/hardware/hw.h +system/hardware/tici/__init__.py +system/hardware/tici/hardware.h +system/hardware/tici/hardware.py +system/hardware/tici/pins.py +system/hardware/tici/agnos.py +system/hardware/tici/agnos.json +system/hardware/tici/amplifier.py +system/hardware/tici/updater +system/hardware/tici/iwlist.py +system/hardware/pc/__init__.py +system/hardware/pc/hardware.py selfdrive/locationd/__init__.py selfdrive/locationd/.gitignore @@ -277,41 +209,46 @@ selfdrive/locationd/generated/ubx.h selfdrive/locationd/generated/gps.cpp selfdrive/locationd/generated/gps.h +selfdrive/locationd/laikad.py +selfdrive/locationd/laikad_helpers.py +selfdrive/locationd/locationd.cc selfdrive/locationd/locationd.h selfdrive/locationd/locationd.cc selfdrive/locationd/paramsd.py selfdrive/locationd/models/.gitignore -selfdrive/locationd/models/live_kf.py selfdrive/locationd/models/car_kf.py -selfdrive/locationd/models/constants.py +selfdrive/locationd/models/gnss_kf.py +selfdrive/locationd/models/live_kf.py selfdrive/locationd/models/live_kf.h selfdrive/locationd/models/live_kf.cc +selfdrive/locationd/models/constants.py +selfdrive/locationd/models/gnss_helpers.py selfdrive/locationd/calibrationd.py -selfdrive/logcatd/SConscript -selfdrive/logcatd/logcatd_systemd.cc +system/logcatd/SConscript +system/logcatd/logcatd_systemd.cc -selfdrive/proclogd/SConscript -selfdrive/proclogd/main.cc -selfdrive/proclogd/proclog.cc -selfdrive/proclogd/proclog.h +system/proclogd/SConscript +system/proclogd/main.cc +system/proclogd/proclog.cc +system/proclogd/proclog.h selfdrive/loggerd/SConscript -selfdrive/loggerd/encoder.h -selfdrive/loggerd/omx_encoder.cc -selfdrive/loggerd/omx_encoder.h +selfdrive/loggerd/encoder/encoder.cc +selfdrive/loggerd/encoder/encoder.h +selfdrive/loggerd/encoder/v4l_encoder.cc +selfdrive/loggerd/encoder/v4l_encoder.h selfdrive/loggerd/video_writer.cc selfdrive/loggerd/video_writer.h selfdrive/loggerd/logger.cc selfdrive/loggerd/logger.h selfdrive/loggerd/loggerd.cc selfdrive/loggerd/loggerd.h -selfdrive/loggerd/main.cc +selfdrive/loggerd/encoderd.cc selfdrive/loggerd/bootlog.cc -selfdrive/loggerd/raw_logger.cc -selfdrive/loggerd/raw_logger.h -selfdrive/loggerd/include/msm_media_info.h +selfdrive/loggerd/encoder/ffmpeg_encoder.cc +selfdrive/loggerd/encoder/ffmpeg_encoder.h selfdrive/loggerd/__init__.py selfdrive/loggerd/config.py @@ -358,6 +295,9 @@ selfdrive/ui/qt/widgets/*.h selfdrive/ui/replay/*.cc selfdrive/ui/replay/*.h +selfdrive/ui/qt/maps/*.cc +selfdrive/ui/qt/maps/*.h + selfdrive/camerad/SConscript selfdrive/camerad/main.cc @@ -365,9 +305,6 @@ selfdrive/camerad/snapshot/* selfdrive/camerad/include/* selfdrive/camerad/cameras/camera_common.h selfdrive/camerad/cameras/camera_common.cc -selfdrive/camerad/cameras/camera_replay.cc -selfdrive/camerad/cameras/camera_replay.h -selfdrive/camerad/cameras/sensor_i2c.h selfdrive/camerad/cameras/sensor2_i2c.h selfdrive/camerad/transforms/rgb_to_yuv.cc @@ -402,6 +339,8 @@ selfdrive/modeld/models/driving.cc selfdrive/modeld/models/driving.h selfdrive/modeld/models/dmonitoring.cc selfdrive/modeld/models/dmonitoring.h +selfdrive/modeld/models/supercombo.dlc +selfdrive/modeld/models/dmonitoring_model_q.dlc selfdrive/modeld/transforms/loadyuv.cc selfdrive/modeld/transforms/loadyuv.h @@ -428,6 +367,8 @@ selfdrive/modeld/runners/run.h selfdrive/monitoring/dmonitoringd.py selfdrive/monitoring/driver_monitor.py +selfdrive/navd/*.py + selfdrive/assets/.gitignore selfdrive/assets/assets.qrc selfdrive/assets/*.png @@ -444,7 +385,6 @@ third_party/SConscript third_party/linux/** third_party/opencl/** -third_party/openmax/** third_party/json11/json11.cpp third_party/json11/json11.hpp @@ -522,17 +462,14 @@ opendbc/can/common.h opendbc/can/common.pxd opendbc/can/common_dbc.h opendbc/can/dbc.cc -opendbc/can/dbc.py -opendbc/can/dbc_template.cc opendbc/can/packer.cc opendbc/can/packer.py opendbc/can/packer_pyx.pyx opendbc/can/parser.cc opendbc/can/parser.py opendbc/can/parser_pyx.pyx -opendbc/can/process_dbc.py -opendbc/can/dbc_out/.gitkeep -opendbc/can/dbc_out/.gitignore + +opendbc/comma_body.dbc opendbc/chrysler_pacifica_2017_hybrid.dbc opendbc/chrysler_pacifica_2017_hybrid_private_fusion.dbc @@ -541,7 +478,6 @@ opendbc/gm_global_a_powertrain_generated.dbc opendbc/gm_global_a_object.dbc opendbc/gm_global_a_chassis.dbc -opendbc/ford_fusion_2018_adas.dbc opendbc/ford_lincoln_base_pt.dbc opendbc/honda_accord_2018_can_generated.dbc @@ -560,6 +496,7 @@ opendbc/honda_odyssey_extreme_edition_2018_china_can_generated.dbc opendbc/honda_insight_ex_2019_can_generated.dbc opendbc/acura_ilx_2016_nidec.dbc +opendbc/kia_ev6.dbc opendbc/hyundai_kia_generic.dbc opendbc/hyundai_kia_mando_front_radar.dbc diff --git a/release/files_pc b/release/files_pc index d00de7e475..01ecae4327 100644 --- a/release/files_pc +++ b/release/files_pc @@ -1,5 +1,7 @@ -selfdrive/ui/replay/* +selfdrive/modeld/runners/onnx* -third_party/mapbox-gl-native-qt/x86_64/** +third_party/mapbox-gl-native-qt/x86_64/*.so -third_party/qt-plugins/x86_64/** +third_party/libyuv/x64/** +third_party/snpe/x86_64/** +third_party/snpe/x86_64-linux-clang/** diff --git a/release/files_tici b/release/files_tici index 68e075c971..485a898799 100644 --- a/release/files_tici +++ b/release/files_tici @@ -2,7 +2,7 @@ third_party/snpe/larch64** third_party/snpe/aarch64-ubuntu-gcc7.5/* third_party/mapbox-gl-native-qt/include/* -selfdrive/timezoned.py +system/timezoned.py selfdrive/assets/navigation/* selfdrive/assets/training_wide/* @@ -11,22 +11,5 @@ selfdrive/camerad/cameras/camera_qcom2.cc selfdrive/camerad/cameras/camera_qcom2.h selfdrive/camerad/cameras/real_debayer.cl -selfdrive/hardware/tici/__init__.py -selfdrive/hardware/tici/hardware.h -selfdrive/hardware/tici/hardware.py -selfdrive/hardware/tici/pins.py -selfdrive/hardware/tici/agnos.py -selfdrive/hardware/tici/agnos.json -selfdrive/hardware/tici/amplifier.py -selfdrive/hardware/tici/updater - selfdrive/ui/qt/spinner_larch64 selfdrive/ui/qt/text_larch64 -selfdrive/ui/qt/maps/*.cc -selfdrive/ui/qt/maps/*.h - -selfdrive/ui/navd/*.cc -selfdrive/ui/navd/*.h -selfdrive/ui/navd/navd -selfdrive/ui/navd/.gitignore - diff --git a/release/identity.sh b/release/identity.sh index b90372d825..c699c94650 100644 --- a/release/identity.sh +++ b/release/identity.sh @@ -2,4 +2,3 @@ export GIT_COMMITTER_NAME="Vehicle Researcher" export GIT_COMMITTER_EMAIL="user@comma.ai" export GIT_AUTHOR_NAME="Vehicle Researcher" export GIT_AUTHOR_EMAIL="user@comma.ai" -export GIT_SSH_COMMAND="ssh -i /data/gitkey" diff --git a/scripts/cell.sh b/scripts/cell.sh new file mode 100755 index 0000000000..cae701eccc --- /dev/null +++ b/scripts/cell.sh @@ -0,0 +1,5 @@ +#!/usr/bin/bash + +nmcli connection modify --temporary lte ipv4.route-metric 1 +nmcli connection modify --temporary lte ipv6.route-metric 1 +nmcli con up lte diff --git a/scripts/clwaste b/scripts/clwaste deleted file mode 100755 index 51770f0e37..0000000000 Binary files a/scripts/clwaste and /dev/null differ diff --git a/scripts/count_cars.py b/scripts/count_cars.py index 46d8499461..25bad2c9b4 100755 --- a/scripts/count_cars.py +++ b/scripts/count_cars.py @@ -2,12 +2,10 @@ from collections import Counter from pprint import pprint -from selfdrive.car.docs import get_tier_car_info +from selfdrive.car.docs import get_all_car_info if __name__ == "__main__": - tiers = get_tier_car_info() - cars = [car for tier_cars in tiers.values() for car in tier_cars] - + cars = get_all_car_info() make_count = Counter(l.make for l in cars) print("\n", "*" * 20, len(cars), "total", "*" * 20, "\n") pprint(make_count) diff --git a/scripts/disable-powersave.py b/scripts/disable-powersave.py index f651bc87f1..93688504f3 100755 --- a/scripts/disable-powersave.py +++ b/scripts/disable-powersave.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -from selfdrive.hardware import HARDWARE +from system.hardware import HARDWARE if __name__ == "__main__": HARDWARE.set_power_save(False) diff --git a/scripts/restart_modem.sh b/scripts/restart_modem.sh deleted file mode 100755 index fac54b32ff..0000000000 --- a/scripts/restart_modem.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/bash -echo "restart" > /sys/kernel/debug/msm_subsys/modem diff --git a/scripts/throttling.sh b/scripts/throttling.sh deleted file mode 100755 index d100c5f5ab..0000000000 --- a/scripts/throttling.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/data/data/com.termux/files/usr/bin/bash -watch -n1 ' - cat /sys/kernel/debug/clk/pwrcl_clk/measure - cat /sys/kernel/debug/clk/perfcl_clk/measure - cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq - cat /sys/class/kgsl/kgsl-3d0/gpuclk - echo - echo -n "CPU0 " ; cat /sys/devices/virtual/thermal/thermal_zone5/temp - echo -n "CPU1 " ; cat /sys/devices/virtual/thermal/thermal_zone7/temp - echo -n "CPU2 " ; cat /sys/devices/virtual/thermal/thermal_zone10/temp - echo -n "CPU3 " ; cat /sys/devices/virtual/thermal/thermal_zone12/temp - echo -n "MEM " ; cat /sys/devices/virtual/thermal/thermal_zone2/temp - echo -n "GPU " ; cat /sys/devices/virtual/thermal/thermal_zone16/temp - echo -n "BAT " ; cat /sys/devices/virtual/thermal/thermal_zone29/temp -' - diff --git a/scripts/waste b/scripts/waste deleted file mode 100755 index e3154ab01f..0000000000 Binary files a/scripts/waste and /dev/null differ diff --git a/scripts/waste.c b/scripts/waste.c index 62233b7fc4..2e492916a7 100644 --- a/scripts/waste.c +++ b/scripts/waste.c @@ -11,7 +11,7 @@ #include #include #include -#include "../selfdrive/common/timing.h" +#include "../common/timing.h" int get_nprocs(void); double *ttime, *oout; diff --git a/scripts/waste.py b/scripts/waste.py index f2820ea670..d3c96bf198 100755 --- a/scripts/waste.py +++ b/scripts/waste.py @@ -6,7 +6,7 @@ from multiprocessing import Process from setproctitle import setproctitle # pylint: disable=no-name-in-module def waste(core): - os.sched_setaffinity(0, [core,]) + os.sched_setaffinity(0, [core,]) # pylint: disable=no-member m1 = np.zeros((200, 200)) + 0.8 m2 = np.zeros((200, 200)) + 1.2 diff --git a/selfdrive/athena/athenad.py b/selfdrive/athena/athenad.py index 919cf0c04e..26220dfa99 100755 --- a/selfdrive/athena/athenad.py +++ b/selfdrive/athena/athenad.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 import base64 +import bz2 import hashlib import io import json @@ -30,13 +31,13 @@ from common.api import Api from common.basedir import PERSIST from common.file_helpers import CallbackReader from common.params import Params -from common.realtime import sec_since_boot -from selfdrive.hardware import HARDWARE, PC, TICI +from common.realtime import sec_since_boot, set_core_affinity +from system.hardware import HARDWARE, PC, AGNOS from selfdrive.loggerd.config import ROOT from selfdrive.loggerd.xattr_cache import getxattr, setxattr from selfdrive.statsd import STATS_DIR -from selfdrive.swaglog import SWAGLOG_DIR, cloudlog -from selfdrive.version import get_commit, get_origin, get_short_branch, get_version +from system.swaglog import SWAGLOG_DIR, cloudlog +from system.version import get_commit, get_origin, get_short_branch, get_version ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai') HANDLER_THREADS = int(os.getenv('HANDLER_THREADS', "4")) @@ -64,6 +65,13 @@ UploadItem = namedtuple('UploadItem', ['path', 'url', 'headers', 'created_at', ' cur_upload_items: Dict[int, Any] = {} + +def strip_bz2_extension(fn): + if fn.endswith('.bz2'): + return fn[:-4] + return fn + + class AbortTransferException(Exception): pass @@ -227,14 +235,29 @@ def upload_handler(end_event: threading.Event) -> None: def _do_upload(upload_item, callback=None): - with open(upload_item.path, "rb") as f: - size = os.fstat(f.fileno()).st_size + path = upload_item.path + compress = False + + # If file does not exist, but does exist without the .bz2 extension we will compress on the fly + if not os.path.exists(path) and os.path.exists(strip_bz2_extension(path)): + path = strip_bz2_extension(path) + compress = True + + with open(path, "rb") as f: + if compress: + cloudlog.event("athena.upload_handler.compress", fn=path, fn_orig=upload_item.path) + data = bz2.compress(f.read()) + size = len(data) + data = io.BytesIO(data) + else: + size = os.fstat(f.fileno()).st_size + data = f if callback: - f = CallbackReader(f, callback, size) + data = CallbackReader(data, callback, size) return requests.put(upload_item.url, - data=f, + data=data, headers={**upload_item.headers, 'Content-Length': str(size)}, timeout=30) @@ -335,8 +358,9 @@ def uploadFilesToUrls(files_data): if len(fn) == 0 or fn[0] == '/' or '..' in fn or 'url' not in file: failed.append(fn) continue + path = os.path.join(ROOT, fn) - if not os.path.exists(path): + if not os.path.exists(path) and not os.path.exists(strip_bz2_extension(path)): failed.append(fn) continue @@ -389,8 +413,8 @@ def primeActivated(activated): @dispatcher.add_method def setBandwithLimit(upload_speed_kbps, download_speed_kbps): - if not TICI: - return {"success": 0, "error": "only supported on comma three"} + if not AGNOS: + return {"success": 0, "error": "only supported on AGNOS"} try: HARDWARE.set_bandwidth_limit(upload_speed_kbps, download_speed_kbps) @@ -415,7 +439,7 @@ def startLocalProxy(global_end_event, remote_ws_uri, local_port): ssock, csock = socket.socketpair() local_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) local_sock.connect(('127.0.0.1', local_port)) - local_sock.setblocking(0) + local_sock.setblocking(False) proxy_end_event = threading.Event() threads = [ @@ -680,6 +704,11 @@ def backoff(retries): def main(): + try: + set_core_affinity([0, 1, 2, 3]) + except Exception: + cloudlog.exception("failed to set core affinity") + params = Params() dongle_id = params.get("DongleId", encoding='utf-8') UploadQueueCache.initialize(upload_queue) @@ -696,7 +725,6 @@ def main(): enable_multithread=True, timeout=30.0) cloudlog.event("athenad.main.connected_ws", ws_uri=ws_uri) - params.delete("PrimeRedirected") conn_retries = 0 cur_upload_items.clear() @@ -706,22 +734,13 @@ def main(): break except (ConnectionError, TimeoutError, WebSocketException): conn_retries += 1 - params.delete("PrimeRedirected") params.delete("LastAthenaPingTime") except socket.timeout: - try: - r = requests.get("http://api.commadotai.com/v1/me", allow_redirects=False, - headers={"User-Agent": f"openpilot-{get_version()}"}, timeout=15.0) - if r.status_code == 302 and r.headers['Location'].startswith("http://u.web2go.com"): - params.put_bool("PrimeRedirected", True) - except Exception: - cloudlog.exception("athenad.socket_timeout.exception") params.delete("LastAthenaPingTime") except Exception: cloudlog.exception("athenad.main.exception") conn_retries += 1 - params.delete("PrimeRedirected") params.delete("LastAthenaPingTime") time.sleep(backoff(conn_retries)) diff --git a/selfdrive/athena/manage_athenad.py b/selfdrive/athena/manage_athenad.py index 58ad58310f..6bbb03a799 100755 --- a/selfdrive/athena/manage_athenad.py +++ b/selfdrive/athena/manage_athenad.py @@ -5,8 +5,8 @@ from multiprocessing import Process from common.params import Params from selfdrive.manager.process import launcher -from selfdrive.swaglog import cloudlog -from selfdrive.version import get_version, is_dirty +from system.swaglog import cloudlog +from system.version import get_version, is_dirty ATHENA_MGR_PID_PARAM = "AthenadPid" diff --git a/selfdrive/athena/registration.py b/selfdrive/athena/registration.py index cc4bd7e647..32bc92059c 100755 --- a/selfdrive/athena/registration.py +++ b/selfdrive/athena/registration.py @@ -11,8 +11,8 @@ from common.params import Params from common.spinner import Spinner from common.basedir import PERSIST from selfdrive.controls.lib.alertmanager import set_offroad_alert -from selfdrive.hardware import HARDWARE, PC -from selfdrive.swaglog import cloudlog +from system.hardware import HARDWARE, PC +from system.swaglog import cloudlog UNREGISTERED_DONGLE_ID = "UnregisteredDevice" @@ -23,13 +23,13 @@ def is_registered_device() -> bool: return dongle not in (None, UNREGISTERED_DONGLE_ID) -def register(show_spinner=False) -> str: +def register(show_spinner=False) -> Optional[str]: params = Params() params.put("SubscriberInfo", HARDWARE.get_subscriber_info()) IMEI = params.get("IMEI", encoding='utf8') HardwareSerial = params.get("HardwareSerial", encoding='utf8') - dongle_id = params.get("DongleId", encoding='utf8') + dongle_id: Optional[str] = params.get("DongleId", encoding='utf8') needs_registration = None in (IMEI, HardwareSerial, dongle_id) pubkey = Path(PERSIST+"/comma/id_rsa.pub") diff --git a/selfdrive/athena/tests/test_athenad.py b/selfdrive/athena/tests/test_athenad.py index 1742ed4347..382b549c1b 100755 --- a/selfdrive/athena/tests/test_athenad.py +++ b/selfdrive/athena/tests/test_athenad.py @@ -16,7 +16,7 @@ from unittest import mock from websocket import ABNF from websocket._exceptions import WebSocketConnectionClosedException -from selfdrive import swaglog +from system import swaglog from selfdrive.athena import athenad from selfdrive.athena.athenad import MAX_RETRY_COUNT, dispatcher from selfdrive.athena.tests.helpers import MockWebsocket, MockParams, MockApi, EchoSocket, with_http_server @@ -81,7 +81,8 @@ class TestAthenadMethods(unittest.TestCase): def test_listDataDirectory(self): route = '2021-03-29--13-32-47' segments = [0, 1, 2, 3, 11] - filenames = ['qlog.bz2', 'qcamera.ts', 'rlog.bz2', 'fcamera.hevc', 'ecamera.hevc', 'dcamera.hevc'] + + filenames = ['qlog', 'qcamera.ts', 'rlog', 'fcamera.hevc', 'ecamera.hevc', 'dcamera.hevc'] files = [f'{route}--{s}/{f}' for s in segments for f in filenames] for file in files: fn = os.path.join(athenad.ROOT, file) @@ -119,6 +120,13 @@ class TestAthenadMethods(unittest.TestCase): self.assertTrue(resp, 'list empty!') self.assertCountEqual(resp, expected) + def test_strip_bz2_extension(self): + fn = os.path.join(athenad.ROOT, 'qlog.bz2') + Path(fn).touch() + if fn.endswith('.bz2'): + self.assertEqual(athenad.strip_bz2_extension(fn), fn[:-4]) + + @with_http_server def test_do_upload(self, host): fn = os.path.join(athenad.ROOT, 'qlog.bz2') diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc index 5b44f4d60b..f47b5936be 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/boardd/boardd.cc @@ -23,11 +23,11 @@ #include "cereal/gen/cpp/car.capnp.h" #include "cereal/messaging/messaging.h" -#include "selfdrive/common/params.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/timing.h" -#include "selfdrive/common/util.h" -#include "selfdrive/hardware/hw.h" +#include "common/params.h" +#include "common/swaglog.h" +#include "common/timing.h" +#include "common/util.h" +#include "system/hardware/hw.h" #include "selfdrive/boardd/pigeon.h" @@ -115,11 +115,15 @@ bool safety_setter_thread(std::vector pandas) { return false; } + // set to ELM327 for fingerprinting pandas[0]->set_safety_model(cereal::CarParams::SafetyModel::ELM327); + for (int i = 1; i < pandas.size(); i++) { + pandas[i]->set_safety_model(cereal::CarParams::SafetyModel::SILENT); + } Params p = Params(); - // switch to SILENT when CarVin param is read + // wait for VIN to be read while (true) { if (do_exit || !check_all_connected(pandas) || !ignition) { return false; @@ -135,7 +139,8 @@ bool safety_setter_thread(std::vector pandas) { util::sleep_for(20); } - pandas[0]->set_safety_model(cereal::CarParams::SafetyModel::ELM327, 1); + // set to ELM327 for ECU knockouts + pandas[0]->set_safety_model(cereal::CarParams::SafetyModel::ELM327, 1U); std::string params; LOGW("waiting for params to set safety model"); @@ -156,7 +161,7 @@ bool safety_setter_thread(std::vector pandas) { capnp::FlatArrayMessageReader cmsg(aligned_buf.align(params.data(), params.size())); cereal::CarParams::Reader car_params = cmsg.getRoot(); cereal::CarParams::SafetyModel safety_model; - uint32_t safety_param; + uint16_t safety_param; auto safety_configs = car_params.getSafetyConfigs(); uint16_t alternative_experience = car_params.getAlternativeExperience(); @@ -400,17 +405,12 @@ void send_peripheral_state(PubMaster *pm, Panda *panda) { auto ps = evt.initPeripheralState(); ps.setPandaType(panda->hw_type); - if (Hardware::TICI()) { - double read_time = millis_since_boot(); - ps.setVoltage(std::atoi(util::read_file("/sys/class/hwmon/hwmon1/in1_input").c_str())); - ps.setCurrent(std::atoi(util::read_file("/sys/class/hwmon/hwmon1/curr1_input").c_str())); - read_time = millis_since_boot() - read_time; - if (read_time > 50) { - LOGW("reading hwmon took %lfms", read_time); - } - } else { - ps.setVoltage(pandaState.voltage_pkt); - ps.setCurrent(pandaState.current_pkt); + double read_time = millis_since_boot(); + ps.setVoltage(Hardware::get_voltage()); + ps.setCurrent(Hardware::get_current()); + read_time = millis_since_boot() - read_time; + if (read_time > 50) { + LOGW("reading hwmon took %lfms", read_time); } uint16_t fan_speed_rpm = panda->get_fan_speed(); @@ -529,9 +529,7 @@ void peripheral_control_thread(Panda *panda) { int cur_integ_lines = event.getDriverCameraState().getIntegLines(); float cur_gain = event.getDriverCameraState().getGain(); - if (Hardware::TICI()) { - cur_integ_lines = integ_lines_filter.update(cur_integ_lines * cur_gain); - } + cur_integ_lines = integ_lines_filter.update(cur_integ_lines * cur_gain); last_front_frame_t = event.getLogMonoTime(); if (cur_integ_lines <= CUTOFF_IL) { @@ -646,8 +644,6 @@ void boardd_main_thread(std::vector serials) { Panda *peripheral_panda = pandas[0]; std::vector threads; - Params().put("LastPeripheralPandaType", std::to_string((int) peripheral_panda->get_hw_type())); - threads.emplace_back(panda_state_thread, &pm, pandas, getenv("STARTED") != nullptr); threads.emplace_back(peripheral_control_thread, peripheral_panda); threads.emplace_back(pigeon_thread, peripheral_panda); diff --git a/selfdrive/boardd/main.cc b/selfdrive/boardd/main.cc index d802e42f86..cb17a584bd 100644 --- a/selfdrive/boardd/main.cc +++ b/selfdrive/boardd/main.cc @@ -1,9 +1,9 @@ #include #include "selfdrive/boardd/boardd.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" -#include "selfdrive/hardware/hw.h" +#include "common/swaglog.h" +#include "common/util.h" +#include "system/hardware/hw.h" int main(int argc, char *argv[]) { LOGW("starting boardd"); @@ -12,7 +12,7 @@ int main(int argc, char *argv[]) { int err; err = util::set_realtime_priority(54); assert(err == 0); - err = util::set_core_affinity({Hardware::TICI() ? 4 : 3}); + err = util::set_core_affinity({4}); assert(err == 0); } diff --git a/selfdrive/boardd/panda.cc b/selfdrive/boardd/panda.cc index 1c287fc57e..d90c4cdab2 100644 --- a/selfdrive/boardd/panda.cc +++ b/selfdrive/boardd/panda.cc @@ -8,9 +8,9 @@ #include "cereal/messaging/messaging.h" #include "panda/board/dlc_to_len.h" -#include "selfdrive/common/gpio.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" +#include "common/gpio.h" +#include "common/swaglog.h" +#include "common/util.h" static int init_usb_ctx(libusb_context **context) { assert(context != nullptr); @@ -247,10 +247,8 @@ int Panda::usb_bulk_read(unsigned char endpoint, unsigned char* data, int length return transferred; } -void Panda::set_safety_model(cereal::CarParams::SafetyModel safety_model, uint32_t safety_param) { - // FIXME: last two bytes must be empty - assert((safety_param >> 16) == 0U); - usb_write(0xdc, (uint16_t)safety_model, (uint16_t)safety_param); +void Panda::set_safety_model(cereal::CarParams::SafetyModel safety_model, uint16_t safety_param) { + usb_write(0xdc, (uint16_t)safety_model, safety_param); } void Panda::set_alternative_experience(uint16_t alternative_experience) { diff --git a/selfdrive/boardd/panda.h b/selfdrive/boardd/panda.h index 9bbeee86b4..23a10d5850 100644 --- a/selfdrive/boardd/panda.h +++ b/selfdrive/boardd/panda.h @@ -73,7 +73,7 @@ class Panda { // Panda functionality cereal::PandaState::PandaType get_hw_type(); - void set_safety_model(cereal::CarParams::SafetyModel safety_model, uint32_t safety_param=0U); + void set_safety_model(cereal::CarParams::SafetyModel safety_model, uint16_t safety_param=0U); void set_alternative_experience(uint16_t alternative_experience); void set_rtc(struct tm sys_time); struct tm get_rtc(); diff --git a/selfdrive/boardd/pandad.py b/selfdrive/boardd/pandad.py index 6619afe72f..54a28a6782 100755 --- a/selfdrive/boardd/pandad.py +++ b/selfdrive/boardd/pandad.py @@ -4,14 +4,14 @@ import os import usb1 import time import subprocess -from typing import NoReturn +from typing import List, NoReturn from functools import cmp_to_key from panda import DEFAULT_FW_FN, DEFAULT_H7_FW_FN, MCU_TYPE_H7, Panda, PandaDFU from common.basedir import BASEDIR from common.params import Params -from selfdrive.hardware import HARDWARE -from selfdrive.swaglog import cloudlog +from system.hardware import HARDWARE +from system.swaglog import cloudlog def get_expected_signature(panda: Panda) -> bytes: @@ -102,7 +102,7 @@ def main() -> NoReturn: cloudlog.info(f"{len(panda_serials)} panda(s) found, connecting - {panda_serials}") # Flash pandas - pandas = [] + pandas: List[Panda] = [] for serial in panda_serials: pandas.append(flash_panda(serial)) @@ -119,7 +119,7 @@ def main() -> NoReturn: # sort pandas to have deterministic order pandas.sort(key=cmp_to_key(panda_sort_cmp)) - panda_serials = list(map(lambda p: p.get_usb_serial(), pandas)) + panda_serials = list(map(lambda p: p.get_usb_serial(), pandas)) # type: ignore # log panda fw versions params.put("PandaSignatures", b','.join(p.get_signature() for p in pandas)) diff --git a/selfdrive/boardd/pigeon.cc b/selfdrive/boardd/pigeon.cc index 912f4b03e7..d23ff90d3d 100644 --- a/selfdrive/boardd/pigeon.cc +++ b/selfdrive/boardd/pigeon.cc @@ -8,9 +8,9 @@ #include #include -#include "selfdrive/common/gpio.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" +#include "common/gpio.h" +#include "common/swaglog.h" +#include "common/util.h" #include "selfdrive/locationd/ublox_msg.h" // Termios on macos doesn't define all baud rate constants diff --git a/selfdrive/boardd/tests/boardd_old.py b/selfdrive/boardd/tests/boardd_old.py index 5e740fbcd8..fad29f6f34 100755 --- a/selfdrive/boardd/tests/boardd_old.py +++ b/selfdrive/boardd/tests/boardd_old.py @@ -13,7 +13,7 @@ import time import cereal.messaging as messaging from common.realtime import Ratekeeper -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog from selfdrive.boardd.boardd import can_capnp_to_can_list from cereal import car diff --git a/selfdrive/boardd/tests/test_boardd b/selfdrive/boardd/tests/test_boardd index f249724f6a..b4455ce67c 100755 Binary files a/selfdrive/boardd/tests/test_boardd and b/selfdrive/boardd/tests/test_boardd differ diff --git a/selfdrive/boardd/tests/test_boardd_loopback.py b/selfdrive/boardd/tests/test_boardd_loopback.py index 631b4c987f..e9bbcb4586 100755 --- a/selfdrive/boardd/tests/test_boardd_loopback.py +++ b/selfdrive/boardd/tests/test_boardd_loopback.py @@ -12,7 +12,7 @@ from common.spinner import Spinner from common.timeout import Timeout from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car import make_can_msg -from selfdrive.hardware import TICI +from system.hardware import TICI from selfdrive.test.helpers import phone_only, with_processes diff --git a/selfdrive/camerad/SConscript b/selfdrive/camerad/SConscript index bb55c825d4..b181fbab75 100644 --- a/selfdrive/camerad/SConscript +++ b/selfdrive/camerad/SConscript @@ -2,39 +2,18 @@ Import('env', 'arch', 'cereal', 'messaging', 'common', 'gpucommon', 'visionipc', libs = ['m', 'pthread', common, 'jpeg', 'OpenCL', 'yuv', cereal, messaging, 'zmq', 'capnp', 'kj', visionipc, gpucommon] +cameras = [] if arch == "larch64": libs += ['atomic'] cameras = ['cameras/camera_qcom2.cc'] -else: - env['CXXFLAGS'] += ["-Wno-deprecated-declarations"] - if USE_WEBCAM: - libs += ['opencv_core', 'opencv_highgui', 'opencv_imgproc', 'opencv_videoio'] - cameras = ['cameras/camera_webcam.cc'] - env = env.Clone() - env.Append(CXXFLAGS = '-DWEBCAM') - env.Append(CFLAGS = '-DWEBCAM') - env.Append(CPPPATH = ['/usr/include/opencv4', '/usr/local/include/opencv4']) - else: - libs += ['avutil', 'avcodec', 'avformat', 'bz2', 'ssl', 'curl', 'crypto'] - # TODO: import replay_lib from root SConstruct - cameras = ['cameras/camera_replay.cc', - env.Object('camera-util', '#/selfdrive/ui/replay/util.cc'), - env.Object('camera-framereader', '#/selfdrive/ui/replay/framereader.cc'), - env.Object('camera-filereader', '#/selfdrive/ui/replay/filereader.cc')] - if arch == "Darwin": - del libs[libs.index('OpenCL')] - del libs[libs.index(gpucommon)][gpucommon.index('GL')] - env = env.Clone() - env['FRAMEWORKS'] = ['OpenCL', 'OpenGL'] - -env.Program('camerad', [ - 'main.cc', - 'cameras/camera_common.cc', - 'transforms/rgb_to_yuv.cc', - 'imgproc/utils.cc', - cameras, - ], LIBS=libs) + env.Program('camerad', [ + 'main.cc', + 'cameras/camera_common.cc', + 'transforms/rgb_to_yuv.cc', + 'imgproc/utils.cc', + cameras, + ], LIBS=libs) if GetOption("test"): env.Program('test/ae_gray_test', [ diff --git a/selfdrive/camerad/cameras/camera_common.cc b/selfdrive/camerad/cameras/camera_common.cc index c37846870e..a94cfedf1a 100644 --- a/selfdrive/camerad/cameras/camera_common.cc +++ b/selfdrive/camerad/cameras/camera_common.cc @@ -11,54 +11,49 @@ #include #include "selfdrive/camerad/imgproc/utils.h" -#include "selfdrive/common/clutil.h" -#include "selfdrive/common/modeldata.h" -#include "selfdrive/common/params.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" -#include "selfdrive/hardware/hw.h" - -#if QCOM2 +#include "common/clutil.h" +#include "common/modeldata.h" +#include "common/swaglog.h" +#include "common/util.h" +#include "system/hardware/hw.h" +#include "msm_media_info.h" + +#ifdef QCOM2 #include "CL/cl_ext_qcom.h" #include "selfdrive/camerad/cameras/camera_qcom2.h" -#elif WEBCAM -#include "selfdrive/camerad/cameras/camera_webcam.h" #else -#include "selfdrive/camerad/cameras/camera_replay.h" +#include "selfdrive/camerad/test/camera_test.h" #endif ExitHandler do_exit; class Debayer { public: - Debayer(cl_device_id device_id, cl_context context, const CameraBuf *b, const CameraState *s) { + Debayer(cl_device_id device_id, cl_context context, const CameraBuf *b, const CameraState *s, int buf_width, int uv_offset) { char args[4096]; const CameraInfo *ci = &s->ci; hdr_ = ci->hdr; snprintf(args, sizeof(args), "-cl-fast-relaxed-math -cl-denorms-are-zero " - "-DFRAME_WIDTH=%d -DFRAME_HEIGHT=%d -DFRAME_STRIDE=%d " - "-DRGB_WIDTH=%d -DRGB_HEIGHT=%d -DRGB_STRIDE=%d " - "-DBAYER_FLIP=%d -DHDR=%d -DCAM_NUM=%d", - ci->frame_width, ci->frame_height, ci->frame_stride, - b->rgb_width, b->rgb_height, b->rgb_stride, - ci->bayer_flip, ci->hdr, s->camera_num); + "-DFRAME_WIDTH=%d -DFRAME_HEIGHT=%d -DFRAME_STRIDE=%d -DFRAME_OFFSET=%d " + "-DRGB_WIDTH=%d -DRGB_HEIGHT=%d -DRGB_STRIDE=%d -DYUV_STRIDE=%d -DUV_OFFSET=%d " + "-DBAYER_FLIP=%d -DHDR=%d -DCAM_NUM=%d%s", + ci->frame_width, ci->frame_height, ci->frame_stride, ci->frame_offset, + b->rgb_width, b->rgb_height, b->rgb_stride, buf_width, uv_offset, + ci->bayer_flip, ci->hdr, s->camera_num, s->camera_num==1 ? " -DVIGNETTING" : ""); const char *cl_file = "cameras/real_debayer.cl"; cl_program prg_debayer = cl_program_from_file(context, device_id, cl_file, args); krnl_ = CL_CHECK_ERR(clCreateKernel(prg_debayer, "debayer10", &err)); CL_CHECK(clReleaseProgram(prg_debayer)); } - void queue(cl_command_queue q, cl_mem cam_buf_cl, cl_mem buf_cl, int width, int height, float gain, float black_level, cl_event *debayer_event) { + void queue(cl_command_queue q, cl_mem cam_buf_cl, cl_mem buf_cl, int width, int height, cl_event *debayer_event) { CL_CHECK(clSetKernelArg(krnl_, 0, sizeof(cl_mem), &cam_buf_cl)); CL_CHECK(clSetKernelArg(krnl_, 1, sizeof(cl_mem), &buf_cl)); + const size_t globalWorkSize[] = {size_t(width / 2), size_t(height / 2)}; const int debayer_local_worksize = 16; - constexpr int localMemSize = (debayer_local_worksize + 2 * (3 / 2)) * (debayer_local_worksize + 2 * (3 / 2)) * sizeof(short int); - const size_t globalWorkSize[] = {size_t(width), size_t(height)}; const size_t localWorkSize[] = {debayer_local_worksize, debayer_local_worksize}; - CL_CHECK(clSetKernelArg(krnl_, 2, localMemSize, 0)); - CL_CHECK(clSetKernelArg(krnl_, 3, sizeof(float), &black_level)); CL_CHECK(clEnqueueNDRangeKernel(q, krnl_, 2, NULL, globalWorkSize, localWorkSize, 0, 0, debayer_event)); } @@ -82,7 +77,7 @@ void CameraBuf::init(cl_device_id device_id, cl_context context, CameraState *s, frame_buf_count = frame_cnt; // RAW frame - const int frame_size = ci->frame_height * ci->frame_stride; + const int frame_size = (ci->frame_height + ci->extra_height) * ci->frame_stride; camera_bufs = std::make_unique(frame_buf_count); camera_bufs_metadata = std::make_unique(frame_buf_count); @@ -95,23 +90,23 @@ void CameraBuf::init(cl_device_id device_id, cl_context context, CameraState *s, rgb_width = ci->frame_width; rgb_height = ci->frame_height; - if (!Hardware::TICI() && ci->bayer) { - // debayering does a 2x downscale - rgb_width = ci->frame_width / 2; - rgb_height = ci->frame_height / 2; - } - yuv_transform = get_model_yuv_transform(ci->bayer); vipc_server->create_buffers(rgb_type, UI_BUF_COUNT, true, rgb_width, rgb_height); rgb_stride = vipc_server->get_buffer(rgb_type)->stride; LOGD("created %d UI vipc buffers with size %dx%d", UI_BUF_COUNT, rgb_width, rgb_height); - vipc_server->create_buffers(yuv_type, YUV_BUFFER_COUNT, false, rgb_width, rgb_height); - LOGD("created %d YUV vipc buffers with size %dx%d", YUV_BUFFER_COUNT, rgb_width, rgb_height); + int nv12_width = VENUS_Y_STRIDE(COLOR_FMT_NV12, rgb_width); + int nv12_height = VENUS_Y_SCANLINES(COLOR_FMT_NV12, rgb_height); + assert(nv12_width == VENUS_UV_STRIDE(COLOR_FMT_NV12, rgb_width)); + assert(nv12_height/2 == VENUS_UV_SCANLINES(COLOR_FMT_NV12, rgb_height)); + size_t nv12_size = 2346 * nv12_width; // comes from v4l2_format.fmt.pix_mp.plane_fmt[0].sizeimage + size_t nv12_uv_offset = nv12_width * nv12_height; + vipc_server->create_buffers_with_sizes(yuv_type, YUV_BUFFER_COUNT, false, rgb_width, rgb_height, nv12_size, nv12_width, nv12_uv_offset); + LOGD("created %d YUV vipc buffers with size %dx%d", YUV_BUFFER_COUNT, nv12_width, nv12_height); if (ci->bayer) { - debayer = new Debayer(device_id, context, this, s); + debayer = new Debayer(device_id, context, this, s, nv12_width, nv12_uv_offset); } rgb2yuv = std::make_unique(context, device_id, rgb_width, rgb_height, rgb_stride); @@ -142,32 +137,24 @@ bool CameraBuf::acquire() { cur_frame_data = camera_bufs_metadata[cur_buf_idx]; cur_rgb_buf = vipc_server->get_buffer(rgb_type); + cur_yuv_buf = vipc_server->get_buffer(yuv_type); cl_mem camrabuf_cl = camera_bufs[cur_buf_idx].buf_cl; cl_event event; double start_time = millis_since_boot(); + cur_camera_buf = &camera_bufs[cur_buf_idx]; + if (debayer) { - float gain = 0.0; - float black_level = 42.0; -#ifndef QCOM2 - gain = camera_state->digital_gain; - if ((int)gain == 0) gain = 1.0; -#else - if (camera_state->camera_id == CAMERA_ID_IMX390) black_level = 64.0; -#endif - debayer->queue(q, camrabuf_cl, cur_rgb_buf->buf_cl, rgb_width, rgb_height, gain, black_level, &event); + debayer->queue(q, camrabuf_cl, cur_yuv_buf->buf_cl, rgb_width, rgb_height, &event); } else { assert(rgb_stride == camera_state->ci.frame_stride); - CL_CHECK(clEnqueueCopyBuffer(q, camrabuf_cl, cur_rgb_buf->buf_cl, 0, 0, cur_rgb_buf->len, 0, 0, &event)); + rgb2yuv->queue(q, camrabuf_cl, cur_rgb_buf->buf_cl); } clWaitForEvents(1, &event); CL_CHECK(clReleaseEvent(event)); - cur_yuv_buf = vipc_server->get_buffer(yuv_type); - rgb2yuv->queue(q, cur_rgb_buf->buf_cl, cur_yuv_buf->buf_cl); - cur_frame_data.processing_time = (millis_since_boot() - start_time) / 1000.0; VisionIpcBufExtra extra = { @@ -175,9 +162,7 @@ bool CameraBuf::acquire() { cur_frame_data.timestamp_sof, cur_frame_data.timestamp_eof, }; - cur_rgb_buf->set_frame_id(cur_frame_data.frame_id); cur_yuv_buf->set_frame_id(cur_frame_data.frame_id); - vipc_server->send(cur_rgb_buf, &extra); vipc_server->send(cur_yuv_buf, &extra); return true; @@ -237,21 +222,40 @@ kj::Array get_frame_image(const CameraBuf *b) { return kj::mv(frame_image); } +kj::Array get_raw_frame_image(const CameraBuf *b) { + const uint8_t *dat = (const uint8_t *)b->cur_camera_buf->addr; + + kj::Array frame_image = kj::heapArray(b->cur_camera_buf->len); + uint8_t *resized_dat = frame_image.begin(); + + memcpy(resized_dat, dat, b->cur_camera_buf->len); + + return kj::mv(frame_image); +} + static kj::Array yuv420_to_jpeg(const CameraBuf *b, int thumbnail_width, int thumbnail_height) { + int downscale = b->cur_yuv_buf->width / thumbnail_width; + assert(downscale * thumbnail_height == b->cur_yuv_buf->height); + int in_stride = b->cur_yuv_buf->stride; + // make the buffer big enough. jpeg_write_raw_data requires 16-pixels aligned height to be used. std::unique_ptr buf(new uint8_t[(thumbnail_width * ((thumbnail_height + 15) & ~15) * 3) / 2]); uint8_t *y_plane = buf.get(); uint8_t *u_plane = y_plane + thumbnail_width * thumbnail_height; uint8_t *v_plane = u_plane + (thumbnail_width * thumbnail_height) / 4; { - int result = libyuv::I420Scale( - b->cur_yuv_buf->y, b->rgb_width, b->cur_yuv_buf->u, b->rgb_width / 2, b->cur_yuv_buf->v, b->rgb_width / 2, - b->rgb_width, b->rgb_height, - y_plane, thumbnail_width, u_plane, thumbnail_width / 2, v_plane, thumbnail_width / 2, - thumbnail_width, thumbnail_height, libyuv::kFilterNone); - if (result != 0) { - LOGE("Generate YUV thumbnail failed."); - return {}; + // subsampled conversion from nv12 to yuv + for (int hy = 0; hy < thumbnail_height/2; hy++) { + for (int hx = 0; hx < thumbnail_width/2; hx++) { + int ix = hx * downscale + (downscale-1)/2; + int iy = hy * downscale + (downscale-1)/2; + y_plane[(hy*2 + 0)*thumbnail_width + (hx*2 + 0)] = b->cur_yuv_buf->y[(iy*2 + 0) * in_stride + ix*2 + 0]; + y_plane[(hy*2 + 0)*thumbnail_width + (hx*2 + 1)] = b->cur_yuv_buf->y[(iy*2 + 0) * in_stride + ix*2 + 1]; + y_plane[(hy*2 + 1)*thumbnail_width + (hx*2 + 0)] = b->cur_yuv_buf->y[(iy*2 + 1) * in_stride + ix*2 + 0]; + y_plane[(hy*2 + 1)*thumbnail_width + (hx*2 + 1)] = b->cur_yuv_buf->y[(iy*2 + 1) * in_stride + ix*2 + 1]; + u_plane[hy*thumbnail_width/2 + hx] = b->cur_yuv_buf->uv[iy*in_stride + ix*2 + 0]; + v_plane[hy*thumbnail_width/2 + hx] = b->cur_yuv_buf->uv[iy*in_stride + ix*2 + 1]; + } } } @@ -377,47 +381,6 @@ std::thread start_process_thread(MultiCameraState *cameras, CameraState *cs, pro return std::thread(processing_thread, cameras, cs, callback); } -static void driver_cam_auto_exposure(CameraState *c, SubMaster &sm) { - static const bool is_rhd = Params().getBool("IsRHD"); - struct ExpRect {int x1, x2, x_skip, y1, y2, y_skip;}; - const CameraBuf *b = &c->buf; - - int x_offset = 0, y_offset = 0; - int frame_width = b->rgb_width, frame_height = b->rgb_height; - - - ExpRect def_rect; - if (Hardware::TICI()) { - x_offset = 630, y_offset = 156; - frame_width = 668, frame_height = frame_width / 1.33; - def_rect = {96, 1832, 2, 242, 1148, 4}; - } else { - def_rect = {is_rhd ? 0 : b->rgb_width * 3 / 5, is_rhd ? b->rgb_width * 2 / 5 : b->rgb_width, 2, - b->rgb_height / 3, b->rgb_height, 1}; - } - - static ExpRect rect = def_rect; - - camera_autoexposure(c, set_exposure_target(b, rect.x1, rect.x2, rect.x_skip, rect.y1, rect.y2, rect.y_skip)); -} - -void common_process_driver_camera(MultiCameraState *s, CameraState *c, int cnt) { - int j = Hardware::TICI() ? 1 : 3; - if (cnt % j == 0) { - s->sm->update(0); - driver_cam_auto_exposure(c, *(s->sm)); - } - MessageBuilder msg; - auto framed = msg.initEvent().initDriverCameraState(); - framed.setFrameType(cereal::FrameData::FrameType::FRONT); - fill_frame_data(framed, c->buf.cur_frame_data); - if (env_send_driver) { - framed.setImage(get_frame_image(&c->buf)); - } - s->pm->send("driverCameraState", msg); -} - - void camerad_thread() { cl_device_id device_id = cl_get_device_id(CL_DEVICE_TYPE_DEFAULT); #ifdef QCOM2 diff --git a/selfdrive/camerad/cameras/camera_common.h b/selfdrive/camerad/cameras/camera_common.h index e415f80982..e9c7ccd757 100644 --- a/selfdrive/camerad/cameras/camera_common.h +++ b/selfdrive/camerad/cameras/camera_common.h @@ -10,11 +10,10 @@ #include "cereal/visionipc/visionipc.h" #include "cereal/visionipc/visionipc_server.h" #include "selfdrive/camerad/transforms/rgb_to_yuv.h" -#include "selfdrive/common/mat.h" -#include "selfdrive/common/queue.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/visionimg.h" -#include "selfdrive/hardware/hw.h" +#include "common/mat.h" +#include "common/queue.h" +#include "common/swaglog.h" +#include "system/hardware/hw.h" #define CAMERA_ID_IMX298 0 #define CAMERA_ID_IMX179 1 @@ -47,15 +46,20 @@ const bool env_disable_road = getenv("DISABLE_ROAD") != NULL; const bool env_disable_wide_road = getenv("DISABLE_WIDE_ROAD") != NULL; const bool env_disable_driver = getenv("DISABLE_DRIVER") != NULL; const bool env_debug_frames = getenv("DEBUG_FRAMES") != NULL; +const bool env_log_raw_frames = getenv("LOG_RAW_FRAMES") != NULL; typedef void (*release_cb)(void *cookie, int buf_idx); typedef struct CameraInfo { - int frame_width, frame_height; - int frame_stride; + uint32_t frame_width, frame_height; + uint32_t frame_stride; bool bayer; int bayer_flip; bool hdr; + uint32_t frame_offset = 0; + uint32_t extra_height = 0; + int registers_offset = -1; + int stats_offset = -1; } CameraInfo; typedef struct FrameMetadata { @@ -111,6 +115,7 @@ public: FrameMetadata cur_frame_data; VisionBuf *cur_rgb_buf; VisionBuf *cur_yuv_buf; + VisionBuf *cur_camera_buf; std::unique_ptr camera_bufs; std::unique_ptr camera_bufs_metadata; int rgb_width, rgb_height, rgb_stride; @@ -129,9 +134,9 @@ typedef void (*process_thread_cb)(MultiCameraState *s, CameraState *c, int cnt); void fill_frame_data(cereal::FrameData::Builder &framed, const FrameMetadata &frame_data); kj::Array get_frame_image(const CameraBuf *b); +kj::Array get_raw_frame_image(const CameraBuf *b); float set_exposure_target(const CameraBuf *b, int x_start, int x_end, int x_skip, int y_start, int y_end, int y_skip); std::thread start_process_thread(MultiCameraState *cameras, CameraState *cs, process_thread_cb callback); -void common_process_driver_camera(MultiCameraState *s, CameraState *c, int cnt); void cameras_init(VisionIpcServer *v, MultiCameraState *s, cl_device_id device_id, cl_context ctx); void cameras_open(MultiCameraState *s); diff --git a/selfdrive/camerad/cameras/camera_qcom2.cc b/selfdrive/camerad/cameras/camera_qcom2.cc index 1d092eb6a6..c1ffc1275a 100644 --- a/selfdrive/camerad/cameras/camera_qcom2.cc +++ b/selfdrive/camerad/cameras/camera_qcom2.cc @@ -19,7 +19,7 @@ #include "media/cam_sensor.h" #include "media/cam_sensor_cmn_header.h" #include "media/cam_sync.h" -#include "selfdrive/common/swaglog.h" +#include "common/swaglog.h" #include "selfdrive/camerad/cameras/sensor2_i2c.h" // For debugging: @@ -31,6 +31,9 @@ const size_t FRAME_WIDTH = 1928; const size_t FRAME_HEIGHT = 1208; const size_t FRAME_STRIDE = 2896; // for 12 bit output. 1928 * 12 / 8 + 4 (alignment) +const size_t AR0231_REGISTERS_HEIGHT = 2; +const size_t AR0231_STATS_HEIGHT = 2; + const int MIPI_SETTLE_CNT = 33; // Calculated by camera_freqs.py CameraInfo cameras_supported[CAMERA_ID_MAX] = { @@ -38,17 +41,24 @@ CameraInfo cameras_supported[CAMERA_ID_MAX] = { .frame_width = FRAME_WIDTH, .frame_height = FRAME_HEIGHT, .frame_stride = FRAME_STRIDE, + .extra_height = AR0231_REGISTERS_HEIGHT + AR0231_STATS_HEIGHT, + + .registers_offset = 0, + .frame_offset = AR0231_REGISTERS_HEIGHT, + .stats_offset = AR0231_REGISTERS_HEIGHT + FRAME_HEIGHT, + .bayer = true, .bayer_flip = 1, - .hdr = false + .hdr = false, }, [CAMERA_ID_IMX390] = { .frame_width = FRAME_WIDTH, .frame_height = FRAME_HEIGHT, .frame_stride = FRAME_STRIDE, + .bayer = true, .bayer_flip = 1, - .hdr = false + .hdr = false, }, }; @@ -64,7 +74,7 @@ const int ANALOG_GAIN_REC_IDX = 0x6; // 0.8x const int ANALOG_GAIN_MAX_IDX = 0xD; // 4.0x const int EXPOSURE_TIME_MIN = 2; // with HDR, fastest ss -const int EXPOSURE_TIME_MAX = 1618; // with HDR, slowest ss, 40ms +const int EXPOSURE_TIME_MAX = 0x0855; // with HDR, slowest ss, 40ms // ************** low level camera helpers **************** int do_cam_control(int fd, int op_code, void *handle, int size) { @@ -81,8 +91,7 @@ int do_cam_control(int fd, int op_code, void *handle, int size) { int ret = HANDLE_EINTR(ioctl(fd, VIDIOC_CAM_CONTROL, &camcontrol)); if (ret == -1) { - printf("OP CODE ERR - %d \n", op_code); - perror("wat"); + LOGE("VIDIOC_CAM_CONTROL error: op_code %d - errno %d", op_code, errno); } return ret; } @@ -509,10 +518,10 @@ void CameraState::config_isp(int io_mem_handle, int fence, int request_id, int b if (io_mem_handle != 0) { io_cfg[0].mem_handle[0] = io_mem_handle; io_cfg[0].planes[0] = (struct cam_plane_cfg){ - .width = FRAME_WIDTH, - .height = FRAME_HEIGHT, - .plane_stride = FRAME_STRIDE, - .slice_height = FRAME_HEIGHT, + .width = ci.frame_width, + .height = ci.frame_height + ci.extra_height, + .plane_stride = ci.frame_stride, + .slice_height = ci.frame_height + ci.extra_height, .meta_stride = 0x0, // YUV has meta(stride=0x400, size=0x5000) .meta_size = 0x0, .meta_offset = 0x0, @@ -536,7 +545,7 @@ void CameraState::config_isp(int io_mem_handle, int fence, int request_id, int b int ret = device_config(multi_cam_state->isp_fd, session_handle, isp_dev_handle, cam_packet_handle); assert(ret == 0); if (ret != 0) { - printf("ISP CONFIG FAILED\n"); + LOGE("isp config failed"); } mm.free(buf2); @@ -553,7 +562,10 @@ void CameraState::enqueue_buffer(int i, bool dp) { sync_wait.sync_obj = sync_objs[i]; sync_wait.timeout_ms = 50; // max dt tolerance, typical should be 23 ret = do_cam_control(multi_cam_state->cam_sync_fd, CAM_SYNC_WAIT, &sync_wait, sizeof(sync_wait)); - // LOGD("fence wait: %d %d", ret, sync_wait.sync_obj); + if (ret != 0) { + LOGE("failed to wait for sync: %d %d", ret, sync_wait.sync_obj); + // TODO: handle frame drop cleanly + } buf.camera_bufs_metadata[i].timestamp_eof = (uint64_t)nanos_since_boot(); // set true eof if (dp) buf.queue(i); @@ -562,14 +574,18 @@ void CameraState::enqueue_buffer(int i, bool dp) { struct cam_sync_info sync_destroy = {0}; sync_destroy.sync_obj = sync_objs[i]; ret = do_cam_control(multi_cam_state->cam_sync_fd, CAM_SYNC_DESTROY, &sync_destroy, sizeof(sync_destroy)); - // LOGD("fence destroy: %d %d", ret, sync_destroy.sync_obj); + if (ret != 0) { + LOGE("failed to destroy sync object: %d %d", ret, sync_destroy.sync_obj); + } } // create output fence struct cam_sync_info sync_create = {0}; strcpy(sync_create.name, "NodeOutputPortFence"); ret = do_cam_control(multi_cam_state->cam_sync_fd, CAM_SYNC_CREATE, &sync_create, sizeof(sync_create)); - // LOGD("fence req: %d %d", ret, sync_create.sync_obj); + if (ret != 0) { + LOGE("failed to create fence: %d %d", ret, sync_create.sync_obj) + } sync_objs[i] = sync_create.sync_obj; // schedule request with camera request manager @@ -578,11 +594,12 @@ void CameraState::enqueue_buffer(int i, bool dp) { req_mgr_sched_request.link_hdl = link_handle; req_mgr_sched_request.req_id = request_id; ret = do_cam_control(multi_cam_state->video0_fd, CAM_REQ_MGR_SCHED_REQ, &req_mgr_sched_request, sizeof(req_mgr_sched_request)); - // LOGD("sched req: %d %d", ret, request_id); + if (ret != 0) { + LOGE("failed to schedule cam mgr request: %d %d", ret, request_id); + } // poke sensor, must happen after schedule sensors_poke(request_id); - // LOGD("Poked sensor"); // submit request to the ife config_isp(buf_handle[i], sync_objs[i], request_id, buf0_handle, 65632*(i+1)); @@ -682,23 +699,23 @@ void CameraState::camera_open() { .lane_cfg = 0x3210, .vc = 0x0, - .dt = 0x2C, // CSI_RAW12 + .dt = 0x12, // Changing stats to 0x2C doesn't work, so change pixels to 0x12 instead .format = CAM_FORMAT_MIPI_RAW_12, .test_pattern = 0x2, // 0x3? .usage_type = 0x0, .left_start = 0, - .left_stop = FRAME_WIDTH - 1, - .left_width = FRAME_WIDTH, + .left_stop = ci.frame_width - 1, + .left_width = ci.frame_width, .right_start = 0, - .right_stop = FRAME_WIDTH - 1, - .right_width = FRAME_WIDTH, + .right_stop = ci.frame_width - 1, + .right_width = ci.frame_width, .line_start = 0, - .line_stop = FRAME_HEIGHT - 1, - .height = FRAME_HEIGHT, + .line_stop = ci.frame_height + ci.extra_height - 1, + .height = ci.frame_height + ci.extra_height, .pixel_clk = 0x0, .batch_size = 0x0, @@ -710,8 +727,8 @@ void CameraState::camera_open() { .data[0] = (struct cam_isp_out_port_info){ .res_type = CAM_ISP_IFE_OUT_RES_RDI_0, .format = CAM_FORMAT_MIPI_RAW_12, - .width = FRAME_WIDTH, - .height = FRAME_HEIGHT, + .width = ci.frame_width, + .height = ci.frame_height + ci.extra_height, .comp_grp_id = 0x0, .split_point = 0x0, .secure_mode = 0x0, }, }; @@ -820,7 +837,6 @@ void cameras_init(VisionIpcServer *v, MultiCameraState *s, cl_device_id device_i s->road_cam.camera_init(s, v, CAMERA_ID_AR0231, 1, 20, device_id, ctx, VISION_STREAM_RGB_ROAD, VISION_STREAM_ROAD, !env_disable_road); s->wide_road_cam.camera_init(s, v, CAMERA_ID_AR0231, 0, 20, device_id, ctx, VISION_STREAM_RGB_WIDE_ROAD, VISION_STREAM_WIDE_ROAD, !env_disable_wide_road); - s->sm = new SubMaster({"driverState"}); s->pm = new PubMaster({"roadCameraState", "driverCameraState", "wideRoadCameraState", "thumbnail"}); } @@ -863,14 +879,14 @@ void cameras_open(MultiCameraState *s) { sub.type = V4L_EVENT_CAM_REQ_MGR_EVENT; sub.id = V4L_EVENT_CAM_REQ_MGR_SOF_BOOT_TS; ret = HANDLE_EINTR(ioctl(s->video0_fd, VIDIOC_SUBSCRIBE_EVENT, &sub)); - printf("req mgr subscribe: %d\n", ret); + LOGD("req mgr subscribe: %d", ret); s->driver_cam.camera_open(); - printf("driver camera opened \n"); + LOGD("driver camera opened"); s->road_cam.camera_open(); - printf("road camera opened \n"); + LOGD("road camera opened"); s->wide_road_cam.camera_open(); - printf("wide road camera opened \n"); + LOGD("wide road camera opened"); } void CameraState::camera_close() { @@ -931,10 +947,73 @@ void cameras_close(MultiCameraState *s) { s->road_cam.camera_close(); s->wide_road_cam.camera_close(); - delete s->sm; delete s->pm; } +std::map> CameraState::ar0231_build_register_lut(uint8_t *data) { + // This function builds a lookup table from register address, to a pair of indices in the + // buffer where to read this address. The buffer contains padding bytes, + // as well as markers to indicate the type of the next byte. + // + // 0xAA is used to indicate the MSB of the address, 0xA5 for the LSB of the address. + // Every byte of data (MSB and LSB) is preceded by 0x5A. Specifying an address is optional + // for contigous ranges. See page 27-29 of the AR0231 Developer guide for more information. + + int max_i[] = {1828 / 2 * 3, 1500 / 2 * 3}; + auto get_next_idx = [](int cur_idx) { + return (cur_idx % 3 == 1) ? cur_idx + 2 : cur_idx + 1; // Every third byte is padding + }; + + std::map> registers; + for (int register_row = 0; register_row < 2; register_row++) { + uint8_t *registers_raw = data + ci.frame_stride * register_row; + assert(registers_raw[0] == 0x0a); // Start of line + + int value_tag_count = 0; + int first_val_idx = 0; + uint16_t cur_addr = 0; + + for (int i = 1; i <= max_i[register_row]; i = get_next_idx(get_next_idx(i))) { + int val_idx = get_next_idx(i); + + uint8_t tag = registers_raw[i]; + uint16_t val = registers_raw[val_idx]; + + if (tag == 0xAA) { // Register MSB tag + cur_addr = val << 8; + } else if (tag == 0xA5) { // Register LSB tag + cur_addr |= val; + cur_addr -= 2; // Next value tag will increment address again + } else if (tag == 0x5A) { // Value tag + + // First tag + if (value_tag_count % 2 == 0) { + cur_addr += 2; + first_val_idx = val_idx; + } else { + registers[cur_addr] = std::make_pair(first_val_idx + ci.frame_stride * register_row, val_idx + ci.frame_stride * register_row); + } + + value_tag_count++; + } + } + } + return registers; +} + +std::map CameraState::ar0231_parse_registers(uint8_t *data, std::initializer_list addrs) { + if (ar0231_register_lut.empty()) { + ar0231_register_lut = ar0231_build_register_lut(data); + } + + std::map registers; + for (uint16_t addr : addrs) { + auto offset = ar0231_register_lut[addr]; + registers[addr] = ((uint16_t)data[offset.first] << 8) | data[offset.second]; + } + return registers; +} + void CameraState::handle_camera_event(void *evdat) { if (!enabled) return; struct cam_req_mgr_message *event_data = (struct cam_req_mgr_message *)evdat; @@ -1114,7 +1193,55 @@ void camera_autoexposure(CameraState *s, float grey_frac) { s->set_camera_exposure(grey_frac); } -// called by processing_thread +static float ar0231_parse_temp_sensor(uint16_t calib1, uint16_t calib2, uint16_t data_reg) { + // See AR0231 Developer Guide - page 36 + float slope = (125.0 - 55.0) / ((float)calib1 - (float)calib2); + float t0 = 55.0 - slope * (float)calib2; + return t0 + slope * (float)data_reg; +} + +static void ar0231_process_registers(MultiCameraState *s, CameraState *c, cereal::FrameData::Builder &framed){ + const uint8_t expected_preamble[] = {0x0a, 0xaa, 0x55, 0x20, 0xa5, 0x55}; + uint8_t *data = (uint8_t*)c->buf.cur_camera_buf->addr + c->ci.registers_offset; + + if (memcmp(data, expected_preamble, std::size(expected_preamble)) != 0){ + LOGE("unexpected register data found"); + return; + } + + auto registers = c->ar0231_parse_registers(data, {0x2000, 0x2002, 0x20b0, 0x20b2, 0x30c6, 0x30c8, 0x30ca, 0x30cc}); + + uint32_t frame_id = ((uint32_t)registers[0x2000] << 16) | registers[0x2002]; + framed.setFrameIdSensor(frame_id); + + float temp_0 = ar0231_parse_temp_sensor(registers[0x30c6], registers[0x30c8], registers[0x20b0]); + float temp_1 = ar0231_parse_temp_sensor(registers[0x30ca], registers[0x30cc], registers[0x20b2]); + framed.setTemperaturesC({temp_0, temp_1}); +} + +static void driver_cam_auto_exposure(CameraState *c) { + struct ExpRect {int x1, x2, x_skip, y1, y2, y_skip;}; + const CameraBuf *b = &c->buf; + static ExpRect rect = {96, 1832, 2, 242, 1148, 4}; + camera_autoexposure(c, set_exposure_target(b, rect.x1, rect.x2, rect.x_skip, rect.y1, rect.y2, rect.y_skip)); +} + +static void process_driver_camera(MultiCameraState *s, CameraState *c, int cnt) { + driver_cam_auto_exposure(c); + + MessageBuilder msg; + auto framed = msg.initEvent().initDriverCameraState(); + framed.setFrameType(cereal::FrameData::FrameType::FRONT); + fill_frame_data(framed, c->buf.cur_frame_data); + if (env_send_driver) { + framed.setImage(get_frame_image(&c->buf)); + } + if (c->camera_id == CAMERA_ID_AR0231) { + ar0231_process_registers(s, c, framed); + } + s->pm->send("driverCameraState", msg); +} + void process_road_camera(MultiCameraState *s, CameraState *c, int cnt) { const CameraBuf *b = &c->buf; @@ -1123,12 +1250,19 @@ void process_road_camera(MultiCameraState *s, CameraState *c, int cnt) { fill_frame_data(framed, b->cur_frame_data); if ((c == &s->road_cam && env_send_road) || (c == &s->wide_road_cam && env_send_wide_road)) { framed.setImage(get_frame_image(b)); + } else if (env_log_raw_frames && c == &s->road_cam && cnt % 100 == 5) { // no overlap with qlog decimation + framed.setImage(get_raw_frame_image(b)); } LOGT(c->buf.cur_frame_data.frame_id, "%s: Image set", c == &s->road_cam ? "RoadCamera" : "WideRoadCamera"); if (c == &s->road_cam) { framed.setTransform(b->yuv_transform.v); LOGT(c->buf.cur_frame_data.frame_id, "%s: Transformed", "RoadCamera"); } + + if (c->camera_id == CAMERA_ID_AR0231) { + ar0231_process_registers(s, c, framed); + } + s->pm->send(c == &s->road_cam ? "roadCameraState" : "wideRoadCameraState", msg); const auto [x, y, w, h] = (c == &s->wide_road_cam) ? std::tuple(96, 250, 1734, 524) : std::tuple(96, 160, 1734, 986); @@ -1139,7 +1273,7 @@ void process_road_camera(MultiCameraState *s, CameraState *c, int cnt) { void cameras_run(MultiCameraState *s) { LOG("-- Starting threads"); std::vector threads; - if (s->driver_cam.enabled) threads.push_back(start_process_thread(s, &s->driver_cam, common_process_driver_camera)); + if (s->driver_cam.enabled) threads.push_back(start_process_thread(s, &s->driver_cam, process_driver_camera)); if (s->road_cam.enabled) threads.push_back(start_process_thread(s, &s->road_cam, process_road_camera)); if (s->wide_road_cam.enabled) threads.push_back(start_process_thread(s, &s->wide_road_cam, process_road_camera)); @@ -1183,7 +1317,7 @@ void cameras_run(MultiCameraState *s) { } else if (event_data->session_hdl == s->driver_cam.session_handle) { s->driver_cam.handle_camera_event(event_data); } else { - printf("Unknown vidioc event source\n"); + LOGE("Unknown vidioc event source"); assert(false); } } @@ -1198,3 +1332,4 @@ void cameras_run(MultiCameraState *s) { cameras_close(s); } + diff --git a/selfdrive/camerad/cameras/camera_qcom2.h b/selfdrive/camerad/cameras/camera_qcom2.h index a7c64c0665..88766a68e9 100644 --- a/selfdrive/camerad/cameras/camera_qcom2.h +++ b/selfdrive/camerad/cameras/camera_qcom2.h @@ -1,11 +1,13 @@ #pragma once #include +#include +#include #include #include "selfdrive/camerad/cameras/camera_common.h" -#include "selfdrive/common/util.h" +#include "common/util.h" #define FRAME_BUF_COUNT 4 @@ -56,6 +58,8 @@ public: void camera_init(MultiCameraState *multi_cam_state, VisionIpcServer * v, int camera_id, int camera_num, unsigned int fps, cl_device_id device_id, cl_context ctx, VisionStreamType rgb_type, VisionStreamType yuv_type, bool enabled); void camera_close(); + std::map ar0231_parse_registers(uint8_t *data, std::initializer_list addrs); + int32_t session_handle; int32_t sensor_dev_handle; int32_t isp_dev_handle; @@ -75,6 +79,7 @@ public: CameraBuf buf; MemoryManager mm; + private: void config_isp(int io_mem_handle, int fence, int request_id, int buf0_mem_handle, int buf0_offset); void enqueue_req_multi(int start, int n, bool dp); @@ -84,6 +89,10 @@ private: int sensors_init(); void sensors_poke(int request_id); void sensors_i2c(struct i2c_random_wr_payload* dat, int len, int op_code, bool data_word); + + // Register parsing + std::map> ar0231_register_lut; + std::map> ar0231_build_register_lut(uint8_t *data); }; typedef struct MultiCameraState { @@ -97,6 +106,5 @@ typedef struct MultiCameraState { CameraState wide_road_cam; CameraState driver_cam; - SubMaster *sm; PubMaster *pm; } MultiCameraState; diff --git a/selfdrive/camerad/cameras/camera_replay.cc b/selfdrive/camerad/cameras/camera_replay.cc deleted file mode 100644 index a9983fe23e..0000000000 --- a/selfdrive/camerad/cameras/camera_replay.cc +++ /dev/null @@ -1,125 +0,0 @@ -#include "selfdrive/camerad/cameras/camera_replay.h" - -#include -#include - -#include "selfdrive/common/clutil.h" -#include "selfdrive/common/util.h" - -extern ExitHandler do_exit; - -void camera_autoexposure(CameraState *s, float grey_frac) {} - -namespace { - -const char *BASE_URL = "https://commadataci.blob.core.windows.net/openpilotci/"; - -const std::string road_camera_route = "0c94aa1e1296d7c6|2021-05-05--19-48-37"; -// const std::string driver_camera_route = "534ccd8a0950a00c|2021-06-08--12-15-37"; - -std::string get_url(std::string route_name, const std::string &camera, int segment_num) { - std::replace(route_name.begin(), route_name.end(), '|', '/'); - return util::string_format("%s%s/%d/%s.hevc", BASE_URL, route_name.c_str(), segment_num, camera.c_str()); -} - -void camera_init(VisionIpcServer *v, CameraState *s, int camera_id, unsigned int fps, cl_device_id device_id, cl_context ctx, VisionStreamType rgb_type, VisionStreamType yuv_type, const std::string &url) { - s->frame = new FrameReader(); - if (!s->frame->load(url)) { - printf("failed to load stream from %s", url.c_str()); - assert(0); - } - - CameraInfo ci = { - .frame_width = s->frame->width, - .frame_height = s->frame->height, - .frame_stride = s->frame->width * 3, - }; - s->ci = ci; - s->camera_num = camera_id; - s->fps = fps; - s->buf.init(device_id, ctx, s, v, FRAME_BUF_COUNT, rgb_type, yuv_type); -} - -void camera_close(CameraState *s) { - delete s->frame; -} - -void run_camera(CameraState *s) { - uint32_t stream_frame_id = 0, frame_id = 0; - size_t buf_idx = 0; - std::unique_ptr rgb_buf = std::make_unique(s->frame->getRGBSize()); - std::unique_ptr yuv_buf = std::make_unique(s->frame->getYUVSize()); - while (!do_exit) { - if (stream_frame_id == s->frame->getFrameCount()) { - // loop stream - stream_frame_id = 0; - } - if (s->frame->get(stream_frame_id++, rgb_buf.get(), yuv_buf.get())) { - s->buf.camera_bufs_metadata[buf_idx] = {.frame_id = frame_id}; - auto &buf = s->buf.camera_bufs[buf_idx]; - CL_CHECK(clEnqueueWriteBuffer(buf.copy_q, buf.buf_cl, CL_TRUE, 0, s->frame->getRGBSize(), rgb_buf.get(), 0, NULL, NULL)); - s->buf.queue(buf_idx); - ++frame_id; - buf_idx = (buf_idx + 1) % FRAME_BUF_COUNT; - } - util::sleep_for(1000 / s->fps); - } -} - -void road_camera_thread(CameraState *s) { - util::set_thread_name("replay_road_camera_thread"); - run_camera(s); -} - -// void driver_camera_thread(CameraState *s) { -// util::set_thread_name("replay_driver_camera_thread"); -// run_camera(s); -// } - -void process_road_camera(MultiCameraState *s, CameraState *c, int cnt) { - const CameraBuf *b = &c->buf; - MessageBuilder msg; - auto framed = msg.initEvent().initRoadCameraState(); - fill_frame_data(framed, b->cur_frame_data); - framed.setImage(kj::arrayPtr((const uint8_t *)b->cur_yuv_buf->addr, b->cur_yuv_buf->len)); - framed.setTransform(b->yuv_transform.v); - s->pm->send("roadCameraState", msg); -} - -// void process_driver_camera(MultiCameraState *s, CameraState *c, int cnt) { -// MessageBuilder msg; -// auto framed = msg.initEvent().initDriverCameraState(); -// framed.setFrameType(cereal::FrameData::FrameType::FRONT); -// fill_frame_data(framed, c->buf.cur_frame_data); -// s->pm->send("driverCameraState", msg); -// } - -} // namespace - -void cameras_init(VisionIpcServer *v, MultiCameraState *s, cl_device_id device_id, cl_context ctx) { - camera_init(v, &s->road_cam, CAMERA_ID_LGC920, 20, device_id, ctx, - VISION_STREAM_RGB_ROAD, VISION_STREAM_ROAD, get_url(road_camera_route, "fcamera", 0)); - // camera_init(v, &s->driver_cam, CAMERA_ID_LGC615, 10, device_id, ctx, - // VISION_STREAM_RGB_DRIVER, VISION_STREAM_DRIVER, get_url(driver_camera_route, "dcamera", 0)); - s->pm = new PubMaster({"roadCameraState", "driverCameraState", "thumbnail"}); -} - -void cameras_open(MultiCameraState *s) {} - -void cameras_close(MultiCameraState *s) { - camera_close(&s->road_cam); - camera_close(&s->driver_cam); - delete s->pm; -} - -void cameras_run(MultiCameraState *s) { - std::vector threads; - threads.push_back(start_process_thread(s, &s->road_cam, process_road_camera)); - // threads.push_back(start_process_thread(s, &s->driver_cam, process_driver_camera)); - // threads.push_back(std::thread(driver_camera_thread, &s->driver_cam)); - road_camera_thread(&s->road_cam); - - for (auto &t : threads) t.join(); - - cameras_close(s); -} diff --git a/selfdrive/camerad/cameras/camera_replay.h b/selfdrive/camerad/cameras/camera_replay.h deleted file mode 100644 index 7c41af0ab4..0000000000 --- a/selfdrive/camerad/cameras/camera_replay.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "selfdrive/camerad/cameras/camera_common.h" -#include "selfdrive/ui/replay/framereader.h" - -#define FRAME_BUF_COUNT 16 - -typedef struct CameraState { - int camera_num; - CameraInfo ci; - - int fps; - float digital_gain = 0; - - CameraBuf buf; - FrameReader *frame = nullptr; -} CameraState; - -typedef struct MultiCameraState { - CameraState road_cam; - CameraState driver_cam; - - SubMaster *sm = nullptr; - PubMaster *pm = nullptr; -} MultiCameraState; diff --git a/selfdrive/camerad/cameras/camera_webcam.cc b/selfdrive/camerad/cameras/camera_webcam.cc deleted file mode 100644 index 6001f9fd3b..0000000000 --- a/selfdrive/camerad/cameras/camera_webcam.cc +++ /dev/null @@ -1,197 +0,0 @@ -#include "selfdrive/camerad/cameras/camera_webcam.h" - -#include - -#include -#include - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wundefined-inline" -#include -#include -#include -#include -#pragma clang diagnostic pop - -#include "selfdrive/common/clutil.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/timing.h" -#include "selfdrive/common/util.h" - -// id of the video capturing device -const int ROAD_CAMERA_ID = util::getenv("ROADCAM_ID", 1); -const int DRIVER_CAMERA_ID = util::getenv("DRIVERCAM_ID", 2); - -#define FRAME_WIDTH 1164 -#define FRAME_HEIGHT 874 -#define FRAME_WIDTH_FRONT 1152 -#define FRAME_HEIGHT_FRONT 864 - -extern ExitHandler do_exit; - -namespace { - -CameraInfo cameras_supported[CAMERA_ID_MAX] = { - // road facing - [CAMERA_ID_LGC920] = { - .frame_width = FRAME_WIDTH, - .frame_height = FRAME_HEIGHT, - .frame_stride = FRAME_WIDTH*3, - .bayer = false, - .bayer_flip = false, - }, - // driver facing - [CAMERA_ID_LGC615] = { - .frame_width = FRAME_WIDTH_FRONT, - .frame_height = FRAME_HEIGHT_FRONT, - .frame_stride = FRAME_WIDTH_FRONT*3, - .bayer = false, - .bayer_flip = false, - }, -}; - -void camera_open(CameraState *s, bool rear) { - // empty -} - -void camera_close(CameraState *s) { - // empty -} - -void camera_init(VisionIpcServer * v, CameraState *s, int camera_id, unsigned int fps, cl_device_id device_id, cl_context ctx, VisionStreamType rgb_type, VisionStreamType yuv_type) { - assert(camera_id < std::size(cameras_supported)); - s->ci = cameras_supported[camera_id]; - assert(s->ci.frame_width != 0); - - s->camera_num = camera_id; - s->fps = fps; - s->buf.init(device_id, ctx, s, v, FRAME_BUF_COUNT, rgb_type, yuv_type); -} - -void run_camera(CameraState *s, cv::VideoCapture &video_cap, float *ts) { - assert(video_cap.isOpened()); - - cv::Size size(s->ci.frame_width, s->ci.frame_height); - const cv::Mat transform = cv::Mat(3, 3, CV_32F, ts); - uint32_t frame_id = 0; - size_t buf_idx = 0; - - while (!do_exit) { - cv::Mat frame_mat, transformed_mat; - video_cap >> frame_mat; - if (frame_mat.empty()) continue; - - cv::warpPerspective(frame_mat, transformed_mat, transform, size, cv::INTER_LINEAR, cv::BORDER_CONSTANT, 0); - - s->buf.camera_bufs_metadata[buf_idx] = {.frame_id = frame_id}; - - auto &buf = s->buf.camera_bufs[buf_idx]; - int transformed_size = transformed_mat.total() * transformed_mat.elemSize(); - CL_CHECK(clEnqueueWriteBuffer(buf.copy_q, buf.buf_cl, CL_TRUE, 0, transformed_size, transformed_mat.data, 0, NULL, NULL)); - - s->buf.queue(buf_idx); - - ++frame_id; - buf_idx = (buf_idx + 1) % FRAME_BUF_COUNT; - } -} - -static void road_camera_thread(CameraState *s) { - util::set_thread_name("webcam_road_camera_thread"); - - cv::VideoCapture cap_road(ROAD_CAMERA_ID, cv::CAP_V4L2); // road - cap_road.set(cv::CAP_PROP_FRAME_WIDTH, 853); - cap_road.set(cv::CAP_PROP_FRAME_HEIGHT, 480); - cap_road.set(cv::CAP_PROP_FPS, s->fps); - cap_road.set(cv::CAP_PROP_AUTOFOCUS, 0); // off - cap_road.set(cv::CAP_PROP_FOCUS, 0); // 0 - 255? - // cv::Rect roi_rear(160, 0, 960, 720); - - // transforms calculation see tools/webcam/warp_vis.py - float ts[9] = {1.50330396, 0.0, -59.40969163, - 0.0, 1.50330396, 76.20704846, - 0.0, 0.0, 1.0}; - // if camera upside down: - // float ts[9] = {-1.50330396, 0.0, 1223.4, - // 0.0, -1.50330396, 797.8, - // 0.0, 0.0, 1.0}; - - run_camera(s, cap_road, ts); -} - -void driver_camera_thread(CameraState *s) { - cv::VideoCapture cap_driver(DRIVER_CAMERA_ID, cv::CAP_V4L2); // driver - cap_driver.set(cv::CAP_PROP_FRAME_WIDTH, 853); - cap_driver.set(cv::CAP_PROP_FRAME_HEIGHT, 480); - cap_driver.set(cv::CAP_PROP_FPS, s->fps); - // cv::Rect roi_front(320, 0, 960, 720); - - // transforms calculation see tools/webcam/warp_vis.py - float ts[9] = {1.42070485, 0.0, -30.16740088, - 0.0, 1.42070485, 91.030837, - 0.0, 0.0, 1.0}; - // if camera upside down: - // float ts[9] = {-1.42070485, 0.0, 1182.2, - // 0.0, -1.42070485, 773.0, - // 0.0, 0.0, 1.0}; - run_camera(s, cap_driver, ts); -} - -} // namespace - -void cameras_init(VisionIpcServer *v, MultiCameraState *s, cl_device_id device_id, cl_context ctx) { - camera_init(v, &s->road_cam, CAMERA_ID_LGC920, 20, device_id, ctx, - VISION_STREAM_RGB_ROAD, VISION_STREAM_ROAD); - camera_init(v, &s->driver_cam, CAMERA_ID_LGC615, 10, device_id, ctx, - VISION_STREAM_RGB_DRIVER, VISION_STREAM_DRIVER); - s->pm = new PubMaster({"roadCameraState", "driverCameraState", "thumbnail"}); -} - -void camera_autoexposure(CameraState *s, float grey_frac) {} - -void cameras_open(MultiCameraState *s) { - // LOG("*** open driver camera ***"); - camera_open(&s->driver_cam, false); - // LOG("*** open road camera ***"); - camera_open(&s->road_cam, true); -} - -void cameras_close(MultiCameraState *s) { - camera_close(&s->road_cam); - camera_close(&s->driver_cam); - delete s->pm; -} - -void process_driver_camera(MultiCameraState *s, CameraState *c, int cnt) { - MessageBuilder msg; - auto framed = msg.initEvent().initDriverCameraState(); - framed.setFrameType(cereal::FrameData::FrameType::FRONT); - fill_frame_data(framed, c->buf.cur_frame_data); - s->pm->send("driverCameraState", msg); -} - -void process_road_camera(MultiCameraState *s, CameraState *c, int cnt) { - const CameraBuf *b = &c->buf; - MessageBuilder msg; - auto framed = msg.initEvent().initRoadCameraState(); - fill_frame_data(framed, b->cur_frame_data); - framed.setImage(kj::arrayPtr((const uint8_t *)b->cur_yuv_buf->addr, b->cur_yuv_buf->len)); - framed.setTransform(b->yuv_transform.v); - s->pm->send("roadCameraState", msg); -} - -void cameras_run(MultiCameraState *s) { - std::vector threads; - threads.push_back(start_process_thread(s, &s->road_cam, process_road_camera)); - threads.push_back(start_process_thread(s, &s->driver_cam, process_driver_camera)); - - std::thread t_rear = std::thread(road_camera_thread, &s->road_cam); - util::set_thread_name("webcam_thread"); - driver_camera_thread(&s->driver_cam); - - t_rear.join(); - - for (auto &t : threads) t.join(); - - cameras_close(s); -} diff --git a/selfdrive/camerad/cameras/camera_webcam.h b/selfdrive/camerad/cameras/camera_webcam.h deleted file mode 100644 index 819387f3d6..0000000000 --- a/selfdrive/camerad/cameras/camera_webcam.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#ifdef __APPLE__ -#include -#else -#include -#endif - -#include "selfdrive/camerad/cameras/camera_common.h" - -#define FRAME_BUF_COUNT 16 - -typedef struct CameraState { - CameraInfo ci; - int camera_num; - int fps; - float digital_gain; - CameraBuf buf; -} CameraState; - - -typedef struct MultiCameraState { - CameraState road_cam; - CameraState driver_cam; - - SubMaster *sm; - PubMaster *pm; -} MultiCameraState; diff --git a/selfdrive/camerad/cameras/real_debayer.cl b/selfdrive/camerad/cameras/real_debayer.cl index 6452e44ebb..fc9f410494 100644 --- a/selfdrive/camerad/cameras/real_debayer.cl +++ b/selfdrive/camerad/cameras/real_debayer.cl @@ -1,206 +1,158 @@ -#pragma OPENCL EXTENSION cl_khr_fp16 : enable - -const __constant half3 color_correction[3] = { - // post wb CCM - (half3)(1.82717181, -0.31231438, 0.07307673), - (half3)(-0.5743977, 1.36858544, -0.53183455), - (half3)(-0.25277411, -0.05627105, 1.45875782), -}; - -// tone mapping params -const half cpk = 0.75; -const half cpb = 0.125; -const half cpxk = 0.0025; -const half cpxb = 0.01; - -half mf(half x, half cp) { - half rk = 9 - 100*cp; - if (x > cp) { - return (rk * (x-cp) * (1-(cpk*cp+cpb)) * (1+1/(rk*(1-cp))) / (1+rk*(x-cp))) + cpk*cp + cpb; - } else if (x < cp) { - return (rk * (x-cp) * (cpk*cp+cpb) * (1+1/(rk*cp)) / (1-rk*(x-cp))) + cpk*cp + cpb; - } else { - return x; - } +#define UV_WIDTH RGB_WIDTH / 2 +#define UV_HEIGHT RGB_HEIGHT / 2 + +#define RGB_TO_Y(r, g, b) ((((mul24(b, 13) + mul24(g, 65) + mul24(r, 33)) + 64) >> 7) + 16) +#define RGB_TO_U(r, g, b) ((mul24(b, 56) - mul24(g, 37) - mul24(r, 19) + 0x8080) >> 8) +#define RGB_TO_V(r, g, b) ((mul24(r, 56) - mul24(g, 47) - mul24(b, 9) + 0x8080) >> 8) +#define AVERAGE(x, y, z, w) ((convert_ushort(x) + convert_ushort(y) + convert_ushort(z) + convert_ushort(w) + 1) >> 1) + +float3 color_correct(float3 rgb) { + // color correction + float3 x = rgb.x * (float3)(1.82717181, -0.31231438, 0.07307673); + x += rgb.y * (float3)(-0.5743977, 1.36858544, -0.53183455); + x += rgb.z * (float3)(-0.25277411, -0.05627105, 1.45875782); + + // tone mapping params + const float gamma_k = 0.75; + const float gamma_b = 0.125; + const float mp = 0.01; // ideally midpoint should be adaptive + const float rk = 9 - 100*mp; + + // poly approximation for s curve + return (x > mp) ? + ((rk * (x-mp) * (1-(gamma_k*mp+gamma_b)) * (1+1/(rk*(1-mp))) / (1+rk*(x-mp))) + gamma_k*mp + gamma_b) : + ((rk * (x-mp) * (gamma_k*mp+gamma_b) * (1+1/(rk*mp)) / (1-rk*(x-mp))) + gamma_k*mp + gamma_b); } -half3 color_correct(half3 rgb) { - half3 ret = (0,0,0); - half cpx = 0.01; - ret += (half)rgb.x * color_correction[0]; - ret += (half)rgb.y * color_correction[1]; - ret += (half)rgb.z * color_correction[2]; - ret.x = mf(ret.x, cpx); - ret.y = mf(ret.y, cpx); - ret.z = mf(ret.z, cpx); - ret = clamp(0.0h, 255.0h, ret*255.0h); - return ret; -} - -inline half val_from_10(const uchar * source, int gx, int gy, half black_level) { - // parse 12bit - int start = gy * FRAME_STRIDE + (3 * (gx / 2)); - int offset = gx % 2; - uint major = (uint)source[start + offset] << 4; - uint minor = (source[start + 2] >> (4 * offset)) & 0xf; - half pv = (half)((major + minor)/4); - - // normalize - pv = max(0.0h, pv - black_level); - pv /= (1024.0f - black_level); - - // correct vignetting - if (CAM_NUM == 1) { // fcamera - gx = (gx - RGB_WIDTH/2); - gy = (gy - RGB_HEIGHT/2); - float r = gx*gx + gy*gy; - half s; - if (r < 62500) { - s = (half)(1.0f + 0.0000008f*r); - } else if (r < 490000) { - s = (half)(0.9625f + 0.0000014f*r); - } else if (r < 1102500) { - s = (half)(1.26434f + 0.0000000000016f*r*r); - } else { - s = (half)(0.53503625f + 0.0000000000022f*r*r); - } - pv = s * pv; +float get_vignetting_s(float r) { + if (r < 62500) { + return (1.0f + 0.0000008f*r); + } else if (r < 490000) { + return (0.9625f + 0.0000014f*r); + } else if (r < 1102500) { + return (1.26434f + 0.0000000000016f*r*r); + } else { + return (0.53503625f + 0.0000000000022f*r*r); } - - pv = clamp(0.0h, 1.0h, pv); - return pv; } -half fabs_diff(half x, half y) { - return fabs(x-y); +float4 val4_from_12(uchar8 pvs, float gain) { + uint4 parsed = (uint4)(((uint)pvs.s0<<4) + (pvs.s1>>4), // is from the previous 10 bit + ((uint)pvs.s2<<4) + (pvs.s4&0xF), + ((uint)pvs.s3<<4) + (pvs.s4>>4), + ((uint)pvs.s5<<4) + (pvs.s7&0xF)); + // normalize and scale + float4 pv = (convert_float4(parsed) - 168.0) / (4096.0 - 168.0); + return clamp(pv*gain, 0.0, 1.0); } -half phi(half x) { - // detection funtion - return 2 - x; - // if (x > 1) { - // return 1 / x; - // } else { - // return 2 - x; - // } +float get_k(float a, float b, float c, float d) { + return 2.0 - (fabs(a - b) + fabs(c - d)); } -__kernel void debayer10(const __global uchar * in, - __global uchar * out, - __local half * cached, - float black_level - ) +__kernel void debayer10(const __global uchar * in, __global uchar * out) { - const int x_global = get_global_id(0); - const int y_global = get_global_id(1); - - const int localRowLen = 2 + get_local_size(0); // 2 padding - const int x_local = get_local_id(0); // 0-15 - const int y_local = get_local_id(1); // 0-15 - const int localOffset = (y_local + 1) * localRowLen + x_local + 1; // max 18x18-1 + const int gid_x = get_global_id(0); + const int gid_y = get_global_id(1); - int out_idx = 3 * x_global + 3 * y_global * RGB_WIDTH; + const int y_top_mod = (gid_y == 0) ? 2: 0; + const int y_bot_mod = (gid_y == (RGB_HEIGHT/2 - 1)) ? 1: 3; - half pv = val_from_10(in, x_global, y_global, black_level); - cached[localOffset] = pv; + float3 rgb; + uchar3 rgb_out[4]; - // don't care - if (x_global < 1 || x_global >= RGB_WIDTH - 1 || y_global < 1 || y_global >= RGB_HEIGHT - 1) { - return; - } + int start = (2 * gid_y - 1) * FRAME_STRIDE + (3 * gid_x - 2) + (FRAME_STRIDE * FRAME_OFFSET); - // cache padding - int localColOffset = -1; - int globalColOffset = -1; - - // cache padding - if (x_local < 1) { - localColOffset = x_local; - globalColOffset = -1; - cached[(y_local + 1) * localRowLen + x_local] = val_from_10(in, x_global-1, y_global, black_level); - } else if (x_local >= get_local_size(0) - 1) { - localColOffset = x_local + 2; - globalColOffset = 1; - cached[localOffset + 1] = val_from_10(in, x_global+1, y_global, black_level); - } + // read in 8x4 chars + uchar8 dat[4]; + dat[0] = vload8(0, in + start + FRAME_STRIDE*y_top_mod); + dat[1] = vload8(0, in + start + FRAME_STRIDE*1); + dat[2] = vload8(0, in + start + FRAME_STRIDE*2); + dat[3] = vload8(0, in + start + FRAME_STRIDE*y_bot_mod); - if (y_local < 1) { - cached[y_local * localRowLen + x_local + 1] = val_from_10(in, x_global, y_global-1, black_level); - if (localColOffset != -1) { - cached[y_local * localRowLen + localColOffset] = val_from_10(in, x_global+globalColOffset, y_global-1, black_level); - } - } else if (y_local >= get_local_size(1) - 1) { - cached[(y_local + 2) * localRowLen + x_local + 1] = val_from_10(in, x_global, y_global+1, black_level); - if (localColOffset != -1) { - cached[(y_local + 2) * localRowLen + localColOffset] = val_from_10(in, x_global+globalColOffset, y_global+1, black_level); - } + // correct vignetting + #if VIGNETTING + int gx = (gid_x*2 - RGB_WIDTH/2); + int gy = (gid_y*2 - RGB_HEIGHT/2); + const float gain = get_vignetting_s(gx*gx + gy*gy); + #else + const float gain = 1.0; + #endif + + // process them to floats + float4 va = val4_from_12(dat[0], gain); + float4 vb = val4_from_12(dat[1], gain); + float4 vc = val4_from_12(dat[2], gain); + float4 vd = val4_from_12(dat[3], gain); + + if (gid_x == 0) { + va.s0 = va.s2; + vb.s0 = vb.s2; + vc.s0 = vc.s2; + vd.s0 = vd.s2; + } else if (gid_x == RGB_WIDTH/2 - 1) { + va.s3 = va.s1; + vb.s3 = vb.s1; + vc.s3 = vc.s1; + vd.s3 = vd.s1; } - // sync - barrier(CLK_LOCAL_MEM_FENCE); - - half d1 = cached[localOffset - localRowLen - 1]; - half d2 = cached[localOffset - localRowLen + 1]; - half d3 = cached[localOffset + localRowLen - 1]; - half d4 = cached[localOffset + localRowLen + 1]; - half n1 = cached[localOffset - localRowLen]; - half n2 = cached[localOffset + 1]; - half n3 = cached[localOffset + localRowLen]; - half n4 = cached[localOffset - 1]; - - half3 rgb; - // a simplified version of https://opensignalprocessingjournal.com/contents/volumes/V6/TOSIGPJ-6-1/TOSIGPJ-6-1.pdf - if (x_global % 2 == 0) { - if (y_global % 2 == 0) { - rgb.y = pv; // G1(R) - half k1 = phi(fabs_diff(d1, pv) + fabs_diff(d2, pv)); - half k2 = phi(fabs_diff(d2, pv) + fabs_diff(d4, pv)); - half k3 = phi(fabs_diff(d3, pv) + fabs_diff(d4, pv)); - half k4 = phi(fabs_diff(d1, pv) + fabs_diff(d3, pv)); - // R_G1 - rgb.x = (k2*n2+k4*n4)/(k2+k4); - // B_G1 - rgb.z = (k1*n1+k3*n3)/(k1+k3); - } else { - rgb.z = pv; // B - half k1 = phi(fabs_diff(d1, d3) + fabs_diff(d2, d4)); - half k2 = phi(fabs_diff(n1, n4) + fabs_diff(n2, n3)); - half k3 = phi(fabs_diff(d1, d2) + fabs_diff(d3, d4)); - half k4 = phi(fabs_diff(n1, n2) + fabs_diff(n3, n4)); - // G_B - rgb.y = (k1*(n1+n3)*0.5+k3*(n2+n4)*0.5)/(k1+k3); - // R_B - rgb.x = (k2*(d2+d3)*0.5+k4*(d1+d4)*0.5)/(k2+k4); - } - } else { - if (y_global % 2 == 0) { - rgb.x = pv; // R - half k1 = phi(fabs_diff(d1, d3) + fabs_diff(d2, d4)); - half k2 = phi(fabs_diff(n1, n4) + fabs_diff(n2, n3)); - half k3 = phi(fabs_diff(d1, d2) + fabs_diff(d3, d4)); - half k4 = phi(fabs_diff(n1, n2) + fabs_diff(n3, n4)); - // G_R - rgb.y = (k1*(n1+n3)*0.5+k3*(n2+n4)*0.5)/(k1+k3); - // B_R - rgb.z = (k2*(d2+d3)*0.5+k4*(d1+d4)*0.5)/(k2+k4); - } else { - rgb.y = pv; // G2(B) - half k1 = phi(fabs_diff(d1, pv) + fabs_diff(d2, pv)); - half k2 = phi(fabs_diff(d2, pv) + fabs_diff(d4, pv)); - half k3 = phi(fabs_diff(d3, pv) + fabs_diff(d4, pv)); - half k4 = phi(fabs_diff(d1, pv) + fabs_diff(d3, pv)); - // R_G2 - rgb.x = (k1*n1+k3*n3)/(k1+k3); - // B_G2 - rgb.z = (k2*n2+k4*n4)/(k2+k4); - } - } - - rgb = clamp(0.0h, 1.0h, rgb); - rgb = color_correct(rgb); - - out[out_idx + 0] = (uchar)(rgb.z); - out[out_idx + 1] = (uchar)(rgb.y); - out[out_idx + 2] = (uchar)(rgb.x); + const float k01 = get_k(va.s0, vb.s1, va.s2, vb.s1); + const float k02 = get_k(va.s2, vb.s1, vc.s2, vb.s1); + const float k03 = get_k(vc.s0, vb.s1, vc.s2, vb.s1); + const float k04 = get_k(va.s0, vb.s1, vc.s0, vb.s1); + rgb.x = (k02*vb.s2+k04*vb.s0)/(k02+k04); // R_G1 + rgb.y = vb.s1; // G1(R) + rgb.z = (k01*va.s1+k03*vc.s1)/(k01+k03); // B_G1 + rgb_out[0] = convert_uchar3_sat(color_correct(clamp(rgb, 0.0, 1.0)) * 255.0); + + const float k11 = get_k(va.s1, vc.s1, va.s3, vc.s3); + const float k12 = get_k(va.s2, vb.s1, vb.s3, vc.s2); + const float k13 = get_k(va.s1, va.s3, vc.s1, vc.s3); + const float k14 = get_k(va.s2, vb.s3, vc.s2, vb.s1); + rgb.x = vb.s2; // R + rgb.y = (k11*(va.s2+vc.s2)*0.5+k13*(vb.s3+vb.s1)*0.5)/(k11+k13); // G_R + rgb.z = (k12*(va.s3+vc.s1)*0.5+k14*(va.s1+vc.s3)*0.5)/(k12+k14); // B_R + rgb_out[1] = convert_uchar3_sat(color_correct(clamp(rgb, 0.0, 1.0)) * 255.0); + + const float k21 = get_k(vb.s0, vd.s0, vb.s2, vd.s2); + const float k22 = get_k(vb.s1, vc.s0, vc.s2, vd.s1); + const float k23 = get_k(vb.s0, vb.s2, vd.s0, vd.s2); + const float k24 = get_k(vb.s1, vc.s2, vd.s1, vc.s0); + rgb.x = (k22*(vb.s2+vd.s0)*0.5+k24*(vb.s0+vd.s2)*0.5)/(k22+k24); // R_B + rgb.y = (k21*(vb.s1+vd.s1)*0.5+k23*(vc.s2+vc.s0)*0.5)/(k21+k23); // G_B + rgb.z = vc.s1; // B + rgb_out[2] = convert_uchar3_sat(color_correct(clamp(rgb, 0.0, 1.0)) * 255.0); + + const float k31 = get_k(vb.s1, vc.s2, vb.s3, vc.s2); + const float k32 = get_k(vb.s3, vc.s2, vd.s3, vc.s2); + const float k33 = get_k(vd.s1, vc.s2, vd.s3, vc.s2); + const float k34 = get_k(vb.s1, vc.s2, vd.s1, vc.s2); + rgb.x = (k31*vb.s2+k33*vd.s2)/(k31+k33); // R_G2 + rgb.y = vc.s2; // G2(B) + rgb.z = (k32*vc.s3+k34*vc.s1)/(k32+k34); // B_G2 + rgb_out[3] = convert_uchar3_sat(color_correct(clamp(rgb, 0.0, 1.0)) * 255.0); + + // write ys + uchar2 yy = (uchar2)( + RGB_TO_Y(rgb_out[0].s0, rgb_out[0].s1, rgb_out[0].s2), + RGB_TO_Y(rgb_out[1].s0, rgb_out[1].s1, rgb_out[1].s2) + ); + vstore2(yy, 0, out + mad24(gid_y * 2, YUV_STRIDE, gid_x * 2)); + yy = (uchar2)( + RGB_TO_Y(rgb_out[2].s0, rgb_out[2].s1, rgb_out[2].s2), + RGB_TO_Y(rgb_out[3].s0, rgb_out[3].s1, rgb_out[3].s2) + ); + vstore2(yy, 0, out + mad24(gid_y * 2 + 1, YUV_STRIDE, gid_x * 2)); + + // write uvs + const short ar = AVERAGE(rgb_out[0].s0, rgb_out[1].s0, rgb_out[2].s0, rgb_out[3].s0); + const short ag = AVERAGE(rgb_out[0].s1, rgb_out[1].s1, rgb_out[2].s1, rgb_out[3].s1); + const short ab = AVERAGE(rgb_out[0].s2, rgb_out[1].s2, rgb_out[2].s2, rgb_out[3].s2); + uchar2 uv = (uchar2)( + RGB_TO_U(ar, ag, ab), + RGB_TO_V(ar, ag, ab) + ); + vstore2(uv, 0, out + UV_OFFSET + mad24(gid_y, YUV_STRIDE, gid_x * 2)); } diff --git a/selfdrive/camerad/cameras/sensor2_i2c.h b/selfdrive/camerad/cameras/sensor2_i2c.h index e85223243f..284347623b 100644 --- a/selfdrive/camerad/cameras/sensor2_i2c.h +++ b/selfdrive/camerad/cameras/sensor2_i2c.h @@ -7,7 +7,7 @@ struct i2c_random_wr_payload init_array_imx390[] = { {0x2008, 0xd0}, {0x2009, 0x07}, {0x200a, 0x00}, // MODE_VMAX = time between frames {0x200C, 0xe4}, {0x200D, 0x0c}, // MODE_HMAX - // crop + // crop {0x3410, 0x88}, {0x3411, 0x7}, // CROP_H_SIZE {0x3418, 0xb8}, {0x3419, 0x4}, // CROP_V_SIZE {0x0078, 1}, {0x03c0, 1}, @@ -49,11 +49,15 @@ struct i2c_random_wr_payload init_array_ar0231[] = { {0x301A, 0x0018}, // RESET_REGISTER // CLOCK Settings + // input clock is 19.2 / 2 * 0x37 = 528 MHz + // pixclk is 528 / 6 = 88 MHz + // full roll time is 1000/(PIXCLK/(LINE_LENGTH_PCK*FRAME_LENGTH_LINES)) = 39.99 ms + // img roll time is 1000/(PIXCLK/(LINE_LENGTH_PCK*Y_OUTPUT_CONTROL)) = 22.85 ms {0x302A, 0x0006}, // VT_PIX_CLK_DIV {0x302C, 0x0001}, // VT_SYS_CLK_DIV {0x302E, 0x0002}, // PRE_PLL_CLK_DIV - {0x3030, 0x0032}, // PLL_MULTIPLIER - {0x3036, 0x000C}, // OP_WORD_CLK_DIV + {0x3030, 0x0037}, // PLL_MULTIPLIER + {0x3036, 0x000C}, // OP_PIX_CLK_DIV {0x3038, 0x0001}, // OP_SYS_CLK_DIV // FORMAT @@ -67,7 +71,7 @@ struct i2c_random_wr_payload init_array_ar0231[] = { {0x30A6, 0x0001}, // Y_ODD_INC_ {0x3402, 0x0788}, // X_OUTPUT_CONTROL {0x3404, 0x04B8}, // Y_OUTPUT_CONTROL - {0x3064, 0x1802}, // SMIA_TEST + {0x3064, 0x1982}, // SMIA_TEST {0x30BA, 0x11F2}, // DIGITAL_CTRL // Enable external trigger and disable GPIO outputs @@ -76,17 +80,17 @@ struct i2c_random_wr_payload init_array_ar0231[] = { {0x340C, 0x802}, // GPIO_HIDRV_EN | GPIO0_ISEL=2 // Readout timing - {0x300C, 0x07B9}, // LINE_LENGTH_PCK - {0x300A, 0x0652}, // FRAME_LENGTH_LINES + {0x300C, 0x0672}, // LINE_LENGTH_PCK (valid for 3-exposure HDR) + {0x300A, 0x0855}, // FRAME_LENGTH_LINES {0x3042, 0x0000}, // EXTRA_DELAY // Readout Settings {0x31AE, 0x0204}, // SERIAL_FORMAT, 4-lane MIPI {0x31AC, 0x0C0C}, // DATA_FORMAT_BITS, 12 -> 12 - {0x3342, 0x122C}, // MIPI_F1_PDT_EDT - {0x3346, 0x122C}, // MIPI_F2_PDT_EDT - {0x334A, 0x122C}, // MIPI_F3_PDT_EDT - {0x334E, 0x122C}, // MIPI_F4_PDT_EDT + {0x3342, 0x1212}, // MIPI_F1_PDT_EDT + {0x3346, 0x1212}, // MIPI_F2_PDT_EDT + {0x334A, 0x1212}, // MIPI_F3_PDT_EDT + {0x334E, 0x1212}, // MIPI_F4_PDT_EDT {0x3344, 0x0011}, // MIPI_F1_VDT_VC {0x3348, 0x0111}, // MIPI_F2_VDT_VC {0x334C, 0x0211}, // MIPI_F3_VDT_VC @@ -101,6 +105,10 @@ struct i2c_random_wr_payload init_array_ar0231[] = { {0x3370, 0x03B1}, // DBLC {0x3044, 0x0400}, // DARK_CONTROL + // Enable temperature sensor + {0x30B4, 0x0007}, // TEMPSENS0_CTRL_REG + {0x30B8, 0x0007}, // TEMPSENS1_CTRL_REG + // Enable dead pixel correction using // the 1D line correction scheme {0x31E0, 0x0003}, @@ -113,10 +121,10 @@ struct i2c_random_wr_payload init_array_ar0231[] = { {0x100C, 0x0589}, // FINE_INTEGRATION_TIME2_MIN {0x100E, 0x07B1}, // FINE_INTEGRATION_TIME3_MIN {0x1010, 0x0139}, // FINE_INTEGRATION_TIME4_MIN + + // TODO: do these have to be lower than LINE_LENGTH_PCK? {0x3014, 0x08CB}, // FINE_INTEGRATION_TIME_ - {0x321E, 0x08CB}, // FINE_INTEGRATION_TIME2 - {0x321E, 0x08CB}, // FINE_INTEGRATION_TIME3 - {0x321E, 0x0894}, // FINE_INTEGRATION_TIME4 + {0x321E, 0x0894}, // FINE_INTEGRATION_TIME2 {0x31D0, 0x0000}, // COMPANDING, no good in 10 bit? {0x33DA, 0x0000}, // COMPANDING diff --git a/selfdrive/camerad/cameras/sensor_i2c.h b/selfdrive/camerad/cameras/sensor_i2c.h deleted file mode 100644 index b46ebb370a..0000000000 --- a/selfdrive/camerad/cameras/sensor_i2c.h +++ /dev/null @@ -1,651 +0,0 @@ -static struct msm_camera_i2c_reg_array init_array_imx298[] = { - {0x101,0x0,0}, // IMAGE_ORIENT - {0x601,0x0,0}, // test pattern - //{0xb02,0,0}, // green correction? - // external clock setting - {0x136,0x18,0}, {0x137,0x0,0}, // EXCK_FREQ = Extclk_frequency_mhz - // global setting? - {0x30f4,0x1,0}, - {0x30f5,0x7a,0}, - {0x30f6,0x0,0}, - {0x30f7,0xec,0}, - {0x30fc,0x1,0}, - {0x3101,0x1,0}, - {0x5b2f,0x8,0}, - {0x5d32,0x5,0}, - {0x5d7c,0x0,0}, - {0x5d7d,0x0,0}, - {0x5db9,0x1,0}, - {0x5e43,0x0,0}, - {0x6300,0x0,0}, - {0x6301,0xea,0}, - {0x6302,0x0,0}, - {0x6303,0xb4,0}, - {0x6564,0x0,0}, - {0x6565,0xb6,0}, - {0x6566,0x0,0}, - {0x6567,0xe6,0}, - {0x6714,0x1,0}, - {0x6758,0xb,0}, - {0x6910,0x4,0}, - {0x6916,0x1,0}, - {0x6918,0x4,0}, - {0x691e,0x1,0}, - {0x6931,0x1,0}, - {0x6937,0x2,0}, - {0x693b,0x2,0}, - {0x6d00,0x4a,0}, - {0x6d01,0x41,0}, - {0x6d02,0x23,0}, - {0x6d05,0x4c,0}, - {0x6d06,0x10,0}, - {0x6d08,0x30,0}, - {0x6d09,0x38,0}, - {0x6d0a,0x2c,0}, - {0x6d0b,0x2d,0}, - {0x6d0c,0x34,0}, - {0x6d0d,0x42,0}, - {0x6d19,0x1c,0}, - {0x6d1a,0x71,0}, - {0x6d1b,0xc6,0}, - {0x6d1c,0x94,0}, - {0x6d24,0xe4,0}, - {0x6d30,0xa,0}, - {0x6d31,0x1,0}, - {0x6d33,0xb,0}, - {0x6d34,0x5,0}, - {0x6d35,0x0,0}, - {0x83c2,0x3,0}, - {0x83c3,0x8,0}, - {0x83c4,0x48,0}, - {0x83c7,0x8,0}, - {0x83cb,0x0,0}, - {0xb101,0xff,0}, - {0xb103,0xff,0}, - {0xb105,0xff,0}, - {0xb107,0xff,0}, - {0xb109,0xff,0}, - {0xb10b,0xff,0}, - {0xb10d,0xff,0}, - {0xb10f,0xff,0}, - {0xb111,0xff,0}, - {0xb163,0x3c,0}, - {0xc2a0,0x8,0}, - {0xc2a3,0x3,0}, - {0xc2a5,0x8,0}, - {0xc2a6,0x48,0}, - {0xc2a9,0x0,0}, - {0xf800,0x5e,0}, - {0xf801,0x5e,0}, - {0xf802,0xcd,0}, - {0xf803,0x20,0}, - {0xf804,0x55,0}, - {0xf805,0xd4,0}, - {0xf806,0x1f,0}, - {0xf808,0xf8,0}, - {0xf809,0x3a,0}, - {0xf80a,0xf1,0}, - {0xf80b,0x7e,0}, - {0xf80c,0x55,0}, - {0xf80d,0x38,0}, - {0xf80e,0xe3,0}, - {0xf810,0x74,0}, - {0xf811,0x41,0}, - {0xf812,0xbf,0}, - {0xf844,0x40,0}, - {0xf845,0xba,0}, - {0xf846,0x70,0}, - {0xf847,0x47,0}, - {0xf848,0xc0,0}, - {0xf849,0xba,0}, - {0xf84a,0x70,0}, - {0xf84b,0x47,0}, - {0xf84c,0x82,0}, - {0xf84d,0xf6,0}, - {0xf84e,0x32,0}, - {0xf84f,0xfd,0}, - {0xf851,0xf0,0}, - {0xf852,0x2,0}, - {0xf853,0xf8,0}, - {0xf854,0x81,0}, - {0xf855,0xf6,0}, - {0xf856,0xc0,0}, - {0xf857,0xff,0}, - {0xf858,0x10,0}, - {0xf859,0xb5,0}, - {0xf85a,0xd,0}, - {0xf85b,0x48,0}, - {0xf85c,0x40,0}, - {0xf85d,0x7a,0}, - {0xf85e,0x1,0}, - {0xf85f,0x28,0}, - {0xf860,0x15,0}, - {0xf861,0xd1,0}, - {0xf862,0xc,0}, - {0xf863,0x49,0}, - {0xf864,0xc,0}, - {0xf865,0x46,0}, - {0xf866,0x40,0}, - {0xf867,0x3c,0}, - {0xf868,0x48,0}, - {0xf869,0x8a,0}, - {0xf86a,0x62,0}, - {0xf86b,0x8a,0}, - {0xf86c,0x80,0}, - {0xf86d,0x1a,0}, - {0xf86e,0x8a,0}, - {0xf86f,0x89,0}, - {0xf871,0xb2,0}, - {0xf872,0x10,0}, - {0xf873,0x18,0}, - {0xf874,0xa,0}, - {0xf875,0x46,0}, - {0xf876,0x20,0}, - {0xf877,0x32,0}, - {0xf878,0x12,0}, - {0xf879,0x88,0}, - {0xf87a,0x90,0}, - {0xf87b,0x42,0}, - {0xf87d,0xda,0}, - {0xf87e,0x10,0}, - {0xf87f,0x46,0}, - {0xf880,0x80,0}, - {0xf881,0xb2,0}, - {0xf882,0x88,0}, - {0xf883,0x81,0}, - {0xf884,0x84,0}, - {0xf885,0xf6,0}, - {0xf886,0xd2,0}, - {0xf887,0xf9,0}, - {0xf888,0xe0,0}, - {0xf889,0x67,0}, - {0xf88a,0x85,0}, - {0xf88b,0xf6,0}, - {0xf88c,0xa1,0}, - {0xf88d,0xfc,0}, - {0xf88e,0x10,0}, - {0xf88f,0xbd,0}, - {0xf891,0x18,0}, - {0xf892,0x21,0}, - {0xf893,0x24,0}, - {0xf895,0x18,0}, - {0xf896,0x19,0}, - {0xf897,0xb4,0}, - {0x4e29,0x1,0}, - // PDAF stuff - {0x3166,0x1,0}, //AREA_EN_0 - {0x3167,0x1,0}, - {0x3168,0x1,0}, - {0x3169,0x1,0}, - {0x316a,0x1,0}, - {0x316b,0x1,0}, - {0x316c,0x1,0}, - {0x316d,0x1,0}, - {0x3158,0x2,0}, - {0x3159,0x2,0}, - {0x315a,0x2,0}, - {0x315b,0x3,0}, - {0x3013,0x7,0}, //RMSC_NR_MODE - {0x3035,0x1,0}, - {0x3051,0x0,0}, - {0x3056,0x2,0}, - {0x3057,0x1,0}, - {0x3060,0x0,0}, - {0x8435,0x0,0}, - {0x8455,0x0,0}, - {0x847c,0x0,0}, - {0x84fb,0x1,0}, - {0x9619,0xa0,0}, - {0x961b,0xa0,0}, - {0x961d,0xa0,0}, - {0x961f,0x20,0}, - {0x9621,0x20,0}, - {0x9623,0x20,0}, - {0x9625,0xa0,0}, - {0x9627,0xa0,0}, - {0x9629,0xa0,0}, - {0x962b,0x20,0}, - {0x962d,0x20,0}, - {0x962f,0x20,0}, - {0x9901,0x35,0}, - {0x9903,0x23,0}, - {0x9905,0x23,0}, - {0x9906,0x0,0}, - {0x9907,0x31,0}, - {0x9908,0x0,0}, - {0x9909,0x1b,0}, - {0x990a,0x0,0}, - {0x990b,0x15,0}, - {0x990d,0x3f,0}, - {0x990f,0x3f,0}, - {0x9911,0x3f,0}, - {0x9913,0x64,0}, - {0x9915,0x64,0}, - {0x9917,0x64,0}, - {0x9919,0x50,0}, - {0x991b,0x60,0}, - {0x991d,0x65,0}, - {0x991f,0x1,0}, - {0x9921,0x1,0}, - {0x9923,0x1,0}, - {0x9925,0x23,0}, - {0x9927,0x23,0}, - {0x9929,0x23,0}, - {0x992b,0x2f,0}, - {0x992d,0x1a,0}, - {0x992f,0x14,0}, - {0x9931,0x3f,0}, - {0x9933,0x3f,0}, - {0x9935,0x3f,0}, - {0x9937,0x6b,0}, - {0x9939,0x7c,0}, - {0x993b,0x81,0}, - {0x9943,0xf,0}, - {0x9945,0xf,0}, - {0x9947,0xf,0}, - {0x9949,0xf,0}, - {0x994b,0xf,0}, - {0x994d,0xf,0}, - {0x994f,0x42,0}, - {0x9951,0xf,0}, - {0x9953,0xb,0}, - {0x9955,0x5a,0}, - {0x9957,0x13,0}, - {0x9959,0xc,0}, - {0x995a,0x0,0}, - {0x995b,0x0,0}, - {0x995c,0x0,0}, - {0x996b,0x0,0}, - {0x996d,0x10,0}, - {0x996f,0x10,0}, - {0x9971,0xc8,0}, - {0x9973,0x32,0}, - {0x9975,0x4,0}, - {0x9976,0xa,0}, - {0x9977,0xa,0}, - {0x9978,0xa,0}, - {0x99a4,0x2f,0}, - {0x99a5,0x2f,0}, - {0x99a6,0x2f,0}, - {0x99a7,0xa,0}, - {0x99a8,0xa,0}, - {0x99a9,0xa,0}, - {0x99aa,0x2f,0}, - {0x99ab,0x2f,0}, - {0x99ac,0x2f,0}, - {0x99ad,0x0,0}, - {0x99ae,0x0,0}, - {0x99af,0x0,0}, - {0x99b0,0x40,0}, - {0x99b1,0x40,0}, - {0x99b2,0x40,0}, - {0x99b3,0x30,0}, - {0x99b4,0x30,0}, - {0x99b5,0x30,0}, - {0x99bb,0xa,0}, - {0x99bd,0xa,0}, - {0x99bf,0xa,0}, - {0x99c0,0x9,0}, - {0x99c1,0x9,0}, - {0x99c2,0x9,0}, - {0x99c6,0x3c,0}, - {0x99c7,0x3c,0}, - {0x99c8,0x3c,0}, - {0x99c9,0xff,0}, - {0x99ca,0xff,0}, - {0x99cb,0xff,0}, - {0x9b01,0x35,0}, - {0x9b03,0x14,0}, - {0x9b05,0x14,0}, - {0x9b07,0x31,0}, - {0x9b09,0x1b,0}, - {0x9b0b,0x15,0}, - {0x9b0d,0x1e,0}, - {0x9b0f,0x1e,0}, - {0x9b11,0x1e,0}, - {0x9b13,0x64,0}, - {0x9b15,0x64,0}, - {0x9b17,0x64,0}, - {0x9b19,0x50,0}, - {0x9b1b,0x60,0}, - {0x9b1d,0x65,0}, - {0x9b1f,0x1,0}, - {0x9b21,0x1,0}, - {0x9b23,0x1,0}, - {0x9b25,0x14,0}, - {0x9b27,0x14,0}, - {0x9b29,0x14,0}, - {0x9b2b,0x2f,0}, - {0x9b2d,0x1a,0}, - {0x9b2f,0x14,0}, - {0x9b31,0x1e,0}, - {0x9b33,0x1e,0}, - {0x9b35,0x1e,0}, - {0x9b37,0x6b,0}, - {0x9b39,0x7c,0}, - {0x9b3b,0x81,0}, - {0x9b43,0xf,0}, - {0x9b45,0xf,0}, - {0x9b47,0xf,0}, - {0x9b49,0xf,0}, - {0x9b4b,0xf,0}, - {0x9b4d,0xf,0}, - {0x9b4f,0x2d,0}, - {0x9b51,0xb,0}, - {0x9b53,0x8,0}, - {0x9b55,0x40,0}, - {0x9b57,0xd,0}, - {0x9b59,0x8,0}, - {0x9b5a,0x0,0}, - {0x9b5b,0x0,0}, - {0x9b5c,0x0,0}, - {0x9b6b,0x0,0}, - {0x9b6d,0x10,0}, - {0x9b6f,0x10,0}, - {0x9b71,0xc8,0}, - {0x9b73,0x32,0}, - {0x9b75,0x4,0}, - {0x9bb0,0x40,0}, - {0x9bb1,0x40,0}, - {0x9bb2,0x40,0}, - {0x9bb3,0x30,0}, - {0x9bb4,0x30,0}, - {0x9bb5,0x30,0}, - {0x9bbb,0xa,0}, - {0x9bbd,0xa,0}, - {0x9bbf,0xa,0}, - {0x9bc0,0x9,0}, - {0x9bc1,0x9,0}, - {0x9bc2,0x9,0}, - {0x9bc6,0x18,0}, - {0x9bc7,0x18,0}, - {0x9bc8,0x18,0}, - {0x9bc9,0xff,0}, - {0x9bca,0xff,0}, - {0x9bcb,0xff,0}, - {0xb2b2,0x1,0}, -}; - -static struct msm_camera_i2c_reg_array mode_setting_array_imx298[] = { -// i2c settings for mode 3 -// { -// .x_output = 2328, -// .y_output = 1748, -// .line_length_pclk = 5536, -// .frame_length_lines = 1802, -// .vt_pixel_clk = 299300000, -// .op_pixel_clk = 299300000, -// .binning_factor = 2, -// .min_fps = 15.000000, -// .max_fps = 30.020000, -// .mode = 1, -// .offset_x = 0, -// .offset_y = 0, -// .scale_factor = 1.000000, -// .is_pdaf_supported = 1, -// } - -// mode settings - -// hdr settings -{0x0114, 0x03, 0}, // CSI_LANE_MODE = 4-lane -/*{0x0220, 0x00, 0}, // HDR_MODE = disable -{0x0221, 0x11, 0}, // HDR_RESO_REDU_H/V = Full Pixel -{0x0222, 0x10, 0}, // EXPO_RATIO = 16*/ -{0x0220, 0x01, 0}, // HDR_MODE = enable with combined gain and 16x ratio -{0x0221, 0x22, 0}, // HDR_RESO_REDU_H/V = 2 binning -{0x0222, 0x10, 0}, // EXPO_RATIO = 16 - -{0x0340, 0x07, 0}, {0x0341, 0x0a, 0}, // FRM_LENGTH = frame_length_lines = 1802 -{0x0342, 0x15, 0}, {0x0343, 0xa0, 0}, // LINE_LENGTH = line_length_pclk = 5536 -{0x0344, 0x00, 0}, {0x0345, 0x00, 0}, // x_addr_start -{0x0346, 0x00, 0}, {0x0347, 0x00, 0}, // y_addr_start -{0x0348, 0x12, 0}, {0x0349, 0x2f, 0}, // x_addr_end -{0x034a, 0x0d, 0}, {0x034b, 0xa7, 0}, // y_addr_end -{0x0381, 0x01, 0}, // x_even_inc -{0x0383, 0x01, 0}, // x_odd_inc -{0x0385, 0x01, 0}, // y_even_inc -{0x0387, 0x01, 0}, // y_odd_inc -{0x0900, 0x01, 0}, // BINNING_MODE = enable -{0x0901, 0x22, 0}, // BINING_TYPE_H/V = 2binning -{0x0902, 0x00, 0}, // binning_weighting = average - -{0x0b06, 1, 0}, // SING_DEF_CORR_EN -{0x0b0a, 1, 0}, // combined defect correct - -{0x3010, 0x66, 0}, // HDR_OUTPUT_CTRL = ATR + HDR compose + DPC1D + DCP2D -{0x3011, 0x01, 0}, // HDR_OUTPUT_CTRL2 = PD enable -{0x30c0, 0x11, 0}, // RED_GAIN_CB? -{0x300d, 0x00, 0}, // FORCE_FDSUM = disable -{0x30fd, 0x00, 0}, -{0x8493, 0x00, 0}, -{0x8863, 0x00, 0}, -{0x90d7, 0x19, 0}, - -// set black level -{0x3090, 1, 0}, -{0x3092, 0, 0}, -{0x3093, 0x38, 0}, - -// output size settings -{0x0112, 0x0a, 0}, {0x0113, 0x0a, 0}, // CS_DT_FMT_H = 0x0a0a (RAW10 output) -{0x034c, 0x09, 0}, {0x034d, 0x18, 0}, // X_OUT_SIZE = 2328 (1164*2) -{0x034e, 0x06, 0}, {0x034f, 0xd4, 0}, // Y_OUT_SIZE = 1748 (874*2) -{0x0401, 0x00, 0}, // SCALING_MODE -{0x0404, 0x00, 0}, {0x0405, 0x10, 0}, // SCALE_M -{0x0408, 0x00, 0}, {0x0409, 0x00, 0}, // DCROP_XOFS -{0x040a, 0x00, 0}, {0x040b, 0x00, 0}, // DCROP_YOFS -{0x040c, 0x09, 0}, {0x040d, 0x18, 0}, // DCROP_WIDTH -{0x040e, 0x06, 0}, {0x040f, 0xd4, 0}, // DCROP_HIGT - -// clock settings -// 299300000 -/* -{0x0301, 0x05, 0}, // VT_PIX_CLK_DIV -{0x0303, 0x02, 0}, // VT_SYS_CLK_DIV -{0x0305, 0x04, 0}, // PRE_PLL_CLK_DIV -{0x0306, 0x00, 0}, {0x0307, 0x7d, 0}, // PLL_MULTIPLIER . mode 1: 0xf6 -{0x0309, 0x0a, 0}, // OP_PIX_CLK_DIV -{0x030b, 0x01, 0}, // OP_SYS_CLK_DIV -{0x030d, 0x0f, 0}, // PREPLLCK_OP_DIV -{0x030e, 0x03, 0}, {0x030f, 0x41, 0}, // PLL_OP_MPY -{0x0310, 0x00, 0}, // PLL_MULT_DRIV -*/ -// 600000000 -{0x0301, 0x05, 0}, -{0x0303, 0x02, 0}, -{0x0305, 0x04, 0}, -{0x0306, 0x00, 0}, -{0x0307, 0xfa, 0}, -{0x0309, 0x0a, 0}, -{0x030b, 0x01, 0}, -{0x030d, 0x0f, 0}, -{0x030e, 0x03, 0}, {0x030f, 0x41, 0}, -{0x0310, 0x00, 0}, - -// data rate settings -/*{0x0820, 0x0b, 0}, // requested_link_bit_rate_mbps = 3000 -{0x0821, 0xb8, 0}, -{0x0822, 0x00, 0}, -{0x0823, 0x00, 0},*/ -{0x0820, 0x17, 0}, // requested_link_bit_rate_mbps = 6000 -{0x0821, 0x70, 0}, -{0x0822, 0x00, 0}, -{0x0823, 0x00, 0}, - -//integration time settings -{0x0202, 0x07, 0}, {0x0203, 0x00, 0}, // INTEG_TIME = 1792 -{0x0224, 0x01, 0}, {0x0225, 0xf4, 0}, // ST_COARSE_INTEG_TIME = 506 - -// gain settings -{0x0204, 0x00, 0}, {0x0205, 0x00, 0}, // ANA_GAIN_GLOBAL = 512 / (512 - X) -{0x0216, 0x00, 0}, {0x0217, 0x00, 0}, // ST_ANA_GAIN_GLOBAL[8] -{0x020e, 0x01, 0}, {0x020f, 0x00, 0}, // DIG_GAIN_GR -{0x0210, 0x01, 0}, {0x0211, 0x00, 0}, // DIG_GAIN_R -{0x0212, 0x01, 0}, {0x0213, 0x00, 0}, // DIG_GAIN_B -{0x0214, 0x01, 0}, {0x0215, 0x00, 0}, // DIG_GAIN_GB - -// HDR white balance settings (ABS_GAIN) -{0xb8e, 0x01, 0}, {0xb8f, 0x00, 0}, // GR -{0xb90, 0x02, 0}, {0xb91, 0x2b, 0}, // R -{0xb92, 0x01, 0}, {0xb93, 0xd4, 0}, // B -{0xb94, 0x01, 0}, {0xb95, 0x00, 0}, // GB - -// phase detection settings -{0x3058, 0x00, 0}, // NML_NR_EN -{0x3103, 0x01, 0}, // NML_PD_CAL_ENABLE = enable -{0x3108, 0x00, 0}, {0x3109, 0x2c, 0}, //PD_AREA_X_OFFSET -{0x310a, 0x00, 0}, {0x310b, 0x24, 0}, //PD_AREA_Y_OFFSET -{0x310c, 0x01, 0}, {0x310d, 0xa4, 0}, //PD_AREA_WIDTH -{0x310e, 0x01, 0}, {0x310f, 0xa4, 0}, //PD_AREA_HEIGHT -// whole size is 0x918 x 0x6d4 -{0x3110, 0x03, 0}, // PD_AREA_0 = 0x375-0x4d1, 0x258-0x3b6 -{0x3111, 0x75, 0}, -{0x3112, 0x02, 0}, -{0x3113, 0x58, 0}, -{0x3114, 0x04, 0}, -{0x3115, 0xd1, 0}, -{0x3116, 0x03, 0}, -{0x3117, 0xb6, 0}, -{0x3118, 0x04, 0}, // PD_AREA_1 = 0x446-0x5a2, 0x258-0x3b6 -{0x3119, 0x46, 0}, -{0x311a, 0x02, 0}, -{0x311b, 0x58, 0}, -{0x311c, 0x05, 0}, -{0x311d, 0xa2, 0}, -{0x311e, 0x03, 0}, -{0x311f, 0xb6, 0}, -{0x3120, 0x03, 0}, // PD_AREA_2 = 0x375-0x4d1, 0x32a-0x488 -{0x3121, 0x75, 0}, -{0x3122, 0x03, 0}, -{0x3123, 0x2a, 0}, -{0x3124, 0x04, 0}, -{0x3125, 0xd1, 0}, -{0x3126, 0x04, 0}, -{0x3127, 0x88, 0}, -{0x3128, 0x04, 0}, // PD_AREA_3 = 0x446-0x5a2, 0x32a-0x488 -{0x3129, 0x46, 0}, -{0x312a, 0x03, 0}, -{0x312b, 0x2a, 0}, -{0x312c, 0x05, 0}, -{0x312d, 0xa2, 0}, -{0x312e, 0x04, 0}, -{0x312f, 0x88, 0}, -{0x3130, 0x03, 0}, // PD_AREA_4 = 0x375-0x5a2, 0x258-0x488 -{0x3131, 0x75, 0}, -{0x3132, 0x02, 0}, -{0x3133, 0x58, 0}, -{0x3134, 0x05, 0}, -{0x3135, 0xa2, 0}, -{0x3136, 0x04, 0}, -{0x3137, 0x88, 0}, -{0x3138, 0x02, 0}, // PD_AREA_5 = 0x2ba-0x65d, 0x210-0x4d0 -{0x3139, 0xba, 0}, -{0x313a, 0x02, 0}, -{0x313b, 0x10, 0}, -{0x313c, 0x06, 0}, -{0x313d, 0x5d, 0}, -{0x313e, 0x04, 0}, -{0x313f, 0xd0, 0}, -{0x3140, 0x00, 0}, // PD_AREA_6 = 0xa1-0x876, 0x6b-0x676 -{0x3141, 0xa1, 0}, -{0x3142, 0x00, 0}, -{0x3143, 0x6b, 0}, -{0x3144, 0x08, 0}, -{0x3145, 0x76, 0}, -{0x3146, 0x06, 0}, -{0x3147, 0x76, 0}, -{0x3148, 0x00, 0}, // PD_AREA_7 = 0xa1-0x876, 0x5e-0x34c -{0x3149, 0xa1, 0}, -{0x314a, 0x00, 0}, -{0x314b, 0x5e, 0}, -{0x314c, 0x08, 0}, -{0x314d, 0x76, 0}, -{0x314e, 0x03, 0}, -{0x314f, 0x4c, 0}, -{0x3165, 0x02, 0}, // AREA_EN_0 = free area -}; - -// static struct msm_camera_i2c_reg_array reg_array3[] = { -// // REG_HOLD ON -// {0x104,0x1,0}, -// // from regression -// {0x3002,0x0,0}, -// // FRM_LENGTH, 1802 vs 3554 -// // {0x340,0x7,0}, {0x341,0xa,0}, // camera start {0x340,0xd,0}, {0x341,0xe2,0}, -// // INTEG_TIME aka coarse_int_time_addr aka shutter speed -// {0x202,0x03,0}, {0x203,0xda,0}, -// // global_gain_addr -// {0x204,0x0,0}, {0x205,0x0,0}, - -// //?? -// {0x20e,0x1,0}, {0x20f,0x0,0}, -// {0x210,0x1,0}, {0x211,0x0,0}, -// {0x212,0x1,0}, {0x213,0x0,0}, -// {0x214,0x1,0}, {0x215,0x0,0}, - -// // REG_HOLD: mode setting -// {0x104,0x0,0}, -// }; - -// start, remove standby mode -static struct msm_camera_i2c_reg_array start_reg_array[] = {{0x100,0x1,0}}; - -// stop, enable standby mode -static struct msm_camera_i2c_reg_array stop_reg_array[] = {{0x100,0x0,0}}; - -/* -// still mode settings: - {0x847f, 0x0c0c,}, //_M_EQCTL - - {0x8436, 0xfd7f,}, //_M_Kgxdr - {0x8440, 0xf07f,}, //_M_X_LMT - {0x8443, 0xb41e,}, //_M_X_TGT - {0x841b, 0x4001,}, //_M_Kgx10 - - {0x84b6, 0xfd7f,}, //_M_Kgydr - {0x84c0, 0xf07f,}, //_M_Y_LMT - {0x84c3, 0xb41e,}, //_M_Y_TGT - {0x849b, 0x4001,}, //_M_Kgy10 - - {0x8438, 0x2d0f,}, //_M_Kgx11 - {0x84b8, 0x2d0f,}, //_M_Kgy11 - {0x8447, 0x002b,}, //_M_KgxTG - {0x84c7, 0x002b,}, //_M_KgyTG - - {0x847f, 0x0d0d,}, //_M_EQCTL -*/ - -static struct msm_camera_i2c_reg_array init_array_ov8865[] = { -// round 1 -//{0x103,0x1,0}, // software reset -{0x100,0x0,0}, // standby on -{0x3638,0xff,0}, -{0x302,0x1e,0}, {0x303,0x0,0}, {0x304,0x3,0}, {0x30d,0x1e,0}, {0x30e,0x0,0}, {0x30f,0x9,0}, {0x312,0x1,0}, {0x31e,0xc,0}, // PLL control -{0x3015,0x1,0}, {0x3018,0x72,0}, {0x3020,0x93,0}, {0x3022,0x1,0}, -{0x3031,0xa,0}, // 10-bit mode -{0x3106,0x1,0}, {0x3305,0xf1,0}, {0x3308,0x0,0}, {0x3309,0x28,0}, {0x330a,0x0,0}, {0x330b,0x20,0}, {0x330c,0x0,0}, {0x330d,0x0,0}, {0x330e,0x0,0}, {0x330f,0x40,0}, {0x3307,0x4,0}, {0x3604,0x4,0}, {0x3602,0x30,0}, {0x3605,0x0,0}, {0x3607,0x20,0}, {0x3608,0x11,0}, {0x3609,0x68,0}, {0x360a,0x40,0}, {0x360c,0xdd,0}, {0x360e,0xc,0}, {0x3610,0x7,0}, {0x3612,0x86,0}, {0x3613,0x58,0}, {0x3614,0x28,0}, {0x3617,0x40,0}, {0x3618,0x5a,0}, {0x3619,0x9b,0}, {0x361c,0x0,0}, {0x361d,0x60,0}, {0x3631,0x60,0}, {0x3633,0x10,0}, {0x3634,0x10,0}, {0x3635,0x10,0}, {0x3636,0x10,0}, {0x3641,0x55,0}, {0x3646,0x86,0}, {0x3647,0x27,0}, {0x364a,0x1b,0}, {0x3500,0x0,0}, {0x3501,0x4c,0}, {0x3502,0x0,0}, {0x3503,0x0,0}, {0x3508,0x2,0}, -{0x3509,0x0,0}, // AEC GAIN -{0x3700,0x24,0}, {0x3701,0xc,0}, {0x3702,0x28,0}, {0x3703,0x19,0}, {0x3704,0x14,0}, {0x3705,0x0,0}, {0x3706,0x38,0}, {0x3707,0x4,0}, {0x3708,0x24,0}, {0x3709,0x40,0}, {0x370a,0x0,0}, {0x370b,0xb8,0}, {0x370c,0x4,0}, {0x3718,0x12,0}, {0x3719,0x31,0}, {0x3712,0x42,0}, {0x3714,0x12,0}, {0x371e,0x19,0}, {0x371f,0x40,0}, {0x3720,0x5,0}, {0x3721,0x5,0}, {0x3724,0x2,0}, {0x3725,0x2,0}, {0x3726,0x6,0}, {0x3728,0x5,0}, {0x3729,0x2,0}, {0x372a,0x3,0}, {0x372b,0x53,0}, {0x372c,0xa3,0}, {0x372d,0x53,0}, {0x372e,0x6,0}, {0x372f,0x10,0}, {0x3730,0x1,0}, {0x3731,0x6,0}, {0x3732,0x14,0}, {0x3733,0x10,0}, {0x3734,0x40,0}, {0x3736,0x20,0}, {0x373a,0x2,0}, {0x373b,0xc,0}, {0x373c,0xa,0}, {0x373e,0x3,0}, {0x3755,0x40,0}, {0x3758,0x0,0}, {0x3759,0x4c,0}, {0x375a,0x6,0}, {0x375b,0x13,0}, {0x375c,0x40,0}, {0x375d,0x2,0}, {0x375e,0x0,0}, {0x375f,0x14,0}, {0x3767,0x1c,0}, {0x3768,0x4,0}, {0x3769,0x20,0}, {0x376c,0xc0,0}, {0x376d,0xc0,0}, {0x376a,0x8,0}, {0x3761,0x0,0}, {0x3762,0x0,0}, {0x3763,0x0,0}, {0x3766,0xff,0}, {0x376b,0x42,0}, {0x3772,0x23,0}, {0x3773,0x2,0}, {0x3774,0x16,0}, {0x3775,0x12,0}, {0x3776,0x8,0}, {0x37a0,0x44,0}, {0x37a1,0x3d,0}, {0x37a2,0x3d,0}, {0x37a3,0x1,0}, {0x37a4,0x0,0}, {0x37a5,0x8,0}, {0x37a6,0x0,0}, {0x37a7,0x44,0}, {0x37a8,0x58,0}, {0x37a9,0x58,0}, {0x3760,0x0,0}, {0x376f,0x1,0}, {0x37aa,0x44,0}, {0x37ab,0x2e,0}, {0x37ac,0x2e,0}, {0x37ad,0x33,0}, {0x37ae,0xd,0}, {0x37af,0xd,0}, {0x37b0,0x0,0}, {0x37b1,0x0,0}, {0x37b2,0x0,0}, {0x37b3,0x42,0}, {0x37b4,0x42,0}, {0x37b5,0x33,0}, {0x37b6,0x0,0}, {0x37b7,0x0,0}, {0x37b8,0x0,0}, {0x37b9,0xff,0}, {0x3800,0x0,0}, {0x3801,0xc,0}, {0x3802,0x0,0}, {0x3803,0xc,0}, -{0x3804,0xc,0}, {0x3805,0xd3,0}, // 3283 -{0x3806,0x9,0}, {0x3807,0xa3,0}, // 2467 -{0x3808,0x6,0}, {0x3809,0x60,0}, // 0x660 = 1632 (width) -{0x380a,0x4,0}, {0x380b,0xc8,0}, // 0x4c8 = 1224 (height) -{0x380c,0x6,0}, {0x380d,0x42,0}, // line_length_pck -{0x380e,0x5,0}, {0x380f,0xda,0}, // frame_length_lines -{0x3810,0x0,0}, {0x3811,0x4,0}, {0x3813,0x4,0}, -{0x3814,0x3,0}, {0x3815,0x1,0}, // H-binning -{0x3820,0x6,0}, // format1 -{0x3821,0x40,0}, // format2 -{0x382a,0x3,0}, {0x382b,0x1,0}, // V-binning -{0x382d,0x7f,0}, {0x3830,0x8,0}, {0x3836,0x2,0}, {0x3837,0x18,0}, -{0x3841,0xff,0}, -{0x3846,0x88,0}, {0x3d85,0x6,0}, {0x3d8c,0x75,0}, {0x3d8d,0xef,0}, {0x3f08,0xb,0}, {0x4000,0xf1,0}, {0x4001,0x14,0}, {0x4005,0x10,0}, {0x4006,0x1,0}, {0x4007,0x1,0}, {0x400b,0xc,0}, {0x400d,0x10,0}, {0x401b,0x0,0}, {0x401d,0x0,0}, {0x4020,0x0,0}, {0x4021,0x0,0}, {0x4022,0x4,0}, {0x4023,0x1f,0}, {0x4024,0x6,0}, {0x4025,0x20,0}, {0x4026,0x6,0}, {0x4027,0x4f,0}, {0x4028,0x0,0}, {0x4029,0x2,0}, {0x402a,0x4,0}, {0x402b,0x4,0}, {0x402c,0x2,0}, {0x402d,0x2,0}, {0x402e,0x8,0}, {0x402f,0x2,0}, {0x401f,0x0,0}, {0x4034,0x3f,0}, {0x4300,0xff,0}, {0x4301,0x0,0}, {0x4302,0xf,0}, {0x4500,0x40,0}, {0x4503,0x10,0}, {0x4601,0x74,0}, {0x481f,0x32,0}, {0x4837,0x15,0}, {0x4850,0x10,0}, {0x4851,0x32,0}, {0x4b00,0x2a,0}, {0x4b0d,0x0,0}, {0x4d00,0x4,0}, {0x4d01,0x18,0}, {0x4d02,0xc3,0}, {0x4d03,0xff,0}, {0x4d04,0xff,0}, {0x4d05,0xff,0}, {0x5000,0x96,0}, {0x5001,0x1,0}, {0x5002,0x8,0}, {0x5901,0x0,0}, -{0x5e00,0x0,0}, -//{0x5e00,0x80,0}, -{0x5e01,0x41,0}, {0x5b00,0x2,0}, {0x5b01,0xd0,0}, {0x5b02,0x3,0}, {0x5b03,0xff,0}, {0x5b05,0x6c,0}, {0x5780,0xfc,0}, {0x5781,0xdf,0}, {0x5782,0x3f,0}, {0x5783,0x8,0}, {0x5784,0xc,0}, {0x5786,0x20,0}, {0x5787,0x40,0}, {0x5788,0x8,0}, {0x5789,0x8,0}, {0x578a,0x2,0}, {0x578b,0x1,0}, {0x578c,0x1,0}, {0x578d,0xc,0}, {0x578e,0x2,0}, {0x578f,0x1,0}, {0x5790,0x1,0}, {0x5800,0x1d,0}, {0x5801,0xe,0}, {0x5802,0xc,0}, {0x5803,0xc,0}, {0x5804,0xf,0}, {0x5805,0x22,0}, {0x5806,0xa,0}, {0x5807,0x6,0}, {0x5808,0x5,0}, {0x5809,0x5,0}, {0x580a,0x7,0}, {0x580b,0xa,0}, {0x580c,0x6,0}, {0x580d,0x2,0}, {0x580e,0x0,0}, {0x580f,0x0,0}, {0x5810,0x3,0}, {0x5811,0x7,0}, {0x5812,0x6,0}, {0x5813,0x2,0}, {0x5814,0x0,0}, {0x5815,0x0,0}, {0x5816,0x3,0}, {0x5817,0x7,0}, {0x5818,0x9,0}, {0x5819,0x6,0}, {0x581a,0x4,0}, {0x581b,0x4,0}, {0x581c,0x6,0}, {0x581d,0xa,0}, {0x581e,0x19,0}, {0x581f,0xd,0}, {0x5820,0xb,0}, {0x5821,0xb,0}, {0x5822,0xe,0}, {0x5823,0x22,0}, {0x5824,0x23,0}, {0x5825,0x28,0}, {0x5826,0x29,0}, {0x5827,0x27,0}, {0x5828,0x13,0}, {0x5829,0x26,0}, {0x582a,0x33,0}, {0x582b,0x32,0}, {0x582c,0x33,0}, {0x582d,0x16,0}, {0x582e,0x14,0}, {0x582f,0x30,0}, {0x5830,0x31,0}, {0x5831,0x30,0}, {0x5832,0x15,0}, {0x5833,0x26,0}, {0x5834,0x23,0}, {0x5835,0x21,0}, {0x5836,0x23,0}, {0x5837,0x5,0}, {0x5838,0x36,0}, {0x5839,0x27,0}, {0x583a,0x28,0}, {0x583b,0x26,0}, {0x583c,0x24,0}, {0x583d,0xdf,0}, -//{0x100,0x1,0}, -// round 2 (color calibration) -{0x7010,0x0,0}, {0x7011,0x0,0}, {0x7012,0x0,0}, {0x7013,0x0,0}, {0x7014,0x0,0}, {0x7015,0x0,0}, {0x7016,0x0,0}, {0x7017,0x0,0}, {0x7018,0x0,0}, {0x7019,0x0,0}, {0x701a,0x0,0}, {0x701b,0x0,0}, {0x701c,0x0,0}, {0x701d,0x0,0}, {0x701e,0x0,0}, {0x701f,0x0,0}, {0x7020,0x0,0}, {0x7021,0x0,0}, {0x7022,0x0,0}, {0x7023,0x0,0}, {0x7024,0x0,0}, {0x7025,0x0,0}, {0x7026,0x0,0}, {0x7027,0x0,0}, {0x7028,0x0,0}, {0x7029,0x0,0}, {0x702a,0x0,0}, {0x702b,0x0,0}, {0x702c,0x0,0}, {0x702d,0x0,0}, {0x702e,0x0,0}, {0x702f,0x0,0}, {0x7030,0x0,0}, {0x7031,0x0,0}, {0x7032,0x0,0}, {0x7033,0x0,0}, {0x7034,0x0,0}, {0x7035,0x0,0}, {0x7036,0x0,0}, {0x7037,0x0,0}, {0x7038,0x0,0}, {0x7039,0x0,0}, {0x703a,0x0,0}, {0x703b,0x0,0}, {0x703c,0x0,0}, {0x703d,0x0,0}, {0x703e,0x0,0}, {0x703f,0x0,0}, {0x7040,0x0,0}, {0x7041,0x0,0}, {0x7042,0x0,0}, {0x7043,0x0,0}, {0x7044,0x0,0}, {0x7045,0x0,0}, {0x7046,0x0,0}, {0x7047,0x0,0}, {0x7048,0x0,0}, {0x7049,0x0,0}, {0x704a,0x0,0}, {0x704b,0x0,0}, {0x704c,0x0,0}, {0x704d,0x0,0}, {0x704e,0x0,0}, {0x704f,0x0,0}, {0x7050,0x0,0}, {0x7051,0x0,0}, {0x7052,0x0,0}, {0x7053,0x0,0}, {0x7054,0x0,0}, {0x7055,0x0,0}, {0x7056,0x0,0}, {0x7057,0x0,0}, {0x7058,0x0,0}, {0x7059,0x0,0}, {0x705a,0x0,0}, {0x705b,0x0,0}, {0x705c,0x0,0}, {0x705d,0x0,0}, {0x705e,0x0,0}, {0x705f,0x0,0}, {0x7060,0x0,0}, {0x7061,0x0,0}, {0x7062,0x0,0}, {0x7063,0x0,0}, {0x7064,0x0,0}, {0x7065,0x0,0}, {0x7066,0x0,0}, {0x7067,0x0,0}, {0x7068,0x0,0}, {0x7069,0x0,0}, {0x706a,0x0,0}, {0x706b,0x0,0}, {0x706c,0x0,0}, {0x706d,0x0,0}, {0x706e,0x0,0}, {0x706f,0x0,0}, {0x7070,0x0,0}, {0x7071,0x0,0}, {0x7072,0x0,0}, {0x7073,0x0,0}, {0x7074,0x0,0}, {0x7075,0x0,0}, {0x7076,0x0,0}, {0x7077,0x0,0}, {0x7078,0x0,0}, {0x7079,0x0,0}, {0x707a,0x0,0}, {0x707b,0x0,0}, {0x707c,0x0,0}, {0x707d,0x0,0}, {0x707e,0x0,0}, {0x707f,0x0,0}, {0x7080,0x0,0}, {0x7081,0x0,0}, {0x7082,0x0,0}, {0x7083,0x0,0}, {0x7084,0x0,0}, {0x7085,0x0,0}, {0x7086,0x0,0}, {0x7087,0x0,0}, {0x7088,0x0,0}, {0x7089,0x0,0}, {0x708a,0x0,0}, {0x708b,0x0,0}, {0x708c,0x0,0}, {0x708d,0x0,0}, {0x708e,0x0,0}, {0x708f,0x0,0}, {0x7090,0x0,0}, {0x7091,0x0,0}, {0x7092,0x0,0}, {0x7093,0x0,0}, {0x7094,0x0,0}, {0x7095,0x0,0}, {0x7096,0x0,0}, {0x7097,0x0,0}, {0x7098,0x0,0}, {0x7099,0x0,0}, {0x709a,0x0,0}, {0x709b,0x0,0}, {0x709c,0x0,0}, {0x709d,0x0,0}, {0x709e,0x0,0}, {0x709f,0x0,0}, {0x70a0,0x0,0}, {0x70a1,0x0,0}, {0x70a2,0x0,0}, {0x70a3,0x0,0}, {0x70a4,0x0,0}, {0x70a5,0x0,0}, {0x70a6,0x0,0}, {0x70a7,0x0,0}, {0x70a8,0x0,0}, {0x70a9,0x0,0}, {0x70aa,0x0,0}, {0x70ab,0x0,0}, {0x70ac,0x0,0}, {0x70ad,0x0,0}, {0x70ae,0x0,0}, {0x70af,0x0,0}, {0x70b0,0x0,0}, {0x70b1,0x0,0}, {0x70b2,0x0,0}, {0x70b3,0x0,0}, {0x70b4,0x0,0}, {0x70b5,0x0,0}, {0x70b6,0x0,0}, {0x70b7,0x0,0}, {0x70b8,0x0,0}, {0x70b9,0x0,0}, {0x70ba,0x0,0}, {0x70bb,0x0,0}, {0x70bc,0x0,0}, {0x70bd,0x0,0}, {0x70be,0x0,0}, {0x70bf,0x0,0}, {0x70c0,0x0,0}, {0x70c1,0x0,0}, {0x70c2,0x0,0}, {0x70c3,0x0,0}, {0x70c4,0x0,0}, {0x70c5,0x0,0}, {0x70c6,0x0,0}, {0x70c7,0x0,0}, {0x70c8,0x0,0}, {0x70c9,0x0,0}, {0x70ca,0x0,0}, {0x70cb,0x0,0}, {0x70cc,0x0,0}, {0x70cd,0x0,0}, {0x70ce,0x0,0}, {0x70cf,0x0,0}, {0x70d0,0x0,0}, {0x70d1,0x0,0}, {0x70d2,0x0,0}, {0x70d3,0x0,0}, {0x70d4,0x0,0}, {0x70d5,0x0,0}, {0x70d6,0x0,0}, {0x70d7,0x0,0}, {0x70d8,0x0,0}, {0x70d9,0x0,0}, {0x70da,0x0,0}, {0x70db,0x0,0}, {0x70dc,0x0,0}, {0x70dd,0x0,0}, {0x70de,0x0,0}, {0x70df,0x0,0}, {0x70e0,0x0,0}, {0x70e1,0x0,0}, {0x70e2,0x0,0}, {0x70e3,0x0,0}, {0x70e4,0x0,0}, {0x70e5,0x0,0}, {0x70e6,0x0,0}, {0x70e7,0x0,0}, {0x70e8,0x0,0}, {0x70e9,0x0,0}, {0x70ea,0x0,0}, {0x70eb,0x0,0}, {0x70ec,0x0,0}, {0x70ed,0x0,0}, {0x70ee,0x0,0}, {0x70ef,0x0,0}, {0x70f0,0x0,0}, {0x70f1,0x0,0}, {0x70f2,0x0,0}, {0x70f3,0x0,0}, {0x70f4,0x0,0}, {0x70f5,0x0,0}, {0x70f6,0x0,0}, {0x70f7,0x0,0}, {0x70f8,0x0,0}, {0x70f9,0x0,0}, {0x70fa,0x0,0}, {0x70fb,0x0,0}, {0x70fc,0x0,0}, {0x70fd,0x0,0}, {0x70fe,0x0,0}, {0x70ff,0x0,0}, {0x7100,0x0,0}, {0x7101,0x0,0}, {0x7102,0x0,0}, {0x7103,0x0,0}, {0x7104,0x0,0}, {0x7105,0x0,0}, {0x7106,0x0,0}, {0x7107,0x0,0}, {0x7108,0x0,0}, {0x7109,0x0,0}, {0x710a,0x0,0}, {0x710b,0x0,0}, {0x710c,0x0,0}, {0x710d,0x0,0}, {0x710e,0x0,0}, {0x710f,0x0,0}, {0x7110,0x0,0}, {0x7111,0x0,0}, {0x7112,0x0,0}, {0x7113,0x0,0}, {0x7114,0x0,0}, {0x7115,0x0,0}, {0x7116,0x0,0}, {0x7117,0x0,0}, {0x7118,0x0,0}, {0x7119,0x0,0}, {0x711a,0x0,0}, {0x711b,0x0,0}, {0x711c,0x0,0}, {0x711d,0x0,0}, {0x711e,0x0,0}, {0x711f,0x0,0}, {0x7120,0x0,0}, {0x7121,0x0,0}, {0x7122,0x0,0}, {0x7123,0x0,0}, {0x7124,0x0,0}, {0x7125,0x0,0}, {0x7126,0x0,0}, {0x7127,0x0,0}, {0x7128,0x0,0}, {0x7129,0x0,0}, {0x712a,0x0,0}, {0x712b,0x0,0}, {0x712c,0x0,0}, {0x712d,0x0,0}, {0x712e,0x0,0}, {0x712f,0x0,0}, {0x7130,0x0,0}, {0x7131,0x0,0}, {0x7132,0x0,0}, {0x501a,0x10,0}, {0x501b,0xd,0}, {0x501c,0x10,0}, {0x501d,0x13,0}, {0x5000,0x96,0}, {0x5800,0x14,0}, {0x5801,0xd,0}, {0x5802,0xa,0}, {0x5803,0xa,0}, {0x5804,0xd,0}, {0x5805,0x13,0}, {0x5806,0xa,0}, {0x5807,0x5,0}, {0x5808,0x3,0}, {0x5809,0x3,0}, {0x580a,0x5,0}, {0x580b,0x9,0}, {0x580c,0x6,0}, {0x580d,0x2,0}, {0x580e,0x0,0}, {0x580f,0x0,0}, {0x5810,0x2,0}, {0x5811,0x5,0}, {0x5812,0x6,0}, {0x5813,0x2,0}, {0x5814,0x0,0}, {0x5815,0x0,0}, {0x5816,0x2,0}, {0x5817,0x5,0}, {0x5818,0xb,0}, {0x5819,0x6,0}, {0x581a,0x3,0}, {0x581b,0x3,0}, {0x581c,0x5,0}, {0x581d,0xa,0}, {0x581e,0x16,0}, {0x581f,0xf,0}, {0x5820,0xb,0}, {0x5821,0xb,0}, {0x5822,0xf,0}, {0x5823,0x15,0}, {0x5824,0x32,0}, {0x5825,0x23,0}, {0x5826,0x23,0}, {0x5827,0x23,0}, {0x5828,0x22,0}, {0x5829,0x21,0}, {0x582a,0x21,0}, {0x582b,0x22,0}, {0x582c,0x21,0},{0x582d,0x11,0}, {0x582e,0x22,0}, {0x582f,0x31,0}, {0x5830,0x41,0}, {0x5831,0x31,0}, {0x5832,0x1,0}, {0x5833,0x21,0}, {0x5834,0x21,0}, {0x5835,0x21,0}, {0x5836,0x11,0}, {0x5837,0x11,0}, {0x5838,0x22,0}, {0x5839,0x22,0}, {0x583a,0x12,0}, {0x583b,0x22,0}, {0x583c,0x22,0}, {0x583d,0xdf,0}, -}; - diff --git a/selfdrive/camerad/imgproc/utils.h b/selfdrive/camerad/imgproc/utils.h index b735975b3e..94323b15c5 100644 --- a/selfdrive/camerad/imgproc/utils.h +++ b/selfdrive/camerad/imgproc/utils.h @@ -4,7 +4,7 @@ #include #include -#include "selfdrive/common/clutil.h" +#include "common/clutil.h" #define NUM_SEGMENTS_X 8 #define NUM_SEGMENTS_Y 6 diff --git a/selfdrive/camerad/main.cc b/selfdrive/camerad/main.cc index 58edaedd9b..32899a8547 100644 --- a/selfdrive/camerad/main.cc +++ b/selfdrive/camerad/main.cc @@ -2,12 +2,12 @@ #include -#include "selfdrive/common/params.h" -#include "selfdrive/common/util.h" -#include "selfdrive/hardware/hw.h" +#include "common/params.h" +#include "common/util.h" +#include "system/hardware/hw.h" int main(int argc, char *argv[]) { - if (Hardware::TICI()) { + if (!Hardware::PC()) { int ret; ret = util::set_realtime_priority(53); assert(ret == 0); diff --git a/selfdrive/camerad/snapshot/snapshot.py b/selfdrive/camerad/snapshot/snapshot.py index 1ec7677d31..fa88849b69 100755 --- a/selfdrive/camerad/snapshot/snapshot.py +++ b/selfdrive/camerad/snapshot/snapshot.py @@ -4,22 +4,21 @@ import time import numpy as np from PIL import Image -from typing import List import cereal.messaging as messaging -from cereal.visionipc.visionipc_pyx import VisionIpcClient, VisionStreamType # pylint: disable=no-name-in-module, import-error +from cereal.visionipc import VisionIpcClient, VisionStreamType from common.params import Params from common.realtime import DT_MDL -from selfdrive.hardware import TICI, PC +from system.hardware import PC from selfdrive.controls.lib.alertmanager import set_offroad_alert from selfdrive.manager.process_config import managed_processes LM_THRESH = 120 # defined in selfdrive/camerad/imgproc/utils.h VISION_STREAMS = { - "roadCameraState": VisionStreamType.VISION_STREAM_RGB_ROAD, - "driverCameraState": VisionStreamType.VISION_STREAM_RGB_DRIVER, - "wideRoadCameraState": VisionStreamType.VISION_STREAM_RGB_WIDE_ROAD, + "roadCameraState": VisionStreamType.VISION_STREAM_ROAD, + "driverCameraState": VisionStreamType.VISION_STREAM_DRIVER, + "wideRoadCameraState": VisionStreamType.VISION_STREAM_WIDE_ROAD, } @@ -28,19 +27,31 @@ def jpeg_write(fn, dat): img.save(fn, "JPEG") -def extract_image(buf, w, h, stride): - img = np.hstack([buf[i * stride:i * stride + 3 * w] for i in range(h)]) - b = img[::3].reshape(h, w) - g = img[1::3].reshape(h, w) - r = img[2::3].reshape(h, w) - return np.dstack([r, g, b]) +def yuv_to_rgb(y, u, v): + ul = np.repeat(np.repeat(u, 2).reshape(u.shape[0], y.shape[1]), 2, axis=0).reshape(y.shape) + vl = np.repeat(np.repeat(v, 2).reshape(v.shape[0], y.shape[1]), 2, axis=0).reshape(y.shape) + yuv = np.dstack((y, ul, vl)).astype(np.int16) + yuv[:, :, 1:] -= 128 -def rois_in_focus(lapres: List[float]) -> float: - return sum(1. / len(lapres) for sharpness in lapres if sharpness >= LM_THRESH) + m = np.array([ + [1.00000, 1.00000, 1.00000], + [0.00000, -0.39465, 2.03211], + [1.13983, -0.58060, 0.00000], + ]) + rgb = np.dot(yuv, m) + return rgb.astype(np.uint8) -def get_snapshots(frame="roadCameraState", front_frame="driverCameraState", focus_perc_threshold=0.): +def extract_image(buf, w, h, stride, uv_offset): + y = np.array(buf[:uv_offset], dtype=np.uint8).reshape((-1, stride))[:h, :w] + u = np.array(buf[uv_offset::2], dtype=np.uint8).reshape((-1, stride//2))[:h//2, :w//2] + v = np.array(buf[uv_offset+1::2], dtype=np.uint8).reshape((-1, stride//2))[:h//2, :w//2] + + return yuv_to_rgb(y, u, v) + + +def get_snapshots(frame="roadCameraState", front_frame="driverCameraState"): sockets = [s for s in (frame, front_frame) if s is not None] sm = messaging.SubMaster(sockets) vipc_clients = {s: VisionIpcClient("camerad", VISION_STREAMS[s], True) for s in sockets} @@ -52,21 +63,14 @@ def get_snapshots(frame="roadCameraState", front_frame="driverCameraState", focu for client in vipc_clients.values(): client.connect(True) - # wait for focus - start_t = time.monotonic() - while time.monotonic() - start_t < 10: - sm.update(100) - if min(sm.rcv_frame.values()) > 1 and rois_in_focus(sm[frame].sharpnessScore) >= focus_perc_threshold: - break - # grab images rear, front = None, None if frame is not None: c = vipc_clients[frame] - rear = extract_image(c.recv(), c.width, c.height, c.stride) + rear = extract_image(c.recv(), c.width, c.height, c.stride, c.uv_offset) if front_frame is not None: c = vipc_clients[front_frame] - front = extract_image(c.recv(), c.width, c.height, c.stride) + front = extract_image(c.recv(), c.width, c.height, c.stride, c.uv_offset) return rear, front @@ -97,11 +101,9 @@ def snapshot(): if not PC: managed_processes['camerad'].start() - frame = "wideRoadCameraState" if TICI else "roadCameraState" + frame = "wideRoadCameraState" front_frame = "driverCameraState" if front_camera_allowed else None - focus_perc_threshold = 0. if TICI else 10 / 12. - - rear, front = get_snapshots(frame, front_frame, focus_perc_threshold) + rear, front = get_snapshots(frame, front_frame) finally: managed_processes['camerad'].stop() params.put_bool("IsTakingSnapshot", False) diff --git a/selfdrive/camerad/test/ae_gray_test.cc b/selfdrive/camerad/test/ae_gray_test.cc index 358d93d759..69ef2ac6de 100644 --- a/selfdrive/camerad/test/ae_gray_test.cc +++ b/selfdrive/camerad/test/ae_gray_test.cc @@ -7,15 +7,9 @@ #include #include -#include "selfdrive/common/util.h" +#include "common/util.h" #include "selfdrive/camerad/cameras/camera_common.h" -// needed by camera_common.cc -void camera_autoexposure(CameraState *s, float grey_frac) {} -void cameras_init(VisionIpcServer *v, MultiCameraState *s, cl_device_id device_id, cl_context ctx) {} -void cameras_open(MultiCameraState *s) {} -void cameras_run(MultiCameraState *s) {} - int main() { // set up fake camerabuf CameraBuf cb = {}; diff --git a/selfdrive/camerad/test/camera_test.h b/selfdrive/camerad/test/camera_test.h new file mode 100644 index 0000000000..a9f213c923 --- /dev/null +++ b/selfdrive/camerad/test/camera_test.h @@ -0,0 +1,25 @@ +// TODO: cleanup AE tests +// needed by camera_common.cc +void camera_autoexposure(CameraState *s, float grey_frac) {} +void cameras_init(VisionIpcServer *v, MultiCameraState *s, cl_device_id device_id, cl_context ctx) {} +void cameras_open(MultiCameraState *s) {} +void cameras_run(MultiCameraState *s) {} + +typedef struct CameraState { + int camera_num; + CameraInfo ci; + + int fps; + float digital_gain = 0; + + CameraBuf buf; +} CameraState; + +typedef struct MultiCameraState { + CameraState road_cam; + CameraState driver_cam; + + PubMaster *pm = nullptr; +} MultiCameraState; + + diff --git a/selfdrive/camerad/test/test_camerad.py b/selfdrive/camerad/test/test_camerad.py index c311c17169..1a2e365a8f 100755 --- a/selfdrive/camerad/test/test_camerad.py +++ b/selfdrive/camerad/test/test_camerad.py @@ -4,7 +4,7 @@ import time import unittest import cereal.messaging as messaging -from selfdrive.hardware import TICI +from system.hardware import TICI from selfdrive.test.helpers import with_processes TEST_TIMESPAN = 30 # random.randint(60, 180) # seconds diff --git a/selfdrive/camerad/test/test_exposure.py b/selfdrive/camerad/test/test_exposure.py index 31bcc28681..f42d0bfbe3 100755 --- a/selfdrive/camerad/test/test_exposure.py +++ b/selfdrive/camerad/test/test_exposure.py @@ -6,7 +6,7 @@ import numpy as np from selfdrive.test.helpers import with_processes from selfdrive.camerad.snapshot.snapshot import get_snapshots -from selfdrive.hardware import TICI +from system.hardware import TICI TEST_TIME = 45 REPEAT = 5 diff --git a/selfdrive/camerad/transforms/rgb_to_yuv.h b/selfdrive/camerad/transforms/rgb_to_yuv.h index 3bb50669ef..e1de180d40 100644 --- a/selfdrive/camerad/transforms/rgb_to_yuv.h +++ b/selfdrive/camerad/transforms/rgb_to_yuv.h @@ -1,6 +1,6 @@ #pragma once -#include "selfdrive/common/clutil.h" +#include "common/clutil.h" class Rgb2Yuv { public: diff --git a/selfdrive/camerad/transforms/rgb_to_yuv_test.cc b/selfdrive/camerad/transforms/rgb_to_yuv_test.cc index 74db2bc1c2..c960d168de 100644 --- a/selfdrive/camerad/transforms/rgb_to_yuv_test.cc +++ b/selfdrive/camerad/transforms/rgb_to_yuv_test.cc @@ -31,7 +31,7 @@ #include "libyuv.h" #include "selfdrive/camerad/transforms/rgb_to_yuv.h" -#include "selfdrive/common/clutil.h" +#include "common/clutil.h" static inline double millis_since_boot() { struct timespec t; diff --git a/selfdrive/car/CARS_template.md b/selfdrive/car/CARS_template.md index 2165bf48bb..891445a558 100644 --- a/selfdrive/car/CARS_template.md +++ b/selfdrive/car/CARS_template.md @@ -1,5 +1,5 @@ {% set footnote_tag = '[{}](#footnotes)' -%} -{% set star_icon = '' -%} +{% set star_icon = '' -%} # Supported Cars @@ -14,31 +14,19 @@ Cars are organized into three tiers: How We Rate The Cars --- -### openpilot Adaptive Cruise Control (ACC) -- {{star_icon.format(Star.FULL.value)}} - openpilot is able to control the gas and brakes. -- {{star_icon.format(Star.HALF.value)}} - openpilot is able to control the gas and brakes with some restrictions. -- {{star_icon.format(Star.EMPTY.value)}} - The gas and brakes are controlled by the car's stock Adaptive Cruise Control (ACC) system. - -### Stop and Go -- {{star_icon.format(Star.FULL.value)}} - Adaptive Cruise Control (ACC) operates down to 0 mph. -- {{star_icon.format(Star.EMPTY.value)}} - Adaptive Cruise Control (ACC) available only above certain speeds. See your car's manual for the minimum speed. - -### Steer to 0 -- {{star_icon.format(Star.FULL.value)}} - openpilot can control the steering wheel down to 0 mph. -- {{star_icon.format(Star.EMPTY.value)}} - No steering control below certain speeds. - -### Steering Torque -- {{star_icon.format(Star.FULL.value)}} - Car has enough steering torque for comfortable highway driving. -- {{star_icon.format(Star.EMPTY.value)}} - Limited ability to make turns. - -### Actively Maintained -- {{star_icon.format(Star.FULL.value)}} - Mainline software support, harness hardware sold by comma, lots of users, primary development target. -- {{star_icon.format(Star.EMPTY.value)}} - Low user count, community maintained, harness hardware not sold by comma. +{% for star_row in star_descriptions.values() %} +{% for name, stars in star_row.items() %} +### {{name}} +{% for star, description in stars %} +- {{star_icon.format(star)}} - {{description}} +{% endfor %} +{% endfor %} +{% endfor %} **All supported cars can move between the tiers as support changes.** {% for tier, cars in tiers.items() %} -## {{tier.name.title()}} Cars +# {{tier.name.title()}} - {{cars | length}} cars |{{Column | map(attribute='value') | join('|')}}| |---|---|---|:---:|:---:|:---:|:---:|:---:| diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py index 408e0d075f..c77e40daaf 100644 --- a/selfdrive/car/__init__.py +++ b/selfdrive/car/__init__.py @@ -1,10 +1,41 @@ # functions common among cars +import capnp + from cereal import car from common.numpy_fast import clip +from typing import Dict, List # kg of standard extra cargo to count for drive, gas, etc... STD_CARGO_KG = 136. +ButtonType = car.CarState.ButtonEvent.Type +EventName = car.CarEvent.EventName + + +def create_button_event(cur_but: int, prev_but: int, buttons_dict: Dict[int, capnp.lib.capnp._EnumModule], + unpressed: int = 0) -> capnp.lib.capnp._DynamicStructBuilder: + if cur_but != unpressed: + be = car.CarState.ButtonEvent(pressed=True) + but = cur_but + else: + be = car.CarState.ButtonEvent(pressed=False) + but = prev_but + be.type = buttons_dict.get(but, ButtonType.unknown) + return be + + +def create_button_enable_events(buttonEvents: capnp.lib.capnp._DynamicListBuilder, pcm_cruise: bool = False) -> List[int]: + events = [] + for b in buttonEvents: + # do enable on both accel and decel buttons + if not pcm_cruise: + if b.type in (ButtonType.accelCruise, ButtonType.decelCruise) and not b.pressed: + events.append(EventName.buttonEnable) + # do disable on button down + if b.type == ButtonType.cancel and b.pressed: + events.append(EventName.buttonCancel) + return events + def gen_empty_fingerprint(): return {i: {} for i in range(0, 4)} @@ -41,7 +72,7 @@ def scale_tire_stiffness(mass, wheelbase, center_to_front, tire_stiffness_factor return tire_stiffness_front, tire_stiffness_rear -def dbc_dict(pt_dbc, radar_dbc, chassis_dbc=None, body_dbc=None): +def dbc_dict(pt_dbc, radar_dbc, chassis_dbc=None, body_dbc=None) -> Dict[str, str]: return {'pt': pt_dbc, 'radar': radar_dbc, 'chassis': chassis_dbc, 'body': body_dbc} diff --git a/selfdrive/car/body/carstate.py b/selfdrive/car/body/carstate.py index 520aab8fa1..dbbd85950d 100644 --- a/selfdrive/car/body/carstate.py +++ b/selfdrive/car/body/carstate.py @@ -20,6 +20,9 @@ class CarState(CarStateBase): ret.steerFaultPermanent = any([cp.vl['VAR_VALUES']['MOTOR_ERR_L'], cp.vl['VAR_VALUES']['MOTOR_ERR_R'], cp.vl['VAR_VALUES']['FAULT']]) + ret.charging = cp.vl["BODY_DATA"]["CHARGER_CONNECTED"] == 1 + ret.fuelGauge = cp.vl["BODY_DATA"]["BATT_PERCENTAGE"] / 100 + # irrelevant for non-car ret.gearShifter = car.CarState.GearShifter.drive ret.cruiseState.enabled = True diff --git a/selfdrive/car/body/interface.py b/selfdrive/car/body/interface.py index 2b44200397..e85735b1a6 100644 --- a/selfdrive/car/body/interface.py +++ b/selfdrive/car/body/interface.py @@ -17,8 +17,8 @@ class CarInterface(CarInterfaceBase): ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.body)] ret.minSteerSpeed = -math.inf + ret.maxLateralAccel = math.inf # TODO: set to a reasonable value ret.steerRatio = 0.5 - ret.steerRateCost = 0.5 ret.steerLimitTimer = 1.0 ret.steerActuatorDelay = 0. diff --git a/selfdrive/car/body/values.py b/selfdrive/car/body/values.py index 04de0ef2e3..0caf93b619 100644 --- a/selfdrive/car/body/values.py +++ b/selfdrive/car/body/values.py @@ -2,7 +2,7 @@ from typing import Dict from cereal import car from selfdrive.car import dbc_dict -from selfdrive.car.docs_definitions import CarInfo +from selfdrive.car.docs_definitions import CarInfo, Harness Ecu = car.CarParams.Ecu SPEED_FROM_RPM = 0.008587 @@ -18,7 +18,7 @@ class CAR: BODY = "COMMA BODY" CAR_INFO: Dict[str, CarInfo] = { - CAR.BODY: CarInfo("comma body", package="All", good_torque=True), + CAR.BODY: CarInfo("comma body", package="All", harness=Harness.none), } FW_VERSIONS = { diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index 46991bb4d2..3bfd99f88d 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -1,17 +1,18 @@ import os -from typing import Any, Dict, List +from typing import Dict, List +from cereal import car from common.params import Params from common.basedir import BASEDIR -from selfdrive.version import is_comma_remote, is_tested_branch +from system.version import is_comma_remote, is_tested_branch +from selfdrive.car.interfaces import get_interface_attr from selfdrive.car.fingerprints import eliminate_incompatible_cars, all_legacy_fingerprint_cars from selfdrive.car.vin import get_vin, VIN_UNKNOWN from selfdrive.car.fw_versions import get_fw_versions, match_fw_to_car -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog import cereal.messaging as messaging from selfdrive.car import gen_empty_fingerprint -from cereal import car EventName = car.CarEvent.EventName @@ -59,19 +60,6 @@ def load_interfaces(brand_names): return ret -def get_interface_attr(attr: str) -> Dict[str, Any]: - # returns given attribute from each interface - brand_names = {} - for car_folder in sorted([x[0] for x in os.walk(BASEDIR + '/selfdrive/car')]): - try: - brand_name = car_folder.split('/')[-1] - attr_data = getattr(__import__(f'selfdrive.car.{brand_name}.values', fromlist=[attr]), attr, None) - brand_names[brand_name] = attr_data - except (ImportError, OSError): - pass - return brand_names - - def _get_interface_names() -> Dict[str, List[str]]: # returns a dict of brand name and its respective models brand_names = {} @@ -116,16 +104,22 @@ def fingerprint(logcan, sendcan): vin = VIN_UNKNOWN exact_fw_match, fw_candidates, car_fw = True, set(), [] + if len(vin) != 17: + cloudlog.event("Malformed VIN", vin=vin, error=True) + vin = VIN_UNKNOWN cloudlog.warning("VIN %s", vin) Params().put("CarVin", vin) finger = gen_empty_fingerprint() candidate_cars = {i: all_legacy_fingerprint_cars() for i in [0, 1]} # attempt fingerprint on both bus 0 and 1 frame = 0 - frame_fingerprint = 10 # 0.1s + frame_fingerprint = 25 # 0.25s car_fingerprint = None done = False + # drain CAN socket so we always get the latest messages + messaging.drain_sock_raw(logcan) + while not done: a = get_one_can(logcan) diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index 0648699f95..3d6295d77d 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -1,16 +1,16 @@ from cereal import car +from opendbc.can.packer import CANPacker from selfdrive.car import apply_toyota_steer_torque_limits -from selfdrive.car.chrysler.chryslercan import create_lkas_hud, create_lkas_command, \ - create_wheel_buttons +from selfdrive.car.chrysler.chryslercan import create_lkas_hud, create_lkas_command, create_wheel_buttons from selfdrive.car.chrysler.values import CAR, CarControllerParams -from opendbc.can.packer import CANPacker -class CarController(): + +class CarController: def __init__(self, dbc_name, CP, VM): self.CP = CP self.apply_steer_last = 0 - self.ccframe = 0 - self.prev_frame = -1 + self.frame = 0 + self.prev_lkas_frame = -1 self.hud_count = 0 self.car_fingerprint = CP.carFingerprint self.gone_fast_yet = False @@ -18,12 +18,13 @@ class CarController(): self.packer = CANPacker(dbc_name) - def update(self, enabled, CS, actuators, pcm_cancel_cmd, hud_alert): + def update(self, CC, CS): # this seems needed to avoid steering faults and to force the sync with the EPS counter - frame = CS.lkas_counter - if self.prev_frame == frame: + if self.prev_lkas_frame == CS.lkas_counter: return car.CarControl.Actuators.new_message(), [] + actuators = CC.actuators + # steer torque new_steer = int(round(actuators.steer * CarControllerParams.STEER_MAX)) apply_steer = apply_toyota_steer_torque_limits(new_steer, self.apply_steer_last, @@ -36,7 +37,7 @@ class CarController(): elif self.car_fingerprint in (CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE_2019): if CS.out.vEgo < (self.CP.minSteerSpeed - 3.0): self.gone_fast_yet = False # < 14.5m/s stock turns off this bit, but fine down to 13.5 - lkas_active = moving_fast and enabled + lkas_active = moving_fast and CC.enabled if not lkas_active: apply_steer = 0 @@ -45,28 +46,23 @@ class CarController(): can_sends = [] - #*** control msgs *** + # *** control msgs *** - if pcm_cancel_cmd: - # TODO: would be better to start from frame_2b3 - new_msg = create_wheel_buttons(self.packer, self.ccframe, cancel=True) - can_sends.append(new_msg) + if CC.cruiseControl.cancel: + can_sends.append(create_wheel_buttons(self.packer, CS.button_counter + 1, cancel=True)) # LKAS_HEARTBIT is forwarded by Panda so no need to send it here. # frame is 100Hz (0.01s period) - if (self.ccframe % 25 == 0): # 0.25s period - if (CS.lkas_car_model != -1): - new_msg = create_lkas_hud( - self.packer, CS.out.gearShifter, lkas_active, hud_alert, - self.hud_count, CS.lkas_car_model) - can_sends.append(new_msg) + if self.frame % 25 == 0: # 0.25s period + if CS.lkas_car_model != -1: + can_sends.append(create_lkas_hud(self.packer, CS.out.gearShifter, lkas_active, + CC.hudControl.visualAlert, self.hud_count, CS.lkas_car_model)) self.hud_count += 1 - new_msg = create_lkas_command(self.packer, int(apply_steer), self.gone_fast_yet, frame) - can_sends.append(new_msg) + can_sends.append(create_lkas_command(self.packer, int(apply_steer), self.gone_fast_yet, CS.lkas_counter)) - self.ccframe += 1 - self.prev_frame = frame + self.frame += 1 + self.prev_lkas_frame = CS.lkas_counter new_actuators = actuators.copy() new_actuators.steer = apply_steer / CarControllerParams.STEER_MAX diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index 5f83bbde8b..8ddf1c8684 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -53,6 +53,7 @@ class CarState(CarStateBase): ret.cruiseState.speed = cp.vl["DASHBOARD"]["ACC_SPEED_CONFIG_KPH"] * CV.KPH_TO_MS # CRUISE_STATE is a three bit msg, 0 is off, 1 and 2 are Non-ACC mode, 3 and 4 are ACC mode, find if there are other states too ret.cruiseState.nonAdaptive = cp.vl["DASHBOARD"]["CRUISE_STATE"] in (1, 2) + ret.accFaulted = cp.vl["ACC_2"]["ACC_FAULTED"] != 0 ret.steeringTorque = cp.vl["EPS_STATUS"]["TORQUE_DRIVER"] ret.steeringTorqueEps = cp.vl["EPS_STATUS"]["TORQUE_MOTOR"] @@ -69,6 +70,7 @@ class CarState(CarStateBase): self.lkas_counter = cp_cam.vl["LKAS_COMMAND"]["COUNTER"] self.lkas_car_model = cp_cam.vl["LKAS_HUD"]["CAR_MODEL"] self.lkas_status_ok = cp_cam.vl["LKAS_HEARTBIT"]["LKAS_STATUS_OK"] + self.button_counter = cp.vl["WHEEL_BUTTONS"]["COUNTER"] return ret @@ -93,6 +95,7 @@ class CarState(CarStateBase): ("STEERING_RATE", "STEERING"), ("TURN_SIGNALS", "STEERING_LEVERS"), ("ACC_STATUS_2", "ACC_2"), + ("ACC_FAULTED", "ACC_2"), ("HIGH_BEAM_FLASH", "STEERING_LEVERS"), ("ACC_SPEED_CONFIG_KPH", "DASHBOARD"), ("CRUISE_STATE", "DASHBOARD"), @@ -102,6 +105,7 @@ class CarState(CarStateBase): ("COUNTER", "EPS_STATUS",), ("TRACTION_OFF", "TRACTION_BUTTON"), ("SEATBELT_DRIVER_UNLATCHED", "SEATBELT_STATUS"), + ("COUNTER", "WHEEL_BUTTONS"), ] checks = [ @@ -114,6 +118,7 @@ class CarState(CarStateBase): ("ACC_2", 50), ("GEAR", 50), ("ACCEL_GAS_134", 50), + ("WHEEL_BUTTONS", 50), ("DASHBOARD", 15), ("STEERING_LEVERS", 10), ("SEATBELT_STATUS", 2), diff --git a/selfdrive/car/chrysler/chryslercan.py b/selfdrive/car/chrysler/chryslercan.py index 4d5226570c..896a6b15da 100644 --- a/selfdrive/car/chrysler/chryslercan.py +++ b/selfdrive/car/chrysler/chryslercan.py @@ -52,6 +52,6 @@ def create_wheel_buttons(packer, frame, cancel=False): # WHEEL_BUTTONS (571) Message sent to cancel ACC. values = { "ACC_CANCEL": cancel, - "COUNTER": frame % 10 + "COUNTER": frame % 0x10 } return packer.make_can_msg("WHEEL_BUTTONS", 0, values) diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index 7751bd151b..817a5b387e 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -20,7 +20,6 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.15, 0.30], [0.03, 0.05]] ret.lateralTuning.pid.kf = 0.00006 # full torque for 10 deg at 80mph means 0.00007818594 ret.steerActuatorDelay = 0.1 - ret.steerRateCost = 0.7 ret.steerLimitTimer = 0.4 if candidate in (CAR.JEEP_CHEROKEE, CAR.JEEP_CHEROKEE_2019): @@ -65,8 +64,4 @@ class CarInterface(CarInterfaceBase): # pass in a car.CarControl # to be called @ 100hz def apply(self, c): - - if (self.CS.frame == -1): - return car.CarControl.Actuators.new_message(), [] # if we haven't seen a frame 220, then do not update. - - return self.CC.update(c.enabled, self.CS, c.actuators, c.cruiseControl.cancel, c.hudControl.visualAlert) + return self.CC.update(c, self.CS) diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index cda15dbbdb..b2757aafc2 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -1,10 +1,13 @@ -from typing import Dict, List, Union +from dataclasses import dataclass +from enum import Enum +from typing import Dict, List, Optional, Union from selfdrive.car import dbc_dict -from selfdrive.car.docs_definitions import CarInfo +from selfdrive.car.docs_definitions import CarInfo, Harness from cereal import car Ecu = car.CarParams.Ecu + class CarControllerParams: STEER_MAX = 261 # 262 faults STEER_DELTA_UP = 3 # 3 is stock. 100 is fine. 200 is too much it seems @@ -19,16 +22,23 @@ class CAR: PACIFICA_2018 = "CHRYSLER PACIFICA 2018" # includes 2017 Pacifica PACIFICA_2020 = "CHRYSLER PACIFICA 2020" JEEP_CHEROKEE = "JEEP GRAND CHEROKEE V6 2018" # includes 2017 Trailhawk - JEEP_CHEROKEE_2019 = "JEEP GRAND CHEROKEE 2019" # includes 2020 Trailhawk + JEEP_CHEROKEE_2019 = "JEEP GRAND CHEROKEE 2019" # includes 2020 Trailhawk + + +@dataclass +class ChryslerCarInfo(CarInfo): + package: str = "Adaptive Cruise" + harness: Enum = Harness.fca -CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { - CAR.PACIFICA_2017_HYBRID: CarInfo("Chrysler Pacifica Hybrid 2017-18", "Adaptive Cruise"), - CAR.PACIFICA_2019_HYBRID: CarInfo("Chrysler Pacifica Hybrid 2019-21", "Adaptive Cruise"), - CAR.PACIFICA_2018: CarInfo("Chrysler Pacifica 2017-18", "Adaptive Cruise"), - CAR.PACIFICA_2020: CarInfo("Chrysler Pacifica 2020", "Adaptive Cruise"), - CAR.JEEP_CHEROKEE: CarInfo("Jeep Grand Cherokee 2016-18", "Adaptive Cruise", "https://www.youtube.com/watch?v=eLR9o2JkuRk"), - CAR.JEEP_CHEROKEE_2019: CarInfo("Jeep Grand Cherokee 2019-20", "Adaptive Cruise", "https://www.youtube.com/watch?v=jBe4lWnRSu4"), +CAR_INFO: Dict[str, Optional[Union[ChryslerCarInfo, List[ChryslerCarInfo]]]] = { + CAR.PACIFICA_2017_HYBRID: ChryslerCarInfo("Chrysler Pacifica Hybrid 2017-18"), + CAR.PACIFICA_2018_HYBRID: None, # same platforms + CAR.PACIFICA_2019_HYBRID: ChryslerCarInfo("Chrysler Pacifica Hybrid 2019-21"), + CAR.PACIFICA_2018: ChryslerCarInfo("Chrysler Pacifica 2017-18"), + CAR.PACIFICA_2020: ChryslerCarInfo("Chrysler Pacifica 2020"), + CAR.JEEP_CHEROKEE: ChryslerCarInfo("Jeep Grand Cherokee 2016-18", video_link="https://www.youtube.com/watch?v=eLR9o2JkuRk"), + CAR.JEEP_CHEROKEE_2019: ChryslerCarInfo("Jeep Grand Cherokee 2019-20", video_link="https://www.youtube.com/watch?v=jBe4lWnRSu4"), } # Unique CAN messages: diff --git a/selfdrive/car/disable_ecu.py b/selfdrive/car/disable_ecu.py index 3a06cc06f1..ac5c6c9f8f 100644 --- a/selfdrive/car/disable_ecu.py +++ b/selfdrive/car/disable_ecu.py @@ -1,5 +1,5 @@ from selfdrive.car.isotp_parallel_query import IsoTpParallelQuery -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog EXT_DIAG_REQUEST = b'\x10\x03' EXT_DIAG_RESPONSE = b'\x50\x03' diff --git a/selfdrive/car/docs.py b/selfdrive/car/docs.py index a39e8df805..860503dbdd 100755 --- a/selfdrive/car/docs.py +++ b/selfdrive/car/docs.py @@ -7,7 +7,7 @@ from natsort import natsorted from typing import Dict, List from common.basedir import BASEDIR -from selfdrive.car.docs_definitions import CarInfo, Column, Star, Tier +from selfdrive.car.docs_definitions import STAR_DESCRIPTIONS, CarInfo, Column, Star, Tier from selfdrive.car.car_helpers import interfaces, get_interface_attr from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR as HKG_RADAR_START_ADDR from selfdrive.car.tests.routes import non_tested_cars @@ -15,9 +15,8 @@ from selfdrive.car.tests.routes import non_tested_cars def get_all_footnotes() -> Dict[Enum, int]: all_footnotes = [] - for _, footnotes in get_interface_attr("Footnote").items(): - if footnotes is not None: - all_footnotes += footnotes + for footnotes in get_interface_attr("Footnote", ignore_none=True).values(): + all_footnotes += footnotes return {fn: idx + 1 for idx, fn in enumerate(all_footnotes)} @@ -26,25 +25,32 @@ CARS_MD_OUT = os.path.join(BASEDIR, "docs", "CARS.md") CARS_MD_TEMPLATE = os.path.join(BASEDIR, "selfdrive", "car", "CARS_template.md") -def get_tier_car_info() -> Dict[Tier, List[CarInfo]]: - tier_car_info: Dict[Tier, List[CarInfo]] = {tier: [] for tier in Tier} +def get_all_car_info() -> List[CarInfo]: + all_car_info: List[CarInfo] = [] + for model, car_info in get_interface_attr("CAR_INFO", combine_brands=True).items(): + # Hyundai exception: those with radar have openpilot longitudinal + fingerprint = {0: {}, 1: {HKG_RADAR_START_ADDR: 8}, 2: {}, 3: {}} + CP = interfaces[model][0].get_params(model, fingerprint=fingerprint, disable_radar=True) + + if CP.dashcamOnly or car_info is None: + continue - for models in get_interface_attr("CAR_INFO").values(): - for model, car_info in models.items(): - # Hyundai exception: those with radar have openpilot longitudinal - fingerprint = {0: {}, 1: {HKG_RADAR_START_ADDR: 8}, 2: {}, 3: {}} - CP = interfaces[model][0].get_params(model, fingerprint=fingerprint, disable_radar=True) + # A platform can include multiple car models + if not isinstance(car_info, list): + car_info = (car_info,) - if CP.dashcamOnly: - continue + for _car_info in car_info: + all_car_info.append(_car_info.init(CP, non_tested_cars, ALL_FOOTNOTES)) - # A platform can include multiple car models - if not isinstance(car_info, list): - car_info = (car_info,) + # Sort cars by make and model + year + sorted_cars: List[CarInfo] = natsorted(all_car_info, key=lambda car: (car.make + car.model).lower()) + return sorted_cars - for _car_info in car_info: - _car_info.init(CP, non_tested_cars, ALL_FOOTNOTES) - tier_car_info[_car_info.tier].append(_car_info) + +def sort_by_tier(all_car_info: List[CarInfo]) -> Dict[Tier, List[CarInfo]]: + tier_car_info: Dict[Tier, List[CarInfo]] = {tier: [] for tier in Tier} + for car_info in all_car_info: + tier_car_info[car_info.tier].append(car_info) # Sort cars by make and model + year for tier, cars in tier_car_info.items(): @@ -53,12 +59,14 @@ def get_tier_car_info() -> Dict[Tier, List[CarInfo]]: return tier_car_info -def generate_cars_md(tier_car_info: Dict[Tier, List[CarInfo]], template_fn: str) -> str: +def generate_cars_md(all_car_info: List[CarInfo], template_fn: str) -> str: with open(template_fn, "r") as f: template = jinja2.Template(f.read(), trim_blocks=True, lstrip_blocks=True) footnotes = [fn.value.text for fn in ALL_FOOTNOTES] - return template.render(tiers=tier_car_info, footnotes=footnotes, Star=Star, Column=Column) + cars_md: str = template.render(tiers=sort_by_tier(all_car_info), all_car_info=all_car_info, + footnotes=footnotes, Star=Star, Column=Column, star_descriptions=STAR_DESCRIPTIONS) + return cars_md if __name__ == "__main__": @@ -70,5 +78,5 @@ if __name__ == "__main__": args = parser.parse_args() with open(args.out, 'w') as f: - f.write(generate_cars_md(get_tier_car_info(), args.template)) + f.write(generate_cars_md(get_all_car_info(), args.template)) print(f"Generated and written to {args.out}") diff --git a/selfdrive/car/docs_definitions.py b/selfdrive/car/docs_definitions.py index e406422981..f09dad7860 100644 --- a/selfdrive/car/docs_definitions.py +++ b/selfdrive/car/docs_definitions.py @@ -1,9 +1,15 @@ +import math + from cereal import car from collections import namedtuple from dataclasses import dataclass from enum import Enum from typing import Dict, List, Optional, Union, no_type_check +TACO_TORQUE_THRESHOLD = 2.5 # m/s^2 +GREAT_TORQUE_THRESHOLD = 1.4 # m/s^2 +GOOD_TORQUE_THRESHOLD = 1.0 # m/s^2 + class Tier(Enum): GOLD = "The best openpilot experience. Great highway driving and beyond." @@ -50,13 +56,16 @@ class CarInfo: min_steer_speed: Optional[float] = None min_enable_speed: Optional[float] = None good_torque: bool = False + harness: Optional[Enum] = None def init(self, CP: car.CarParams, non_tested_cars: List[str], all_footnotes: Dict[Enum, int]): # TODO: set all the min steer speeds in carParams and remove this min_steer_speed = CP.minSteerSpeed if self.min_steer_speed is not None: min_steer_speed = self.min_steer_speed - assert CP.minSteerSpeed == 0, f"Minimum steer speed set in both CarInfo and CarParams for {CP.carFingerprint}" + assert CP.minSteerSpeed == 0, f"{CP.carFingerprint}: Minimum steer speed set in both CarInfo and CarParams" + + assert self.harness is not None, f"{CP.carFingerprint}: Need to specify car harness" # TODO: set all the min enable speeds in carParams correctly and remove this min_enable_speed = CP.minEnableSpeed @@ -70,27 +79,34 @@ class CarInfo: Column.MODEL: self.model, Column.PACKAGE: self.package, # StarColumns - Column.LONGITUDINAL: CP.openpilotLongitudinalControl and not CP.radarOffCan, - Column.FSR_LONGITUDINAL: min_enable_speed <= 0., - Column.FSR_STEERING: min_steer_speed <= 0., - Column.STEERING_TORQUE: self.good_torque, - Column.MAINTAINED: CP.carFingerprint not in non_tested_cars, + Column.LONGITUDINAL: Star.FULL if CP.openpilotLongitudinalControl and not CP.radarOffCan else Star.EMPTY, + Column.FSR_LONGITUDINAL: Star.FULL if min_enable_speed <= 0. else Star.EMPTY, + Column.FSR_STEERING: Star.FULL if min_steer_speed <= 0. else Star.EMPTY, + Column.STEERING_TORQUE: Star.FULL if self.good_torque else Star.EMPTY, # TODO: remove hardcoding and use maxLateralAccel + Column.MAINTAINED: Star.FULL if CP.carFingerprint not in non_tested_cars and self.harness is not Harness.none else Star.EMPTY, } + if not math.isnan(CP.maxLateralAccel): + if CP.maxLateralAccel >= GREAT_TORQUE_THRESHOLD: + self.row[Column.STEERING_TORQUE] = Star.FULL + elif CP.maxLateralAccel >= GOOD_TORQUE_THRESHOLD: + self.row[Column.STEERING_TORQUE] = Star.HALF + else: + self.row[Column.STEERING_TORQUE] = Star.EMPTY + if CP.notCar: for col in StarColumns: - self.row[col] = True + self.row[col] = Star.FULL self.all_footnotes = all_footnotes for column in StarColumns: - self.row[column] = Star.FULL if self.row[column] else Star.EMPTY - # Demote if footnote specifies a star footnote = get_footnote(self.footnotes, column) if footnote is not None and footnote.value.star is not None: self.row[column] = footnote.value.star self.tier = {5: Tier.GOLD, 4: Tier.SILVER}.get(list(self.row.values()).count(Star.FULL), Tier.BRONZE) + return self @no_type_check def get_column(self, column: Column, star_icon: str, footnote_tag: str) -> str: @@ -103,3 +119,66 @@ class CarInfo: item += footnote_tag.format(self.all_footnotes[footnote]) return item + + +class Harness(Enum): + nidec = "Honda Nidec" + bosch = "Honda Bosch A" + toyota = "Toyota" + subaru = "Subaru" + fca = "FCA" + vw = "VW" + j533 = "J533" + hyundai_a = "Hyundai A" + hyundai_b = "Hyundai B" + hyundai_c = "Hyundai C" + hyundai_d = "Hyundai D" + hyundai_e = "Hyundai E" + hyundai_f = "Hyundai F" + hyundai_g = "Hyundai G" + hyundai_h = "Hyundai H" + hyundai_i = "Hyundai I" + hyundai_j = "Hyundai J" + hyundai_k = "Hyundai K" + hyundai_l = "Hyundai L" + hyundai_m = "Hyundai M" + hyundai_n = "Hyundai N" + hyundai_o = "Hyundai O" + custom = "Developer" + obd_ii = "OBD-II" + nissan_a = "Nissan A" + nissan_b = "Nissan B" + mazda = "Mazda" + none = "None" + + +STAR_DESCRIPTIONS = { + "Gas & Brakes": { # icon and row name + "openpilot Adaptive Cruise Control (ACC)": [ # star column + [Star.FULL.value, "openpilot is able to control the gas and brakes."], + [Star.HALF.value, "openpilot is able to control the gas and brakes with some restrictions."], + [Star.EMPTY.value, "The gas and brakes are controlled by the car's stock Adaptive Cruise Control (ACC) system."], + ], + Column.FSR_LONGITUDINAL.value: [ + [Star.FULL.value, "Adaptive Cruise Control (ACC) operates down to 0 mph."], + [Star.EMPTY.value, "Adaptive Cruise Control (ACC) available only above certain speeds. See your car's manual for the minimum speed."], + ], + }, + "Steering": { + Column.FSR_STEERING.value: [ + [Star.FULL.value, "openpilot can control the steering wheel down to 0 mph."], + [Star.EMPTY.value, "No steering control below certain speeds."], + ], + Column.STEERING_TORQUE.value: [ + [Star.FULL.value, "Car has enough steering torque to take tighter turns."], + [Star.HALF.value, "Car has enough steering torque for comfortable highway driving."], + [Star.EMPTY.value, "Limited ability to make turns."], + ], + }, + "Support": { + Column.MAINTAINED.value: [ + [Star.FULL.value, "Mainline software support, harness hardware sold by comma, lots of users, primary development target."], + [Star.EMPTY.value, "Low user count, community maintained, harness hardware not sold by comma."], + ], + }, +} diff --git a/selfdrive/car/fingerprints.py b/selfdrive/car/fingerprints.py index 9b280f3b45..1a9bb8c4e7 100644 --- a/selfdrive/car/fingerprints.py +++ b/selfdrive/car/fingerprints.py @@ -1,44 +1,12 @@ -import os -from common.basedir import BASEDIR +from selfdrive.car.interfaces import get_interface_attr -def get_attr_from_cars(attr, result=dict, combine_brands=True): - # read all the folders in selfdrive/car and return a dict where: - # - keys are all the car models - # - values are attr values from all car folders - result = result() - - for car_folder in [x[0] for x in os.walk(BASEDIR + '/selfdrive/car')]: - try: - car_name = car_folder.split('/')[-1] - values = __import__(f'selfdrive.car.{car_name}.values', fromlist=[attr]) - if hasattr(values, attr): - attr_values = getattr(values, attr) - else: - continue - - if isinstance(attr_values, dict): - for f, v in attr_values.items(): - if combine_brands: - result[f] = v - else: - if car_name not in result: - result[car_name] = {} - result[car_name][f] = v - elif isinstance(attr_values, list): - result += attr_values - - except (ImportError, OSError): - pass - - return result - - -FW_VERSIONS = get_attr_from_cars('FW_VERSIONS') -_FINGERPRINTS = get_attr_from_cars('FINGERPRINTS') +FW_VERSIONS = get_interface_attr('FW_VERSIONS', combine_brands=True, ignore_none=True) +_FINGERPRINTS = get_interface_attr('FINGERPRINTS', combine_brands=True, ignore_none=True) _DEBUG_ADDRESS = {1880: 8} # reserved for debug purposes + def is_valid_for_fingerprint(msg, car_fingerprint): adr = msg.address # ignore addresses that are more than 11 bits diff --git a/selfdrive/car/ford/interface.py b/selfdrive/car/ford/interface.py index ec7c723669..c608cc08d9 100644 --- a/selfdrive/car/ford/interface.py +++ b/selfdrive/car/ford/interface.py @@ -59,7 +59,6 @@ class CarInterface(CarInterfaceBase): # LCA can steer down to zero ret.minSteerSpeed = 0. - ret.steerRateCost = 1.0 ret.centerToFront = ret.wheelbase * 0.44 ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) diff --git a/selfdrive/car/ford/radar_interface.py b/selfdrive/car/ford/radar_interface.py index 1dfc27e672..866602cf09 100644 --- a/selfdrive/car/ford/radar_interface.py +++ b/selfdrive/car/ford/radar_interface.py @@ -9,6 +9,9 @@ RADAR_MSGS = list(range(0x500, 0x540)) def _create_radar_can_parser(car_fingerprint): + if DBC[car_fingerprint]['radar'] is None: + return None + msg_n = len(RADAR_MSGS) signals = list(zip(['X_Rel'] * msg_n + ['Angle'] * msg_n + ['V_Rel'] * msg_n, RADAR_MSGS * 3)) @@ -27,6 +30,9 @@ class RadarInterface(RadarInterfaceBase): self.updated_messages = set() def update(self, can_strings): + if self.rcp is None: + return super().update(None) + vls = self.rcp.update_strings(can_strings) self.updated_messages.update(vls) diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index cee7b979ec..aae011ad3d 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -35,6 +35,8 @@ class CAR: CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { + CAR.ESCAPE_MK4: CarInfo("Ford Escape", "NA"), + CAR.FOCUS_MK4: CarInfo("Ford Focus", "NA"), } @@ -77,6 +79,6 @@ FW_VERSIONS = { DBC = { - CAR.ESCAPE_MK4: dbc_dict('ford_lincoln_base_pt', 'ford_fusion_2018_adas'), - CAR.FOCUS_MK4: dbc_dict('ford_lincoln_base_pt', 'ford_fusion_2018_adas'), + CAR.ESCAPE_MK4: dbc_dict('ford_lincoln_base_pt', None), + CAR.FOCUS_MK4: dbc_dict('ford_lincoln_base_pt', None), } diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index 120174c451..c7253d794d 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -1,18 +1,18 @@ #!/usr/bin/env python3 import struct import traceback -from typing import Any, List from collections import defaultdict -from dataclasses import dataclass - +from dataclasses import dataclass, field +from typing import Any, List from tqdm import tqdm import panda.python.uds as uds from cereal import car -from selfdrive.car.fingerprints import FW_VERSIONS, get_attr_from_cars +from selfdrive.car.interfaces import get_interface_attr +from selfdrive.car.fingerprints import FW_VERSIONS from selfdrive.car.isotp_parallel_query import IsoTpParallelQuery from selfdrive.car.toyota.values import CAR as TOYOTA -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog Ecu = car.CarParams.Ecu @@ -96,9 +96,11 @@ class Request: brand: str request: List[bytes] response: List[bytes] + whitelist_ecus: List[int] = field(default_factory=list) rx_offset: int = DEFAULT_RX_OFFSET bus: int = 1 + REQUESTS: List[Request] = [ # Subaru Request( @@ -303,7 +305,7 @@ def get_fw_versions(logcan, sendcan, extra=None, timeout=0.1, debug=False, progr addrs = [] parallel_addrs = [] - versions = get_attr_from_cars('FW_VERSIONS', combine_brands=False) + versions = get_interface_attr('FW_VERSIONS', ignore_none=True) if extra is not None: versions.update(extra) @@ -328,23 +330,26 @@ def get_fw_versions(logcan, sendcan, extra=None, timeout=0.1, debug=False, progr for addr_chunk in chunks(addr): for r in REQUESTS: try: - addrs = [(a, s) for (b, a, s) in addr_chunk if b in (r.brand, 'any')] + addrs = [(a, s) for (b, a, s) in addr_chunk if b in (r.brand, 'any') and + (len(r.whitelist_ecus) == 0 or ecu_types[(a, s)] in r.whitelist_ecus)] if addrs: query = IsoTpParallelQuery(sendcan, logcan, r.bus, addrs, r.request, r.response, r.rx_offset, debug=debug) t = 2 * timeout if i == 0 else timeout - fw_versions.update(query.get_data(t)) + fw_versions.update({addr: (version, r.request, r.rx_offset) for addr, version in query.get_data(t).items()}) except Exception: cloudlog.warning(f"FW query exception: {traceback.format_exc()}") # Build capnp list to put into CarParams car_fw = [] - for addr, version in fw_versions.items(): + for addr, (version, request, rx_offset) in fw_versions.items(): f = car.CarParams.CarFw.new_message() f.ecu = ecu_types[addr] f.fwVersion = version f.address = addr[0] + f.responseAddress = addr[0] + rx_offset + f.request = request if addr[1] is not None: f.subAddress = addr[1] diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index b94fd0f2ab..48b9f25444 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -28,10 +28,15 @@ class CarState(CarStateBase): ret.vEgoRaw = mean([ret.wheelSpeeds.fl, ret.wheelSpeeds.fr, ret.wheelSpeeds.rl, ret.wheelSpeeds.rr]) ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) ret.standstill = ret.vEgoRaw < 0.01 - ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["ECMPRDNL"]["PRNDL"], None)) - ret.brakePressed = pt_cp.vl["ECMEngineStatus"]["Brake_Pressed"] != 0 + + # Brake pedal's potentiometer returns near-zero reading even when pedal is not pressed. ret.brake = pt_cp.vl["EBCMBrakePedalPosition"]["BrakePedalPosition"] / 0xd0 + ret.brakePressed = pt_cp.vl["EBCMBrakePedalPosition"]["BrakePedalPosition"] >= 10 + + # Regen braking is braking + if self.car_fingerprint == CAR.VOLT: + ret.brakePressed = ret.brakePressed or pt_cp.vl["EBCMRegenPaddle"]["RegenPaddle"] != 0 ret.gas = pt_cp.vl["AcceleratorPedal2"]["AcceleratorPedal2"] / 254. ret.gasPressed = ret.gas > 1e-5 @@ -59,17 +64,13 @@ class CarState(CarStateBase): ret.leftBlinker = pt_cp.vl["BCMTurnSignals"]["TurnSignals"] == 1 ret.rightBlinker = pt_cp.vl["BCMTurnSignals"]["TurnSignals"] == 2 - ret.parkingBrake = pt_cp.vl["EPBStatus"]["EPBClosed"] == 1 + ret.parkingBrake = pt_cp.vl["VehicleIgnitionAlt"]["ParkBrake"] == 1 ret.cruiseState.available = pt_cp.vl["ECMEngineStatus"]["CruiseMainOn"] != 0 ret.espDisabled = pt_cp.vl["ESPStatus"]["TractionControlOn"] != 1 - self.pcm_acc_status = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] - - # Regen braking is braking - if self.car_fingerprint == CAR.VOLT: - ret.brakePressed = ret.brakePressed or pt_cp.vl["EBCMRegenPaddle"]["RegenPaddle"] != 0 + ret.accFaulted = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.FAULTED - ret.cruiseState.enabled = self.pcm_acc_status != AccState.OFF - ret.cruiseState.standstill = self.pcm_acc_status == AccState.STANDSTILL + ret.cruiseState.enabled = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] != AccState.OFF + ret.cruiseState.standstill = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.STANDSTILL return ret @@ -99,9 +100,8 @@ class CarState(CarStateBase): ("LKATorqueDelivered", "PSCMStatus"), ("LKATorqueDeliveredStatus", "PSCMStatus"), ("TractionControlOn", "ESPStatus"), - ("EPBClosed", "EPBStatus"), + ("ParkBrake", "VehicleIgnitionAlt"), ("CruiseMainOn", "ECMEngineStatus"), - ("Brake_Pressed", "ECMEngineStatus"), ] checks = [ @@ -110,7 +110,7 @@ class CarState(CarStateBase): ("PSCMStatus", 10), ("ESPStatus", 10), ("BCMDoorBeltStatus", 10), - ("EPBStatus", 20), + ("VehicleIgnitionAlt", 10), ("EBCMWheelSpdFront", 20), ("EBCMWheelSpdRear", 20), ("AcceleratorPedal2", 33), diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 64ec9d4242..9c1744dfb4 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -3,13 +3,15 @@ from cereal import car from math import fabs from common.conversions import Conversions as CV -from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config -from selfdrive.car.gm.values import CAR, CruiseButtons, \ - AccState, CarControllerParams +from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config +from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams from selfdrive.car.interfaces import CarInterfaceBase ButtonType = car.CarState.ButtonEvent.Type EventName = car.CarEvent.EventName +BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.DECEL_SET: ButtonType.decelCruise, + CruiseButtons.MAIN: ButtonType.altButton3, CruiseButtons.CANCEL: ButtonType.cancel} + class CarInterface(CarInterfaceBase): @staticmethod @@ -56,22 +58,29 @@ class CarInterface(CarInterfaceBase): ret.openpilotLongitudinalControl = True tire_stiffness_factor = 0.444 # not optimized yet - # Start with a baseline lateral tuning for all GM vehicles. Override tuning as needed in each model section below. + # Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below. ret.minSteerSpeed = 7 * CV.MPH_TO_MS ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.00]] ret.lateralTuning.pid.kf = 0.00004 # full torque for 20 deg at 80mph means 0.00007818594 - ret.steerRateCost = 1.0 ret.steerActuatorDelay = 0.1 # Default delay, not measured yet + ret.longitudinalTuning.kpBP = [5., 35.] + ret.longitudinalTuning.kpV = [2.4, 1.5] + ret.longitudinalTuning.kiBP = [0.] + ret.longitudinalTuning.kiV = [0.36] + + ret.steerLimitTimer = 0.4 + ret.radarTimeStep = 0.0667 # GM radar runs at 15Hz instead of standard 20Hz + + # supports stop and go, but initial engage must (conservatively) be above 18mph + ret.minEnableSpeed = 18 * CV.MPH_TO_MS + if candidate == CAR.VOLT: - # supports stop and go, but initial engage must be above 18mph (which include conservatism) - ret.minEnableSpeed = 18 * CV.MPH_TO_MS ret.mass = 1607. + STD_CARGO_KG ret.wheelbase = 2.69 ret.steerRatio = 17.7 # Stock 15.7, LiveParameters tire_stiffness_factor = 0.469 # Stock Michelin Energy Saver A/S, LiveParameters - ret.steerRatioRear = 0. ret.centerToFront = ret.wheelbase * 0.45 # Volt Gen 1, TODO corner weigh ret.lateralTuning.pid.kpBP = [0., 40.] @@ -82,12 +91,9 @@ class CarInterface(CarInterfaceBase): ret.steerActuatorDelay = 0.2 elif candidate == CAR.MALIBU: - # supports stop and go, but initial engage must be above 18mph (which include conservatism) - ret.minEnableSpeed = 18 * CV.MPH_TO_MS ret.mass = 1496. + STD_CARGO_KG ret.wheelbase = 2.83 ret.steerRatio = 15.8 - ret.steerRatioRear = 0. ret.centerToFront = ret.wheelbase * 0.4 # wild guess elif candidate == CAR.HOLDEN_ASTRA: @@ -95,33 +101,26 @@ class CarInterface(CarInterfaceBase): ret.wheelbase = 2.662 # Remaining parameters copied from Volt for now ret.centerToFront = ret.wheelbase * 0.4 - ret.minEnableSpeed = 18 * CV.MPH_TO_MS ret.steerRatio = 15.7 - ret.steerRatioRear = 0. elif candidate == CAR.ACADIA: ret.minEnableSpeed = -1. # engage speed is decided by pcm ret.mass = 4353. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.86 ret.steerRatio = 14.4 # end to end is 13.46 - ret.steerRatioRear = 0. ret.centerToFront = ret.wheelbase * 0.4 - ret.lateralTuning.pid.kf = 1. # get_steer_feedforward_acadia() + ret.lateralTuning.pid.kf = 1. # get_steer_feedforward_acadia() elif candidate == CAR.BUICK_REGAL: - ret.minEnableSpeed = 18 * CV.MPH_TO_MS ret.mass = 3779. * CV.LB_TO_KG + STD_CARGO_KG # (3849+3708)/2 ret.wheelbase = 2.83 # 111.4 inches in meters ret.steerRatio = 14.4 # guess for tourx - ret.steerRatioRear = 0. ret.centerToFront = ret.wheelbase * 0.4 # guess for tourx elif candidate == CAR.CADILLAC_ATS: - ret.minEnableSpeed = 18 * CV.MPH_TO_MS ret.mass = 1601. + STD_CARGO_KG ret.wheelbase = 2.78 ret.steerRatio = 15.3 - ret.steerRatioRear = 0. ret.centerToFront = ret.wheelbase * 0.49 elif candidate == CAR.ESCALADE_ESV: @@ -144,14 +143,6 @@ class CarInterface(CarInterfaceBase): ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, tire_stiffness_factor=tire_stiffness_factor) - ret.longitudinalTuning.kpBP = [5., 35.] - ret.longitudinalTuning.kpV = [2.4, 1.5] - ret.longitudinalTuning.kiBP = [0.] - ret.longitudinalTuning.kiV = [0.36] - - ret.steerLimitTimer = 0.4 - ret.radarTimeStep = 0.0667 # GM radar runs at 15Hz instead of standard 20Hz - return ret # returns a car.CarState @@ -160,29 +151,14 @@ class CarInterface(CarInterfaceBase): ret.steeringRateLimited = self.CC.steer_rate_limited if self.CC is not None else False - buttonEvents = [] - if self.CS.cruise_buttons != self.CS.prev_cruise_buttons and self.CS.prev_cruise_buttons != CruiseButtons.INIT: - be = car.CarState.ButtonEvent.new_message() - be.type = ButtonType.unknown - if self.CS.cruise_buttons != CruiseButtons.UNPRESS: - be.pressed = True - but = self.CS.cruise_buttons - else: - be.pressed = False - but = self.CS.prev_cruise_buttons - if but == CruiseButtons.RES_ACCEL: - if not (ret.cruiseState.enabled and ret.standstill): - be.type = ButtonType.accelCruise # Suppress resume button if we're resuming from stop so we don't adjust speed. - elif but == CruiseButtons.DECEL_SET: - be.type = ButtonType.decelCruise - elif but == CruiseButtons.CANCEL: - be.type = ButtonType.cancel - elif but == CruiseButtons.MAIN: - be.type = ButtonType.altButton3 - buttonEvents.append(be) - - ret.buttonEvents = buttonEvents + be = create_button_event(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT, CruiseButtons.UNPRESS) + + # Suppress resume button if we're resuming from stop so we don't adjust speed. + if be.type == ButtonType.accelCruise and (ret.cruiseState.enabled and ret.standstill): + be.type = ButtonType.unknown + + ret.buttonEvents = [be] events = self.create_common_events(ret, pcm_enable=False) @@ -190,19 +166,11 @@ class CarInterface(CarInterfaceBase): events.add(EventName.belowEngageSpeed) if ret.cruiseState.standstill: events.add(EventName.resumeRequired) - if self.CS.pcm_acc_status == AccState.FAULTED: - events.add(EventName.accFaulted) if ret.vEgo < self.CP.minSteerSpeed: events.add(car.CarEvent.EventName.belowSteerSpeed) # handle button presses - for b in ret.buttonEvents: - # do enable on both accel and decel buttons - if b.type in (ButtonType.accelCruise, ButtonType.decelCruise) and not b.pressed: - events.add(EventName.buttonEnable) - # do disable on button down - if b.type == ButtonType.cancel and b.pressed: - events.add(EventName.buttonCancel) + events.events.extend(create_button_enable_events(ret.buttonEvents)) ret.events = events.to_msg() diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 65d42579d3..8ef33e8297 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -1,9 +1,10 @@ +from dataclasses import dataclass from enum import Enum from typing import Dict, List, Union from cereal import car from selfdrive.car import dbc_dict -from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column +from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, Harness Ecu = car.CarParams.Ecu @@ -62,14 +63,20 @@ class Footnote(Enum): Column.MODEL) -CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { - CAR.HOLDEN_ASTRA: CarInfo("Holden Astra 2017", "Adaptive Cruise"), - CAR.VOLT: CarInfo("Chevrolet Volt 2017-18", "Adaptive Cruise", footnotes=[Footnote.OBD_II], min_enable_speed=0), - CAR.CADILLAC_ATS: CarInfo("Cadillac ATS Premium Performance 2018", "Adaptive Cruise"), - CAR.MALIBU: CarInfo("Chevrolet Malibu Premier 2017", "Adaptive Cruise"), - CAR.ACADIA: CarInfo("GMC Acadia 2018", "Adaptive Cruise", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo", footnotes=[Footnote.OBD_II]), - CAR.BUICK_REGAL: CarInfo("Buick Regal Essence 2018", "Adaptive Cruise"), - CAR.ESCALADE_ESV: CarInfo("Cadillac Escalade ESV 2016", "ACC + LKAS", footnotes=[Footnote.OBD_II]), +@dataclass +class GMCarInfo(CarInfo): + package: str = "Adaptive Cruise" + harness: Enum = Harness.none + + +CAR_INFO: Dict[str, Union[GMCarInfo, List[GMCarInfo]]] = { + CAR.HOLDEN_ASTRA: GMCarInfo("Holden Astra 2017", harness=Harness.custom), + CAR.VOLT: GMCarInfo("Chevrolet Volt 2017-18", footnotes=[Footnote.OBD_II], min_enable_speed=0, harness=Harness.custom), + CAR.CADILLAC_ATS: GMCarInfo("Cadillac ATS Premium Performance 2018"), + CAR.MALIBU: GMCarInfo("Chevrolet Malibu Premier 2017", harness=Harness.custom), + CAR.ACADIA: GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo", footnotes=[Footnote.OBD_II]), + CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"), + CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "ACC + LKAS", footnotes=[Footnote.OBD_II]), } diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py index dc7648ce58..a6aa84adf6 100644 --- a/selfdrive/car/honda/carcontroller.py +++ b/selfdrive/car/honda/carcontroller.py @@ -95,8 +95,8 @@ def process_hud_alert(hud_alert): HUDData = namedtuple("HUDData", - ["pcm_accel", "v_cruise", "car", - "lanes", "fcw", "acc_alert", "steer_required"]) + ["pcm_accel", "v_cruise", "lead_visible", + "lanes_visible", "fcw", "acc_alert", "steer_required"]) class CarController: @@ -112,10 +112,10 @@ class CarController: self.apply_brake_last = 0 self.last_pump_ts = 0. - self.accel = 0 - self.speed = 0 - self.gas = 0 - self.brake = 0 + self.accel = 0.0 + self.speed = 0.0 + self.gas = 0.0 + self.brake = 0.0 def update(self, CC, CS): actuators = CC.actuators @@ -138,19 +138,6 @@ class CarController: self.brake_last = rate_limit(pre_limit_brake, self.brake_last, -2., DT_CTRL) # vehicle hud display, wait for one update from 10Hz 0x304 msg - if hud_control.lanesVisible: - hud_lanes = 1 - else: - hud_lanes = 0 - - if CC.enabled: - if hud_control.leadVisible: - hud_car = 2 - else: - hud_car = 1 - else: - hud_car = 0 - fcw_display, steer_required, acc_alert = process_hud_alert(hud_control.visualAlert) # **** process the car messages **** @@ -172,8 +159,6 @@ class CarController: can_sends.append(hondacan.create_steering_control(self.packer, apply_steer, CC.latActive, self.CP.carFingerprint, idx, CS.CP.openpilotLongitudinalControl)) - stopping = actuators.longControlState == LongCtrlState.stopping - # wind brake from air resistance decel at high speed wind_brake = interp(CS.out.vEgo, [0.0, 2.3, 35.0], [0.001, 0.002, 0.15]) # all of this is only relevant for HONDA NIDEC @@ -222,7 +207,9 @@ class CarController: if self.CP.carFingerprint in HONDA_BOSCH: self.accel = clip(accel, self.params.BOSCH_ACCEL_MIN, self.params.BOSCH_ACCEL_MAX) self.gas = interp(accel, self.params.BOSCH_GAS_LOOKUP_BP, self.params.BOSCH_GAS_LOOKUP_V) - can_sends.extend(hondacan.create_acc_commands(self.packer, CC.enabled, CC.longActive, accel, self.gas, + + stopping = actuators.longControlState == LongCtrlState.stopping + can_sends.extend(hondacan.create_acc_commands(self.packer, CC.enabled, CC.longActive, self.accel, self.gas, idx, stopping, self.CP.carFingerprint)) else: apply_brake = clip(self.brake_last - wind_brake, 0.0, 1.0) @@ -252,9 +239,9 @@ class CarController: # Send dashboard UI commands. if self.frame % 10 == 0: idx = (self.frame // 10) % 4 - hud = HUDData(int(pcm_accel), int(round(hud_v_cruise)), hud_car, - hud_lanes, fcw_display, acc_alert, steer_required) - can_sends.extend(hondacan.create_ui_commands(self.packer, self.CP, pcm_speed, hud, CS.is_metric, idx, CS.stock_hud)) + hud = HUDData(int(pcm_accel), int(round(hud_v_cruise)), hud_control.leadVisible, + hud_control.lanesVisible, fcw_display, acc_alert, steer_required) + can_sends.extend(hondacan.create_ui_commands(self.packer, self.CP, CC.enabled, pcm_speed, hud, CS.is_metric, idx, CS.stock_hud)) if self.CP.openpilotLongitudinalControl and self.CP.carFingerprint not in HONDA_BOSCH: self.speed = pcm_speed diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index 5314fe375e..f5cdc838c4 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -22,9 +22,9 @@ def get_can_signals(CP, gearbox_msg, main_on_sig_msg): ("STEER_ANGLE_RATE", "STEERING_SENSORS"), ("MOTOR_TORQUE", "STEER_MOTOR_TORQUE"), ("STEER_TORQUE_SENSOR", "STEER_STATUS"), + ("IMPERIAL_UNIT", "CAR_SPEED"), ("LEFT_BLINKER", "SCM_FEEDBACK"), ("RIGHT_BLINKER", "SCM_FEEDBACK"), - ("GEAR", gearbox_msg), ("SEATBELT_DRIVER_LAMP", "SEATBELT_STATUS"), ("SEATBELT_DRIVER_LATCHED", "SEATBELT_STATUS"), ("BRAKE_PRESSED", "POWERTRAIN_DATA"), @@ -35,6 +35,7 @@ def get_can_signals(CP, gearbox_msg, main_on_sig_msg): ("BRAKE_HOLD_ACTIVE", "VSA_STATUS"), ("STEER_STATUS", "STEER_STATUS"), ("GEAR_SHIFTER", gearbox_msg), + ("GEAR", gearbox_msg), ("PEDAL_GAS", "POWERTRAIN_DATA"), ("CRUISE_SETTING", "SCM_BUTTONS"), ("ACC_STATUS", "POWERTRAIN_DATA"), @@ -48,9 +49,10 @@ def get_can_signals(CP, gearbox_msg, main_on_sig_msg): ("SEATBELT_STATUS", 10), ("CRUISE", 10), ("POWERTRAIN_DATA", 100), + ("CAR_SPEED", 10), ("VSA_STATUS", 50), ("STEER_STATUS", 100), - ("STEER_MOTOR_TORQUE", 0), # TODO: not on every car + ("STEER_MOTOR_TORQUE", 0), # TODO: not on every car ] if CP.carFingerprint == CAR.ODYSSEY_CHN: @@ -73,16 +75,11 @@ def get_can_signals(CP, gearbox_msg, main_on_sig_msg): signals.append(("BRAKE_PRESSED", "BRAKE_MODULE")) checks.append(("BRAKE_MODULE", 50)) - if CP.carFingerprint in HONDA_BOSCH: - signals += [ - ("EPB_STATE", "EPB_STATUS"), - ("IMPERIAL_UNIT", "CAR_SPEED"), - ] - checks += [ - ("EPB_STATUS", 50), - ("CAR_SPEED", 10), - ] + if CP.carFingerprint in (HONDA_BOSCH | {CAR.CIVIC, CAR.ODYSSEY, CAR.ODYSSEY_CHN}): + signals.append(("EPB_STATE", "EPB_STATUS")) + checks.append(("EPB_STATUS", 50)) + if CP.carFingerprint in HONDA_BOSCH: if not CP.openpilotLongitudinalControl: signals += [ ("CRUISE_CONTROL_LABEL", "ACC_HUD"), @@ -121,17 +118,6 @@ def get_can_signals(CP, gearbox_msg, main_on_sig_msg): ("STANDSTILL", 50), ] - if CP.carFingerprint == CAR.CIVIC: - signals += [("IMPERIAL_UNIT", "HUD_SETTING"), - ("EPB_STATE", "EPB_STATUS")] - checks += [ - ("HUD_SETTING", 50), - ("EPB_STATUS", 50), - ] - elif CP.carFingerprint in (CAR.ODYSSEY, CAR.ODYSSEY_CHN): - signals.append(("EPB_STATE", "EPB_STATUS")) - checks.append(("EPB_STATUS", 50)) - # add gas interceptor reading if we are using it if CP.enableGasInterceptor: signals.append(("INTERCEPTOR_GAS", "GAS_SENSOR")) @@ -179,6 +165,11 @@ class CarState(CarStateBase): # update prevs, update must run once per loop self.prev_cruise_buttons = self.cruise_buttons self.prev_cruise_setting = self.cruise_setting + self.cruise_setting = cp.vl["SCM_BUTTONS"]["CRUISE_SETTING"] + self.cruise_buttons = cp.vl["SCM_BUTTONS"]["CRUISE_BUTTONS"] + + # used for car hud message + self.is_metric = not cp.vl["CAR_SPEED"]["IMPERIAL_UNIT"] # ******************* parse out can ******************* # STANDSTILL->WHEELS_MOVING bit can be noisy around zero, so use XMISSION_SPEED @@ -219,16 +210,12 @@ class CarState(CarStateBase): ret.steeringAngleDeg = cp.vl["STEERING_SENSORS"]["STEER_ANGLE"] ret.steeringRateDeg = cp.vl["STEERING_SENSORS"]["STEER_ANGLE_RATE"] - self.cruise_setting = cp.vl["SCM_BUTTONS"]["CRUISE_SETTING"] - self.cruise_buttons = cp.vl["SCM_BUTTONS"]["CRUISE_BUTTONS"] - ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_stalk( 250, cp.vl["SCM_FEEDBACK"]["LEFT_BLINKER"], cp.vl["SCM_FEEDBACK"]["RIGHT_BLINKER"]) ret.brakeHoldActive = cp.vl["VSA_STATUS"]["BRAKE_HOLD_ACTIVE"] == 1 # TODO: set for all cars - if self.CP.carFingerprint in (CAR.CIVIC, CAR.ODYSSEY, CAR.ODYSSEY_CHN, CAR.CRV_5G, CAR.ACCORD, CAR.ACCORDH, CAR.CIVIC_BOSCH, - CAR.CIVIC_BOSCH_DIESEL, CAR.CRV_HYBRID, CAR.INSIGHT, CAR.ACURA_RDX_3G, CAR.HONDA_E): + if self.CP.carFingerprint in (HONDA_BOSCH | {CAR.CIVIC, CAR.ODYSSEY, CAR.ODYSSEY_CHN}): ret.parkingBrake = cp.vl["EPB_STATUS"]["EPB_STATE"] != 0 gear = int(cp.vl[self.gearbox_msg]["GEAR_SHIFTER"]) @@ -281,14 +268,6 @@ class CarState(CarStateBase): if ret.brake > 0.1: ret.brakePressed = True - # TODO: discover the CAN msg that has the imperial unit bit for all other cars - if self.CP.carFingerprint in (CAR.CIVIC, ): - self.is_metric = not cp.vl["HUD_SETTING"]["IMPERIAL_UNIT"] - elif self.CP.carFingerprint in HONDA_BOSCH: - self.is_metric = not cp.vl["CAR_SPEED"]["IMPERIAL_UNIT"] - else: - self.is_metric = False - if self.CP.carFingerprint in HONDA_BOSCH: ret.stockAeb = (not self.CP.openpilotLongitudinalControl) and bool(cp.vl["ACC_CONTROL"]["AEB_STATUS"] and cp.vl["ACC_CONTROL"]["ACCEL_COMMAND"] < -1e-5) else: diff --git a/selfdrive/car/honda/hondacan.py b/selfdrive/car/honda/hondacan.py index dcdc0e5f94..3d8c79c809 100644 --- a/selfdrive/car/honda/hondacan.py +++ b/selfdrive/car/honda/hondacan.py @@ -98,47 +98,40 @@ def create_bosch_supplemental_1(packer, car_fingerprint, idx): return packer.make_can_msg("BOSCH_SUPPLEMENTAL_1", bus, values, idx) -def create_ui_commands(packer, CP, pcm_speed, hud, is_metric, idx, stock_hud): +def create_ui_commands(packer, CP, enabled, pcm_speed, hud, is_metric, idx, stock_hud): commands = [] bus_pt = get_pt_bus(CP.carFingerprint) radar_disabled = CP.carFingerprint in HONDA_BOSCH and CP.openpilotLongitudinalControl bus_lkas = get_lkas_cmd_bus(CP.carFingerprint, radar_disabled) if CP.openpilotLongitudinalControl: + acc_hud_values = { + 'CRUISE_SPEED': hud.v_cruise, + 'ENABLE_MINI_CAR': 1, + 'HUD_DISTANCE': 3, # max distance setting on display + 'IMPERIAL_UNIT': int(not is_metric), + 'HUD_LEAD': 2 if enabled and hud.lead_visible else 1 if enabled else 0, + 'SET_ME_X01_2': 1, + } + if CP.carFingerprint in HONDA_BOSCH: - acc_hud_values = { - 'CRUISE_SPEED': hud.v_cruise, - 'ENABLE_MINI_CAR': 1, - 'SET_TO_1': 1, - 'HUD_LEAD': hud.car, - 'HUD_DISTANCE': 3, - 'ACC_ON': hud.car != 0, - 'SET_TO_X1': 1, - 'IMPERIAL_UNIT': int(not is_metric), - 'FCM_OFF': 1, - } + acc_hud_values['ACC_ON'] = int(enabled) + acc_hud_values['FCM_OFF'] = 1 + acc_hud_values['FCM_OFF_2'] = 1 else: - acc_hud_values = { - 'PCM_SPEED': pcm_speed * CV.MS_TO_KPH, - 'PCM_GAS': hud.pcm_accel, - 'CRUISE_SPEED': hud.v_cruise, - 'ENABLE_MINI_CAR': 1, - 'HUD_LEAD': hud.car, - 'HUD_DISTANCE': 3, # max distance setting on display - 'IMPERIAL_UNIT': int(not is_metric), - 'SET_ME_X01_2': 1, - 'SET_ME_X01': 1, - "FCM_OFF": stock_hud["FCM_OFF"], - "FCM_OFF_2": stock_hud["FCM_OFF_2"], - "FCM_PROBLEM": stock_hud["FCM_PROBLEM"], - "ICONS": stock_hud["ICONS"], - } + acc_hud_values['PCM_SPEED'] = pcm_speed * CV.MS_TO_KPH + acc_hud_values['PCM_GAS'] = hud.pcm_accel + acc_hud_values['SET_ME_X01'] = 1 + acc_hud_values['FCM_OFF'] = stock_hud['FCM_OFF'] + acc_hud_values['FCM_OFF_2'] = stock_hud['FCM_OFF_2'] + acc_hud_values['FCM_PROBLEM'] = stock_hud['FCM_PROBLEM'] + acc_hud_values['ICONS'] = stock_hud['ICONS'] commands.append(packer.make_can_msg("ACC_HUD", bus_pt, acc_hud_values, idx)) lkas_hud_values = { 'SET_ME_X41': 0x41, 'STEERING_REQUIRED': hud.steer_required, - 'SOLID_LANES': hud.lanes, + 'SOLID_LANES': hud.lanes_visible, 'BEEP': 0, } diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 265175d940..994152608e 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -4,7 +4,7 @@ from panda import Panda from common.conversions import Conversions as CV from common.numpy_fast import interp from selfdrive.car.honda.values import CarControllerParams, CruiseButtons, HondaFlags, CAR, HONDA_BOSCH, HONDA_NIDEC_ALT_SCM_MESSAGES, HONDA_BOSCH_ALT_BRAKE_SIGNAL -from selfdrive.car import STD_CARGO_KG, CivicParams, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config +from selfdrive.car import STD_CARGO_KG, CivicParams, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.disable_ecu import disable_ecu @@ -12,6 +12,8 @@ from selfdrive.car.disable_ecu import disable_ecu ButtonType = car.CarState.ButtonEvent.Type EventName = car.CarEvent.EventName TransmissionType = car.CarParams.TransmissionType +BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.DECEL_SET: ButtonType.decelCruise, + CruiseButtons.MAIN: ButtonType.altButton3, CruiseButtons.CANCEL: ButtonType.cancel} class CarInterface(CarInterfaceBase): @@ -214,8 +216,8 @@ class CarInterface(CarInterfaceBase): ret.wheelbase = 2.68 ret.centerToFront = ret.wheelbase * 0.38 ret.steerRatio = 15.0 # as spec - ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 1000], [0, 1000]] # TODO: determine if there is a dead zone at the top end tire_stiffness_factor = 0.444 + ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 1000], [0, 1000]] # TODO: determine if there is a dead zone at the top end ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] elif candidate == CAR.ACURA_RDX_3G: @@ -317,7 +319,6 @@ class CarInterface(CarInterfaceBase): tire_stiffness_factor=tire_stiffness_factor) ret.steerActuatorDelay = 0.1 - ret.steerRateCost = 0.5 ret.steerLimitTimer = 0.8 return ret @@ -334,37 +335,11 @@ class CarInterface(CarInterfaceBase): buttonEvents = [] if self.CS.cruise_buttons != self.CS.prev_cruise_buttons: - be = car.CarState.ButtonEvent.new_message() - be.type = ButtonType.unknown - if self.CS.cruise_buttons != 0: - be.pressed = True - but = self.CS.cruise_buttons - else: - be.pressed = False - but = self.CS.prev_cruise_buttons - if but == CruiseButtons.RES_ACCEL: - be.type = ButtonType.accelCruise - elif but == CruiseButtons.DECEL_SET: - be.type = ButtonType.decelCruise - elif but == CruiseButtons.CANCEL: - be.type = ButtonType.cancel - elif but == CruiseButtons.MAIN: - be.type = ButtonType.altButton3 - buttonEvents.append(be) + buttonEvents.append(create_button_event(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT)) if self.CS.cruise_setting != self.CS.prev_cruise_setting: - be = car.CarState.ButtonEvent.new_message() - be.type = ButtonType.unknown - if self.CS.cruise_setting != 0: - be.pressed = True - but = self.CS.cruise_setting - else: - be.pressed = False - but = self.CS.prev_cruise_setting - if but == 1: - be.type = ButtonType.altButton1 - # TODO: more buttons? - buttonEvents.append(be) + buttonEvents.append(create_button_event(self.CS.cruise_setting, self.CS.prev_cruise_setting, {1: ButtonType.altButton1})) + ret.buttonEvents = buttonEvents # events @@ -391,16 +366,7 @@ class CarInterface(CarInterfaceBase): events.add(EventName.manualRestart) # handle button presses - for b in ret.buttonEvents: - - # do enable on both accel and decel buttons - if not self.CP.pcmCruise: - if b.type in (ButtonType.accelCruise, ButtonType.decelCruise) and not b.pressed: - events.add(EventName.buttonEnable) - - # do disable on button down - if b.type == ButtonType.cancel and b.pressed: - events.add(EventName.buttonCancel) + events.events.extend(create_button_enable_events(ret.buttonEvents, self.CP.pcmCruise)) ret.events = events.to_msg() diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index ab1f44ac87..152f71e98a 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -1,14 +1,16 @@ +from dataclasses import dataclass from enum import Enum, IntFlag -from typing import Dict, List, Union +from typing import Dict, List, Optional, Union from cereal import car -from selfdrive.car import dbc_dict -from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column from common.conversions import Conversions as CV +from selfdrive.car import dbc_dict +from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, Harness Ecu = car.CarParams.Ecu VisualAlert = car.CarControl.HUDControl.VisualAlert + class CarControllerParams: # Allow small margin below -3.5 m/s^2 from ISO 15622:2018 since we # perform the closed loop control, and might need some @@ -53,6 +55,7 @@ class CruiseButtons: CANCEL = 2 MAIN = 1 + # See dbc files for info on values VISUAL_HUD = { VisualAlert.none: 0, @@ -97,33 +100,41 @@ class Footnote(Enum): Column.FSR_STEERING) -CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { +@dataclass +class HondaCarInfo(CarInfo): + package: str = "Honda Sensing" + min_steer_speed: float = 12. * CV.MPH_TO_MS + + +CAR_INFO: Dict[str, Optional[Union[HondaCarInfo, List[HondaCarInfo]]]] = { CAR.ACCORD: [ - CarInfo("Honda Accord 2018-21", "All", video_link="https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS), - CarInfo("Honda Inspire 2018", "All", min_steer_speed=3. * CV.MPH_TO_MS), + HondaCarInfo("Honda Accord 2018-21", "All", video_link="https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch), + HondaCarInfo("Honda Inspire 2018", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch), ], - CAR.ACCORDH: CarInfo("Honda Accord Hybrid 2018-21", "All", min_steer_speed=3. * CV.MPH_TO_MS), - CAR.CIVIC: CarInfo("Honda Civic 2016-18", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), + CAR.ACCORDH: HondaCarInfo("Honda Accord Hybrid 2018-21", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch), + CAR.CIVIC: HondaCarInfo("Honda Civic 2016-18", harness=Harness.nidec), CAR.CIVIC_BOSCH: [ - CarInfo("Honda Civic 2019-20", "All", video_link="https://www.youtube.com/watch?v=4Iz1Mz5LGF8", footnotes=[Footnote.CIVIC_DIESEL], min_steer_speed=2. * CV.MPH_TO_MS), - CarInfo("Honda Civic Hatchback 2017-21", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), + HondaCarInfo("Honda Civic 2019-20", "All", video_link="https://www.youtube.com/watch?v=4Iz1Mz5LGF8", footnotes=[Footnote.CIVIC_DIESEL], min_steer_speed=2. * CV.MPH_TO_MS, harness=Harness.bosch), + HondaCarInfo("Honda Civic Hatchback 2017-21", harness=Harness.bosch), ], - CAR.ACURA_ILX: CarInfo("Acura ILX 2016-19", "AcuraWatch Plus", min_steer_speed=25. * CV.MPH_TO_MS), - CAR.CRV: CarInfo("Honda CR-V 2015-16", "Touring", min_steer_speed=12. * CV.MPH_TO_MS), - CAR.CRV_5G: CarInfo("Honda CR-V 2017-21", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), - # CAR.CRV_EU: CarInfo("Honda CR-V EU", "Touring"), # Euro version of CRV Touring - CAR.CRV_HYBRID: CarInfo("Honda CR-V Hybrid 2017-19", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), - CAR.FIT: CarInfo("Honda Fit 2018-19", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), - CAR.FREED: CarInfo("Honda Freed 2020", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), - CAR.HRV: CarInfo("Honda HR-V 2019-20", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), - CAR.ODYSSEY: CarInfo("Honda Odyssey 2018-20", "Honda Sensing"), - CAR.ACURA_RDX: CarInfo("Acura RDX 2016-18", "AcuraWatch Plus", min_steer_speed=12. * CV.MPH_TO_MS), - CAR.ACURA_RDX_3G: CarInfo("Acura RDX 2019-21", "All", min_steer_speed=3. * CV.MPH_TO_MS), - CAR.PILOT: CarInfo("Honda Pilot 2016-21", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), - CAR.PASSPORT: CarInfo("Honda Passport 2019-21", "All", min_steer_speed=12. * CV.MPH_TO_MS), - CAR.RIDGELINE: CarInfo("Honda Ridgeline 2017-21", "Honda Sensing", min_steer_speed=12. * CV.MPH_TO_MS), - CAR.INSIGHT: CarInfo("Honda Insight 2019-21", "All", min_steer_speed=3. * CV.MPH_TO_MS), - CAR.HONDA_E: CarInfo("Honda e 2020", "All", min_steer_speed=3. * CV.MPH_TO_MS), + CAR.CIVIC_BOSCH_DIESEL: None, # same platform + CAR.ACURA_ILX: HondaCarInfo("Acura ILX 2016-19", "AcuraWatch Plus", min_steer_speed=25. * CV.MPH_TO_MS, harness=Harness.nidec), + CAR.CRV: HondaCarInfo("Honda CR-V 2015-16", "Touring", harness=Harness.nidec), + CAR.CRV_5G: HondaCarInfo("Honda CR-V 2017-21", harness=Harness.bosch), + CAR.CRV_EU: None, # HondaCarInfo("Honda CR-V EU", "Touring"), # Euro version of CRV Touring + CAR.CRV_HYBRID: HondaCarInfo("Honda CR-V Hybrid 2017-19", harness=Harness.bosch), + CAR.FIT: HondaCarInfo("Honda Fit 2018-19", harness=Harness.nidec), + CAR.FREED: HondaCarInfo("Honda Freed 2020", harness=Harness.nidec), + CAR.HRV: HondaCarInfo("Honda HR-V 2019-20", harness=Harness.nidec), + CAR.ODYSSEY: HondaCarInfo("Honda Odyssey 2018-20", min_steer_speed=0., harness=Harness.nidec), + CAR.ODYSSEY_CHN: None, # Chinese version of Odyssey + CAR.ACURA_RDX: HondaCarInfo("Acura RDX 2016-18", "AcuraWatch Plus", harness=Harness.nidec), + CAR.ACURA_RDX_3G: HondaCarInfo("Acura RDX 2019-21", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch), + CAR.PILOT: HondaCarInfo("Honda Pilot 2016-21", harness=Harness.nidec), + CAR.PASSPORT: HondaCarInfo("Honda Passport 2019-21", "All", harness=Harness.nidec), + CAR.RIDGELINE: HondaCarInfo("Honda Ridgeline 2017-22", harness=Harness.nidec), + CAR.INSIGHT: HondaCarInfo("Honda Insight 2019-21", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch), + CAR.HONDA_E: HondaCarInfo("Honda e 2020", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch), } diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index 9abdf8d03a..fb3579464a 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -3,8 +3,8 @@ from common.realtime import DT_CTRL from common.numpy_fast import clip, interp from common.conversions import Conversions as CV from selfdrive.car import apply_std_steer_torque_limits -from selfdrive.car.hyundai.hyundaican import create_lkas11, create_clu11, create_lfahda_mfc, create_acc_commands, create_acc_opt, create_frt_radar_opt -from selfdrive.car.hyundai.values import Buttons, CarControllerParams, CAR +from selfdrive.car.hyundai import hda2can, hyundaican +from selfdrive.car.hyundai.values import Buttons, CarControllerParams, HDA2_CAR, CAR from opendbc.can.packer import CANPacker VisualAlert = car.CarControl.HUDControl.VisualAlert @@ -44,13 +44,12 @@ class CarController: self.apply_steer_last = 0 self.car_fingerprint = CP.carFingerprint self.steer_rate_limited = False - self.last_resume_frame = 0 + self.last_button_frame = 0 self.accel = 0 def update(self, CC, CS): actuators = CC.actuators hud_control = CC.hudControl - pcm_cancel_cmd = CC.cruiseControl.cancel # Steering Torque new_steer = int(round(actuators.steer * self.params.STEER_MAX)) @@ -67,58 +66,74 @@ class CarController: can_sends = [] - # tester present - w/ no response (keeps radar disabled) - if self.CP.openpilotLongitudinalControl: - if self.frame % 100 == 0: - can_sends.append([0x7D0, 0, b"\x02\x3E\x80\x00\x00\x00\x00\x00", 0]) - - can_sends.append(create_lkas11(self.packer, self.frame, self.car_fingerprint, apply_steer, CC.latActive, - CS.lkas11, sys_warning, sys_state, CC.enabled, - hud_control.leftLaneVisible, hud_control.rightLaneVisible, - left_lane_warning, right_lane_warning)) - - if not self.CP.openpilotLongitudinalControl: - if pcm_cancel_cmd: - can_sends.append(create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL)) - elif CS.out.cruiseState.standstill: - # send resume at a max freq of 10Hz - if (self.frame - self.last_resume_frame) * DT_CTRL > 0.1: - # send 25 messages at a time to increases the likelihood of resume being accepted - can_sends.extend([create_clu11(self.packer, self.frame, CS.clu11, Buttons.RES_ACCEL)] * 25) - self.last_resume_frame = self.frame - - if self.frame % 2 == 0 and self.CP.openpilotLongitudinalControl: - accel = actuators.accel - jerk = 0 - - if CC.longActive: - jerk = clip(2.0 * (accel - CS.out.aEgo), -12.7, 12.7) - if accel < 0: - accel = interp(accel - CS.out.aEgo, [-1.0, -0.5], [2 * accel, accel]) - - accel = clip(accel, CarControllerParams.ACCEL_MIN, CarControllerParams.ACCEL_MAX) - - lead_visible = False - stopping = actuators.longControlState == LongCtrlState.stopping - set_speed_in_units = hud_control.setSpeed * (CV.MS_TO_MPH if CS.clu11["CF_Clu_SPEED_UNIT"] == 1 else CV.MS_TO_KPH) - can_sends.extend(create_acc_commands(self.packer, CC.enabled, accel, jerk, int(self.frame / 2), lead_visible, - set_speed_in_units, stopping, CS.out.gasPressed)) - self.accel = accel - - # 20 Hz LFA MFA message - if self.frame % 5 == 0 and self.car_fingerprint in (CAR.SONATA, CAR.PALISADE, CAR.IONIQ, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV_2021, - CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KIA_CEED, CAR.KIA_SELTOS, CAR.KONA_EV, - CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.SANTA_FE_2022, - CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.GENESIS_G70_2020, CAR.SANTA_FE_PHEV_2022): - can_sends.append(create_lfahda_mfc(self.packer, CC.enabled)) - - # 5 Hz ACC options - if self.frame % 20 == 0 and self.CP.openpilotLongitudinalControl: - can_sends.extend(create_acc_opt(self.packer)) - - # 2 Hz front radar options - if self.frame % 50 == 0 and self.CP.openpilotLongitudinalControl: - can_sends.append(create_frt_radar_opt(self.packer)) + if self.CP.carFingerprint in HDA2_CAR: + # steering control + can_sends.append(hda2can.create_lkas(self.packer, CC.enabled, self.frame, CC.latActive, apply_steer)) + + # cruise cancel + if (self.frame - self.last_button_frame) * DT_CTRL > 0.25: + if CC.cruiseControl.cancel: + for _ in range(20): + can_sends.append(hda2can.create_buttons(self.packer, CS.buttons_counter+1, True, False)) + self.last_button_frame = self.frame + + # cruise standstill resume + elif CC.enabled and CS.out.cruiseState.standstill: + can_sends.append(hda2can.create_buttons(self.packer, CS.buttons_counter+1, False, True)) + self.last_button_frame = self.frame + else: + + # tester present - w/ no response (keeps radar disabled) + if self.CP.openpilotLongitudinalControl: + if self.frame % 100 == 0: + can_sends.append([0x7D0, 0, b"\x02\x3E\x80\x00\x00\x00\x00\x00", 0]) + + can_sends.append(hyundaican.create_lkas11(self.packer, self.frame, self.car_fingerprint, apply_steer, CC.latActive, + CS.lkas11, sys_warning, sys_state, CC.enabled, + hud_control.leftLaneVisible, hud_control.rightLaneVisible, + left_lane_warning, right_lane_warning)) + + if not self.CP.openpilotLongitudinalControl: + if CC.cruiseControl.cancel: + can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL)) + elif CS.out.cruiseState.standstill: + # send resume at a max freq of 10Hz + if (self.frame - self.last_button_frame) * DT_CTRL > 0.1: + # send 25 messages at a time to increases the likelihood of resume being accepted + can_sends.extend([hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.RES_ACCEL)] * 25) + self.last_button_frame = self.frame + + if self.frame % 2 == 0 and self.CP.openpilotLongitudinalControl: + accel = actuators.accel + jerk = 0 + + if CC.longActive: + jerk = clip(2.0 * (accel - CS.out.aEgo), -12.7, 12.7) + if accel < 0: + accel = interp(accel - CS.out.aEgo, [-1.0, -0.5], [2 * accel, accel]) + + accel = clip(accel, CarControllerParams.ACCEL_MIN, CarControllerParams.ACCEL_MAX) + + stopping = actuators.longControlState == LongCtrlState.stopping + set_speed_in_units = hud_control.setSpeed * (CV.MS_TO_MPH if CS.clu11["CF_Clu_SPEED_UNIT"] == 1 else CV.MS_TO_KPH) + can_sends.extend(hyundaican.create_acc_commands(self.packer, CC.enabled, accel, jerk, int(self.frame / 2), + hud_control.leadVisible, set_speed_in_units, stopping, CS.out.gasPressed)) + self.accel = accel + + # 20 Hz LFA MFA message + if self.frame % 5 == 0 and self.car_fingerprint in (CAR.SONATA, CAR.PALISADE, CAR.IONIQ, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV_2021, + CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KIA_CEED, CAR.KIA_SELTOS, CAR.KONA_EV, + CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.SANTA_FE_2022, + CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.GENESIS_G70_2020, CAR.SANTA_FE_PHEV_2022): + can_sends.append(hyundaican.create_lfahda_mfc(self.packer, CC.enabled)) + + # 5 Hz ACC options + if self.frame % 20 == 0 and self.CP.openpilotLongitudinalControl: + can_sends.extend(hyundaican.create_acc_opt(self.packer)) + + # 2 Hz front radar options + if self.frame % 50 == 0 and self.CP.openpilotLongitudinalControl: + can_sends.append(hyundaican.create_frt_radar_opt(self.packer)) new_actuators = actuators.copy() new_actuators.steer = apply_steer / self.params.STEER_MAX diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index 7752bf82cd..9d864faac4 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -5,7 +5,7 @@ from cereal import car from common.conversions import Conversions as CV from opendbc.can.parser import CANParser from opendbc.can.can_define import CANDefine -from selfdrive.car.hyundai.values import DBC, STEER_THRESHOLD, FEATURES, EV_CAR, HYBRID_CAR, Buttons +from selfdrive.car.hyundai.values import DBC, STEER_THRESHOLD, FEATURES, HDA2_CAR, EV_CAR, HYBRID_CAR, Buttons from selfdrive.car.interfaces import CarStateBase PREV_BUTTON_SAMPLES = 4 @@ -19,14 +19,23 @@ class CarState(CarStateBase): self.cruise_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES) self.main_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES) - if self.CP.carFingerprint in FEATURES["use_cluster_gears"]: + if CP.carFingerprint in HDA2_CAR: + self.shifter_values = can_define.dv["ACCELERATOR"]["GEAR"] + elif self.CP.carFingerprint in FEATURES["use_cluster_gears"]: self.shifter_values = can_define.dv["CLU15"]["CF_Clu_Gear"] elif self.CP.carFingerprint in FEATURES["use_tcu_gears"]: self.shifter_values = can_define.dv["TCU12"]["CUR_GR"] else: # preferred and elect gear methods use same definition self.shifter_values = can_define.dv["LVR12"]["CF_Lvr_Gear"] + self.brake_error = False + self.park_brake = False + self.buttons_counter = 0 + def update(self, cp, cp_cam): + if self.CP.carFingerprint in HDA2_CAR: + return self.update_hda2(cp, cp_cam) + ret = car.CarState.new_message() ret.doorOpen = any([cp.vl["CGW1"]["CF_Gway_DrvDrSw"], cp.vl["CGW1"]["CF_Gway_AstDrSw"], @@ -120,10 +129,57 @@ class CarState(CarStateBase): return ret + def update_hda2(self, cp, cp_cam): + ret = car.CarState.new_message() + + ret.gas = cp.vl["ACCELERATOR"]["ACCELERATOR_PEDAL"] / 255. + ret.gasPressed = ret.gas > 1e-3 + ret.brakePressed = cp.vl["BRAKE"]["BRAKE_PRESSED"] == 1 + + ret.doorOpen = cp.vl["DOORS_SEATBELTS"]["DRIVER_DOOR_OPEN"] == 1 + ret.seatbeltUnlatched = cp.vl["DOORS_SEATBELTS"]["DRIVER_SEATBELT_LATCHED"] == 0 + + gear = cp.vl["ACCELERATOR"]["GEAR"] + ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(gear)) + + # TODO: figure out positions + ret.wheelSpeeds = self.get_wheel_speeds( + cp.vl["WHEEL_SPEEDS"]["WHEEL_SPEED_1"], + cp.vl["WHEEL_SPEEDS"]["WHEEL_SPEED_2"], + cp.vl["WHEEL_SPEEDS"]["WHEEL_SPEED_3"], + cp.vl["WHEEL_SPEEDS"]["WHEEL_SPEED_4"], + ) + ret.vEgoRaw = (ret.wheelSpeeds.fl + ret.wheelSpeeds.fr + ret.wheelSpeeds.rl + ret.wheelSpeeds.rr) / 4. + ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) + ret.standstill = ret.vEgoRaw < 0.1 + + ret.steeringRateDeg = cp.vl["STEERING_SENSORS"]["STEERING_RATE"] + ret.steeringAngleDeg = cp.vl["STEERING_SENSORS"]["STEERING_ANGLE"] * -1 + ret.steeringTorque = cp.vl["MDPS"]["STEERING_COL_TORQUE"] + ret.steeringTorqueEps = cp.vl["MDPS"]["STEERING_OUT_TORQUE"] + ret.steeringPressed = abs(ret.steeringTorque) > STEER_THRESHOLD + + ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(50, cp.vl["BLINKERS"]["LEFT_LAMP"], + cp.vl["BLINKERS"]["RIGHT_LAMP"]) + + ret.cruiseState.available = True + ret.cruiseState.enabled = cp.vl["SCC1"]["CRUISE_ACTIVE"] == 1 + ret.cruiseState.standstill = cp.vl["CRUISE_INFO"]["CRUISE_STANDSTILL"] == 1 + + speed_factor = CV.MPH_TO_MS if cp.vl["CLUSTER_INFO"]["DISTANCE_UNIT"] == 1 else CV.KPH_TO_MS + ret.cruiseState.speed = cp.vl["CRUISE_INFO"]["SET_SPEED"] * speed_factor + + self.buttons_counter = cp.vl["CRUISE_BUTTONS"]["_COUNTER"] + + return ret + @staticmethod def get_can_parser(CP): + if CP.carFingerprint in HDA2_CAR: + return CarState.get_can_parser_hda2(CP) + signals = [ - # sig_name, sig_address + # signal_name, signal_address ("WHL_SPD_FL", "WHL_SPD11"), ("WHL_SPD_FR", "WHL_SPD11"), ("WHL_SPD_RL", "WHL_SPD11"), @@ -135,9 +191,9 @@ class CarState(CarStateBase): ("CF_Gway_DrvSeatBeltSw", "CGW1"), ("CF_Gway_DrvDrSw", "CGW1"), # Driver Door - ("CF_Gway_AstDrSw", "CGW1"), # Passenger door - ("CF_Gway_RLDrSw", "CGW2"), # Rear reft door - ("CF_Gway_RRDrSw", "CGW2"), # Rear right door + ("CF_Gway_AstDrSw", "CGW1"), # Passenger Door + ("CF_Gway_RLDrSw", "CGW2"), # Rear left Door + ("CF_Gway_RRDrSw", "CGW2"), # Rear right Door ("CF_Gway_TurnSigLh", "CGW1"), ("CF_Gway_TurnSigRh", "CGW1"), ("CF_Gway_ParkBrakeSw", "CGW1"), @@ -175,7 +231,6 @@ class CarState(CarStateBase): ("SAS_Angle", "SAS11"), ("SAS_Speed", "SAS11"), ] - checks = [ # address, frequency ("MDPS12", 50), @@ -198,7 +253,6 @@ class CarState(CarStateBase): ("ACC_ObjDist", "SCC11"), ("ACCMode", "SCC12"), ] - checks += [ ("SCC11", 50), ("SCC12", 50), @@ -256,8 +310,11 @@ class CarState(CarStateBase): @staticmethod def get_cam_can_parser(CP): + if CP.carFingerprint in HDA2_CAR: + return None + signals = [ - # sig_name, sig_address + # signal_name, signal_address ("CF_Lkas_LdwsActivemode", "LKAS11"), ("CF_Lkas_LdwsSysState", "LKAS11"), ("CF_Lkas_SysWarning", "LKAS11"), @@ -274,9 +331,55 @@ class CarState(CarStateBase): ("CF_Lkas_FcwOpt_USM", "LKAS11"), ("CF_Lkas_LdwsOpt_USM", "LKAS11"), ] - checks = [ ("LKAS11", 100) ] return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 2) + + @staticmethod + def get_can_parser_hda2(CP): + signals = [ + ("WHEEL_SPEED_1", "WHEEL_SPEEDS"), + ("WHEEL_SPEED_2", "WHEEL_SPEEDS"), + ("WHEEL_SPEED_3", "WHEEL_SPEEDS"), + ("WHEEL_SPEED_4", "WHEEL_SPEEDS"), + + ("ACCELERATOR_PEDAL", "ACCELERATOR"), + ("GEAR", "ACCELERATOR"), + ("BRAKE_PRESSED", "BRAKE"), + + ("STEERING_RATE", "STEERING_SENSORS"), + ("STEERING_ANGLE", "STEERING_SENSORS"), + ("STEERING_COL_TORQUE", "MDPS"), + ("STEERING_OUT_TORQUE", "MDPS"), + + ("CRUISE_ACTIVE", "SCC1"), + ("SET_SPEED", "CRUISE_INFO"), + ("CRUISE_STANDSTILL", "CRUISE_INFO"), + ("_COUNTER", "CRUISE_BUTTONS"), + + ("DISTANCE_UNIT", "CLUSTER_INFO"), + + ("LEFT_LAMP", "BLINKERS"), + ("RIGHT_LAMP", "BLINKERS"), + + ("DRIVER_DOOR_OPEN", "DOORS_SEATBELTS"), + ("DRIVER_SEATBELT_LATCHED", "DOORS_SEATBELTS"), + ] + + checks = [ + ("WHEEL_SPEEDS", 100), + ("ACCELERATOR", 100), + ("BRAKE", 100), + ("STEERING_SENSORS", 100), + ("MDPS", 100), + ("SCC1", 50), + ("CRUISE_INFO", 50), + ("CRUISE_BUTTONS", 50), + ("CLUSTER_INFO", 4), + ("BLINKERS", 4), + ("DOORS_SEATBELTS", 4), + ] + + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 5) diff --git a/selfdrive/car/hyundai/hda2can.py b/selfdrive/car/hyundai/hda2can.py new file mode 100644 index 0000000000..e4c658c1a9 --- /dev/null +++ b/selfdrive/car/hyundai/hda2can.py @@ -0,0 +1,23 @@ +def create_lkas(packer, enabled, frame, lat_active, apply_steer): + values = { + "LKA_MODE": 2, + "LKA_ICON": 2 if enabled else 1, + "TORQUE_REQUEST": apply_steer, + "LKA_ASSIST": 0, + "STEER_REQ": 1 if lat_active else 0, + "STEER_MODE": 0, + "SET_ME_1": 0, + "NEW_SIGNAL_1": 0, + "NEW_SIGNAL_2": 0, + } + return packer.make_can_msg("LKAS", 4, values, frame % 255) + + +def create_buttons(packer, cnt, cancel, resume): + values = { + "_COUNTER": cnt % 0xf, + "SET_ME_1": 1, + "DISTANCE_BTN": 1 if resume else 0, + "PAUSE_RESUME_BTN": 1 if cancel else 0, + } + return packer.make_can_msg("CRUISE_BUTTONS", 5, values) diff --git a/selfdrive/car/hyundai/hyundaican.py b/selfdrive/car/hyundai/hyundaican.py index d03eb135fc..53499053e0 100644 --- a/selfdrive/car/hyundai/hyundaican.py +++ b/selfdrive/car/hyundai/hyundaican.py @@ -86,8 +86,8 @@ def create_acc_commands(packer, enabled, accel, jerk, idx, lead_visible, set_spe "TauGapSet": 4, "VSetDis": set_speed if enabled else 0, "AliveCounterACC": idx % 0x10, - "ObjValid": 1 if lead_visible else 0, - "ACC_ObjStatus": 1 if lead_visible else 0, + "ObjValid": 0, # TODO: these two bits may allow for better longitudinal control + "ACC_ObjStatus": 0, "ACC_ObjLatPos": 0, "ACC_ObjRelSpd": 0, "ACC_ObjDist": 0, diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 999910eff1..497d6b3f30 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -1,16 +1,20 @@ #!/usr/bin/env python3 +import os from cereal import car from panda import Panda from common.conversions import Conversions as CV -from selfdrive.car.hyundai.values import CAR, DBC, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons, CarControllerParams +from selfdrive.car.hyundai.values import CAR, DBC, HDA2_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons, CarControllerParams from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR -from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config +from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.disable_ecu import disable_ecu +from selfdrive.controls.lib.latcontrol_torque import set_torque_tune ButtonType = car.CarState.ButtonEvent.Type EventName = car.CarEvent.EventName ENABLE_BUTTONS = (Buttons.RES_ACCEL, Buttons.SET_DECEL, Buttons.CANCEL) +BUTTONS_DICT = {Buttons.RES_ACCEL: ButtonType.accelCruise, Buttons.SET_DECEL: ButtonType.decelCruise, + Buttons.GAP_DIST: ButtonType.gapAdjustCruise, Buttons.CANCEL: ButtonType.cancel} class CarInterface(CarInterfaceBase): @@ -35,9 +39,10 @@ class CarInterface(CarInterfaceBase): # These cars likely still work fine. Once a user confirms each car works and a test route is # added to selfdrive/car/tests/routes.py, we can remove it from this list. ret.dashcamOnly = candidate in {CAR.KIA_OPTIMA_H, CAR.ELANTRA_GT_I30} + if candidate in HDA2_CAR: + ret.dashcamOnly = not os.path.exists('/data/enable-ev6') ret.steerActuatorDelay = 0.1 # Default delay - ret.steerRateCost = 0.5 ret.steerLimitTimer = 0.4 tire_stiffness_factor = 1. @@ -48,8 +53,8 @@ class CarInterface(CarInterfaceBase): ret.longitudinalTuning.kiV = [0.0] ret.stopAccel = 0.0 - ret.longitudinalActuatorDelayUpperBound = 1.0 # s - + ret.longitudinalActuatorDelayUpperBound = 1.0 # s + torque_params = CarInterfaceBase.get_torque_params(candidate) if candidate in (CAR.SANTA_FE, CAR.SANTA_FE_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022): ret.lateralTuning.pid.kf = 0.00005 ret.mass = 3982. * CV.LB_TO_KG + STD_CARGO_KG @@ -60,13 +65,11 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[9., 22.], [9., 22.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2, 0.35], [0.05, 0.09]] elif candidate in (CAR.SONATA, CAR.SONATA_HYBRID): - ret.lateralTuning.pid.kf = 0.00005 ret.mass = 1513. + STD_CARGO_KG ret.wheelbase = 2.84 ret.steerRatio = 13.27 * 1.15 # 15% higher at the center seems reasonable tire_stiffness_factor = 0.65 - ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] - ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] + set_torque_tune(ret.lateralTuning, torque_params['LAT_ACCEL_FACTOR'], torque_params['FRICTION']) elif candidate == CAR.SONATA_LF: ret.lateralTuning.pid.kf = 0.00005 ret.mass = 4497. * CV.LB_TO_KG @@ -92,21 +95,17 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] ret.minSteerSpeed = 32 * CV.MPH_TO_MS elif candidate == CAR.ELANTRA_2021: - ret.lateralTuning.pid.kf = 0.00005 ret.mass = (2800. * CV.LB_TO_KG) + STD_CARGO_KG ret.wheelbase = 2.72 ret.steerRatio = 12.9 tire_stiffness_factor = 0.65 - ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] - ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] + set_torque_tune(ret.lateralTuning, torque_params['LAT_ACCEL_FACTOR'], torque_params['FRICTION']) elif candidate == CAR.ELANTRA_HEV_2021: - ret.lateralTuning.pid.kf = 0.00005 ret.mass = (3017. * CV.LB_TO_KG) + STD_CARGO_KG ret.wheelbase = 2.72 ret.steerRatio = 12.9 tire_stiffness_factor = 0.65 - ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] - ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] + set_torque_tune(ret.lateralTuning, torque_params['LAT_ACCEL_FACTOR'], torque_params['FRICTION']) elif candidate == CAR.HYUNDAI_GENESIS: ret.lateralTuning.pid.kf = 0.00005 ret.mass = 2060. + STD_CARGO_KG @@ -125,8 +124,8 @@ class CarInterface(CarInterfaceBase): elif candidate in (CAR.KONA, CAR.KONA_EV, CAR.KONA_HEV): ret.lateralTuning.pid.kf = 0.00005 ret.mass = {CAR.KONA_EV: 1685., CAR.KONA_HEV: 1425.}.get(candidate, 1275.) + STD_CARGO_KG - ret.wheelbase = 2.7 - ret.steerRatio = 13.73 * 1.15 # Spec + ret.wheelbase = 2.6 + ret.steerRatio = 13.42 # Spec tire_stiffness_factor = 0.385 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] @@ -162,9 +161,9 @@ class CarInterface(CarInterfaceBase): tire_stiffness_factor = 0.5 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] - elif candidate == CAR.TUCSON_DIESEL_2019: + elif candidate == CAR.TUCSON: ret.lateralTuning.pid.kf = 0.00005 - ret.mass = 3633. * CV.LB_TO_KG + ret.mass = 3520. * CV.LB_TO_KG ret.wheelbase = 2.67 ret.steerRatio = 14.00 * 1.15 tire_stiffness_factor = 0.385 @@ -204,13 +203,12 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.indi.actuatorEffectivenessBP = [0.] ret.lateralTuning.indi.actuatorEffectivenessV = [1.8] elif candidate in (CAR.KIA_OPTIMA, CAR.KIA_OPTIMA_H): - ret.lateralTuning.pid.kf = 0.00005 ret.mass = 3558. * CV.LB_TO_KG ret.wheelbase = 2.80 ret.steerRatio = 13.75 tire_stiffness_factor = 0.5 - ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] - ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] + torque_params = CarInterfaceBase.get_torque_params(CAR.KIA_OPTIMA) + set_torque_tune(ret.lateralTuning, torque_params['LAT_ACCEL_FACTOR'], torque_params['FRICTION']) elif candidate == CAR.KIA_STINGER: ret.lateralTuning.pid.kf = 0.00005 ret.mass = 1825. + STD_CARGO_KG @@ -243,6 +241,17 @@ class CarInterface(CarInterfaceBase): tire_stiffness_factor = 0.5 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] + elif candidate == CAR.KIA_EV6: + ret.mass = 2055 + STD_CARGO_KG + ret.wheelbase = 2.9 + ret.steerRatio = 16. + ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.noOutput), + get_safety_config(car.CarParams.SafetyModel.hyundaiHDA2)] + tire_stiffness_factor = 0.65 + + ret.maxLateralAccel = 2. + # TODO override until there is more data + set_torque_tune(ret.lateralTuning, 2.0, 0.05) # Genesis elif candidate == CAR.GENESIS_G70: @@ -321,42 +330,20 @@ class CarInterface(CarInterfaceBase): # To avoid re-engaging when openpilot cancels, check user engagement intention via buttons # Main button also can trigger an engagement on these cars allow_enable = any(btn in ENABLE_BUTTONS for btn in self.CS.cruise_buttons) or any(self.CS.main_buttons) - events = self.create_common_events(ret, pcm_enable=self.CS.CP.pcmCruise, allow_enable=allow_enable) + allow_enable = allow_enable or self.CP.carFingerprint in HDA2_CAR + events = self.create_common_events(ret, pcm_enable=self.CS.CP.pcmCruise, allow_enable=allow_enable or True) if self.CS.brake_error: events.add(EventName.brakeUnavailable) - if self.CS.CP.openpilotLongitudinalControl: - buttonEvents = [] - - if self.CS.cruise_buttons[-1] != self.CS.prev_cruise_buttons: - be = car.CarState.ButtonEvent.new_message() - be.type = ButtonType.unknown - if self.CS.cruise_buttons[-1] != 0: - be.pressed = True - but = self.CS.cruise_buttons[-1] - else: - be.pressed = False - but = self.CS.prev_cruise_buttons - if but == Buttons.RES_ACCEL: - be.type = ButtonType.accelCruise - elif but == Buttons.SET_DECEL: - be.type = ButtonType.decelCruise - elif but == Buttons.GAP_DIST: - be.type = ButtonType.gapAdjustCruise - elif but == Buttons.CANCEL: - be.type = ButtonType.cancel - buttonEvents.append(be) - - ret.buttonEvents = buttonEvents - - for b in ret.buttonEvents: - # do enable on both accel and decel buttons - if b.type in (ButtonType.accelCruise, ButtonType.decelCruise) and not b.pressed: - events.add(EventName.buttonEnable) - # do disable on button down - if b.type == ButtonType.cancel and b.pressed: - events.add(EventName.buttonCancel) + if self.CS.CP.openpilotLongitudinalControl and self.CS.cruise_buttons[-1] != self.CS.prev_cruise_buttons: + buttonEvents = [create_button_event(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT)] + # Handle CF_Clu_CruiseSwState changing buttons mid-press + if self.CS.cruise_buttons[-1] != 0 and self.CS.prev_cruise_buttons != 0: + buttonEvents.append(create_button_event(0, self.CS.prev_cruise_buttons, BUTTONS_DICT)) + + ret.buttonEvents = buttonEvents + events.events.extend(create_button_enable_events(ret.buttonEvents)) # low speed steer alert hysteresis logic (only for cars with steer cut off above 10 m/s) if ret.vEgo < (self.CP.minSteerSpeed + 2.) and self.CP.minSteerSpeed > 10.: diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 1a20ab6d6b..df7ce1e6f4 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -1,13 +1,13 @@ from dataclasses import dataclass -from typing import Dict, List, Union +from typing import Dict, List, Optional, Union from cereal import car from common.conversions import Conversions as CV from selfdrive.car import dbc_dict -from selfdrive.car.docs_definitions import CarInfo +from selfdrive.car.docs_definitions import CarInfo, Harness Ecu = car.CarParams.Ecu -# Steer torque limits + class CarControllerParams: ACCEL_MIN = -3.5 # m/s ACCEL_MAX = 2.0 # m/s @@ -15,7 +15,9 @@ class CarControllerParams: def __init__(self, CP): # To determine the limit for your car, find the maximum value that the stock LKAS will request. # If the max stock LKAS request is <384, add your car to this list. - if CP.carFingerprint in (CAR.GENESIS_G80, CAR.GENESIS_G90, CAR.ELANTRA, CAR.HYUNDAI_GENESIS, CAR.ELANTRA_GT_I30, CAR.IONIQ, + if CP.carFingerprint in HDA2_CAR: + self.STEER_MAX = 150 + elif CP.carFingerprint in (CAR.GENESIS_G80, CAR.GENESIS_G90, CAR.ELANTRA, CAR.HYUNDAI_GENESIS, CAR.ELANTRA_GT_I30, CAR.IONIQ, CAR.IONIQ_EV_LTD, CAR.SANTA_FE_PHEV_2022, CAR.SONATA_LF, CAR.KIA_FORTE, CAR.KIA_NIRO_HEV, CAR.KIA_OPTIMA_H, CAR.KIA_SORENTO, CAR.KIA_STINGER): self.STEER_MAX = 255 @@ -50,7 +52,7 @@ class CAR: SANTA_FE_PHEV_2022 = "HYUNDAI SANTA FE PlUG-IN HYBRID 2022" SONATA = "HYUNDAI SONATA 2020" SONATA_LF = "HYUNDAI SONATA 2019" - TUCSON_DIESEL_2019 = "HYUNDAI TUCSON DIESEL 2019" + TUCSON = "HYUNDAI TUCSON 2019" PALISADE = "HYUNDAI PALISADE 2020" VELOSTER = "HYUNDAI VELOSTER 2019" SONATA_HYBRID = "HYUNDAI SONATA HYBRID 2021" @@ -67,6 +69,7 @@ class CAR: KIA_SORENTO = "KIA SORENTO GT LINE 2018" KIA_STINGER = "KIA STINGER GT2 2018" KIA_CEED = "KIA CEED INTRO ED 2019" + KIA_EV6 = "KIA EV6 2022" # Genesis GENESIS_G70 = "GENESIS G70 2018" @@ -77,58 +80,79 @@ class CAR: @dataclass class HyundaiCarInfo(CarInfo): + # TODO: we can probably remove LKAS. LKAS is standard on many + # HKG and for others, it's likely packaged together with SCC package: str = "SCC + LKAS" good_torque: bool = True -CAR_INFO: Dict[str, Union[HyundaiCarInfo, List[HyundaiCarInfo]]] = { - CAR.ELANTRA: HyundaiCarInfo("Hyundai Elantra 2017-19", min_enable_speed=19 * CV.MPH_TO_MS), - CAR.ELANTRA_2021: HyundaiCarInfo("Hyundai Elantra 2021-22", video_link="https://youtu.be/_EdYQtV52-c"), - CAR.ELANTRA_HEV_2021: HyundaiCarInfo("Hyundai Elantra Hybrid 2021-22", video_link="https://youtu.be/_EdYQtV52-c"), - CAR.HYUNDAI_GENESIS: HyundaiCarInfo("Hyundai Genesis 2015-16", min_enable_speed=19 * CV.MPH_TO_MS), - CAR.IONIQ: HyundaiCarInfo("Hyundai Ioniq Hybrid 2017-19"), - CAR.IONIQ_HEV_2022: HyundaiCarInfo("Hyundai Ioniq Hybrid 2020-22", "SCC + LFA"), - CAR.IONIQ_EV_LTD: HyundaiCarInfo("Hyundai Ioniq Electric 2019"), - CAR.IONIQ_EV_2020: HyundaiCarInfo("Hyundai Ioniq Electric 2020"), - CAR.IONIQ_PHEV_2019: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2019", "SCC + LKAS"), - CAR.IONIQ_PHEV: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2020-21"), - CAR.KONA: HyundaiCarInfo("Hyundai Kona 2020"), - CAR.KONA_EV: HyundaiCarInfo("Hyundai Kona Electric 2018-21"), - CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020"), - CAR.SANTA_FE: HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All"), - CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-22", "All"), - CAR.SANTA_FE_HEV_2022: HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022", "All"), - CAR.SANTA_FE_PHEV_2022: HyundaiCarInfo("Hyundai Santa Fe Plug-in Hybrid 2022", "All"), - CAR.SONATA: HyundaiCarInfo("Hyundai Sonata 2020-22", "All", video_link="https://www.youtube.com/watch?v=ix63r9kE3Fw"), - CAR.SONATA_LF: HyundaiCarInfo("Hyundai Sonata 2018-19"), - CAR.TUCSON_DIESEL_2019: HyundaiCarInfo("Hyundai Tucson Diesel 2019", "SCC + LKAS"), +CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { + CAR.ELANTRA: HyundaiCarInfo("Hyundai Elantra 2017-19", min_enable_speed=19 * CV.MPH_TO_MS, harness=Harness.hyundai_b), + CAR.ELANTRA_2021: HyundaiCarInfo("Hyundai Elantra 2021-22", video_link="https://youtu.be/_EdYQtV52-c", harness=Harness.hyundai_k), + CAR.ELANTRA_HEV_2021: HyundaiCarInfo("Hyundai Elantra Hybrid 2021-22", video_link="https://youtu.be/_EdYQtV52-c", harness=Harness.hyundai_k), + CAR.ELANTRA_GT_I30: None, # dashcamOnly and same platform as CAR.ELANTRA + CAR.HYUNDAI_GENESIS: HyundaiCarInfo("Hyundai Genesis 2015-16", min_enable_speed=19 * CV.MPH_TO_MS, harness=Harness.hyundai_j), + CAR.IONIQ: HyundaiCarInfo("Hyundai Ioniq Hybrid 2017-19", harness=Harness.hyundai_c), + CAR.IONIQ_HEV_2022: HyundaiCarInfo("Hyundai Ioniq Hybrid 2020-22", "SCC + LFA", harness=Harness.hyundai_h), + CAR.IONIQ_EV_LTD: HyundaiCarInfo("Hyundai Ioniq Electric 2019", harness=Harness.hyundai_c), + CAR.IONIQ_EV_2020: HyundaiCarInfo("Hyundai Ioniq Electric 2020", harness=Harness.hyundai_h), + CAR.IONIQ_PHEV_2019: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2019", harness=Harness.hyundai_c), + CAR.IONIQ_PHEV: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2020-21", harness=Harness.hyundai_h), + CAR.KONA: HyundaiCarInfo("Hyundai Kona 2020", harness=Harness.hyundai_b), + CAR.KONA_EV: HyundaiCarInfo("Hyundai Kona Electric 2018-21", harness=Harness.hyundai_g), + CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020", harness=Harness.hyundai_i), + CAR.SANTA_FE: HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All", harness=Harness.hyundai_d), + CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-22", "All", harness=Harness.hyundai_l), + CAR.SANTA_FE_HEV_2022: HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022", "All", harness=Harness.hyundai_l), + CAR.SANTA_FE_PHEV_2022: HyundaiCarInfo("Hyundai Santa Fe Plug-in Hybrid 2022", "All", harness=Harness.hyundai_l), + CAR.SONATA: HyundaiCarInfo("Hyundai Sonata 2020-22", "All", video_link="https://www.youtube.com/watch?v=ix63r9kE3Fw", harness=Harness.hyundai_a), + CAR.SONATA_LF: HyundaiCarInfo("Hyundai Sonata 2018-19", harness=Harness.hyundai_e), + CAR.TUCSON: [ + HyundaiCarInfo("Hyundai Tucson 2021", min_enable_speed=19 * CV.MPH_TO_MS, harness=Harness.hyundai_l), + HyundaiCarInfo("Hyundai Tucson Diesel 2019", harness=Harness.hyundai_l), + ], CAR.PALISADE: [ - HyundaiCarInfo("Hyundai Palisade 2020-21", "All", video_link="https://youtu.be/TAnDqjF4fDY?t=456"), - HyundaiCarInfo("Kia Telluride 2020"), + HyundaiCarInfo("Hyundai Palisade 2020-21", "All", video_link="https://youtu.be/TAnDqjF4fDY?t=456", harness=Harness.hyundai_h), + HyundaiCarInfo("Kia Telluride 2020", harness=Harness.hyundai_h), ], - CAR.VELOSTER: HyundaiCarInfo("Hyundai Veloster 2019-20", min_enable_speed=5. * CV.MPH_TO_MS), - CAR.SONATA_HYBRID: HyundaiCarInfo("Hyundai Sonata Hybrid 2020-22", "All"), + CAR.VELOSTER: HyundaiCarInfo("Hyundai Veloster 2019-20", min_enable_speed=5. * CV.MPH_TO_MS, harness=Harness.hyundai_e), + CAR.SONATA_HYBRID: HyundaiCarInfo("Hyundai Sonata Hybrid 2020-22", "All", harness=Harness.hyundai_a), # Kia - CAR.KIA_FORTE: HyundaiCarInfo("Kia Forte 2018-21"), - CAR.KIA_K5_2021: HyundaiCarInfo("Kia K5 2021-22", "SCC + LFA"), - CAR.KIA_NIRO_EV: HyundaiCarInfo("Kia Niro Electric 2019-22", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo"), - CAR.KIA_NIRO_HEV: HyundaiCarInfo("Kia Niro Plug-in Hybrid 2019", min_enable_speed=10. * CV.MPH_TO_MS), - CAR.KIA_NIRO_HEV_2021: HyundaiCarInfo("Kia Niro Hybrid 2021-22"), + CAR.KIA_FORTE: [ + HyundaiCarInfo("Kia Forte 2018", harness=Harness.hyundai_b), + HyundaiCarInfo("Kia Forte 2019-21", harness=Harness.hyundai_g), + ], + CAR.KIA_K5_2021: HyundaiCarInfo("Kia K5 2021-22", "SCC", harness=Harness.hyundai_a), + CAR.KIA_NIRO_EV: [ + HyundaiCarInfo("Kia Niro Electric 2019-20", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_f), + HyundaiCarInfo("Kia Niro Electric 2021", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_c), + HyundaiCarInfo("Kia Niro Electric 2022", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_h), + ], + CAR.KIA_NIRO_HEV: HyundaiCarInfo("Kia Niro Plug-in Hybrid 2019", min_enable_speed=10. * CV.MPH_TO_MS, harness=Harness.hyundai_c), + CAR.KIA_NIRO_HEV_2021: [ + HyundaiCarInfo("Kia Niro Hybrid 2021", harness=Harness.hyundai_f), # TODO: could be hyundai_d, verify + HyundaiCarInfo("Kia Niro Hybrid 2022", harness=Harness.hyundai_h), + ], CAR.KIA_OPTIMA: [ - HyundaiCarInfo("Kia Optima 2017", min_steer_speed=32. * CV.MPH_TO_MS), - HyundaiCarInfo("Kia Optima 2019"), + HyundaiCarInfo("Kia Optima 2017", min_steer_speed=32. * CV.MPH_TO_MS, harness=Harness.hyundai_b), + HyundaiCarInfo("Kia Optima 2019", harness=Harness.hyundai_g), ], - CAR.KIA_SELTOS: HyundaiCarInfo("Kia Seltos 2021"), - CAR.KIA_SORENTO: HyundaiCarInfo("Kia Sorento 2018-19", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8"), - CAR.KIA_STINGER: HyundaiCarInfo("Kia Stinger 2018", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0"), - CAR.KIA_CEED: HyundaiCarInfo("Kia Ceed 2019"), + CAR.KIA_OPTIMA_H: HyundaiCarInfo("Kia Optima 2017, 2019"), # TODO: info may be incorrect + CAR.KIA_SELTOS: HyundaiCarInfo("Kia Seltos 2021", harness=Harness.hyundai_a), + CAR.KIA_SORENTO: [ + HyundaiCarInfo("Kia Sorento 2018", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", harness=Harness.hyundai_c), + HyundaiCarInfo("Kia Sorento 2019", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", harness=Harness.hyundai_e), + ], + CAR.KIA_STINGER: HyundaiCarInfo("Kia Stinger 2018", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0", harness=Harness.hyundai_c), + CAR.KIA_CEED: HyundaiCarInfo("Kia Ceed 2019", harness=Harness.hyundai_e), + CAR.KIA_EV6: HyundaiCarInfo("Kia EV6 2022", "All", harness=Harness.none), # Genesis - CAR.GENESIS_G70: HyundaiCarInfo("Genesis G70 2018", "All"), - CAR.GENESIS_G70_2020: HyundaiCarInfo("Genesis G70 2020", "All"), - CAR.GENESIS_G80: HyundaiCarInfo("Genesis G80 2018", "All"), - CAR.GENESIS_G90: HyundaiCarInfo("Genesis G90 2018", "All"), + CAR.GENESIS_G70: HyundaiCarInfo("Genesis G70 2018", "All", harness=Harness.hyundai_f), + CAR.GENESIS_G70_2020: HyundaiCarInfo("Genesis G70 2020", "All", harness=Harness.hyundai_f), + CAR.GENESIS_G80: HyundaiCarInfo("Genesis G80 2018", "All", harness=Harness.hyundai_h), + CAR.GENESIS_G90: HyundaiCarInfo("Genesis G90 2018", "All", harness=Harness.hyundai_c), } class Buttons: @@ -358,7 +382,7 @@ FW_VERSIONS = { b'\xf1\x00DN ESC \x06 104\x19\x08\x01 58910-L0100', b'\xf1\x00DN ESC \x07 104\x19\x08\x01 58910-L0100', b'\xf1\x00DN ESC \x08 103\x19\x06\x01 58910-L1300', - b'\xf1\x8758910-L0100\xf1\x00DN ESC \a 106 \a\x01 58910-L0100', + b'\xf1\x8758910-L0100\xf1\x00DN ESC \x07 106 \x07\x01 58910-L0100', b'\xf1\x8758910-L0100\xf1\x00DN ESC \x06 104\x19\x08\x01 58910-L0100', b'\xf1\x8758910-L0100\xf1\x00DN ESC \x06 106 \x07\x01 58910-L0100', b'\xf1\x8758910-L0100\xf1\x00DN ESC \x07 104\x19\x08\x01 58910-L0100', @@ -379,6 +403,7 @@ FW_VERSIONS = { b'HM6M1_0a0_F00', b'HM6M1_0a0_G20', b'HM6M2_0a0_BD0', + b'\xf1\x8739110-2S278\xf1\x82DNDVD5GMCCXXXL5B', ], (Ecu.eps, 0x7d4, None): [ b'\xf1\x00DN8 MDPS C 1,00 1,01 56310L0010\x00 4DNAC101', # modified firmware @@ -460,6 +485,7 @@ FW_VERSIONS = { b'\xf1\x87SAMFBA7978674GJ2gw\x87xgw\x97ywwwwvUGeUUeU\x87O\xfb\xff\x98w\x8f\xfffF\xf1\x81U913\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U913\x00\x00\x00\x00\x00\x00SDN8T16NB2\n\xdd^\xbc', b'\xf1\x87SAMFBA9283024GJ2wwwwEUuWwwgwwwwwwwww\x87/\xfb\xff\x98w\x8f\xff<\xd3\xf1\x81U913\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U913\x00\x00\x00\x00\x00\x00SDN8T16NB2\n\xdd^\xbc', b'\xf1\x87SAMFBA9708354GJ2wwwwVf\x86h\x88wx\x87xww\x87\x88\x88\x88\x88w/\xfa\xff\x97w\x8f\xff\x86\xa0\xf1\x81U913\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U913\x00\x00\x00\x00\x00\x00SDN8T16NB2\n\xdd^\xbc', + b'\xf1\x87SANDB45316691GC6\x99\x99\x99\x99\x88\x88\xa8\x8avfwfwwww\x87wxwT\x9f\xfd\xff\x88wo\xff\x1c\xfa\xf1\x89HT6WAD10A1\xf1\x82SDN8G25NB3\x00\x00\x00\x00\x00\x00', ], }, CAR.SONATA_LF: { @@ -477,6 +503,7 @@ FW_VERSIONS = { ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00LFF LKAS AT USA LHD 1.00 1.01 95740-C1000 E51', + b'\xf1\x00LFF LKAS AT USA LHD 1.01 1.02 95740-C1000 E52', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x006T6H0_C2\x00\x006T6B4051\x00\x00TLF0G24NL1\xb0\x9f\xee\xf5', @@ -485,20 +512,25 @@ FW_VERSIONS = { b'\xf1\x87\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf1\x816T6B4051\x00\x00\xf1\x006T6H0_C2\x00\x006T6B4051\x00\x00TLF0G24SL2n\x8d\xbe\xd8', b'\xf1\x87LAHSGN012918KF10\x98\x88x\x87\x88\x88x\x87\x88\x88\x98\x88\x87w\x88w\x88\x88\x98\x886o\xf6\xff\x98w\x7f\xff3\x00\xf1\x816W3B1051\x00\x00\xf1\x006W351_C2\x00\x006W3B1051\x00\x00TLF0T20NL2\x00\x00\x00\x00', b'\xf1\x87LAHSGN012918KF10\x98\x88x\x87\x88\x88x\x87\x88\x88\x98\x88\x87w\x88w\x88\x88\x98\x886o\xf6\xff\x98w\x7f\xff3\x00\xf1\x816W3B1051\x00\x00\xf1\x006W351_C2\x00\x006W3B1051\x00\x00TLF0T20NL2H\r\xbdm', + b'\xf1\x87LAJSG49645724HF0\x87x\x87\x88\x87www\x88\x99\xa8\x89\x88\x99\xa8\x89\x88\x99\xa8\x89S_\xfb\xff\x87f\x7f\xff^2\xf1\x816W3B1051\x00\x00\xf1\x006W351_C2\x00\x006W3B1051\x00\x00TLF0T20NL2H\r\xbdm', ], }, - CAR.TUCSON_DIESEL_2019: { + CAR.TUCSON: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00TL__ FCA F-CUP 1.00 1.01 99110-D3500 ', + b'\xf1\x00TL__ FCA F-CUP 1.00 1.02 99110-D3510 ', ], (Ecu.engine, 0x7e0, None): [ b'\xf1\x8971TLC2NAIDDIR002\xf1\x8271TLC2NAIDDIR002', + b'\xf1\x81606G3051\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00TL MFC AT KOR LHD 1.00 1.02 95895-D3800 180719', + b'\xf1\x00TL MFC AT USA LHD 1.00 1.06 95895-D3800 190107', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x87LBJXAN202299KF22\x87x\x87\x88ww\x87xx\x88\x97\x88\x87\x88\x98x\x88\x99\x98\x89\x87o\xf6\xff\x87w\x7f\xff\x12\x9a\xf1\x81U083\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U083\x00\x00\x00\x00\x00\x00TTL2V20KL1\x8fRn\x8a', + b'\xf1\x87KMLDCU585233TJ20wx\x87\x88x\x88\x98\x89vfwfwwww\x87f\x9f\xff\x98\xff\x7f\xf9\xf7s\xf1\x816T6G4051\x00\x00\xf1\x006T6J0_C2\x00\x006T6G4051\x00\x00TTL4G24NH2\x00\x00\x00\x00', ], }, CAR.SANTA_FE: { @@ -792,21 +824,26 @@ FW_VERSIONS = { (Ecu.eps, 0x7d4, None): [ b'\xf1\x00IK MDPS R 1.00 1.07 57700-G9220 4I2VL107', b'\xf1\x00IK MDPS R 1.00 1.07 57700-G9420 4I4VL107', + b'\xf1\x00IK MDPS R 1.00 1.08 57700-G9420 4I4VL108', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x87VCJLP18407832DN3\x88vXfvUVT\x97eFU\x87d7v\x88eVeveFU\x89\x98\x7f\xff\xb2\xb0\xf1\x81E25\x00\x00\x00', b'\x00\x00\x00\x00\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T33NB4\xecE\xefL', b'\xf1\x87VDKLT18912362DN4wfVfwefeveVUwfvw\x88vWfvUFU\x89\xa9\x8f\xff\x87w\xf1\x81E25\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T33NB4\xecE\xefL', + b'\xf1\x87VDJLC18480772DK9\x88eHfwfff\x87eFUeDEU\x98eFe\x86T5DVyo\xff\x87s\xf1\x81E25\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T33KB5\x9f\xa5&\x81', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00IK__ SCC F-CUP 1.00 1.02 96400-G9100 ', b'\xf1\x00IK__ SCC F-CUP 1.00 1.02 96400-G9100 \xf1\xa01.02', + b'\xf1\x00IK__ SCC FHCUP 1.00 1.02 96400-G9000 ', ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00IK MFC AT USA LHD 1.00 1.01 95740-G9000 170920', + b'\xf1\x00IK MFC AT KOR LHD 1.00 1.01 95740-G9000 170920', ], (Ecu.engine, 0x7e0, None): [ b'\xf1\x81640J0051\x00\x00\x00\x00\x00\x00\x00\x00', + b'\xf1\x81640H0051\x00\x00\x00\x00\x00\x00\x00\x00', ], }, CAR.KONA: { @@ -819,7 +856,7 @@ FW_VERSIONS = { }, CAR.KIA_CEED: { (Ecu.fwdRadar, 0x7D0, None): [b'\xf1\000CD__ SCC F-CUP 1.00 1.02 99110-J7000 ', ], - (Ecu.esp, 0x7D4, None): [b'\xf1\000CD MDPS C 1.00 1.06 56310-XX000 4CDEC106', ], + (Ecu.eps, 0x7D4, None): [b'\xf1\000CD MDPS C 1.00 1.06 56310-XX000 4CDEC106', ], (Ecu.fwdCamera, 0x7C4, None): [b'\xf1\000CD LKAS AT EUR LHD 1.00 1.01 99211-J7000 B40', ], (Ecu.engine, 0x7E0, None): [b'\001TCD-JECU4F202H0K', ], (Ecu.transmission, 0x7E1, None): [ @@ -922,6 +959,7 @@ FW_VERSIONS = { b'\xf1\x8799110Q4000\xf1\x00DEev SCC F-CUP 1.00 1.00 99110-Q4000 ', b'\xf1\x8799110Q4100\xf1\x00DEev SCC F-CUP 1.00 1.00 99110-Q4100 ', b'\xf1\x8799110Q4500\xf1\x00DEev SCC F-CUP 1.00 1.00 99110-Q4500 ', + b'\xf1\x8799110Q4600\xf1\x00DEev SCC F-CUP 1.00 1.00 99110-Q4600 ', b'\xf1\x8799110Q4600\xf1\x00DEev SCC FNCUP 1.00 1.00 99110-Q4600 ', b'\xf1\x8799110Q4600\xf1\x00DEev SCC FHCUP 1.00 1.00 99110-Q4600 ', ], @@ -1146,6 +1184,21 @@ FW_VERSIONS = { b'\xf1\x81640F0051\x00\x00\x00\x00\x00\x00\x00\x00' ], }, + CAR.KIA_EV6: { + (Ecu.esp, 0x7d1, None): [ + b'\xf1\x8758520CV100\xf1\x00CV IEB \x02 101!\x10\x18 58520-CV100', + ], + (Ecu.eps, 0x7d4, None): [ + b'\xf1\x00CV1 MDPS R 1.00 1.04 57700-CV000 1B30', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00CV1_ RDR ----- 1.00 1.01 99110-CV000 ', + b'\xf1\x8799110CV000\xf1\x00CV1_ RDR ----- 1.00 1.01 99110-CV000 ', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00CV1 MFC AT USA LHD 1.00 1.05 99210-CV000 211027', + ], + }, } CHECKSUM = { @@ -1156,13 +1209,15 @@ CHECKSUM = { FEATURES = { # which message has the gear "use_cluster_gears": {CAR.ELANTRA, CAR.ELANTRA_GT_I30, CAR.KONA}, - "use_tcu_gears": {CAR.KIA_OPTIMA, CAR.SONATA_LF, CAR.VELOSTER, CAR.TUCSON_DIESEL_2019}, + "use_tcu_gears": {CAR.KIA_OPTIMA, CAR.SONATA_LF, CAR.VELOSTER, CAR.TUCSON}, "use_elect_gears": {CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV, CAR.KIA_NIRO_HEV_2021, CAR.KIA_OPTIMA_H, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.IONIQ, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.IONIQ_PHEV_2019}, # these cars use the FCA11 message for the AEB and FCW signals, all others use SCC12 - "use_fca": {CAR.SONATA, CAR.SONATA_HYBRID, CAR.ELANTRA, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.ELANTRA_GT_I30, CAR.KIA_STINGER, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KONA_EV, CAR.KIA_FORTE, CAR.KIA_NIRO_EV, CAR.PALISADE, CAR.GENESIS_G70, CAR.GENESIS_G70_2020, CAR.KONA, CAR.SANTA_FE, CAR.KIA_SELTOS, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.TUCSON_DIESEL_2019}, + "use_fca": {CAR.SONATA, CAR.SONATA_HYBRID, CAR.ELANTRA, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.ELANTRA_GT_I30, CAR.KIA_STINGER, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KONA_EV, CAR.KIA_FORTE, CAR.KIA_NIRO_EV, CAR.PALISADE, CAR.GENESIS_G70, CAR.GENESIS_G70_2020, CAR.KONA, CAR.SANTA_FE, CAR.KIA_SELTOS, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.TUCSON}, } +HDA2_CAR = {CAR.KIA_EV6, } + HYBRID_CAR = {CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.KIA_NIRO_HEV, CAR.KIA_NIRO_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.IONIQ_PHEV_2019} # these cars use a different gas signal EV_CAR = {CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.KIA_NIRO_EV} @@ -1206,10 +1261,11 @@ DBC = { CAR.SANTA_FE_PHEV_2022: dbc_dict('hyundai_kia_generic', None), CAR.SONATA: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'), CAR.SONATA_LF: dbc_dict('hyundai_kia_generic', None), # Has 0x5XX messages, but different format - CAR.TUCSON_DIESEL_2019: dbc_dict('hyundai_kia_generic', None), + CAR.TUCSON: dbc_dict('hyundai_kia_generic', None), CAR.PALISADE: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'), CAR.VELOSTER: dbc_dict('hyundai_kia_generic', None), CAR.KIA_CEED: dbc_dict('hyundai_kia_generic', None), + CAR.KIA_EV6: dbc_dict('kia_ev6', None), CAR.SONATA_HYBRID: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'), } diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 23822fe454..9220aee522 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -1,13 +1,15 @@ +import json import os import time from abc import abstractmethod, ABC -from typing import Dict, Tuple, List +from typing import Any, Dict, Tuple, List from cereal import car +from common.basedir import BASEDIR +from common.conversions import Conversions as CV from common.kalman.simple_kalman import KF1D from common.realtime import DT_CTRL from selfdrive.car import gen_empty_fingerprint -from common.conversions import Conversions as CV from selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX from selfdrive.controls.lib.events import Events from selfdrive.controls.lib.vehicle_model import VehicleModel @@ -18,11 +20,11 @@ EventName = car.CarEvent.EventName MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS ACCEL_MAX = 2.0 ACCEL_MIN = -3.5 +TORQUE_PARAMS_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data.json') # generic car and radar interfaces - class CarInterfaceBase(ABC): def __init__(self, CP, CarController, CarState): self.CP = CP @@ -81,6 +83,7 @@ class CarInterfaceBase(ABC): ret.steerControlType = car.CarParams.SteerControlType.torque ret.minSteerSpeed = 0. ret.wheelSpeedFactor = 1.0 + ret.maxLateralAccel = CarInterfaceBase.get_torque_params(candidate)['MAX_LAT_ACCEL_MEASURED'] ret.pcmCruise = True # openpilot's state is tied to the PCM's cruise state on most cars ret.minEnableSpeed = -1. # enable is done by stock ACC, so ignore this @@ -104,6 +107,12 @@ class CarInterfaceBase(ABC): ret.steerLimitTimer = 1.0 return ret + @staticmethod + def get_torque_params(candidate, default=float('NaN')): + with open(TORQUE_PARAMS_PATH) as f: + data = json.load(f) + return {key: data[key].get(candidate, default) for key in data} + @abstractmethod def _update(self, c: car.CarControl) -> car.CarState: pass @@ -159,6 +168,8 @@ class CarInterfaceBase(ABC): events.add(EventName.brakeHold) if cs_out.parkingBrake: events.add(EventName.parkBrake) + if cs_out.accFaulted: + events.add(EventName.accFaulted) # Handle permanent and temporary steering faults self.steering_unpressed = 0 if cs_out.steeringPressed else self.steering_unpressed + 1 @@ -291,3 +302,31 @@ class CarStateBase(ABC): @staticmethod def get_loopback_can_parser(CP): return None + + +# interface-specific helpers + +def get_interface_attr(attr: str, combine_brands: bool = False, ignore_none: bool = False) -> Dict[str, Any]: + # read all the folders in selfdrive/car and return a dict where: + # - keys are all the car models or brand names + # - values are attr values from all car folders + result = {} + for car_folder in sorted([x[0] for x in os.walk(BASEDIR + '/selfdrive/car')]): + try: + brand_name = car_folder.split('/')[-1] + brand_values = __import__(f'selfdrive.car.{brand_name}.values', fromlist=[attr]) + if hasattr(brand_values, attr) or not ignore_none: + attr_data = getattr(brand_values, attr, None) + else: + continue + + if combine_brands: + if isinstance(attr_data, dict): + for f, v in attr_data.items(): + result[f] = v + else: + result[brand_name] = attr_data + except (ImportError, OSError): + pass + + return result diff --git a/selfdrive/car/isotp_parallel_query.py b/selfdrive/car/isotp_parallel_query.py index 1209a8f1a1..0e807512cf 100644 --- a/selfdrive/car/isotp_parallel_query.py +++ b/selfdrive/car/isotp_parallel_query.py @@ -4,13 +4,13 @@ from functools import partial from typing import Optional import cereal.messaging as messaging -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog from selfdrive.boardd.boardd import can_list_to_can_capnp from panda.python.uds import CanClient, IsoTpMessage, FUNCTIONAL_ADDRS, get_rx_addr_for_tx_addr class IsoTpParallelQuery: - def __init__(self, sendcan, logcan, bus, addrs, request, response, response_offset=0x8, functional_addr=False, debug=False): + def __init__(self, sendcan, logcan, bus, addrs, request, response, response_offset=0x8, functional_addr=False, debug=False, response_pending_timeout=10): self.sendcan = sendcan self.logcan = logcan self.bus = bus @@ -18,6 +18,7 @@ class IsoTpParallelQuery: self.response = response self.debug = debug self.functional_addr = functional_addr + self.response_pending_timeout = response_pending_timeout self.real_addrs = [] for a in addrs: @@ -71,10 +72,7 @@ class IsoTpParallelQuery: messaging.drain_sock(self.logcan) self.msg_buffer = defaultdict(list) - def get_data(self, timeout, total_timeout=None): - if total_timeout is None: - total_timeout = 10 * timeout - + def get_data(self, timeout, total_timeout=60.): self._drain_rx() # Create message objects @@ -100,7 +98,7 @@ class IsoTpParallelQuery: results = {} start_time = time.monotonic() - last_response_time = start_time + response_timeouts = {tx_addr: start_time + timeout for tx_addr in self.msg_addrs} while True: self.rx() @@ -123,7 +121,7 @@ class IsoTpParallelQuery: response_valid = dat[:len(expected_response)] == expected_response if response_valid: - last_response_time = time.monotonic() + response_timeouts[tx_addr] = time.monotonic() + timeout if counter + 1 < len(self.request): msg.send(self.request[counter + 1]) request_counter[tx_addr] += 1 @@ -131,13 +129,19 @@ class IsoTpParallelQuery: results[tx_addr] = dat[len(expected_response):] request_done[tx_addr] = True else: - request_done[tx_addr] = True - cloudlog.warning(f"iso-tp query bad response: 0x{dat.hex()}") + error_code = dat[2] if len(dat) > 2 else -1 + if error_code == 0x78: + response_timeouts[tx_addr] = time.monotonic() + self.response_pending_timeout + if self.debug: + cloudlog.warning(f"iso-tp query response pending: {tx_addr}") + else: + request_done[tx_addr] = True + cloudlog.warning(f"iso-tp query bad response: {tx_addr} - 0x{dat.hex()}") cur_time = time.monotonic() - if cur_time - last_response_time > timeout: + if cur_time - max(response_timeouts.values()) > 0: for tx_addr in msgs: - if (request_counter[tx_addr] > 0) and (not request_done[tx_addr]): + if request_counter[tx_addr] > 0 and not request_done[tx_addr]: cloudlog.warning(f"iso-tp query timeout after receiving response: {tx_addr}") break diff --git a/selfdrive/car/mazda/carcontroller.py b/selfdrive/car/mazda/carcontroller.py index 68eebeaf71..d003079d63 100644 --- a/selfdrive/car/mazda/carcontroller.py +++ b/selfdrive/car/mazda/carcontroller.py @@ -27,6 +27,7 @@ class CarController(): CS.out.steeringTorque, CarControllerParams) self.steer_rate_limited = new_steer != apply_steer + if c.enabled: if CS.out.standstill and frame % 5 == 0: # Mazda Stop and Go requires a RES button (or gas) press if the car stops more than 3 seconds # Send Resume button at 20hz if we're engaged at standstill to support full stop and go! diff --git a/selfdrive/car/mazda/interface.py b/selfdrive/car/mazda/interface.py index 0ef573c6b6..cbeb910de2 100755 --- a/selfdrive/car/mazda/interface.py +++ b/selfdrive/car/mazda/interface.py @@ -25,7 +25,6 @@ class CarInterface(CarInterfaceBase): ret.dashcamOnly = candidate not in (CAR.CX5_2022, CAR.CX9_2021) ret.steerActuatorDelay = 0.1 - ret.steerRateCost = 1.0 ret.steerLimitTimer = 0.8 tire_stiffness_factor = 0.70 # not optimized yet diff --git a/selfdrive/car/mazda/values.py b/selfdrive/car/mazda/values.py index 6b6aa05c29..5c80303dbc 100644 --- a/selfdrive/car/mazda/values.py +++ b/selfdrive/car/mazda/values.py @@ -1,7 +1,9 @@ +from dataclasses import dataclass +from enum import Enum from typing import Dict, List, Union from selfdrive.car import dbc_dict -from selfdrive.car.docs_definitions import CarInfo +from selfdrive.car.docs_definitions import CarInfo, Harness from cereal import car Ecu = car.CarParams.Ecu @@ -27,13 +29,19 @@ class CAR: CX5_2022 = "MAZDA CX-5 2022" -CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { - CAR.CX5: CarInfo("Mazda CX-5 2017, 2019", "All"), # TODO: verify years and torque for first 4 - CAR.CX9: CarInfo("Mazda CX-9 2016-17", "All"), - CAR.MAZDA3: CarInfo("Mazda 3 2017", "All"), - CAR.MAZDA6: CarInfo("Mazda 6 2017", "All"), - CAR.CX9_2021: CarInfo("Mazda CX-9 2021", "All", good_torque=True), - CAR.CX5_2022: CarInfo("Mazda CX-5 2022", "All", good_torque=True), +@dataclass +class MazdaCarInfo(CarInfo): + package: str = "All" + harness: Enum = Harness.mazda + + +CAR_INFO: Dict[str, Union[MazdaCarInfo, List[MazdaCarInfo]]] = { + CAR.CX5: MazdaCarInfo("Mazda CX-5 2017, 2019"), # TODO: verify years and torque for first 4 + CAR.CX9: MazdaCarInfo("Mazda CX-9 2016-17"), + CAR.MAZDA3: MazdaCarInfo("Mazda 3 2017"), + CAR.MAZDA6: MazdaCarInfo("Mazda 6 2017"), + CAR.CX9_2021: MazdaCarInfo("Mazda CX-9 2021", good_torque=True), + CAR.CX5_2022: MazdaCarInfo("Mazda CX-5 2022", good_torque=True), } diff --git a/selfdrive/car/mock/interface.py b/selfdrive/car/mock/interface.py index 65e886751d..715850c227 100755 --- a/selfdrive/car/mock/interface.py +++ b/selfdrive/car/mock/interface.py @@ -2,7 +2,7 @@ import math from cereal import car from common.conversions import Conversions as CV -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog import cereal.messaging as messaging from selfdrive.car import gen_empty_fingerprint, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase diff --git a/selfdrive/car/mock/values.py b/selfdrive/car/mock/values.py index 77d8171b0b..dfc7902e41 100644 --- a/selfdrive/car/mock/values.py +++ b/selfdrive/car/mock/values.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Union +from typing import Dict, List, Optional, Union from selfdrive.car.docs_definitions import CarInfo @@ -7,4 +7,6 @@ class CAR: MOCK = 'mock' -CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = {} +CAR_INFO: Dict[str, Optional[Union[CarInfo, List[CarInfo]]]] = { + CAR.MOCK: None, +} diff --git a/selfdrive/car/nissan/interface.py b/selfdrive/car/nissan/interface.py index 3bf34e8266..436cef68bf 100644 --- a/selfdrive/car/nissan/interface.py +++ b/selfdrive/car/nissan/interface.py @@ -14,7 +14,6 @@ class CarInterface(CarInterfaceBase): ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.nissan)] ret.steerLimitTimer = 1.0 - ret.steerRateCost = 0.5 ret.steerActuatorDelay = 0.1 diff --git a/selfdrive/car/nissan/values.py b/selfdrive/car/nissan/values.py index a201c9113c..5ffef691d1 100644 --- a/selfdrive/car/nissan/values.py +++ b/selfdrive/car/nissan/values.py @@ -1,7 +1,9 @@ -from typing import Dict, List, Union +from dataclasses import dataclass +from typing import Dict, List, Optional, Union +from enum import Enum from selfdrive.car import dbc_dict -from selfdrive.car.docs_definitions import CarInfo +from selfdrive.car.docs_definitions import CarInfo, Harness from cereal import car Ecu = car.CarParams.Ecu @@ -24,11 +26,18 @@ class CAR: ALTIMA = "NISSAN ALTIMA 2020" -CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { - CAR.XTRAIL: CarInfo("Nissan X-Trail 2017", "ProPILOT"), - CAR.LEAF: CarInfo("Nissan Leaf 2018-22", "ProPILOT"), - CAR.ROGUE: CarInfo("Nissan Rogue 2018-20", "ProPILOT"), - CAR.ALTIMA: CarInfo("Nissan Altima 2019-20", "ProPILOT"), +@dataclass +class NissanCarInfo(CarInfo): + package: str = "ProPILOT" + harness: Enum = Harness.nissan_a + + +CAR_INFO: Dict[str, Optional[Union[NissanCarInfo, List[NissanCarInfo]]]] = { + CAR.XTRAIL: NissanCarInfo("Nissan X-Trail 2017"), + CAR.LEAF: NissanCarInfo("Nissan Leaf 2018-22"), + CAR.LEAF_IC: None, # same platforms + CAR.ROGUE: NissanCarInfo("Nissan Rogue 2018-20"), + CAR.ALTIMA: NissanCarInfo("Nissan Altima 2019-20", harness=Harness.nissan_b), } FINGERPRINTS = { diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index d0d8e91ce1..8c5cab86e8 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -22,7 +22,6 @@ class CarInterface(CarInterfaceBase): ret.dashcamOnly = candidate in PREGLOBAL_CARS - ret.steerRateCost = 0.7 ret.steerLimitTimer = 0.4 if candidate == CAR.ASCENT: diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 4b6f3604b3..45358eb3a4 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -1,11 +1,14 @@ from dataclasses import dataclass +from enum import Enum from typing import Dict, List, Union from selfdrive.car import dbc_dict -from selfdrive.car.docs_definitions import CarInfo +from selfdrive.car.docs_definitions import CarInfo, Harness from cereal import car + Ecu = car.CarParams.Ecu + class CarControllerParams: def __init__(self, CP): if CP.carFingerprint == CAR.IMPREZA_2020: @@ -34,19 +37,20 @@ class CAR: @dataclass class SubaruCarInfo(CarInfo): package: str = "EyeSight" + harness: Enum = Harness.subaru CAR_INFO: Dict[str, Union[SubaruCarInfo, List[SubaruCarInfo]]] = { - CAR.ASCENT: SubaruCarInfo("Subaru Ascent 2019-20"), + CAR.ASCENT: SubaruCarInfo("Subaru Ascent 2019-20", "All"), CAR.IMPREZA: [ - SubaruCarInfo("Subaru Impreza 2017-19", good_torque=True), - SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26", good_torque=True), + SubaruCarInfo("Subaru Impreza 2017-19"), + SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), ], CAR.IMPREZA_2020: [ SubaruCarInfo("Subaru Impreza 2020-21"), SubaruCarInfo("Subaru Crosstrek 2020-21"), ], - CAR.FORESTER: SubaruCarInfo("Subaru Forester 2019-21", good_torque=True), + CAR.FORESTER: SubaruCarInfo("Subaru Forester 2019-21", "All"), CAR.FORESTER_PREGLOBAL: SubaruCarInfo("Subaru Forester 2017-18"), CAR.LEGACY_PREGLOBAL: SubaruCarInfo("Subaru Legacy 2015-18"), CAR.OUTBACK_PREGLOBAL: SubaruCarInfo("Subaru Outback 2015-17"), @@ -121,6 +125,7 @@ FW_VERSIONS = { b'\x00\x00d)\x00\x00\x00\x00', b'\x00\x00c\xf4\x00\x00\x00\x00', b'\x00\x00d\xdc\x00\x00\x00\x00', + b'\x00\x00dd\x00\x00\x00\x00', ], (Ecu.engine, 0x7e0, None): [ b'\xaa\x61\x66\x73\x07', diff --git a/selfdrive/car/tesla/carcontroller.py b/selfdrive/car/tesla/carcontroller.py index 2c1f55e7de..cf43b8ef00 100644 --- a/selfdrive/car/tesla/carcontroller.py +++ b/selfdrive/car/tesla/carcontroller.py @@ -9,7 +9,6 @@ class CarController: self.CP = CP self.frame = 0 self.last_angle = 0 - self.long_control_counter = 0 self.packer = CANPacker(dbc_name) self.pt_packer = CANPacker(DBC[CP.carFingerprint]['pt']) self.tesla_can = TeslaCAN(self.packer, self.pt_packer) @@ -41,15 +40,15 @@ class CarController: self.last_angle = apply_angle can_sends.append(self.tesla_can.create_steering_control(apply_angle, lkas_enabled, self.frame)) - # Longitudinal control (40Hz) - if self.CP.openpilotLongitudinalControl and self.frame % 5 in (0, 2): + # Longitudinal control (in sync with stock message, about 40Hz) + if self.CP.openpilotLongitudinalControl: target_accel = actuators.accel target_speed = max(CS.out.vEgo + (target_accel * CarControllerParams.ACCEL_TO_SPEED_MULTIPLIER), 0) max_accel = 0 if target_accel < 0 else target_accel min_accel = 0 if target_accel > 0 else target_accel - can_sends.extend(self.tesla_can.create_longitudinal_commands(CS.acc_state, target_speed, min_accel, max_accel, self.long_control_counter)) - self.long_control_counter += 1 + while len(CS.das_control_counters) > 0: + can_sends.extend(self.tesla_can.create_longitudinal_commands(CS.acc_state, target_speed, min_accel, max_accel, CS.das_control_counters.popleft())) # Cancel on user steering override, since there is no steering torque blending if hands_on_fault: diff --git a/selfdrive/car/tesla/carstate.py b/selfdrive/car/tesla/carstate.py index 435beedc9c..0f373842f2 100644 --- a/selfdrive/car/tesla/carstate.py +++ b/selfdrive/car/tesla/carstate.py @@ -1,4 +1,5 @@ import copy +from collections import deque from cereal import car from common.conversions import Conversions as CV from selfdrive.car.tesla.values import DBC, CANBUS, GEAR_MAP, DOORS, BUTTONS @@ -17,6 +18,7 @@ class CarState(CarStateBase): self.hands_on_level = 0 self.steer_warning = None self.acc_state = 0 + self.das_control_counters = deque(maxlen=32) def update(self, cp, cp_cam): ret = car.CarState.new_message() @@ -87,9 +89,13 @@ class CarState(CarStateBase): # TODO: blindspot + # AEB + ret.stockAeb = (cp_cam.vl["DAS_control"]["DAS_aebEvent"] == 1) + # Messages needed by carcontroller self.msg_stw_actn_req = copy.copy(cp.vl["STW_ACTN_RQ"]) self.acc_state = cp_cam.vl["DAS_control"]["DAS_accState"] + self.das_control_counters.extend(cp_cam.vl_all["DAS_control"]["DAS_controlCounter"]) return ret @@ -177,6 +183,8 @@ class CarState(CarStateBase): signals = [ # sig_name, sig_address ("DAS_accState", "DAS_control"), + ("DAS_aebEvent", "DAS_control"), + ("DAS_controlCounter", "DAS_control"), ] checks = [ # sig_address, frequency diff --git a/selfdrive/car/tesla/interface.py b/selfdrive/car/tesla/interface.py index 71594cecb6..d4eda38e64 100755 --- a/selfdrive/car/tesla/interface.py +++ b/selfdrive/car/tesla/interface.py @@ -42,7 +42,6 @@ class CarInterface(CarInterfaceBase): ret.steerLimitTimer = 1.0 ret.steerActuatorDelay = 0.25 - ret.steerRateCost = 0.5 if candidate in (CAR.AP2_MODELS, CAR.AP1_MODELS): ret.mass = 2100. + STD_CARGO_KG diff --git a/selfdrive/car/tesla/teslacan.py b/selfdrive/car/tesla/teslacan.py index 17a3b11985..e5d904f80e 100644 --- a/selfdrive/car/tesla/teslacan.py +++ b/selfdrive/car/tesla/teslacan.py @@ -51,7 +51,7 @@ class TeslaCAN: "DAS_jerkMax": CarControllerParams.JERK_LIMIT_MAX, "DAS_accelMin": min_accel, "DAS_accelMax": max_accel, - "DAS_controlCounter": (cnt % 8), + "DAS_controlCounter": cnt, "DAS_controlChecksum": 0, } diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 88309e571d..a9d36f9eab 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -26,10 +26,10 @@ non_tested_cars = [ HYUNDAI.KIA_OPTIMA_H, ] -TestRoute = namedtuple('TestRoute', ['route', 'car_fingerprint', 'segment'], defaults=(None,)) +TestRoute = namedtuple('TestRoute', ['route', 'car_model', 'segment'], defaults=(None,)) routes = [ - TestRoute("d6ac8ebdb47bc549|2022-03-31--13-10-06", COMMA.BODY), + TestRoute("efdf9af95e71cd84|2022-05-13--19-03-31", COMMA.BODY), TestRoute("0c94aa1e1296d7c6|2021-05-05--19-48-37", CHRYSLER.JEEP_CHEROKEE), TestRoute("91dfedae61d7bd75|2021-05-22--20-07-52", CHRYSLER.JEEP_CHEROKEE_2019), @@ -84,7 +84,7 @@ routes = [ TestRoute("c75a59efa0ecd502|2021-03-11--20-52-55", HYUNDAI.KIA_SELTOS), TestRoute("5b7c365c50084530|2020-04-15--16-13-24", HYUNDAI.SONATA), TestRoute("b2a38c712dcf90bd|2020-05-18--18-12-48", HYUNDAI.SONATA_LF), - TestRoute("fb3fd42f0baaa2f8|2022-03-30--15-25-05", HYUNDAI.TUCSON_DIESEL_2019), + TestRoute("fb3fd42f0baaa2f8|2022-03-30--15-25-05", HYUNDAI.TUCSON), TestRoute("5875672fc1d4bf57|2020-07-23--21-33-28", HYUNDAI.KIA_SORENTO), TestRoute("9c917ba0d42ffe78|2020-04-17--12-43-19", HYUNDAI.PALISADE), TestRoute("3f29334d6134fcd4|2022-03-30--22-00-50", HYUNDAI.IONIQ_PHEV_2019), @@ -98,6 +98,7 @@ routes = [ TestRoute("49f3c13141b6bc87|2021-07-28--08-05-13", HYUNDAI.KONA_HEV), TestRoute("5dddcbca6eb66c62|2020-07-26--13-24-19", HYUNDAI.KIA_STINGER), TestRoute("d624b3d19adce635|2020-08-01--14-59-12", HYUNDAI.VELOSTER), + TestRoute("d824e27e8c60172c|2022-05-19--16-15-28", HYUNDAI.KIA_EV6), TestRoute("007d5e4ad9f86d13|2021-09-30--15-09-23", HYUNDAI.KIA_K5_2021), TestRoute("50c6c9b85fd1ff03|2020-10-26--17-56-06", HYUNDAI.KIA_NIRO_EV), TestRoute("173219cf50acdd7b|2021-07-05--10-27-41", HYUNDAI.KIA_NIRO_HEV), @@ -127,6 +128,7 @@ routes = [ TestRoute("b14c5b4742e6fc85|2020-07-28--19-50-11", TOYOTA.RAV4), TestRoute("32a7df20486b0f70|2020-02-06--16-06-50", TOYOTA.RAV4H), TestRoute("cdf2f7de565d40ae|2019-04-25--03-53-41", TOYOTA.RAV4_TSS2), + TestRoute("a5c341bb250ca2f0|2022-05-18--16-05-17", TOYOTA.RAV4_TSS2_2022), TestRoute("7e34a988419b5307|2019-12-18--19-13-30", TOYOTA.RAV4H_TSS2), TestRoute("2475fb3eb2ffcc2e|2022-04-29--12-46-23", TOYOTA.RAV4H_TSS2_2022), TestRoute("e6a24be49a6cd46e|2019-10-29--10-52-42", TOYOTA.LEXUS_ES_TSS2), @@ -142,6 +144,7 @@ routes = [ TestRoute("ec429c0f37564e3c|2020-02-01--17-28-12", TOYOTA.LEXUS_NXH), TestRoute("964c09eb11ca8089|2020-11-03--22-04-00", TOYOTA.LEXUS_NX), TestRoute("3fd5305f8b6ca765|2021-04-28--19-26-49", TOYOTA.LEXUS_NX_TSS2), + TestRoute("09ae96064ed85a14|2022-06-09--12-22-31", TOYOTA.LEXUS_NXH_TSS2), TestRoute("0a302ffddbb3e3d3|2020-02-08--16-19-08", TOYOTA.HIGHLANDER_TSS2), TestRoute("437e4d2402abf524|2021-05-25--07-58-50", TOYOTA.HIGHLANDERH_TSS2), TestRoute("3183cd9b021e89ce|2021-05-25--10-34-44", TOYOTA.HIGHLANDER), diff --git a/selfdrive/car/tests/test_car_interfaces.py b/selfdrive/car/tests/test_car_interfaces.py index 92024ab0c2..15df1aafef 100755 --- a/selfdrive/car/tests/test_car_interfaces.py +++ b/selfdrive/car/tests/test_car_interfaces.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import math import unittest import importlib from parameterized import parameterized @@ -32,14 +33,15 @@ class TestCarInterfaces(unittest.TestCase): assert car_interface self.assertGreater(car_params.mass, 1) - self.assertGreater(car_params.steerRateCost, 1e-3) if car_params.steerControlType != car.CarParams.SteerControlType.angle: tuning = car_params.lateralTuning.which() if tuning == 'pid': self.assertTrue(len(car_params.lateralTuning.pid.kpV)) elif tuning == 'torque': - self.assertTrue(car_params.lateralTuning.torque.kf > 0) + kf = car_params.lateralTuning.torque.kf + self.assertTrue(not math.isnan(kf) and kf > 0) + self.assertTrue(not math.isnan(car_params.lateralTuning.torque.friction)) elif tuning == 'indi': self.assertTrue(len(car_params.lateralTuning.indi.outerLoopGainV)) diff --git a/selfdrive/car/tests/test_docs.py b/selfdrive/car/tests/test_docs.py index 6c7ae1fdac..b4bc14ef00 100755 --- a/selfdrive/car/tests/test_docs.py +++ b/selfdrive/car/tests/test_docs.py @@ -1,32 +1,47 @@ #!/usr/bin/env python3 import unittest -from selfdrive.car.docs import CARS_MD_OUT, CARS_MD_TEMPLATE, generate_cars_md, get_tier_car_info +from selfdrive.car.car_helpers import interfaces, get_interface_attr +from selfdrive.car.docs import CARS_MD_OUT, CARS_MD_TEMPLATE, generate_cars_md, get_all_car_info +from selfdrive.car.docs_definitions import Column, Star class TestCarDocs(unittest.TestCase): def setUp(self): - self.tier_cars = get_tier_car_info() + self.all_cars = get_all_car_info() def test_generator(self): - generated_cars_md = generate_cars_md(self.tier_cars, CARS_MD_TEMPLATE) + generated_cars_md = generate_cars_md(self.all_cars, CARS_MD_TEMPLATE) with open(CARS_MD_OUT, "r") as f: current_cars_md = f.read() self.assertEqual(generated_cars_md, current_cars_md, "Run selfdrive/car/docs.py to generate new supported cars documentation") + def test_missing_car_info(self): + all_car_info_platforms = get_interface_attr("CAR_INFO", combine_brands=True).keys() + for platform in sorted(interfaces.keys()): + if platform not in all_car_info_platforms: + self.fail("Platform: {} doesn't exist in CarInfo".format(platform)) + def test_naming_conventions(self): # Asserts market-standard car naming conventions by make - for cars in self.tier_cars.values(): - for car in cars: - if car.car_name == "hyundai": - tokens = car.model.lower().split(" ") - self.assertNotIn("phev", tokens, "Use `Plug-in Hybrid`") - self.assertNotIn("hev", tokens, "Use `Hybrid`") - self.assertNotIn("ev", tokens, "Use `Electric`") - if "plug-in hybrid" in car.model.lower(): - self.assertIn("Plug-in Hybrid", car.model, "Use correct capitalization") + for car in self.all_cars: + tokens = car.model.lower().split(" ") + if car.car_name == "hyundai": + self.assertNotIn("phev", tokens, "Use `Plug-in Hybrid`") + self.assertNotIn("hev", tokens, "Use `Hybrid`") + self.assertNotIn("ev", tokens, "Use `Electric`") + if "plug-in hybrid" in car.model.lower(): + self.assertIn("Plug-in Hybrid", car.model, "Use correct capitalization") + elif car.car_name == "toyota": + if "rav4" in tokens: + self.assertIn("RAV4", car.model, "Use correct capitalization") + + def test_torque_star(self): + for car in self.all_cars: + if car.car_name == "honda": + self.assertTrue(car.row[Column.STEERING_TORQUE] in (Star.EMPTY, Star.HALF), f"{car.name} has full torque star") if __name__ == "__main__": diff --git a/selfdrive/car/tests/test_fw_fingerprint.py b/selfdrive/car/tests/test_fw_fingerprint.py index ae209b2910..ed7e420e1a 100755 --- a/selfdrive/car/tests/test_fw_fingerprint.py +++ b/selfdrive/car/tests/test_fw_fingerprint.py @@ -4,9 +4,9 @@ import unittest from parameterized import parameterized from cereal import car -from selfdrive.car.car_helpers import interfaces +from selfdrive.car.car_helpers import get_interface_attr, interfaces from selfdrive.car.fingerprints import FW_VERSIONS -from selfdrive.car.fw_versions import match_fw_to_car +from selfdrive.car.fw_versions import REQUESTS, match_fw_to_car CarFw = car.CarParams.CarFw Ecu = car.CarParams.Ecu @@ -57,6 +57,23 @@ class TestFwFingerprint(unittest.TestCase): self.assertTrue(passed, "Blacklisted FW versions found") + def test_fw_request_ecu_whitelist(self): + passed = True + brands = set(r.brand for r in REQUESTS) + versions = get_interface_attr('FW_VERSIONS') + for brand in brands: + whitelisted_ecus = [ecu for r in REQUESTS for ecu in r.whitelist_ecus if r.brand == brand] + brand_ecus = set([fw[0] for car_fw in versions[brand].values() for fw in car_fw]) + + # each ecu in brand's fw versions needs to be whitelisted at least once + ecus_not_whitelisted = set(brand_ecus) - set(whitelisted_ecus) + if len(whitelisted_ecus) and len(ecus_not_whitelisted): + ecu_strings = ", ".join([f'Ecu.{ECU_NAME[ecu]}' for ecu in ecus_not_whitelisted]) + print(f'{brand.title()}: FW query whitelist missing ecus: {ecu_strings}') + passed = False + + self.assertTrue(passed, "Not all ecus in FW versions found in query whitelists") + if __name__ == "__main__": unittest.main() diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 17044c432d..27dc4ba776 100755 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -18,6 +18,7 @@ from selfdrive.car.hyundai.values import CAR as HYUNDAI from selfdrive.car.tests.routes import non_tested_cars, routes, TestRoute from selfdrive.test.openpilotci import get_url from tools.lib.logreader import LogReader +from tools.lib.route import Route from panda.tests.safety import libpandasafety_py from panda.tests.safety.common import package_can_msg @@ -35,7 +36,7 @@ ignore_addr_checks_valid = [ # build list of test cases routes_by_car = defaultdict(set) for r in routes: - routes_by_car[r.car_fingerprint].add(r) + routes_by_car[r.car_model].add(r) test_cases: List[Tuple[str, Optional[TestRoute]]] = [] for i, c in enumerate(sorted(all_known_cars())): @@ -45,12 +46,17 @@ for i, c in enumerate(sorted(all_known_cars())): SKIP_ENV_VAR = "SKIP_LONG_TESTS" -@parameterized_class(('car_model', 'test_route'), test_cases) -class TestCarModel(unittest.TestCase): +class TestCarModelBase(unittest.TestCase): + car_model = None + test_route = None + ci = True @unittest.skipIf(SKIP_ENV_VAR in os.environ, f"Long running test skipped. Unset {SKIP_ENV_VAR} to run") @classmethod def setUpClass(cls): + if cls.__name__ == 'TestCarModel' or cls.__name__.endswith('Base'): + raise unittest.SkipTest + if cls.test_route is None: if cls.car_model in non_tested_cars: print(f"Skipping tests for {cls.car_model}: missing route") @@ -64,12 +70,15 @@ class TestCarModel(unittest.TestCase): for seg in test_segs: try: - lr = LogReader(get_url(cls.test_route.route, seg)) + if cls.ci: + lr = LogReader(get_url(cls.test_route.route, seg)) + else: + lr = LogReader(Route(cls.test_route.route).log_paths()[seg]) except Exception: continue can_msgs = [] - fingerprint = {i: dict() for i in range(3)} + fingerprint = defaultdict(dict) for msg in lr: if msg.which() == "can": for m in msg.can: @@ -79,6 +88,8 @@ class TestCarModel(unittest.TestCase): elif msg.which() == "carParams": if msg.carParams.openpilotLongitudinalControl: disable_radar = True + if cls.car_model is None and not cls.ci: + cls.car_model = msg.carParams.carFingerprint if len(can_msgs) > int(50 / DT_CTRL): break @@ -98,8 +109,10 @@ class TestCarModel(unittest.TestCase): # TODO: check safetyModel is in release panda build self.safety = libpandasafety_py.libpandasafety - set_status = self.safety.set_safety_hooks(self.CP.safetyConfigs[0].safetyModel.raw, self.CP.safetyConfigs[0].safetyParam) - self.assertEqual(0, set_status, f"failed to set safetyModel {self.CP.safetyConfigs}") + + cfg = self.CP.safetyConfigs[-1] + set_status = self.safety.set_safety_hooks(cfg.safetyModel.raw, cfg.safetyParam) + self.assertEqual(0, set_status, f"failed to set safetyModel {cfg}") self.safety.init_tests() def test_car_params(self): @@ -108,7 +121,6 @@ class TestCarModel(unittest.TestCase): # make sure car params are within a valid range self.assertGreater(self.CP.mass, 1) - self.assertGreater(self.CP.steerRateCost, 1e-3) if self.CP.steerControlType != car.CarParams.SteerControlType.angle: tuning = self.CP.lateralTuning.which() @@ -143,11 +155,11 @@ class TestCarModel(unittest.TestCase): assert RI error_cnt = 0 - for msg in self.can_msgs: - radar_data = RI.update((msg.as_builder().to_bytes(),)) - if radar_data is not None: - error_cnt += car.RadarData.Error.canError in radar_data.errors - self.assertLess(error_cnt, 20) + for i, msg in enumerate(self.can_msgs): + rr = RI.update((msg.as_builder().to_bytes(),)) + if rr is not None and i > 50: + error_cnt += car.RadarData.Error.canError in rr.errors + self.assertEqual(error_cnt, 0) def test_panda_safety_rx_valid(self): if self.CP.dashcamOnly: @@ -166,7 +178,7 @@ class TestCarModel(unittest.TestCase): if msg.src >= 64: continue - to_send = package_can_msg([msg.address, 0, msg.dat, msg.src]) + to_send = package_can_msg([msg.address, 0, msg.dat, msg.src % 4]) if self.safety.safety_rx_hook(to_send) != 1: failed_addrs[hex(msg.address)] += 1 @@ -247,5 +259,10 @@ class TestCarModel(unittest.TestCase): self.assertFalse(len(failed_checks), f"panda safety doesn't agree with openpilot: {failed_checks}") +@parameterized_class(('car_model', 'test_route'), test_cases) +class TestCarModel(TestCarModelBase): + pass + + if __name__ == "__main__": unittest.main() diff --git a/selfdrive/car/torque_data.json b/selfdrive/car/torque_data.json new file mode 100644 index 0000000000..63ee0e9bcd --- /dev/null +++ b/selfdrive/car/torque_data.json @@ -0,0 +1 @@ +{"LAT_ACCEL_FACTOR": {"HONDA PILOT 2017": 1.682289482065265, "HONDA CIVIC 2016": 1.5248128495527884, "TOYOTA CAMRY 2018": 2.1115709806216447, "TOYOTA COROLLA HYBRID TSS2 2019": 2.3250600977240077, "TOYOTA RAV4 2019": 2.625504029066767, "HYUNDAI PALISADE 2020": 2.5250855675875634, "TOYOTA SIENNA 2018": 1.8254254785341577, "ACURA RDX 2020": 1.3998101622214894, "TOYOTA RAV4 2017": 1.948190869577896, "HONDA RIDGELINE 2017": 1.4158181862793415, "TOYOTA PRIUS 2017": 1.9142926195557595, "TOYOTA HIGHLANDER HYBRID 2020": 2.1097056247344392, "HYUNDAI SONATA 2020": 3.2488989629905944, "KIA STINGER GT2 2018": 2.7592622336517834, "TOYOTA HIGHLANDER 2020": 2.0408544157877055, "HONDA ACCORD 2018": 1.6374118241564064, "TOYOTA PRIUS TSS2 2021": 2.3207270770298365, "NISSAN LEAF 2018": NaN, "CHRYSLER PACIFICA HYBRID 2019": 1.46050785084946, "LEXUS NX 2020": 2.29533657249232, "TOYOTA RAV4 HYBRID 2019": 2.4003012079562085, "HONDA CIVIC (BOSCH) 2019": 1.6523031416671652, "KIA NIRO HYBRID 2021": 2.743464625803003, "HONDA ACCORD HYBRID 2018": 1.5904016830979033, "LEXUS NX HYBRID 2018": 2.398678119681945, "TOYOTA COROLLA TSS2 2019": 2.3859244449846466, "VOLKSWAGEN ARTEON 1ST GEN": 1.4249208219414902, "TOYOTA CAMRY HYBRID 2021": 2.5434553806317055, "VOLKSWAGEN JETTA 7TH GEN": 1.2228130240634283, "HONDA INSIGHT 2019": 1.468352089969897, "SUBARU FORESTER 2019": 3.6185035528523546, "HYUNDAI ELANTRA 2021": 3.5294999663335185, "HYUNDAI IONIQ ELECTRIC LIMITED 2019": 2.2179616966432905, "HYUNDAI KONA HYBRID 2020": 4.493208192966529, "HONDA ODYSSEY 2018": 1.8838175399087222, "LEXUS RX 2016": 1.3912132245094184, "TOYOTA COROLLA 2017": 3.0143547548384735, "LEXUS ES 2019": 2.012201253045193, "HYUNDAI SANTA FE 2019": 3.039728566484244, "TOYOTA AVALON 2022": 2.4619858654670885, "JEEP GRAND CHEROKEE V6 2018": 1.8411674990629987, "CHEVROLET VOLT PREMIER 2017": 1.5943438675127841, "TOYOTA RAV4 HYBRID 2017": 1.9803053616868995, "LEXUS RX 2020": 1.664616846377383, "TOYOTA HIGHLANDER HYBRID 2018": 1.8866764457400844, "TOYOTA CAMRY HYBRID 2018": 2.014213351947917, "TESLA AP2 MODEL S": NaN, "VOLKSWAGEN GOLF 7TH GEN": 1.4428896585442685, "TOYOTA MIRAI 2021": 2.7217623852898853, "LEXUS IS 2018": 3.5624668608596837, "TOYOTA HIGHLANDER 2017": 1.9199133105823853, "HYUNDAI SONATA HYBRID 2021": 2.7313907441569554, "VOLKSWAGEN ATLAS 1ST GEN": 1.4483948408160645, "LEXUS ES HYBRID 2019": 2.4138026617523547, "HYUNDAI GENESIS 2015-2016": 1.7636839808044658, "JEEP GRAND CHEROKEE 2019": 1.787264083939164, "SUBARU ASCENT LIMITED 2019": 3.0494069339774565, "HONDA CR-V 2017": 1.9828470679233807, "HONDA FIT 2018": 1.594940026552055, "TOYOTA CAMRY 2021": 2.5057990840460342, "AUDI Q3 2ND GEN": 1.4558300885316715, "AUDI A3 3RD GEN": 1.5304173783542625, "LEXUS RX HYBRID 2017": 1.577216425446677, "HONDA CIVIC 2022": 2.69252285552613, "GENESIS G70 2018": 3.866842361627636, "CHRYSLER PACIFICA HYBRID 2018": 1.5771851419640903, "VOLKSWAGEN PASSAT 8TH GEN": 1.2985597059739313, "HONDA CR-V 2016": 0.7745984062630755, "HYUNDAI IONIQ PHEV 2020": 2.5696218908589383, "GMC ACADIA DENALI 2018": 1.3310088601868082, "HYUNDAI SONATA 2019": 1.9736552675022665, "TOYOTA AVALON 2019": 1.7245149905226294, "TOYOTA C-HR 2018": 1.5895016960662856, "HONDA CR-V HYBRID 2019": 2.0687746810729193, "CHRYSLER PACIFICA 2020": 1.40536880000744, "HYUNDAI IONIQ ELECTRIC 2020": 3.3220838625838667, "VOLKSWAGEN TIGUAN 2ND GEN": NaN, "LEXUS NX 2018": 1.7753192756242595, "KIA OPTIMA SX 2019 & 2016": 3.12625562280304, "TOYOTA AVALON HYBRID 2019": 1.7681286449373381, "TOYOTA RAV4 HYBRID 2022": 2.5518187542231816, "HONDA PASSPORT 2021": 1.5174924139130355, "KIA K5 2021": 2.482916204106975, "ACURA ILX 2016": 1.5237423964720282, "HYUNDAI IONIQ HYBRID 2017-2019": 2.3723887901632645, "KIA NIRO EV 2020": 2.924651969180446, "SUBARU IMPREZA SPORT 2020": 2.5317689549587694, "CHRYSLER PACIFICA HYBRID 2017": 1.167126725149114, "HYUNDAI KONA ELECTRIC 2019": 4.201092987427836, "HYUNDAI ELANTRA HYBRID 2021": 3.7153193626001926, "HYUNDAI SANTA FE HYBRID 2022": 3.3049230586030545, "CHRYSLER PACIFICA 2018": 1.524867383058782, "NISSAN ROGUE 2019": NaN, "KIA SORENTO GT LINE 2018": 2.5970979517766213, "COMMA BODY": NaN, "NISSAN LEAF 2018 Instrument Cluster": NaN, "LEXUS RX HYBRID 2020": 1.5460982690267173, "MAZDA CX-9 2021": 1.9514800984278198, "HYUNDAI SANTA FE 2022": 3.5354982200434524, "HYUNDAI SANTA FE PlUG-IN HYBRID 2022": 1.8902492836532216, "HONDA HRV 2019": 2.1262957371020352, "TOYOTA AVALON HYBRID 2022": 2.4142150048378683, "SUBARU IMPREZA LIMITED 2019": 1.2203463907025918, "GENESIS G80 2017": 2.4086794443413906, "VOLKSWAGEN TAOS 1ST GEN": 2.0031666974545947, "KIA FORTE E 2018 & GT 2021": 2.022553820222557, "CADILLAC ESCALADE ESV 2016": 1.5522339636408988, "TOYOTA C-HR 2021": 1.6519334844316687, "TOYOTA C-HR HYBRID 2018": 1.3193315010905482}, "MAX_LAT_ACCEL_MEASURED": {"HONDA PILOT 2017": 0.9069354290994807, "HONDA CIVIC 2016": 0.4030275472529351, "TOYOTA CAMRY 2018": 1.686123168195758, "TOYOTA COROLLA HYBRID TSS2 2019": 1.9139332621491167, "TOYOTA RAV4 2019": 2.234047196286479, "HYUNDAI PALISADE 2020": 1.8303582523301922, "TOYOTA SIENNA 2018": 1.4752503435300715, "ACURA RDX 2020": 0.40911581320000334, "TOYOTA RAV4 2017": 1.6622227720995595, "HONDA RIDGELINE 2017": 0.8224685813281227, "TOYOTA PRIUS 2017": 1.4548827870876067, "TOYOTA HIGHLANDER HYBRID 2020": 2.0649784271823037, "HYUNDAI SONATA 2020": 2.243989856570093, "KIA STINGER GT2 2018": 1.9531287107084392, "TOYOTA HIGHLANDER 2020": 1.659381392090836, "HONDA ACCORD 2018": 0.40486739531686267, "TOYOTA PRIUS TSS2 2021": 1.861541601048098, "NISSAN LEAF 2018": NaN, "CHRYSLER PACIFICA HYBRID 2019": 1.1930739374812243, "LEXUS NX 2020": 1.565268724838564, "TOYOTA RAV4 HYBRID 2019": 2.0915384047218426, "HONDA CIVIC (BOSCH) 2019": 0.4062886118517984, "KIA NIRO HYBRID 2021": NaN, "HONDA ACCORD HYBRID 2018": 0.35128914564548286, "LEXUS NX HYBRID 2018": 1.81821359787186, "TOYOTA COROLLA TSS2 2019": 1.911280958056631, "VOLKSWAGEN ARTEON 1ST GEN": 1.2587939472578302, "TOYOTA CAMRY HYBRID 2021": 2.312510643730013, "VOLKSWAGEN JETTA 7TH GEN": 1.232161945396623, "HONDA INSIGHT 2019": 0.5174836462945298, "SUBARU FORESTER 2019": 2.29255993930968, "HYUNDAI ELANTRA 2021": NaN, "HYUNDAI IONIQ ELECTRIC LIMITED 2019": 2.133978602602408, "HYUNDAI KONA HYBRID 2020": NaN, "HONDA ODYSSEY 2018": 0.8254773781363679, "LEXUS RX 2016": 1.0954776820595344, "TOYOTA COROLLA 2017": 2.2012870528168964, "LEXUS ES 2019": 2.069508805495439, "HYUNDAI SANTA FE 2019": 2.3763720477660253, "TOYOTA AVALON 2022": 2.531962323786023, "JEEP GRAND CHEROKEE V6 2018": 1.4193323242487865, "CHEVROLET VOLT PREMIER 2017": 1.8576430337666092, "TOYOTA RAV4 HYBRID 2017": 1.7425797219020926, "LEXUS RX 2020": 1.5118835180227874, "TOYOTA HIGHLANDER HYBRID 2018": 1.6872527654528833, "TOYOTA CAMRY HYBRID 2018": 1.6793468378089895, "TESLA AP2 MODEL S": NaN, "VOLKSWAGEN GOLF 7TH GEN": 1.5614447712441282, "TOYOTA MIRAI 2021": 2.271146483563897, "LEXUS IS 2018": NaN, "TOYOTA HIGHLANDER 2017": 1.6573774863189379, "HYUNDAI SONATA HYBRID 2021": 1.9464120717803253, "VOLKSWAGEN ATLAS 1ST GEN": 1.6867005451451638, "LEXUS ES HYBRID 2019": 1.956450687999482, "HYUNDAI GENESIS 2015-2016": 1.5359761378898085, "JEEP GRAND CHEROKEE 2019": 1.2418961305308847, "SUBARU ASCENT LIMITED 2019": NaN, "HONDA CR-V 2017": 0.2642062271814174, "HONDA FIT 2018": 0.5896345937094754, "TOYOTA CAMRY 2021": 2.1783533980215166, "AUDI Q3 2ND GEN": 1.1582239457022647, "AUDI A3 3RD GEN": 1.598699116126939, "LEXUS RX HYBRID 2017": 1.319771127672888, "HONDA CIVIC 2022": 1.1806949852580793, "GENESIS G70 2018": 2.2496820850331134, "CHRYSLER PACIFICA HYBRID 2018": 1.294798200968084, "VOLKSWAGEN PASSAT 8TH GEN": 1.247540921731637, "HONDA CR-V 2016": 0.6991119250342539, "HYUNDAI IONIQ PHEV 2020": 1.9062392690595655, "GMC ACADIA DENALI 2018": 1.2986994230652662, "HYUNDAI SONATA 2019": 1.257445187146704, "TOYOTA AVALON 2019": 1.664577368475227, "TOYOTA C-HR 2018": 1.308490445144888, "HONDA CR-V HYBRID 2019": 0.4693072746041504, "CHRYSLER PACIFICA 2020": 1.1712413003138664, "HYUNDAI IONIQ ELECTRIC 2020": NaN, "VOLKSWAGEN TIGUAN 2ND GEN": 1.1573057001955744, "LEXUS NX 2018": 1.9457312007432144, "KIA OPTIMA SX 2019 & 2016": 2.0928228595938845, "TOYOTA AVALON HYBRID 2019": NaN, "TOYOTA RAV4 HYBRID 2022": 1.7647290773049569, "HONDA PASSPORT 2021": 0.8248357750132685, "KIA K5 2021": 1.4628018983720577, "ACURA ILX 2016": 0.6330753921140401, "HYUNDAI IONIQ HYBRID 2017-2019": NaN, "KIA NIRO EV 2020": 2.020186575503497, "SUBARU IMPREZA SPORT 2020": 2.136786720514988, "CHRYSLER PACIFICA HYBRID 2017": 1.0642918033307907, "HYUNDAI KONA ELECTRIC 2019": NaN, "HYUNDAI ELANTRA HYBRID 2021": NaN, "HYUNDAI SANTA FE HYBRID 2022": NaN, "CHRYSLER PACIFICA 2018": 1.3654603720349934, "NISSAN ROGUE 2019": NaN, "KIA SORENTO GT LINE 2018": NaN, "COMMA BODY": NaN, "NISSAN LEAF 2018 Instrument Cluster": NaN, "LEXUS RX HYBRID 2020": 1.255230465866663, "MAZDA CX-9 2021": NaN, "HYUNDAI SANTA FE 2022": 3.3823387508235827, "HYUNDAI SANTA FE PlUG-IN HYBRID 2022": 1.544104124172169, "HONDA HRV 2019": 0.7492792210307291, "TOYOTA AVALON HYBRID 2022": NaN, "SUBARU IMPREZA LIMITED 2019": 0.8127509604734238, "GENESIS G80 2017": NaN, "VOLKSWAGEN TAOS 1ST GEN": 1.6590543949912684, "KIA FORTE E 2018 & GT 2021": 2.3970573789339786, "CADILLAC ESCALADE ESV 2016": NaN, "TOYOTA C-HR 2021": 1.3559230155096402, "TOYOTA C-HR HYBRID 2018": 0.8910235787356033}, "FRICTION": {"HONDA PILOT 2017": 0.2168217463499328, "HONDA CIVIC 2016": 0.28406761310944795, "TOYOTA CAMRY 2018": 0.1327947477896041, "TOYOTA COROLLA HYBRID TSS2 2019": 0.21792021497538405, "TOYOTA RAV4 2019": 0.12757022360707945, "HYUNDAI PALISADE 2020": 0.13391574986922777, "TOYOTA SIENNA 2018": 0.1853443239485906, "ACURA RDX 2020": 0.18058553315570297, "TOYOTA RAV4 2017": 0.14319170324556796, "HONDA RIDGELINE 2017": 0.2380553573913589, "TOYOTA PRIUS 2017": 0.2079869382946584, "TOYOTA HIGHLANDER HYBRID 2020": 0.14038812589302646, "HYUNDAI SONATA 2020": 0.08266051305053168, "KIA STINGER GT2 2018": 0.11909534626930472, "TOYOTA HIGHLANDER 2020": 0.14658637853444048, "HONDA ACCORD 2018": 0.21616610462729247, "TOYOTA PRIUS TSS2 2021": 0.20613763260512002, "NISSAN LEAF 2018": NaN, "CHRYSLER PACIFICA HYBRID 2019": 0.16250373743651828, "LEXUS NX 2020": 0.14404022591302845, "TOYOTA RAV4 HYBRID 2019": 0.1319247989758836, "HONDA CIVIC (BOSCH) 2019": 0.2575217845562353, "KIA NIRO HYBRID 2021": 0.14468633728800306, "HONDA ACCORD HYBRID 2018": 0.21150723931119184, "LEXUS NX HYBRID 2018": 0.16117151597250162, "TOYOTA COROLLA TSS2 2019": 0.21045927995242877, "VOLKSWAGEN ARTEON 1ST GEN": 0.17828895368353925, "TOYOTA CAMRY HYBRID 2021": 0.16283734136957057, "VOLKSWAGEN JETTA 7TH GEN": 0.19508489725001105, "HONDA INSIGHT 2019": 0.25750800088299297, "SUBARU FORESTER 2019": 0.11783702069698135, "HYUNDAI ELANTRA 2021": 0.09377564130711125, "HYUNDAI IONIQ ELECTRIC LIMITED 2019": 0.14740189509875762, "HYUNDAI KONA HYBRID 2020": 0.0863709736632968, "HONDA ODYSSEY 2018": 0.2125595696498247, "LEXUS RX 2016": 0.21475140622981923, "TOYOTA COROLLA 2017": 0.12325064090161544, "LEXUS ES 2019": 0.12757526660498053, "HYUNDAI SANTA FE 2019": 0.12230125806479573, "TOYOTA AVALON 2022": 0.11030226705639488, "JEEP GRAND CHEROKEE V6 2018": 0.12871972792344108, "CHEVROLET VOLT PREMIER 2017": 0.16697256960295873, "TOYOTA RAV4 HYBRID 2017": 0.14074453855329072, "LEXUS RX 2020": 0.2249895411716623, "TOYOTA HIGHLANDER HYBRID 2018": 0.16692807938039034, "TOYOTA CAMRY HYBRID 2018": 0.13418904852016877, "TESLA AP2 MODEL S": NaN, "VOLKSWAGEN GOLF 7TH GEN": 0.19324413131475543, "TOYOTA MIRAI 2021": 0.20035237756713503, "LEXUS IS 2018": 0.073103111226694, "TOYOTA HIGHLANDER 2017": 0.17502689439420385, "HYUNDAI SONATA HYBRID 2021": 0.09518615688045734, "VOLKSWAGEN ATLAS 1ST GEN": 0.12761803335799474, "LEXUS ES HYBRID 2019": 0.1682771025433274, "HYUNDAI GENESIS 2015-2016": 0.10254237048034251, "JEEP GRAND CHEROKEE 2019": 0.15702739382013717, "SUBARU ASCENT LIMITED 2019": 0.12936982863095342, "HONDA CR-V 2017": 0.22518506713451308, "HONDA FIT 2018": 0.10803295063463647, "TOYOTA CAMRY 2021": 0.15512845523424743, "AUDI Q3 2ND GEN": 0.14083949977629878, "AUDI A3 3RD GEN": 0.1611945965384188, "LEXUS RX HYBRID 2017": 0.19322020114452776, "HONDA CIVIC 2022": 0.24279247053469405, "GENESIS G70 2018": 0.06869638264150804, "CHRYSLER PACIFICA HYBRID 2018": 0.13887505891474383, "VOLKSWAGEN PASSAT 8TH GEN": 0.21714039653367842, "HONDA CR-V 2016": 0.41726236462791455, "HYUNDAI IONIQ PHEV 2020": 0.13800461817330806, "GMC ACADIA DENALI 2018": 0.3447163106452739, "HYUNDAI SONATA 2019": 0.15371520337813344, "TOYOTA AVALON 2019": 0.10392921606262978, "TOYOTA C-HR 2018": 0.2015190716953846, "HONDA CR-V HYBRID 2019": 0.19595630321202379, "CHRYSLER PACIFICA 2020": 0.14337114313208268, "HYUNDAI IONIQ ELECTRIC 2020": 0.08104502306679212, "VOLKSWAGEN TIGUAN 2ND GEN": NaN, "LEXUS NX 2018": 0.1471001686544422, "KIA OPTIMA SX 2019 & 2016": 0.11703652166984638, "TOYOTA AVALON HYBRID 2019": 0.10863628402866225, "TOYOTA RAV4 HYBRID 2022": 0.14334213238415072, "HONDA PASSPORT 2021": 0.19826160782809032, "KIA K5 2021": 0.1027179720106188, "ACURA ILX 2016": 0.35663988815912573, "HYUNDAI IONIQ HYBRID 2017-2019": 0.12332151728479951, "KIA NIRO EV 2020": 0.0892074288578785, "SUBARU IMPREZA SPORT 2020": 0.15841234487251604, "CHRYSLER PACIFICA HYBRID 2017": 0.1345638758810282, "HYUNDAI KONA ELECTRIC 2019": 0.08503096350356723, "HYUNDAI ELANTRA HYBRID 2021": 0.09887804390243872, "HYUNDAI SANTA FE HYBRID 2022": 0.11171499761140577, "CHRYSLER PACIFICA 2018": 0.13611561752951415, "NISSAN ROGUE 2019": NaN, "KIA SORENTO GT LINE 2018": 0.10502695501512567, "COMMA BODY": NaN, "NISSAN LEAF 2018 Instrument Cluster": NaN, "LEXUS RX HYBRID 2020": 0.21818156330777305, "MAZDA CX-9 2021": 0.1793735649504697, "HYUNDAI SANTA FE 2022": 0.09184808719698756, "HYUNDAI SANTA FE PlUG-IN HYBRID 2022": 0.14050744688135813, "HONDA HRV 2019": 0.17840321248608593, "TOYOTA AVALON HYBRID 2022": 0.16159049452515487, "SUBARU IMPREZA LIMITED 2019": 0.20322553080306893, "GENESIS G80 2017": 0.07934444681782107, "VOLKSWAGEN TAOS 1ST GEN": 0.18276122764341485, "KIA FORTE E 2018 & GT 2021": 0.11406160665068436, "CADILLAC ESCALADE ESV 2016": 0.15063766975884627, "TOYOTA C-HR 2021": 0.22798633346500694, "TOYOTA C-HR HYBRID 2018": 0.2036375866375624}, "ERROR_RATIO": {"HONDA PILOT 2017": 0.6158457247286419, "HONDA CIVIC 2016": 2.0785618623350928, "TOYOTA CAMRY 2018": 0.17356565057429169, "TOYOTA COROLLA HYBRID TSS2 2019": 0.10094741777075293, "TOYOTA RAV4 2019": 0.11812042718338775, "HYUNDAI PALISADE 2020": 0.30639442561268304, "TOYOTA SIENNA 2018": 0.1117307389748361, "ACURA RDX 2020": 1.9801454495960717, "TOYOTA RAV4 2017": 0.08589486116378196, "HONDA RIDGELINE 2017": 0.4319851914417577, "TOYOTA PRIUS 2017": 0.17281316158588575, "TOYOTA HIGHLANDER HYBRID 2020": 0.046325388721577, "HYUNDAI SONATA 2020": 0.4109860794021653, "KIA STINGER GT2 2018": 0.3517628781488943, "TOYOTA HIGHLANDER 2020": 0.14155072865224166, "HONDA ACCORD 2018": 2.510398061115294, "TOYOTA PRIUS TSS2 2021": 0.13593456264106363, "NISSAN LEAF 2018": NaN, "CHRYSLER PACIFICA HYBRID 2019": 0.08794943266738546, "LEXUS NX 2020": 0.3743942573190866, "TOYOTA RAV4 HYBRID 2019": 0.0845492503791727, "HONDA CIVIC (BOSCH) 2019": 2.4329816697390063, "KIA NIRO HYBRID 2021": NaN, "HONDA ACCORD HYBRID 2018": 2.9252406767451804, "LEXUS NX HYBRID 2018": 0.23060712246809048, "TOYOTA COROLLA TSS2 2019": 0.13822363784977285, "VOLKSWAGEN ARTEON 1ST GEN": 0.009661691674299285, "TOYOTA CAMRY HYBRID 2021": 0.029451711159377333, "VOLKSWAGEN JETTA 7TH GEN": 0.16591473170144055, "HONDA INSIGHT 2019": 1.3398692842898896, "SUBARU FORESTER 2019": 0.5269683780697442, "HYUNDAI ELANTRA 2021": NaN, "HYUNDAI IONIQ ELECTRIC LIMITED 2019": 0.02971857401969039, "HYUNDAI KONA HYBRID 2020": NaN, "HONDA ODYSSEY 2018": 1.0245957242729038, "LEXUS RX 2016": 0.07392586589971588, "TOYOTA COROLLA 2017": 0.31336988069649124, "LEXUS ES 2019": 0.08933657038050916, "HYUNDAI SANTA FE 2019": 0.2276812089092099, "TOYOTA AVALON 2022": 0.07120118798045925, "JEEP GRAND CHEROKEE V6 2018": 0.2065164316228118, "CHEVROLET VOLT PREMIER 2017": 0.2316223989408518, "TOYOTA RAV4 HYBRID 2017": 0.055653752888652736, "LEXUS RX 2020": 0.047792182371008345, "TOYOTA HIGHLANDER HYBRID 2018": 0.019259474082467202, "TOYOTA CAMRY HYBRID 2018": 0.11949733140330816, "TESLA AP2 MODEL S": NaN, "VOLKSWAGEN GOLF 7TH GEN": 0.1996863736436734, "TOYOTA MIRAI 2021": 0.11019259478417197, "LEXUS IS 2018": NaN, "TOYOTA HIGHLANDER 2017": 0.05279963713251727, "HYUNDAI SONATA HYBRID 2021": 0.3543918194389536, "VOLKSWAGEN ATLAS 1ST GEN": 0.21694647502209782, "LEXUS ES HYBRID 2019": 0.14775474433507507, "HYUNDAI GENESIS 2015-2016": 0.0814892037361157, "JEEP GRAND CHEROKEE 2019": 0.3126997097753535, "SUBARU ASCENT LIMITED 2019": NaN, "HONDA CR-V 2017": 5.652613829506629, "HONDA FIT 2018": 1.5217432826711779, "TOYOTA CAMRY 2021": 0.07910435053686729, "AUDI Q3 2ND GEN": 0.13535089102138698, "AUDI A3 3RD GEN": 0.14353941401245793, "LEXUS RX HYBRID 2017": 0.048663813961824696, "HONDA CIVIC 2022": 1.0748206908458815, "GENESIS G70 2018": 0.688303429295532, "CHRYSLER PACIFICA HYBRID 2018": 0.11083725786301112, "VOLKSWAGEN PASSAT 8TH GEN": 0.13315924904555493, "HONDA CR-V 2016": 0.488871482749128, "HYUNDAI IONIQ PHEV 2020": 0.2756096845519595, "GMC ACADIA DENALI 2018": 0.24055364003040136, "HYUNDAI SONATA 2019": 0.4473315280277132, "TOYOTA AVALON 2019": 0.026428086100632363, "TOYOTA C-HR 2018": 0.06075105822970755, "HONDA CR-V HYBRID 2019": 2.9906016360828276, "CHRYSLER PACIFICA 2020": 0.07748732608487266, "HYUNDAI IONIQ ELECTRIC 2020": NaN, "VOLKSWAGEN TIGUAN 2ND GEN": NaN, "LEXUS NX 2018": 0.16318394527060903, "KIA OPTIMA SX 2019 & 2016": 0.4378756841929454, "TOYOTA AVALON HYBRID 2019": NaN, "TOYOTA RAV4 HYBRID 2022": 0.36478548056633514, "HONDA PASSPORT 2021": 0.5993860184637646, "KIA K5 2021": 0.6271500841947655, "ACURA ILX 2016": 0.8435442647921855, "HYUNDAI IONIQ HYBRID 2017-2019": NaN, "KIA NIRO EV 2020": 0.40355577782011604, "SUBARU IMPREZA SPORT 2020": 0.11071291640854522, "CHRYSLER PACIFICA HYBRID 2017": 0.029812269495458284, "HYUNDAI KONA ELECTRIC 2019": NaN, "HYUNDAI ELANTRA HYBRID 2021": NaN, "HYUNDAI SANTA FE HYBRID 2022": NaN, "CHRYSLER PACIFICA 2018": 0.01705753895996445, "NISSAN ROGUE 2019": NaN, "KIA SORENTO GT LINE 2018": NaN, "COMMA BODY": NaN, "NISSAN LEAF 2018 Instrument Cluster": NaN, "LEXUS RX HYBRID 2020": 0.05790668871480552, "MAZDA CX-9 2021": NaN, "HYUNDAI SANTA FE 2022": 0.018126919430513307, "HYUNDAI SANTA FE PlUG-IN HYBRID 2022": 0.1331760659016062, "HONDA HRV 2019": 1.599688433820939, "TOYOTA AVALON HYBRID 2022": NaN, "SUBARU IMPREZA LIMITED 2019": 0.2514545160390271, "GENESIS G80 2017": NaN, "VOLKSWAGEN TAOS 1ST GEN": 0.09725484306423876, "KIA FORTE E 2018 & GT 2021": 0.20381871942480628, "CADILLAC ESCALADE ESV 2016": NaN, "TOYOTA C-HR 2021": 0.05016813984196128, "TOYOTA C-HR HYBRID 2018": 0.2521485862766935}} \ No newline at end of file diff --git a/selfdrive/car/toyota/carcontroller.py b/selfdrive/car/toyota/carcontroller.py index 1c01703d7e..33e3fe118e 100644 --- a/selfdrive/car/toyota/carcontroller.py +++ b/selfdrive/car/toyota/carcontroller.py @@ -54,8 +54,7 @@ class CarController: apply_steer = apply_toyota_steer_torque_limits(new_steer, self.last_steer, CS.out.steeringTorqueEps, self.torque_rate_limits) self.steer_rate_limited = new_steer != apply_steer - # Cut steering while we're in a known fault state (2s) - if not CC.latActive or CS.steer_state in (9, 25): + if not CC.latActive: apply_steer = 0 apply_steer_req = 0 else: diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index 54922ac2de..281d01026f 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -82,7 +82,10 @@ class CarState(CarStateBase): ret.steeringTorqueEps = cp.vl["STEER_TORQUE_SENSOR"]["STEER_TORQUE_EPS"] * self.eps_torque_scale # we could use the override bit from dbc, but it's triggered at too high torque values ret.steeringPressed = abs(ret.steeringTorque) > STEER_THRESHOLD - ret.steerFaultTemporary = cp.vl["EPS_STATUS"]["LKA_STATE"] not in (1, 5) + # steer rate fault, goes to 21 or 25 for 1 frame, then 9 for ~2 seconds + ret.steerFaultTemporary = cp.vl["EPS_STATUS"]["LKA_STATE"] in (0, 9, 21, 25) + # 17 is a fault from a prolonged high torque delta between cmd and user + ret.steerFaultPermanent = cp.vl["EPS_STATUS"]["LKA_STATE"] == 17 if self.CP.carFingerprint in (CAR.LEXUS_IS, CAR.LEXUS_RC): ret.cruiseState.available = cp.vl["DSU_CRUISE"]["MAIN_ON"] != 0 @@ -120,8 +123,6 @@ class CarState(CarStateBase): ret.stockAeb = bool(cp_cam.vl["PRE_COLLISION"]["PRECOLLISION_ACTIVE"] and cp_cam.vl["PRE_COLLISION"]["FORCE"] < -1e-5) ret.espDisabled = cp.vl["ESP_CONTROL"]["TC_DISABLED"] != 0 - # 2 is standby, 10 is active. TODO: check that everything else is really a faulty state - self.steer_state = cp.vl["EPS_STATUS"]["LKA_STATE"] if self.CP.enableBsm: ret.leftBlindspot = (cp.vl["BSM"]["L_ADJACENT"] == 1) or (cp.vl["BSM"]["L_APPROACHING"] == 1) diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index 872a27c645..d0f4789775 100644 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -2,6 +2,7 @@ from cereal import car from common.conversions import Conversions as CV from panda import Panda +from selfdrive.controls.lib.latcontrol_torque import set_torque_tune from selfdrive.car.toyota.tunes import LatTunes, LongTunes, set_long_tune, set_lat_tune from selfdrive.car.toyota.values import Ecu, CAR, ToyotaFlags, TSS2_CAR, RADAR_ACC_CAR, NO_DSU_CAR, MIN_ACC_SPEED, EPS_SCALE, EV_HYBRID_CAR, CarControllerParams from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config @@ -31,6 +32,9 @@ class CarInterface(CarInterfaceBase): ret.stoppingControl = False # Toyota starts braking more when it thinks you want to stop stop_and_go = False + torque_params = CarInterfaceBase.get_torque_params(candidate) + steering_angle_deadzone_deg = 0.0 + set_torque_tune(ret.lateralTuning, torque_params['LAT_ACCEL_FACTOR'], torque_params['FRICTION'], steering_angle_deadzone_deg) if candidate == CAR.PRIUS: stop_and_go = True @@ -38,16 +42,22 @@ class CarInterface(CarInterfaceBase): ret.steerRatio = 15.74 # unknown end-to-end spec tire_stiffness_factor = 0.6371 # hand-tune ret.mass = 3045. * CV.LB_TO_KG + STD_CARGO_KG - set_lat_tune(ret.lateralTuning, LatTunes.INDI_PRIUS) - ret.steerActuatorDelay = 0.3 + # Only give steer angle deadzone to for bad angle sensor prius + for fw in car_fw: + if fw.ecu == "eps" and not fw.fwVersion == b'8965B47060\x00\x00\x00\x00\x00\x00': + steering_angle_deadzone_deg = 1.0 + set_torque_tune(ret.lateralTuning, torque_params['LAT_ACCEL_FACTOR'], torque_params['FRICTION'], steering_angle_deadzone_deg) elif candidate == CAR.PRIUS_V: stop_and_go = True ret.wheelbase = 2.78 ret.steerRatio = 17.4 tire_stiffness_factor = 0.5533 - ret.mass = 4387. * CV.LB_TO_KG + STD_CARGO_KG - set_lat_tune(ret.lateralTuning, LatTunes.TORQUE) + ret.mass = 3340. * CV.LB_TO_KG + STD_CARGO_KG + # TODO override until there is enough data + ret.maxLateralAccel = 1.8 + torque_params = CarInterfaceBase.get_torque_params(CAR.PRIUS) + set_torque_tune(ret.lateralTuning, torque_params['LAT_ACCEL_FACTOR'], torque_params['FRICTION'], steering_angle_deadzone_deg) elif candidate in (CAR.RAV4, CAR.RAV4H): stop_and_go = True if (candidate in CAR.RAV4H) else False @@ -55,14 +65,12 @@ class CarInterface(CarInterfaceBase): ret.steerRatio = 16.88 # 14.5 is spec end-to-end tire_stiffness_factor = 0.5533 ret.mass = 3650. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid - set_lat_tune(ret.lateralTuning, LatTunes.TORQUE, MAX_LAT_ACCEL=2.5, FRICTION=0.06) elif candidate == CAR.COROLLA: ret.wheelbase = 2.70 ret.steerRatio = 18.27 tire_stiffness_factor = 0.444 # not optimized yet ret.mass = 2860. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid - set_lat_tune(ret.lateralTuning, LatTunes.PID_A) elif candidate in (CAR.LEXUS_RX, CAR.LEXUS_RXH, CAR.LEXUS_RX_TSS2, CAR.LEXUS_RXH_TSS2): stop_and_go = True @@ -87,7 +95,8 @@ class CarInterface(CarInterfaceBase): ret.steerRatio = 13.7 tire_stiffness_factor = 0.7933 ret.mass = 3400. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid - set_lat_tune(ret.lateralTuning, LatTunes.PID_C) + if candidate not in (CAR.CAMRY_TSS2, CAR.CAMRYH_TSS2): + set_lat_tune(ret.lateralTuning, LatTunes.PID_C) elif candidate in (CAR.HIGHLANDER_TSS2, CAR.HIGHLANDERH_TSS2): stop_and_go = True @@ -115,7 +124,7 @@ class CarInterface(CarInterfaceBase): ret.mass = 3505. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid set_lat_tune(ret.lateralTuning, LatTunes.PID_H) - elif candidate in (CAR.RAV4_TSS2, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022): + elif candidate in (CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022): stop_and_go = True ret.wheelbase = 2.68986 ret.steerRatio = 14.3 @@ -123,6 +132,10 @@ class CarInterface(CarInterfaceBase): ret.mass = 3585. * CV.LB_TO_KG + STD_CARGO_KG # Average between ICE and Hybrid set_lat_tune(ret.lateralTuning, LatTunes.PID_D) + # TODO: remove once there's data + if candidate == CAR.RAV4_TSS2_2022: + ret.maxLateralAccel = CarInterfaceBase.get_torque_params(CAR.RAV4H_TSS2_2022)['MAX_LAT_ACCEL_MEASURED'] + # 2019+ RAV4 TSS2 uses two different steering racks and specific tuning seems to be necessary. # See https://github.com/commaai/openpilot/pull/21429#issuecomment-873652891 for fw in car_fw: @@ -136,7 +149,6 @@ class CarInterface(CarInterfaceBase): ret.steerRatio = 13.9 tire_stiffness_factor = 0.444 # not optimized yet ret.mass = 3060. * CV.LB_TO_KG + STD_CARGO_KG - set_lat_tune(ret.lateralTuning, LatTunes.TORQUE, MAX_LAT_ACCEL=3.0, FRICTION=0.08) elif candidate in (CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2, CAR.LEXUS_ESH): stop_and_go = True @@ -169,7 +181,7 @@ class CarInterface(CarInterfaceBase): ret.mass = 3108 * CV.LB_TO_KG + STD_CARGO_KG # mean between min and max set_lat_tune(ret.lateralTuning, LatTunes.PID_M) - elif candidate in (CAR.LEXUS_NXH, CAR.LEXUS_NX, CAR.LEXUS_NX_TSS2): + elif candidate in (CAR.LEXUS_NX, CAR.LEXUS_NXH, CAR.LEXUS_NX_TSS2, CAR.LEXUS_NXH_TSS2): stop_and_go = True ret.wheelbase = 2.66 ret.steerRatio = 14.7 @@ -201,7 +213,6 @@ class CarInterface(CarInterfaceBase): ret.mass = 4305. * CV.LB_TO_KG + STD_CARGO_KG set_lat_tune(ret.lateralTuning, LatTunes.PID_J) - ret.steerRateCost = 1. ret.centerToFront = ret.wheelbase * 0.44 # TODO: get actual value, for now starting with reasonable value for diff --git a/selfdrive/car/toyota/tunes.py b/selfdrive/car/toyota/tunes.py index 8ea1d6547f..3de6daae21 100644 --- a/selfdrive/car/toyota/tunes.py +++ b/selfdrive/car/toyota/tunes.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 from enum import Enum - +from selfdrive.controls.lib.latcontrol_torque import set_torque_tune class LongTunes(Enum): PEDAL = 0 @@ -50,24 +50,9 @@ def set_long_tune(tune, name): ###### LAT ###### -def set_lat_tune(tune, name, MAX_LAT_ACCEL=2.5, FRICTION=.1): +def set_lat_tune(tune, name, MAX_LAT_ACCEL=2.5, FRICTION=0.01, steering_angle_deadzone_deg=0.0, use_steering_angle=True): if name == LatTunes.TORQUE: - tune.init('torque') - tune.torque.useSteeringAngle = True - tune.torque.kp = 2.0 / MAX_LAT_ACCEL - tune.torque.kf = 1.0 / MAX_LAT_ACCEL - tune.torque.ki = 0.5 / MAX_LAT_ACCEL - tune.torque.friction = FRICTION - elif name == LatTunes.INDI_PRIUS: - tune.init('indi') - tune.indi.innerLoopGainBP = [0.] - tune.indi.innerLoopGainV = [4.0] - tune.indi.outerLoopGainBP = [0.] - tune.indi.outerLoopGainV = [3.0] - tune.indi.timeConstantBP = [0.] - tune.indi.timeConstantV = [1.0] - tune.indi.actuatorEffectivenessBP = [0.] - tune.indi.actuatorEffectivenessV = [1.0] + set_torque_tune(tune, MAX_LAT_ACCEL, FRICTION, steering_angle_deadzone_deg) elif 'PID' in str(name): tune.init('pid') tune.pid.kiBP = [0.0] diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 2d9948b9ab..2c151266cf 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -6,7 +6,7 @@ from typing import Dict, List, Union from cereal import car from common.conversions import Conversions as CV from selfdrive.car import dbc_dict -from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, Star +from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, Harness, Star Ecu = car.CarParams.Ecu MIN_ACC_SPEED = 19. * CV.MPH_TO_MS @@ -62,6 +62,7 @@ class CAR: RAV4 = "TOYOTA RAV4 2017" RAV4H = "TOYOTA RAV4 HYBRID 2017" RAV4_TSS2 = "TOYOTA RAV4 2019" + RAV4_TSS2_2022 = "TOYOTA RAV4 2022" RAV4H_TSS2 = "TOYOTA RAV4 HYBRID 2019" RAV4H_TSS2_2022 = "TOYOTA RAV4 HYBRID 2022" MIRAI = "TOYOTA MIRAI 2021" # TSS 2.5 @@ -76,6 +77,7 @@ class CAR: LEXUS_NX = "LEXUS NX 2018" LEXUS_NXH = "LEXUS NX HYBRID 2018" LEXUS_NX_TSS2 = "LEXUS NX 2020" + LEXUS_NXH_TSS2 = "LEXUS NX HYBRID 2020" LEXUS_RC = "LEXUS RC 2020" LEXUS_RX = "LEXUS RX 2016" LEXUS_RXH = "LEXUS RX HYBRID 2017" @@ -91,15 +93,12 @@ class Footnote(Enum): CAMRY = CarFootnote( "28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.", Column.FSR_LONGITUDINAL) - ANGLE_SENSOR = CarFootnote( - "An inaccurate steering wheel angle sensor makes precise control difficult.", - Column.STEERING_TORQUE, star=Star.HALF) @dataclass class ToyotaCarInfo(CarInfo): package: str = "All" - good_torque: bool = True + harness: Enum = Harness.toyota CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { @@ -131,10 +130,10 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { CAR.HIGHLANDERH: ToyotaCarInfo("Toyota Highlander Hybrid 2017-19", footnotes=[Footnote.DSU]), CAR.HIGHLANDERH_TSS2: ToyotaCarInfo("Toyota Highlander Hybrid 2020-22"), CAR.PRIUS: [ - ToyotaCarInfo("Toyota Prius 2016-20", "TSS-P", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0", footnotes=[Footnote.DSU, Footnote.ANGLE_SENSOR]), - ToyotaCarInfo("Toyota Prius Prime 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0", footnotes=[Footnote.DSU, Footnote.ANGLE_SENSOR]), + ToyotaCarInfo("Toyota Prius 2016-20", "TSS-P", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0", footnotes=[Footnote.DSU]), + ToyotaCarInfo("Toyota Prius Prime 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0", footnotes=[Footnote.DSU]), ], - CAR.PRIUS_V: ToyotaCarInfo("Toyota Prius v 2017", "TSS-P", min_enable_speed=MIN_ACC_SPEED, footnotes=[Footnote.DSU, Footnote.ANGLE_SENSOR]), + CAR.PRIUS_V: ToyotaCarInfo("Toyota Prius v 2017", "TSS-P", min_enable_speed=MIN_ACC_SPEED, footnotes=[Footnote.DSU]), CAR.PRIUS_TSS2: [ ToyotaCarInfo("Toyota Prius 2021-22", video_link="https://www.youtube.com/watch?v=J58TvCpUd4U"), ToyotaCarInfo("Toyota Prius Prime 2021-22", video_link="https://www.youtube.com/watch?v=J58TvCpUd4U"), @@ -142,8 +141,9 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { CAR.RAV4: ToyotaCarInfo("Toyota RAV4 2016-18", "TSS-P", footnotes=[Footnote.DSU]), CAR.RAV4H: ToyotaCarInfo("Toyota RAV4 Hybrid 2016-18", "TSS-P", footnotes=[Footnote.DSU]), CAR.RAV4_TSS2: ToyotaCarInfo("Toyota RAV4 2019-21", video_link="https://www.youtube.com/watch?v=wJxjDd42gGA"), + CAR.RAV4_TSS2_2022: ToyotaCarInfo("Toyota RAV4 2022"), CAR.RAV4H_TSS2: ToyotaCarInfo("Toyota RAV4 Hybrid 2019-21"), - CAR.RAV4H_TSS2_2022: ToyotaCarInfo("Toyota RAV4 Hybrid 2022"), + CAR.RAV4H_TSS2_2022: ToyotaCarInfo("Toyota RAV4 Hybrid 2022", video_link="https://youtu.be/U0nH9cnrFB0"), CAR.MIRAI: ToyotaCarInfo("Toyota Mirai 2021"), CAR.SIENNA: ToyotaCarInfo("Toyota Sienna 2018-20", video_link="https://www.youtube.com/watch?v=q1UPOo4Sh68", footnotes=[Footnote.DSU]), @@ -151,11 +151,12 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { CAR.LEXUS_CTH: ToyotaCarInfo("Lexus CT Hybrid 2017-18", "LSS", footnotes=[Footnote.DSU]), CAR.LEXUS_ESH: ToyotaCarInfo("Lexus ES Hybrid 2017-18", "LSS", footnotes=[Footnote.DSU]), CAR.LEXUS_ES_TSS2: ToyotaCarInfo("Lexus ES 2019-21"), - CAR.LEXUS_ESH_TSS2: ToyotaCarInfo("Lexus ES Hybrid 2019-21"), + CAR.LEXUS_ESH_TSS2: ToyotaCarInfo("Lexus ES Hybrid 2019-22"), CAR.LEXUS_IS: ToyotaCarInfo("Lexus IS 2017-19"), CAR.LEXUS_NX: ToyotaCarInfo("Lexus NX 2018-19", footnotes=[Footnote.DSU]), CAR.LEXUS_NXH: ToyotaCarInfo("Lexus NX Hybrid 2018-19", footnotes=[Footnote.DSU]), CAR.LEXUS_NX_TSS2: ToyotaCarInfo("Lexus NX 2020"), + CAR.LEXUS_NXH_TSS2: ToyotaCarInfo("Lexus NX Hybrid 2020"), CAR.LEXUS_RC: ToyotaCarInfo("Lexus RC 2020"), CAR.LEXUS_RX: ToyotaCarInfo("Lexus RX 2016-18", footnotes=[Footnote.DSU]), CAR.LEXUS_RXH: ToyotaCarInfo("Lexus RX Hybrid 2016-19", footnotes=[Footnote.DSU]), @@ -556,6 +557,7 @@ FW_VERSIONS = { b'\x033F401100\x00\x00\x00\x00\x00\x00\x00\x00A0202000\x00\x00\x00\x00\x00\x00\x00\x00895231203102\x00\x00\x00\x00', b'\x033F401200\x00\x00\x00\x00\x00\x00\x00\x00A0202000\x00\x00\x00\x00\x00\x00\x00\x00895231203202\x00\x00\x00\x00', b'\x033F424000\x00\x00\x00\x00\x00\x00\x00\x00A0202000\x00\x00\x00\x00\x00\x00\x00\x00895231203202\x00\x00\x00\x00', + b'\x033F424000\x00\x00\x00\x00\x00\x00\x00\x00A0202000\x00\x00\x00\x00\x00\x00\x00\x00895231203302\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'8821F0W01000 ', @@ -672,6 +674,7 @@ FW_VERSIONS = { b'\x01896630ZP1000\x00\x00\x00\x00', b'\x01896630ZP2000\x00\x00\x00\x00', b'\x01896630ZQ5000\x00\x00\x00\x00', + b'\x01896630ZU9000\x00\x00\x00\x00', b'\x018966312L8000\x00\x00\x00\x00', b'\x018966312M0000\x00\x00\x00\x00', b'\x018966312M9000\x00\x00\x00\x00', @@ -738,6 +741,7 @@ FW_VERSIONS = { b'\x01F152612C00\x00\x00\x00\x00\x00\x00', b'F152602191\x00\x00\x00\x00\x00\x00', b'\x01F152612862\x00\x00\x00\x00\x00\x00', + b'\x01F152612B91\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'\x018821F3301100\x00\x00\x00\x00', @@ -908,6 +912,7 @@ FW_VERSIONS = { b'\x01F15260E051\x00\x00\x00\x00\x00\x00', b'\x01F15260E061\x00\x00\x00\x00\x00\x00', b'\x01F15260E110\x00\x00\x00\x00\x00\x00', + b'\x01F15260E170\x00\x00\x00\x00\x00\x00', ], (Ecu.engine, 0x700, None): [ b'\x01896630E62100\x00\x00\x00\x00', @@ -927,10 +932,12 @@ FW_VERSIONS = { (Ecu.fwdRadar, 0x750, 0xf): [ b'\x018821F3301400\x00\x00\x00\x00', b'\x018821F6201200\x00\x00\x00\x00', + b'\x018821F6201300\x00\x00\x00\x00', ], (Ecu.fwdCamera, 0x750, 0x6d): [ b'\x028646F0E02100\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', b'\x028646F4803000\x00\x00\x00\x008646G5301200\x00\x00\x00\x00', + b'\x028646F4803000\x00\x00\x00\x008646G3304000\x00\x00\x00\x00', ], }, CAR.HIGHLANDERH_TSS2: { @@ -959,10 +966,12 @@ FW_VERSIONS = { (Ecu.fwdRadar, 0x750, 0xf): [ b'\x018821F3301400\x00\x00\x00\x00', b'\x018821F6201200\x00\x00\x00\x00', + b'\x018821F6201300\x00\x00\x00\x00', ], (Ecu.fwdCamera, 0x750, 0x6d): [ b'\x028646F0E02100\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', b'\x028646F4803000\x00\x00\x00\x008646G5301200\x00\x00\x00\x00', + b'\x028646F4803000\x00\x00\x00\x008646G3304000\x00\x00\x00\x00', ], }, CAR.LEXUS_IS: { @@ -1242,6 +1251,7 @@ FW_VERSIONS = { b'\x01F15260R220\x00\x00\x00\x00\x00\x00', b'\x01F15260R290\x00\x00\x00\x00\x00\x00', b'\x01F15260R300\x00\x00\x00\x00\x00\x00', + b'\x01F15260R302\x00\x00\x00\x00\x00\x00', b'\x01F152642551\x00\x00\x00\x00\x00\x00', b'\x01F152642561\x00\x00\x00\x00\x00\x00', b'\x01F152642700\x00\x00\x00\x00\x00\x00', @@ -1275,6 +1285,25 @@ FW_VERSIONS = { b'\x028646F4203800\x00\x00\x00\x008646G2601500\x00\x00\x00\x00', ], }, + CAR.RAV4_TSS2_2022: { + (Ecu.esp, 0x7b0, None): [ + b'\x01F15260R350\x00\x00\x00\x00\x00\x00', + b'\x01F15260R361\x00\x00\x00\x00\x00\x00', + ], + (Ecu.eps, 0x7a1, None): [ + b'\x028965B0R01500\x00\x00\x00\x008965B0R02500\x00\x00\x00\x00', + ], + (Ecu.engine, 0x700, None): [ + b'\x01896634AA1000\x00\x00\x00\x00', + b'\x01896634A88000\x00\x00\x00\x00', + ], + (Ecu.fwdRadar, 0x750, 0xf): [ + b'\x018821F0R01100\x00\x00\x00\x00', + ], + (Ecu.fwdCamera, 0x750, 0x6d): [ + b'\x028646F0R02100\x00\x00\x00\x008646G0R01100\x00\x00\x00\x00', + ], + }, CAR.RAV4H_TSS2: { (Ecu.engine, 0x700, None): [ b'\x01896634A15000\x00\x00\x00\x00', @@ -1337,6 +1366,7 @@ FW_VERSIONS = { b'\x01F15264283100\x00\x00\x00\x00', b'\x01F15264286200\x00\x00\x00\x00', b'\x01F15264286100\x00\x00\x00\x00', + b'\x01F15264283200\x00\x00\x00\x00', ], (Ecu.eps, 0x7a1, None): [ b'\x028965B0R01500\x00\x00\x00\x008965B0R02500\x00\x00\x00\x00', @@ -1347,6 +1377,8 @@ FW_VERSIONS = { b'\x01896634A62000\x00\x00\x00\x00', b'\x01896634A08000\x00\x00\x00\x00', b'\x01896634A61000\x00\x00\x00\x00', + b'\x01896634A02001\x00\x00\x00\x00', + b'\x01896634A03000\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'\x018821F0R01100\x00\x00\x00\x00', @@ -1448,22 +1480,26 @@ FW_VERSIONS = { b'\x028966333T0100\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', b'\x028966333V4000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', b'\x02896633T09000\x00\x00\x00\x00897CF3307001\x00\x00\x00\x00', + b'\x01896633T38000\x00\x00\x00\x00', ], (Ecu.esp, 0x7b0, None): [ b'F152633423\x00\x00\x00\x00\x00\x00', b'F152633680\x00\x00\x00\x00\x00\x00', b'F152633681\x00\x00\x00\x00\x00\x00', + b'F152633F50\x00\x00\x00\x00\x00\x00', ], (Ecu.eps, 0x7a1, None): [ b'8965B33252\x00\x00\x00\x00\x00\x00', b'8965B33590\x00\x00\x00\x00\x00\x00', b'8965B33690\x00\x00\x00\x00\x00\x00', + b'8965B33721\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'\x018821F3301100\x00\x00\x00\x00', b'\x018821F3301200\x00\x00\x00\x00', b'\x018821F3301300\x00\x00\x00\x00', b'\x018821F3301400\x00\x00\x00\x00', + b'\x018821F6201300\x00\x00\x00\x00', ], (Ecu.fwdCamera, 0x750, 0x6d): [ b'\x028646F33030D0\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', @@ -1472,6 +1508,7 @@ FW_VERSIONS = { b'\x028646F3304100\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', b'\x028646F3304200\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', b'\x028646F3304300\x00\x00\x00\x008646G2601500\x00\x00\x00\x00', + b'\x028646F3309100\x00\x00\x00\x008646G3304000\x00\x00\x00\x00', ], }, CAR.LEXUS_ESH: { @@ -1547,6 +1584,23 @@ FW_VERSIONS = { b'\x028646F7803100\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', ], }, + CAR.LEXUS_NXH_TSS2: { + (Ecu.engine, 0x7e0, None): [ + b'\x0237887000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', + ], + (Ecu.esp, 0x7b0, None): [ + b'F152678210\x00\x00\x00\x00\x00\x00', + ], + (Ecu.eps, 0x7a1, None): [ + b'8965B78120\x00\x00\x00\x00\x00\x00', + ], + (Ecu.fwdRadar, 0x750, 0xf): [ + b'\x018821F3301400\x00\x00\x00\x00', + ], + (Ecu.fwdCamera, 0x750, 0x6d): [ + b'\x028646F78030A0\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', + ], + }, CAR.LEXUS_NXH: { (Ecu.engine, 0x7e0, None): [ b'\x0237841000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', @@ -1710,6 +1764,7 @@ FW_VERSIONS = { b'\x01896634D12000\x00\x00\x00\x00', b'\x01896634D12100\x00\x00\x00\x00', b'\x01896634D43000\x00\x00\x00\x00', + b'\x01896630ED0100\x00\x00\x00\x00', ], (Ecu.esp, 0x7b0, None): [ b'\x01F15260E031\x00\x00\x00\x00\x00\x00', @@ -1736,11 +1791,13 @@ FW_VERSIONS = { CAR.LEXUS_RXH_TSS2: { (Ecu.engine, 0x7e0, None): [ b'\x02348X8000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x02348Y3000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', b'\x0234D14000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', b'\x0234D16000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.esp, 0x7b0, None): [ b'F152648831\x00\x00\x00\x00\x00\x00', + b'F152648891\x00\x00\x00\x00\x00\x00', b'F152648D00\x00\x00\x00\x00\x00\x00', b'F152648D60\x00\x00\x00\x00\x00\x00', ], @@ -1758,6 +1815,7 @@ FW_VERSIONS = { CAR.PRIUS_TSS2: { (Ecu.engine, 0x700, None): [ b'\x028966347B1000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x028966347C4000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', b'\x028966347C6000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', b'\x028966347C8000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', b'\x038966347C0000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00897CF4710101\x00\x00\x00\x00', @@ -1785,7 +1843,10 @@ FW_VERSIONS = { }, CAR.MIRAI: { (Ecu.esp, 0x7D1, None): [b'\x01898A36203000\x00\x00\x00\x00',], - (Ecu.esp, 0x7B0, None): [b'\x01F15266203200\x00\x00\x00\x00',], # a second ESP ECU + (Ecu.esp, 0x7B0, None): [ # a second ESP ECU + b'\x01F15266203200\x00\x00\x00\x00', + b'\x01F15266203500\x00\x00\x00\x00', + ], (Ecu.eps, 0x7A1, None): [b'\x028965B6204100\x00\x00\x00\x008965B6203100\x00\x00\x00\x00',], (Ecu.fwdRadar, 0x750, 0xf): [b'\x018821F6201200\x00\x00\x00\x00',], (Ecu.fwdCamera, 0x750, 0x6d): [b'\x028646F6201400\x00\x00\x00\x008646G5301200\x00\x00\x00\x00',], @@ -1856,6 +1917,7 @@ DBC = { CAR.AVALON_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.AVALONH_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.RAV4_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), + CAR.RAV4_TSS2_2022: dbc_dict('toyota_nodsu_pt_generated', None), CAR.COROLLA_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.COROLLAH_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.LEXUS_ES_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), @@ -1869,6 +1931,7 @@ DBC = { CAR.LEXUS_NXH: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), CAR.LEXUS_NX: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), CAR.LEXUS_NX_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), + CAR.LEXUS_NXH_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.PRIUS_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.MIRAI: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.ALPHARD_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), @@ -1879,18 +1942,18 @@ DBC = { EPS_SCALE = defaultdict(lambda: 73, {CAR.PRIUS: 66, CAR.COROLLA: 88, CAR.LEXUS_IS: 77, CAR.LEXUS_RC: 77, CAR.LEXUS_CTH: 100, CAR.PRIUS_V: 100}) # Toyota/Lexus Safety Sense 2.0 and 2.5 -TSS2_CAR = {CAR.RAV4_TSS2, CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2, CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022, +TSS2_CAR = {CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2, CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022, CAR.LEXUS_RX_TSS2, CAR.LEXUS_RXH_TSS2, CAR.HIGHLANDER_TSS2, CAR.HIGHLANDERH_TSS2, CAR.PRIUS_TSS2, CAR.CAMRY_TSS2, CAR.CAMRYH_TSS2, - CAR.MIRAI, CAR.LEXUS_NX_TSS2, CAR.ALPHARD_TSS2, CAR.AVALON_TSS2, CAR.AVALONH_TSS2, CAR.ALPHARDH_TSS2} + CAR.MIRAI, CAR.LEXUS_NX_TSS2, CAR.LEXUS_NXH_TSS2, CAR.ALPHARD_TSS2, CAR.AVALON_TSS2, CAR.AVALONH_TSS2, CAR.ALPHARDH_TSS2} NO_DSU_CAR = TSS2_CAR | {CAR.CHR, CAR.CHRH, CAR.CAMRY, CAR.CAMRYH} # these cars have a radar which sends ACC messages instead of the camera -RADAR_ACC_CAR = {CAR.RAV4H_TSS2_2022} +RADAR_ACC_CAR = {CAR.RAV4H_TSS2_2022, CAR.RAV4_TSS2_2022} EV_HYBRID_CAR = {CAR.AVALONH_2019, CAR.AVALONH_TSS2, CAR.CAMRYH, CAR.CAMRYH_TSS2, CAR.CHRH, CAR.COROLLAH_TSS2, CAR.HIGHLANDERH, CAR.HIGHLANDERH_TSS2, CAR.PRIUS, CAR.PRIUS_V, CAR.RAV4H, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022, CAR.LEXUS_CTH, CAR.MIRAI, CAR.LEXUS_ESH, CAR.LEXUS_ESH_TSS2, CAR.LEXUS_NXH, CAR.LEXUS_RXH, - CAR.LEXUS_RXH_TSS2, CAR.PRIUS_TSS2, CAR.ALPHARDH_TSS2} + CAR.LEXUS_RXH_TSS2, CAR.LEXUS_NXH_TSS2, CAR.PRIUS_TSS2, CAR.ALPHARDH_TSS2} # no resume button press required NO_STOP_TIMER_CAR = TSS2_CAR | {CAR.PRIUS_V, CAR.RAV4H, CAR.HIGHLANDERH, CAR.HIGHLANDER, CAR.SIENNA, CAR.LEXUS_ESH} diff --git a/selfdrive/car/vin.py b/selfdrive/car/vin.py index 648f416511..7413c3f235 100755 --- a/selfdrive/car/vin.py +++ b/selfdrive/car/vin.py @@ -1,25 +1,37 @@ #!/usr/bin/env python3 +import struct import traceback import cereal.messaging as messaging +import panda.python.uds as uds from panda.python.uds import FUNCTIONAL_ADDRS from selfdrive.car.isotp_parallel_query import IsoTpParallelQuery -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog + +OBD_VIN_REQUEST = b'\x09\x02' +OBD_VIN_RESPONSE = b'\x49\x02\x01' + +UDS_VIN_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + struct.pack("!H", uds.DATA_IDENTIFIER_TYPE.VIN) +UDS_VIN_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x40]) + struct.pack("!H", uds.DATA_IDENTIFIER_TYPE.VIN) -VIN_REQUEST = b'\x09\x02' -VIN_RESPONSE = b'\x49\x02\x01' VIN_UNKNOWN = "0" * 17 def get_vin(logcan, sendcan, bus, timeout=0.1, retry=5, debug=False): - for i in range(retry): - try: - query = IsoTpParallelQuery(sendcan, logcan, bus, FUNCTIONAL_ADDRS, [VIN_REQUEST], [VIN_RESPONSE], functional_addr=True, debug=debug) - for addr, vin in query.get_data(timeout).items(): - return addr[0], vin.decode() - print(f"vin query retry ({i+1}) ...") - except Exception: - cloudlog.warning(f"VIN query exception: {traceback.format_exc()}") + for request, response in ((UDS_VIN_REQUEST, UDS_VIN_RESPONSE), (OBD_VIN_REQUEST, OBD_VIN_RESPONSE)): + for i in range(retry): + try: + query = IsoTpParallelQuery(sendcan, logcan, bus, FUNCTIONAL_ADDRS, [request, ], [response, ], functional_addr=True, debug=debug) + for addr, vin in query.get_data(timeout).items(): + + # Honda Bosch response starts with a length, trim to correct length + if vin.startswith(b'\x11'): + vin = vin[1:18] + + return addr[0], vin.decode() + print(f"vin query retry ({i+1}) ...") + except Exception: + cloudlog.warning(f"VIN query exception: {traceback.format_exc()}") return 0, VIN_UNKNOWN diff --git a/selfdrive/car/volkswagen/carcontroller.py b/selfdrive/car/volkswagen/carcontroller.py index 740b4476af..ca84fbc02e 100644 --- a/selfdrive/car/volkswagen/carcontroller.py +++ b/selfdrive/car/volkswagen/carcontroller.py @@ -49,7 +49,7 @@ class CarController(): if actuators.longControlState == LongCtrlState.stopping and CS.out.vEgo < 0.2: self.acc_stopping = True acc_hold_request = True - if CS.esp_hold_confirmation: + if CS.out.cruiseState.standstill: acc_hold_type = 1 # hold stopping_distance = 3.5 else: @@ -154,7 +154,7 @@ class CarController(): # Cancel ACC if it's engaged with OP disengaged. self.graButtonStatesToSend = BUTTON_STATES.copy() self.graButtonStatesToSend["cancel"] = True - elif c.enabled and CS.esp_hold_confirmation: + elif c.enabled and CS.out.cruiseState.standstill: # Blip the Resume button if we're engaged at standstill. # FIXME: This is a naive implementation, improve with visiond or radar input. self.graButtonStatesToSend = BUTTON_STATES.copy() diff --git a/selfdrive/car/volkswagen/carstate.py b/selfdrive/car/volkswagen/carstate.py index 3ead56341b..014fc9a573 100644 --- a/selfdrive/car/volkswagen/carstate.py +++ b/selfdrive/car/volkswagen/carstate.py @@ -51,7 +51,6 @@ class CarState(CarStateBase): ret.brake = pt_cp.vl["ESP_05"]["ESP_Bremsdruck"] / 250.0 # FIXME: this is pressure in Bar, not sure what OP expects ret.brakePressed = bool(pt_cp.vl["ESP_05"]["ESP_Fahrer_bremst"]) ret.parkingBrake = bool(pt_cp.vl["Kombi_01"]["KBI_Handbremse"]) # FIXME: need to include an EPB check as well - self.esp_hold_confirmation = pt_cp.vl["ESP_21"]["ESP_Haltebestaetigung"] # Update gear and/or clutch position data. if trans_type == TransmissionType.automatic: @@ -109,6 +108,8 @@ class CarState(CarStateBase): # ACC okay but disabled (1), or a radar visibility or other fault/disruption (6 or 7) ret.cruiseState.available = False ret.cruiseState.enabled = False + ret.cruiseState.standstill = bool(pt_cp.vl["ESP_21"]["ESP_Haltebestaetigung"]) + ret.accFaulted = pt_cp.vl["TSK_06"]["TSK_Status"] in (6, 7) # Update ACC setpoint. When the setpoint is zero or there's an error, the # radar sends a set-speed of ~90.69 m/s / 203mph. diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index 4f1673de4f..d7679b47e1 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -47,14 +47,13 @@ class CarInterface(CarInterfaceBase): if Params().get_bool("DisableRadar") and ret.networkLocation == NetworkLocation.gateway: ret.openpilotLongitudinalControl = True - ret.safetyConfigs[0].safetyParam |= Panda.FLAG_VOLKSWAGEN_LONG_CONTROL + ret.safetyConfigs[0].safetyParam |= Panda.FLAG_VOLKSWAGEN_MQB_LONG if ret.transmissionType == TransmissionType.manual: ret.minEnableSpeed = 4.5 # FIXME: estimated, fine-tune # Global lateral tuning defaults, can be overridden per-vehicle ret.steerActuatorDelay = 0.1 - ret.steerRateCost = 1.0 ret.steerLimitTimer = 0.4 ret.steerRatio = 15.6 # Let the params learner figure this out tire_stiffness_factor = 1.0 # Let the params learner figure this out @@ -197,10 +196,6 @@ class CarInterface(CarInterfaceBase): events = self.create_common_events(ret, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic], pcm_enable=not self.CS.CP.openpilotLongitudinalControl) - # Vehicle health and operation safety checks - if self.CS.tsk_status in (6, 7): - events.add(EventName.accFaulted) - # Low speed steer alert hysteresis logic if self.CP.minSteerSpeed > 0. and ret.vEgo < (self.CP.minSteerSpeed + 1.): self.low_speed_alert = True diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index a9996fdfc1..e541a29a88 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -5,13 +5,14 @@ from typing import Dict, List, Union from cereal import car from selfdrive.car import dbc_dict -from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column +from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, Harness Ecu = car.CarParams.Ecu NetworkLocation = car.CarParams.NetworkLocation TransmissionType = car.CarParams.TransmissionType GearShifter = car.CarState.GearShifter + class CarControllerParams: HCA_STEP = 2 # HCA_01 message frequency 50Hz LDW_STEP = 10 # LDW_02 message frequency 10Hz @@ -31,18 +32,20 @@ class CarControllerParams: STEER_DRIVER_ALLOWANCE = 80 STEER_DRIVER_MULTIPLIER = 3 # weight driver torque heavily STEER_DRIVER_FACTOR = 1 # from dbc - ACCEL_MAX = 2.0 # 2.0 m/s max acceleration ACCEL_MIN = -3.5 # 3.5 m/s max deceleration + class CANBUS: pt = 0 cam = 2 + class DBC_FILES: mqb = "vw_mqb_2010" # Used for all cars with MQB-style CAN messaging -DBC = defaultdict(lambda: dbc_dict(DBC_FILES.mqb, None)) # type: Dict[str, Dict[str, str]] + +DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict(DBC_FILES.mqb, None)) BUTTON_STATES = { "accelCruise": False, @@ -65,6 +68,7 @@ MQB_LDW_MESSAGES = { "laneAssistDeactivated": 10, # "Lane Assist deactivated." silent with persistent icon afterward } + # Check the 7th and 8th characters of the VIN before adding a new CAR. If the # chassis code is already listed below, don't add a new CAR, just add to the # FW_VERSIONS for that existing CAR. @@ -115,11 +119,12 @@ class Footnote(Enum): class VWCarInfo(CarInfo): package: str = "Driver Assistance" good_torque: bool = True + harness: Enum = Harness.vw CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = { - CAR.ARTEON_MK1: VWCarInfo("Volkswagen Arteon 2018, 2021", footnotes=[Footnote.VW_HARNESS]), - CAR.ATLAS_MK1: VWCarInfo("Volkswagen Atlas 2018-19, 2022", footnotes=[Footnote.VW_HARNESS]), + CAR.ARTEON_MK1: VWCarInfo("Volkswagen Arteon 2018, 2021", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + CAR.ATLAS_MK1: VWCarInfo("Volkswagen Atlas 2018-19, 2022", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), CAR.GOLF_MK7: [ VWCarInfo("Volkswagen e-Golf 2014, 2018-20"), VWCarInfo("Volkswagen Golf 2015-20"), @@ -134,17 +139,17 @@ CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = { VWCarInfo("Volkswagen Jetta 2018-21"), VWCarInfo("Volkswagen Jetta GLI 2021"), ], - CAR.PASSAT_MK8: VWCarInfo("Volkswagen Passat 2016-18", footnotes=[Footnote.PASSAT]), + CAR.PASSAT_MK8: VWCarInfo("Volkswagen Passat 2015-19", footnotes=[Footnote.PASSAT]), CAR.POLO_MK6: VWCarInfo("Volkswagen Polo 2020"), - CAR.TAOS_MK1: VWCarInfo("Volkswagen Taos 2022", footnotes=[Footnote.VW_HARNESS]), - CAR.TCROSS_MK1: VWCarInfo("Volkswagen T-Cross 2021", footnotes=[Footnote.VW_HARNESS]), - CAR.TIGUAN_MK2: VWCarInfo("Volkswagen Tiguan 2019-22", footnotes=[Footnote.VW_HARNESS]), + CAR.TAOS_MK1: VWCarInfo("Volkswagen Taos 2022", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + CAR.TCROSS_MK1: VWCarInfo("Volkswagen T-Cross 2021", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + CAR.TIGUAN_MK2: VWCarInfo("Volkswagen Tiguan 2019-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), CAR.TOURAN_MK2: VWCarInfo("Volkswagen Touran 2017"), CAR.TRANSPORTER_T61: [ - VWCarInfo("Volkswagen Caravelle 2020", footnotes=[Footnote.VW_HARNESS]), - VWCarInfo("Volkswagen California 2021", footnotes=[Footnote.VW_HARNESS]), + VWCarInfo("Volkswagen Caravelle 2020", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + VWCarInfo("Volkswagen California 2021", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), ], - CAR.TROC_MK1: VWCarInfo("Volkswagen T-Roc 2021", footnotes=[Footnote.VW_HARNESS]), + CAR.TROC_MK1: VWCarInfo("Volkswagen T-Roc 2021", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), CAR.AUDI_A3_MK3: [ VWCarInfo("Audi A3 2014-19", "ACC + Lane Assist"), VWCarInfo("Audi A3 Sportback e-tron 2017-18", "ACC + Lane Assist"), @@ -438,46 +443,55 @@ FW_VERSIONS = { CAR.PASSAT_MK8: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704E906023AH\xf1\x893379', + b'\xf1\x8704L906026ET\xf1\x891990', b'\xf1\x8704L906026GA\xf1\x892013', b'\xf1\x8704L906026KD\xf1\x894798', b'\xf1\x873G0906264 \xf1\x890004', ], (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x870CW300043H \xf1\x891601', b'\xf1\x870CW300048R \xf1\x890610', b'\xf1\x870D9300014L \xf1\x895002', + b'\xf1\x870D9300041A \xf1\x894801', b'\xf1\x870DD300045T \xf1\x891601', b'\xf1\x870GC300042H \xf1\x891404', ], (Ecu.srs, 0x715, None): [ + b'\xf1\x873Q0959655AE\xf1\x890195\xf1\x82\r56140056130012416612124111', b'\xf1\x873Q0959655AN\xf1\x890306\xf1\x82\r58160058140013036914110311', b'\xf1\x873Q0959655BB\xf1\x890195\xf1\x82\r56140056130012026612120211', b'\xf1\x873Q0959655BK\xf1\x890703\xf1\x82\0165915005914001344701311442900', + b'\xf1\x873Q0959655CN\xf1\x890720\xf1\x82\x0e5915005914001305701311052900', b'\xf1\x875Q0959655S \xf1\x890870\xf1\x82\02315120011111200631145171716121691132111', ], (Ecu.eps, 0x712, None): [ + b'\xf1\x875Q0909143M \xf1\x892041\xf1\x820522B0060803', b'\xf1\x875Q0909143M \xf1\x892041\xf1\x820522B0080803', b'\xf1\x875Q0909144AB\xf1\x891082\xf1\x82\00521B00606A1', b'\xf1\x875Q0909144S \xf1\x891063\xf1\x82\00516B00501A1', b'\xf1\x875Q0909144T \xf1\x891072\xf1\x82\00521B00703A1', + b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567B0020600', ], (Ecu.fwdRadar, 0x757, None): [ + b'\xf1\x873Q0907572A \xf1\x890130', b'\xf1\x873Q0907572B \xf1\x890192', b'\xf1\x873Q0907572C \xf1\x890195', + b'\xf1\x873Q0907572C \xf1\x890196', b'\xf1\x875Q0907572R \xf1\x890771', ], }, CAR.POLO_MK6: { (Ecu.engine, 0x7e0, None): [ - b'\xf1\x8704C906025H \xf1\x895177', + b'\xf1\x8704C906025H \xf1\x895177', ], (Ecu.transmission, 0x7e1, None): [ - b'\xf1\x870CW300050D \xf1\x891908', + b'\xf1\x870CW300050D \xf1\x891908', ], (Ecu.srs, 0x715, None): [ b'\xf1\x872Q0959655AJ\xf1\x890250\xf1\x82\x1248130411110416--04040404784811152H14', ], (Ecu.eps, 0x712, None): [ - b'\xf1\x872Q1909144M \xf1\x896041', + b'\xf1\x872Q1909144M \xf1\x896041', ], (Ecu.fwdRadar, 0x757, None): [ b'\xf1\x872Q0907572R \xf1\x890372', @@ -485,19 +499,23 @@ FW_VERSIONS = { }, CAR.TAOS_MK1: { (Ecu.engine, 0x7e0, None): [ - b'\xf1\x8705E906013E \xf1\x891624', + b'\xf1\x8704E906027NJ\xf1\x891445', + b'\xf1\x8705E906013E \xf1\x891624', ], (Ecu.transmission, 0x7e1, None): [ - b'\xf1\x8709S927158BL\xf1\x893791', + b'\xf1\x8709S927158BL\xf1\x893791', + b'\xf1\x8709S927158FF\xf1\x893876', ], - (Ecu.fwdRadar, 0x757, None): [ - b'\xf1\x872Q0907572T \xf1\x890383', + (Ecu.srs, 0x715, None): [ + b'\xf1\x875Q0959655CB\xf1\x890421\xf1\x82\x1311111111333500314646021450149333613100', + b'\xf1\x875Q0959655CE\xf1\x890421\xf1\x82\x1311110011333300314240021350139333613100', ], (Ecu.eps, 0x712, None): [ - b'\xf1\x875QM909144C \xf1\x891082\xf1\x82\x0521060605A1', + b'\xf1\x875QM909144C \xf1\x891082\xf1\x82\x0521060405A1', + b'\xf1\x875QM909144C \xf1\x891082\xf1\x82\x0521060605A1', ], - (Ecu.srs, 0x715, None): [ - b'\xf1\x875Q0959655CB\xf1\x890421\xf1\x82\x1311111111333500314646021450149333613100', + (Ecu.fwdRadar, 0x757, None): [ + b'\xf1\x872Q0907572T \xf1\x890383', ], }, CAR.TCROSS_MK1: { @@ -519,6 +537,7 @@ FW_VERSIONS = { }, CAR.TIGUAN_MK2: { (Ecu.engine, 0x7e0, None): [ + b'\xf1\x8704E906027NB\xf1\x899504', b'\xf1\x8704L906026EJ\xf1\x893661', b'\xf1\x8704L906027G \xf1\x899893', b'\xf1\x875N0906259 \xf1\x890002', @@ -530,6 +549,7 @@ FW_VERSIONS = { b'\xf1\x8709G927158DT\xf1\x893698', b'\xf1\x8709G927158GC\xf1\x893821', b'\xf1\x8709G927158GD\xf1\x893820', + b'\xf1\x870D9300043 \xf1\x895202', b'\xf1\x870DL300011N \xf1\x892001', b'\xf1\x870DL300011N \xf1\x892012', b'\xf1\x870DL300013A \xf1\x893005', @@ -541,11 +561,14 @@ FW_VERSIONS = { b'\xf1\x875Q0959655BM\xf1\x890403\xf1\x82\02316143231313500314641011750179333423100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\02312110031333300314240583752379333423100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\02331310031333336313140013950399333423100', + b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x1331310031333334313140013750379333423100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x1331310031333334313140573752379333423100', b'\xf1\x875Q0959655CB\xf1\x890421\xf1\x82\x1316143231313500314647021750179333613100', ], (Ecu.eps, 0x712, None): [ b'\xf1\x875Q0909143M \xf1\x892041\xf1\x820529A6060603', + b'\xf1\x875Q0909144AB\xf1\x891082\xf1\x82\x0521A60604A1', + b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567A6000600', b'\xf1\x875QF909144B \xf1\x895582\xf1\x82\00571A60634A1', b'\xf1\x875QM909144B \xf1\x891081\xf1\x82\x0521A60604A1', b'\xf1\x875QM909144C \xf1\x891082\xf1\x82\x0521A60604A1', diff --git a/selfdrive/common/SConscript b/selfdrive/common/SConscript deleted file mode 100644 index e53cb7615d..0000000000 --- a/selfdrive/common/SConscript +++ /dev/null @@ -1,35 +0,0 @@ -Import('env', 'arch', 'SHARED') - -if SHARED: - fxn = env.SharedLibrary -else: - fxn = env.Library - -common_libs = [ - 'params.cc', - 'statlog.cc', - 'swaglog.cc', - 'util.cc', - 'gpio.cc', - 'i2c.cc', - 'watchdog.cc', -] - -_common = fxn('common', common_libs, LIBS="json11") - -files = [ - 'clutil.cc', - 'visionimg.cc', -] - -if arch == "larch64": - _gpu_libs = ["GLESv2"] -else: - _gpu_libs = ["GL"] - -_gpucommon = fxn('gpucommon', files, LIBS=_gpu_libs) -Export('_common', '_gpucommon', '_gpu_libs') - -if GetOption('test'): - env.Program('tests/test_util', ['tests/test_util.cc'], LIBS=[_common]) - env.Program('tests/test_swaglog', ['tests/test_swaglog.cc'], LIBS=[_common, 'json11', 'zmq', 'pthread']) diff --git a/selfdrive/common/version.h b/selfdrive/common/version.h deleted file mode 100644 index 1fcbdac271..0000000000 --- a/selfdrive/common/version.h +++ /dev/null @@ -1 +0,0 @@ -#define COMMA_VERSION "0.8.14" diff --git a/selfdrive/common/visionimg.cc b/selfdrive/common/visionimg.cc deleted file mode 100644 index b67f0e202d..0000000000 --- a/selfdrive/common/visionimg.cc +++ /dev/null @@ -1,14 +0,0 @@ -#include "selfdrive/common/visionimg.h" - -#include - -EGLImageTexture::EGLImageTexture(const VisionBuf *buf) { - glGenTextures(1, &frame_tex); - glBindTexture(GL_TEXTURE_2D, frame_tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, buf->width, buf->height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); - glGenerateMipmap(GL_TEXTURE_2D); -} - -EGLImageTexture::~EGLImageTexture() { - glDeleteTextures(1, &frame_tex); -} diff --git a/selfdrive/common/visionimg.h b/selfdrive/common/visionimg.h deleted file mode 100644 index 0cb41a32b8..0000000000 --- a/selfdrive/common/visionimg.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "cereal/visionipc/visionbuf.h" - -#ifdef __APPLE__ -#include -#else -#include -#endif - -class EGLImageTexture { - public: - EGLImageTexture(const VisionBuf *buf); - ~EGLImageTexture(); - GLuint frame_tex = 0; -}; diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 6dff3bb2e1..033072aa73 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import os import math -from numbers import Number +from typing import SupportsFloat from cereal import car, log from common.numpy_fast import clip @@ -11,12 +11,13 @@ from common.params import Params, put_nonblocking import cereal.messaging as messaging from common.conversions import Conversions as CV from panda import ALTERNATIVE_EXPERIENCE -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car.car_helpers import get_car, get_startup_event, get_one_can from selfdrive.controls.lib.lane_planner import CAMERA_OFFSET from selfdrive.controls.lib.drive_helpers import update_v_cruise, initialize_v_cruise from selfdrive.controls.lib.drive_helpers import get_lag_adjusted_curvature +from selfdrive.controls.lib.latcontrol import LatControl from selfdrive.controls.lib.longcontrol import LongControl from selfdrive.controls.lib.latcontrol_pid import LatControlPID from selfdrive.controls.lib.latcontrol_indi import LatControlINDI @@ -26,7 +27,7 @@ from selfdrive.controls.lib.events import Events, ET from selfdrive.controls.lib.alertmanager import AlertManager, set_offroad_alert from selfdrive.controls.lib.vehicle_model import VehicleModel from selfdrive.locationd.calibrationd import Calibration -from selfdrive.hardware import HARDWARE, TICI +from system.hardware import HARDWARE from selfdrive.manager.process_config import managed_processes SOFT_DISABLE_TIME = 3 # seconds @@ -67,17 +68,14 @@ class Controls: self.pm = messaging.PubMaster(['sendcan', 'controlsState', 'carState', 'carControl', 'carEvents', 'carParams']) - self.camera_packets = ["roadCameraState", "driverCameraState"] - if TICI: - self.camera_packets.append("wideRoadCameraState") + self.camera_packets = ["roadCameraState", "driverCameraState", "wideRoadCameraState"] self.can_sock = can_sock if can_sock is None: can_timeout = None if os.environ.get('NO_CAN_TIMEOUT', False) else 20 self.can_sock = messaging.sub_sock('can', timeout=can_timeout) - if TICI: - self.log_sock = messaging.sub_sock('androidLog') + self.log_sock = messaging.sub_sock('androidLog') if CI is None: # wait for one pandaState and one CAN packet @@ -137,6 +135,7 @@ class Controls: self.LoC = LongControl(self.CP) self.VM = VehicleModel(self.CP) + self.LaC: LatControl if self.CP.steerControlType == car.CarParams.SteerControlType.angle: self.LaC = LatControlAngle(self.CP, self.CI) elif self.CP.lateralTuning.which() == 'pid': @@ -165,6 +164,8 @@ class Controls: self.logged_comm_issue = None self.button_timers = {ButtonEvent.Type.decelCruise: 0, ButtonEvent.Type.accelCruise: 0} self.last_actuators = car.CarControl.Actuators.new_message() + self.desired_curvature = 0.0 + self.desired_curvature_rate = 0.0 # TODO: no longer necessary, aside from process replay self.sm['liveParameters'].valid = True @@ -287,6 +288,7 @@ class Controls: # Handle HW and system malfunctions # Order is very intentional here. Be careful when modifying this. + # All events here should at least have NO_ENTRY and SOFT_DISABLE. num_events = len(self.events) not_running = {p.name for p in self.sm['managerState'].processes if not p.running and p.shouldBeRunning} @@ -343,7 +345,7 @@ class Controls: # Check for mismatch between openpilot and car's PCM cruise_mismatch = CS.cruiseState.enabled and (not self.enabled or not self.CP.pcmCruise) self.cruise_mismatch_counter = self.cruise_mismatch_counter + 1 if cruise_mismatch else 0 - if self.cruise_mismatch_counter > int(3. / DT_CTRL): + if self.cruise_mismatch_counter > int(6. / DT_CTRL): self.events.add(EventName.cruiseMismatch) # Check for FCW @@ -353,17 +355,16 @@ class Controls: if planner_fcw or model_fcw: self.events.add(EventName.fcw) - if TICI: - for m in messaging.drain_sock(self.log_sock, wait_for_one=False): - try: - msg = m.androidLog.message - if any(err in msg for err in ("ERROR_CRC", "ERROR_ECC", "ERROR_STREAM_UNDERFLOW", "APPLY FAILED")): - csid = msg.split("CSID:")[-1].split(" ")[0] - evt = CSID_MAP.get(csid, None) - if evt is not None: - self.events.add(evt) - except UnicodeDecodeError: - pass + for m in messaging.drain_sock(self.log_sock, wait_for_one=False): + try: + msg = m.androidLog.message + if any(err in msg for err in ("ERROR_CRC", "ERROR_ECC", "ERROR_STREAM_UNDERFLOW", "APPLY FAILED")): + csid = msg.split("CSID:")[-1].split(" ")[0] + evt = CSID_MAP.get(csid, None) + if evt is not None: + self.events.add(evt) + except UnicodeDecodeError: + pass # TODO: fix simulator if not SIMULATION: @@ -438,7 +439,8 @@ class Controls: # if stock cruise is completely disabled, then we can use our own set speed logic if not self.CP.pcmCruise: - self.v_cruise_kph = update_v_cruise(self.v_cruise_kph, CS.buttonEvents, self.button_timers, self.enabled, self.is_metric) + self.v_cruise_kph = update_v_cruise(self.v_cruise_kph, CS.vEgo, CS.gasPressed, CS.buttonEvents, + self.button_timers, self.enabled, self.is_metric) else: if CS.cruiseState.available: self.v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH @@ -569,13 +571,13 @@ class Controls: actuators.accel = self.LoC.update(CC.longActive, CS, long_plan, pid_accel_limits, t_since_plan) # Steering PID loop and lateral MPC - desired_curvature, desired_curvature_rate = get_lag_adjusted_curvature(self.CP, CS.vEgo, - lat_plan.psis, - lat_plan.curvatures, - lat_plan.curvatureRates) + self.desired_curvature, self.desired_curvature_rate = get_lag_adjusted_curvature(self.CP, CS.vEgo, + lat_plan.psis, + lat_plan.curvatures, + lat_plan.curvatureRates) actuators.steer, actuators.steeringAngleDeg, lac_log = self.LaC.update(CC.latActive, CS, self.VM, params, - self.last_actuators, desired_curvature, - desired_curvature_rate, self.sm['liveLocationKalman']) + self.last_actuators, self.desired_curvature, + self.desired_curvature_rate, self.sm['liveLocationKalman']) else: lac_log = log.ControlsState.LateralDebugState.new_message() if self.sm.rcv_frame['testJoystick'] > 0: @@ -607,7 +609,7 @@ class Controls: # Ensure no NaNs/Infs for p in ACTUATOR_FIELDS: attr = getattr(actuators, p) - if not isinstance(attr, Number): + if not isinstance(attr, SupportsFloat): continue if not math.isfinite(attr): @@ -679,7 +681,7 @@ class Controls: if self.enabled: clear_event_types.add(ET.NO_ENTRY) - alerts = self.events.create_alerts(self.current_alert_types, [self.CP, self.sm, self.is_metric, self.soft_disable_timer]) + alerts = self.events.create_alerts(self.current_alert_types, [self.CP, CS, self.sm, self.is_metric, self.soft_disable_timer]) self.AM.add_many(self.sm.frame, alerts) current_alert = self.AM.process_alerts(self.sm.frame, clear_event_types) if current_alert: @@ -719,6 +721,8 @@ class Controls: controlsState.enabled = self.enabled controlsState.active = self.active controlsState.curvature = curvature + controlsState.desiredCurvature = self.desired_curvature + controlsState.desiredCurvatureRate = self.desired_curvature_rate controlsState.state = self.state controlsState.engageable = not self.events.any(ET.NO_ENTRY) controlsState.longControlState = self.LoC.long_control_state diff --git a/selfdrive/controls/lib/drive_helpers.py b/selfdrive/controls/lib/drive_helpers.py index a9725a475f..1fecdd7c63 100644 --- a/selfdrive/controls/lib/drive_helpers.py +++ b/selfdrive/controls/lib/drive_helpers.py @@ -1,8 +1,9 @@ import math + from cereal import car +from common.conversions import Conversions as CV from common.numpy_fast import clip, interp from common.realtime import DT_MDL -from common.conversions import Conversions as CV from selfdrive.modeld.constants import T_IDXS # WARNING: this value was determined based on the model's training distribution, @@ -19,14 +20,15 @@ CAR_ROTATION_RADIUS = 0.0 # EU guidelines MAX_LATERAL_JERK = 5.0 +ButtonType = car.CarState.ButtonEvent.Type CRUISE_LONG_PRESS = 50 CRUISE_NEAREST_FUNC = { - car.CarState.ButtonEvent.Type.accelCruise: math.ceil, - car.CarState.ButtonEvent.Type.decelCruise: math.floor, + ButtonType.accelCruise: math.ceil, + ButtonType.decelCruise: math.floor, } CRUISE_INTERVAL_SIGN = { - car.CarState.ButtonEvent.Type.accelCruise: +1, - car.CarState.ButtonEvent.Type.decelCruise: -1, + ButtonType.accelCruise: +1, + ButtonType.decelCruise: -1, } @@ -36,11 +38,21 @@ class MPC_COST_LAT: STEER_RATE = 1.0 +def apply_deadzone(error, deadzone): + if error > deadzone: + error -= deadzone + elif error < - deadzone: + error += deadzone + else: + error = 0. + return error + + def rate_limit(new_value, last_value, dw_step, up_step): return clip(new_value, last_value + dw_step, last_value + up_step) -def update_v_cruise(v_cruise_kph, buttonEvents, button_timers, enabled, metric): +def update_v_cruise(v_cruise_kph, v_ego, gas_pressed, buttonEvents, button_timers, enabled, metric): # handle button presses. TODO: this should be in state_control, but a decelCruise press # would have the effect of both enabling and changing speed is checked after the state transition if not enabled: @@ -55,7 +67,7 @@ def update_v_cruise(v_cruise_kph, buttonEvents, button_timers, enabled, metric): for b in buttonEvents: if b.type.raw in button_timers and not b.pressed: if button_timers[b.type.raw] > CRUISE_LONG_PRESS: - return v_cruise_kph # end long press + return v_cruise_kph # end long press button_type = b.type.raw break else: @@ -67,10 +79,15 @@ def update_v_cruise(v_cruise_kph, buttonEvents, button_timers, enabled, metric): if button_type: v_cruise_delta = v_cruise_delta * (5 if long_press else 1) - if long_press and v_cruise_kph % v_cruise_delta != 0: # partial interval + if long_press and v_cruise_kph % v_cruise_delta != 0: # partial interval v_cruise_kph = CRUISE_NEAREST_FUNC[button_type](v_cruise_kph / v_cruise_delta) * v_cruise_delta else: v_cruise_kph += v_cruise_delta * CRUISE_INTERVAL_SIGN[button_type] + + # If set is pressed while overriding, clip cruise speed to minimum of vEgo + if gas_pressed and button_type in (ButtonType.decelCruise, ButtonType.setCruise): + v_cruise_kph = max(v_cruise_kph, v_ego * CV.MS_TO_KPH) + v_cruise_kph = clip(round(v_cruise_kph, 1), V_CRUISE_MIN, V_CRUISE_MAX) return v_cruise_kph @@ -79,7 +96,7 @@ def update_v_cruise(v_cruise_kph, buttonEvents, button_timers, enabled, metric): def initialize_v_cruise(v_ego, buttonEvents, v_cruise_last): for b in buttonEvents: # 250kph or above probably means we never had a set speed - if b.type in (car.CarState.ButtonEvent.Type.accelCruise, car.CarState.ButtonEvent.Type.resumeCruise) and v_cruise_last < 250: + if b.type in (ButtonType.accelCruise, ButtonType.resumeCruise) and v_cruise_last < 250: return v_cruise_last return int(round(clip(v_ego * CV.MS_TO_KPH, V_CRUISE_ENABLE_MIN, V_CRUISE_MAX))) @@ -90,26 +107,27 @@ def get_lag_adjusted_curvature(CP, v_ego, psis, curvatures, curvature_rates): psis = [0.0]*CONTROL_N curvatures = [0.0]*CONTROL_N curvature_rates = [0.0]*CONTROL_N + v_ego = max(v_ego, 0.1) # TODO this needs more thought, use .2s extra for now to estimate other delays delay = CP.steerActuatorDelay + .2 - current_curvature = curvatures[0] - psi = interp(delay, T_IDXS[:CONTROL_N], psis) - desired_curvature_rate = curvature_rates[0] # MPC can plan to turn the wheel and turn back before t_delay. This means # in high delay cases some corrections never even get commanded. So just use # psi to calculate a simple linearization of desired curvature - curvature_diff_from_psi = psi / (max(v_ego, 1e-1) * delay) - current_curvature - desired_curvature = current_curvature + 2 * curvature_diff_from_psi + current_curvature_desired = curvatures[0] + psi = interp(delay, T_IDXS[:CONTROL_N], psis) + average_curvature_desired = psi / (v_ego * delay) + desired_curvature = 2 * average_curvature_desired - current_curvature_desired - v_ego = max(v_ego, 0.1) + # This is the "desired rate of the setpoint" not an actual desired rate + desired_curvature_rate = curvature_rates[0] max_curvature_rate = MAX_LATERAL_JERK / (v_ego**2) safe_desired_curvature_rate = clip(desired_curvature_rate, -max_curvature_rate, max_curvature_rate) safe_desired_curvature = clip(desired_curvature, - current_curvature - max_curvature_rate * DT_MDL, - current_curvature + max_curvature_rate * DT_MDL) + current_curvature_desired - max_curvature_rate * DT_MDL, + current_curvature_desired + max_curvature_rate * DT_MDL) return safe_desired_curvature, safe_desired_curvature_rate diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index 12a42a7e3c..cc63d4995d 100644 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -1,3 +1,4 @@ +import math import os from enum import IntEnum from typing import Dict, Union, Callable, List, Optional @@ -7,7 +8,7 @@ import cereal.messaging as messaging from common.conversions import Conversions as CV from common.realtime import DT_CTRL from selfdrive.locationd.calibrationd import MIN_SPEED_FILTER -from selfdrive.version import get_short_branch +from system.version import get_short_branch AlertSize = log.ControlsState.AlertSize AlertStatus = log.ControlsState.AlertStatus @@ -135,12 +136,16 @@ class Alert: return f"{self.alert_text_1}/{self.alert_text_2} {self.priority} {self.visual_alert} {self.audible_alert}" def __gt__(self, alert2) -> bool: + if not isinstance(alert2, Alert): + return False return self.priority > alert2.priority class NoEntryAlert(Alert): - def __init__(self, alert_text_2: str, visual_alert: car.CarControl.HUDControl.VisualAlert=VisualAlert.none): - super().__init__("openpilot Unavailable", alert_text_2, AlertStatus.normal, + def __init__(self, alert_text_2: str, + alert_text_1: str = "openpilot Unavailable", + visual_alert: car.CarControl.HUDControl.VisualAlert=VisualAlert.none): + super().__init__(alert_text_1, alert_text_2, AlertStatus.normal, AlertSize.mid, Priority.LOW, visual_alert, AudibleAlert.refuse, 3.) @@ -199,35 +204,35 @@ def get_display_speed(speed_ms: float, metric: bool) -> str: # ********** alert callback functions ********** -AlertCallbackType = Callable[[car.CarParams, messaging.SubMaster, bool, int], Alert] +AlertCallbackType = Callable[[car.CarParams, car.CarState, messaging.SubMaster, bool, int], Alert] def soft_disable_alert(alert_text_2: str) -> AlertCallbackType: - def func(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: + def func(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: if soft_disable_time < int(0.5 / DT_CTRL): return ImmediateDisableAlert(alert_text_2) return SoftDisableAlert(alert_text_2) return func def user_soft_disable_alert(alert_text_2: str) -> AlertCallbackType: - def func(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: + def func(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: if soft_disable_time < int(0.5 / DT_CTRL): return ImmediateDisableAlert(alert_text_2) return UserSoftDisableAlert(alert_text_2) return func -def startup_master_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: +def startup_master_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: branch = get_short_branch("") if "REPLAY" in os.environ: branch = "replay" return StartupAlert("WARNING: This branch is not tested", branch, alert_status=AlertStatus.userPrompt) -def below_engage_speed_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: +def below_engage_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: return NoEntryAlert(f"Speed Below {get_display_speed(CP.minEnableSpeed, metric)}") -def below_steer_speed_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: +def below_steer_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: return Alert( f"Steer Unavailable Below {get_display_speed(CP.minSteerSpeed, metric)}", "", @@ -235,7 +240,7 @@ def below_steer_speed_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: Priority.MID, VisualAlert.steerRequired, AudibleAlert.prompt, 0.4) -def calibration_incomplete_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: +def calibration_incomplete_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: return Alert( "Calibration in Progress: %d%%" % sm['liveCalibration'].calPerc, f"Drive Above {get_display_speed(MIN_SPEED_FILTER, metric)}", @@ -243,7 +248,7 @@ def calibration_incomplete_alert(CP: car.CarParams, sm: messaging.SubMaster, met Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2) -def no_gps_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: +def no_gps_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: gps_integrated = sm['peripheralState'].pandaType in (log.PandaState.PandaType.uno, log.PandaState.PandaType.dos) return Alert( "Poor GPS reception", @@ -253,39 +258,72 @@ def no_gps_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_ # *** debug alerts *** -def out_of_space_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: +def out_of_space_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: full_perc = round(100. - sm['deviceState'].freeSpacePercent) return NormalPermanentAlert("Out of Storage", f"{full_perc}% full") -def overheat_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: +def posenet_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: + mdl = sm['modelV2'].velocity.x[0] if len(sm['modelV2'].velocity.x) else math.nan + err = CS.vEgo - mdl + msg = f"Speed Error: {err:.1f} m/s" + return NoEntryAlert(msg, alert_text_1="Posenet Speed Invalid") + + +def process_not_running_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: + not_running = [p.name for p in sm['managerState'].processes if not p.running and p.shouldBeRunning] + msg = ', '.join(not_running) + return NoEntryAlert(msg, alert_text_1="Process Not Running") + + +def comm_issue_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: + bs = [s for s in sm.data.keys() if not sm.all_checks([s, ])] + msg = ', '.join(bs[:4]) # can't fit too many on one line + return NoEntryAlert(msg, alert_text_1="Communication Issue Between Processes") + + +def camera_malfunction_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: + all_cams = ('roadCameraState', 'driverCameraState', 'wideRoadCameraState') + bad_cams = [s.replace('State', '') for s in all_cams if s in sm.data.keys() and not sm.all_checks([s, ])] + return NormalPermanentAlert("Camera Malfunction", ', '.join(bad_cams)) + + +def calibration_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: + rpy = sm['liveCalibration'].rpyCalib + yaw = math.degrees(rpy[2] if len(rpy) == 3 else math.nan) + pitch = math.degrees(rpy[1] if len(rpy) == 3 else math.nan) + angles = f"Pitch: {pitch:.1f}°, Yaw: {yaw:.1f}°" + return NormalPermanentAlert("Calibration Invalid", angles) + + +def overheat_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: cpu = max(sm['deviceState'].cpuTempC, default=0.) gpu = max(sm['deviceState'].gpuTempC, default=0.) temp = max((cpu, gpu, sm['deviceState'].memoryTempC)) - return NormalPermanentAlert("System Overheated", f"{temp} °C") + return NormalPermanentAlert("System Overheated", f"{temp:.0f} °C") -def low_memory_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: +def low_memory_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: return NormalPermanentAlert("Low Memory", f"{sm['deviceState'].memoryUsagePercent}% used") -def high_cpu_usage_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: +def high_cpu_usage_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: x = max(sm['deviceState'].cpuUsagePercent, default=0.) return NormalPermanentAlert("High CPU Usage", f"{x}% used") -def modeld_lagging_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: - return NormalPermanentAlert("Driving model lagging", f"{sm['modelV2'].frameDropPerc}% frames dropped") +def modeld_lagging_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: + return NormalPermanentAlert("Driving Model Lagging", f"{sm['modelV2'].frameDropPerc:.1f}% frames dropped") -def wrong_car_mode_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: +def wrong_car_mode_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: text = "Cruise Mode Disabled" if CP.carName == "honda": text = "Main Switch Off" return NoEntryAlert(text) -def joystick_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: +def joystick_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: axes = sm['testJoystick'].axes gb, steer = list(axes)[:2] if len(axes) else (0., 0.) vals = f"Gas: {round(gb * 100.)}%, Steer: {round(steer * 100.)}%" @@ -519,11 +557,15 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { # Camera is not outputting frames EventName.cameraMalfunction: { - ET.PERMANENT: NormalPermanentAlert("Camera Malfunction", "Likely Hardware Issue"), + ET.PERMANENT: camera_malfunction_alert, + ET.SOFT_DISABLE: soft_disable_alert("Camera Malfunction"), + ET.NO_ENTRY: NoEntryAlert("Camera Malfunction: Reboot Your Device"), }, # Camera framerate too low EventName.cameraFrameRate: { ET.PERMANENT: NormalPermanentAlert("Camera Frame Rate Low", "Reboot your Device"), + ET.SOFT_DISABLE: soft_disable_alert("Camera Frame Rate Low"), + ET.NO_ENTRY: NoEntryAlert("Camera Frame Rate Low: Reboot Your Device"), }, # Unused @@ -651,7 +693,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { # and attaching while making sure the device is pointed straight forward and is level. # See https://comma.ai/setup for more information EventName.calibrationInvalid: { - ET.PERMANENT: NormalPermanentAlert("Calibration Invalid", "Remount Device and Recalibrate"), + ET.PERMANENT: calibration_invalid_alert, ET.SOFT_DISABLE: soft_disable_alert("Calibration Invalid: Remount Device & Recalibrate"), ET.NO_ENTRY: NoEntryAlert("Calibration Invalid: Remount Device & Recalibrate"), }, @@ -688,7 +730,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { # ten times the regular interval, or the average interval is more than 10% too high. EventName.commIssue: { ET.SOFT_DISABLE: soft_disable_alert("Communication Issue between Processes"), - ET.NO_ENTRY: NoEntryAlert("Communication Issue between Processes"), + ET.NO_ENTRY: comm_issue_alert, }, EventName.commIssueAvgFreq: { ET.SOFT_DISABLE: soft_disable_alert("Low Communication Rate between Processes"), @@ -702,7 +744,8 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { # Thrown when manager detects a service exited unexpectedly while driving EventName.processNotRunning: { - ET.NO_ENTRY: NoEntryAlert("System Malfunction: Reboot Your Device"), + ET.NO_ENTRY: process_not_running_alert, + ET.SOFT_DISABLE: soft_disable_alert("Process Not Running"), }, EventName.radarFault: { @@ -714,8 +757,8 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { # is not processing frames fast enough they have to be dropped. This alert is # thrown when over 20% of frames are dropped. EventName.modeldLagging: { - ET.SOFT_DISABLE: soft_disable_alert("Driving model lagging"), - ET.NO_ENTRY: NoEntryAlert("Driving model lagging"), + ET.SOFT_DISABLE: soft_disable_alert("Driving Model Lagging"), + ET.NO_ENTRY: NoEntryAlert("Driving Model Lagging"), ET.PERMANENT: modeld_lagging_alert, }, @@ -725,8 +768,8 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { # usually means the model has trouble understanding the scene. This is used # as a heuristic to warn the driver. EventName.posenetInvalid: { - ET.SOFT_DISABLE: soft_disable_alert("Model Output Uncertain"), - ET.NO_ENTRY: NoEntryAlert("Model Output Uncertain"), + ET.SOFT_DISABLE: soft_disable_alert("Posenet Speed Invalid"), + ET.NO_ENTRY: posenet_invalid_alert, }, # When the localizer detects an acceleration of more than 40 m/s^2 (~4G) we @@ -850,9 +893,9 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { # are received on the car side this usually means the relay hasn't opened correctly # and this alert is thrown. EventName.relayMalfunction: { - ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Harness Malfunction"), - ET.PERMANENT: NormalPermanentAlert("Harness Malfunction", "Check Hardware"), - ET.NO_ENTRY: NoEntryAlert("Harness Malfunction"), + ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Harness Relay Malfunction"), + ET.PERMANENT: NormalPermanentAlert("Harness Relay Malfunction", "Check Hardware"), + ET.NO_ENTRY: NoEntryAlert("Harness Relay Malfunction"), }, EventName.noTarget: { diff --git a/selfdrive/controls/lib/lane_planner.py b/selfdrive/controls/lib/lane_planner.py index aedf61a073..1facb66d63 100644 --- a/selfdrive/controls/lib/lane_planner.py +++ b/selfdrive/controls/lib/lane_planner.py @@ -3,20 +3,14 @@ from cereal import log from common.filter_simple import FirstOrderFilter from common.numpy_fast import interp from common.realtime import DT_MDL -from selfdrive.hardware import TICI -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog TRAJECTORY_SIZE = 33 # camera offset is meters from center car to camera -# model path is in the frame of the camera. Empirically -# the model knows the difference between TICI and EON -# so a path offset is not needed +# model path is in the frame of the camera PATH_OFFSET = 0.00 -if TICI: - CAMERA_OFFSET = 0.04 -else: - CAMERA_OFFSET = 0.0 +CAMERA_OFFSET = 0.04 class LanePlanner: diff --git a/selfdrive/controls/lib/latcontrol_indi.py b/selfdrive/controls/lib/latcontrol_indi.py index b5041eb172..79c881d11b 100644 --- a/selfdrive/controls/lib/latcontrol_indi.py +++ b/selfdrive/controls/lib/latcontrol_indi.py @@ -78,6 +78,7 @@ class LatControlINDI(LatControl): steers_des += math.radians(params.angleOffsetDeg) indi_log.steeringAngleDesiredDeg = math.degrees(steers_des) + # desired rate is the desired rate of change in the setpoint, not the absolute desired curvature rate_des = VM.get_steer_from_curvature(-desired_curvature_rate, CS.vEgo, 0) indi_log.steeringRateDesiredDeg = math.degrees(rate_des) diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index a73744de74..f72ffc4b88 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -4,6 +4,7 @@ from cereal import log from common.numpy_fast import interp from selfdrive.controls.lib.latcontrol import LatControl, MIN_STEER_SPEED from selfdrive.controls.lib.pid import PIDController +from selfdrive.controls.lib.drive_helpers import apply_deadzone from selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY # At higher speeds (25+mph) we can assume: @@ -18,23 +19,29 @@ from selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY # move it at all, this is compensated for too. -LOW_SPEED_FACTOR = 200 -JERK_THRESHOLD = 0.2 +FRICTION_THRESHOLD = 0.2 + + +def set_torque_tune(tune, MAX_LAT_ACCEL=2.5, FRICTION=0.01, steering_angle_deadzone_deg=0.0): + tune.init('torque') + tune.torque.useSteeringAngle = True + tune.torque.kp = 1.0 / MAX_LAT_ACCEL + tune.torque.kf = 1.0 / MAX_LAT_ACCEL + tune.torque.ki = 0.1 / MAX_LAT_ACCEL + tune.torque.friction = FRICTION + tune.torque.steeringAngleDeadzoneDeg = steering_angle_deadzone_deg class LatControlTorque(LatControl): def __init__(self, CP, CI): super().__init__(CP, CI) - self.CP = CP self.pid = PIDController(CP.lateralTuning.torque.kp, CP.lateralTuning.torque.ki, k_f=CP.lateralTuning.torque.kf, pos_limit=self.steer_max, neg_limit=-self.steer_max) self.get_steer_feedforward = CI.get_steer_feedforward_function() self.use_steering_angle = CP.lateralTuning.torque.useSteeringAngle self.friction = CP.lateralTuning.torque.friction - - def reset(self): - super().reset() - self.pid.reset() + self.kf = CP.lateralTuning.torque.kf + self.steering_angle_deadzone_deg = CP.lateralTuning.torque.steeringAngleDeadzoneDeg def update(self, active, CS, VM, params, last_actuators, desired_curvature, desired_curvature_rate, llk): pid_log = log.ControlsState.LateralTorqueState.new_message() @@ -42,29 +49,38 @@ class LatControlTorque(LatControl): if CS.vEgo < MIN_STEER_SPEED or not active: output_torque = 0.0 pid_log.active = False - self.pid.reset() else: if self.use_steering_angle: actual_curvature = -VM.calc_curvature(math.radians(CS.steeringAngleDeg - params.angleOffsetDeg), CS.vEgo, params.roll) + curvature_deadzone = abs(VM.calc_curvature(math.radians(self.steering_angle_deadzone_deg), CS.vEgo, 0.0)) else: - actual_curvature = llk.angularVelocityCalibrated.value[2] / CS.vEgo + actual_curvature_vm = -VM.calc_curvature(math.radians(CS.steeringAngleDeg - params.angleOffsetDeg), CS.vEgo, params.roll) + actual_curvature_llk = llk.angularVelocityCalibrated.value[2] / CS.vEgo + actual_curvature = interp(CS.vEgo, [2.0, 5.0], [actual_curvature_vm, actual_curvature_llk]) + curvature_deadzone = 0.0 desired_lateral_accel = desired_curvature * CS.vEgo ** 2 - desired_lateral_jerk = desired_curvature_rate * CS.vEgo ** 2 + + # desired rate is the desired rate of change in the setpoint, not the absolute desired curvature + #desired_lateral_jerk = desired_curvature_rate * CS.vEgo ** 2 actual_lateral_accel = actual_curvature * CS.vEgo ** 2 + lateral_accel_deadzone = curvature_deadzone * CS.vEgo ** 2 + - setpoint = desired_lateral_accel + LOW_SPEED_FACTOR * desired_curvature - measurement = actual_lateral_accel + LOW_SPEED_FACTOR * actual_curvature - error = setpoint - measurement + low_speed_factor = interp(CS.vEgo, [0, 15], [500, 0]) + setpoint = desired_lateral_accel + low_speed_factor * desired_curvature + measurement = actual_lateral_accel + low_speed_factor * actual_curvature + error = apply_deadzone(setpoint - measurement, lateral_accel_deadzone) pid_log.error = error ff = desired_lateral_accel - params.roll * ACCELERATION_DUE_TO_GRAVITY # convert friction into lateral accel units for feedforward - friction_compensation = interp(desired_lateral_jerk, [-JERK_THRESHOLD, JERK_THRESHOLD], [-self.friction, self.friction]) - ff += friction_compensation / self.CP.lateralTuning.torque.kf + friction_compensation = interp(error, [-FRICTION_THRESHOLD, FRICTION_THRESHOLD], [-self.friction, self.friction]) + ff += friction_compensation / self.kf + freeze_integrator = CS.steeringRateLimited or CS.steeringPressed or CS.vEgo < 5 output_torque = self.pid.update(error, - override=CS.steeringPressed, feedforward=ff, + feedforward=ff, speed=CS.vEgo, - freeze_integrator=CS.steeringRateLimited) + freeze_integrator=freeze_integrator) pid_log.active = True pid_log.p = self.pid.p @@ -73,6 +89,8 @@ class LatControlTorque(LatControl): pid_log.f = self.pid.f pid_log.output = -output_torque pid_log.saturated = self._check_saturation(self.steer_max - abs(output_torque) < 1e-3, CS) + pid_log.actualLateralAccel = actual_lateral_accel + pid_log.desiredLateralAccel = desired_lateral_accel # TODO left is positive in this convention return -output_torque, 0.0, pid_log diff --git a/selfdrive/controls/lib/lateral_planner.py b/selfdrive/controls/lib/lateral_planner.py index f60b3159b9..019a19fb1d 100644 --- a/selfdrive/controls/lib/lateral_planner.py +++ b/selfdrive/controls/lib/lateral_planner.py @@ -1,7 +1,7 @@ import numpy as np from common.realtime import sec_since_boot, DT_MDL from common.numpy_fast import interp -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog from selfdrive.controls.lib.lateral_mpc_lib.lat_mpc import LateralMpc from selfdrive.controls.lib.drive_helpers import CONTROL_N, MPC_COST_LAT, LAT_MPC_N, CAR_ROTATION_RADIUS from selfdrive.controls.lib.lane_planner import LanePlanner, TRAJECTORY_SIZE @@ -11,13 +11,12 @@ from cereal import log class LateralPlanner: - def __init__(self, CP, use_lanelines=True, wide_camera=False): + def __init__(self, use_lanelines=True, wide_camera=False): self.use_lanelines = use_lanelines self.LP = LanePlanner(wide_camera) self.DH = DesireHelper() self.last_cloudlog_t = 0 - self.steer_rate_cost = CP.steerRateCost self.solution_invalid_cnt = 0 self.path_xyz = np.zeros((TRAJECTORY_SIZE, 3)) @@ -59,13 +58,12 @@ class LateralPlanner: # Calculate final driving path and set MPC costs if self.use_lanelines: d_path_xyz = self.LP.get_d_path(v_ego, self.t_idxs, self.path_xyz) - self.lat_mpc.set_weights(MPC_COST_LAT.PATH, MPC_COST_LAT.HEADING, self.steer_rate_cost) + self.lat_mpc.set_weights(MPC_COST_LAT.PATH, MPC_COST_LAT.HEADING, MPC_COST_LAT.STEER_RATE) else: d_path_xyz = self.path_xyz - path_cost = np.clip(abs(self.path_xyz[0, 1] / self.path_xyz_stds[0, 1]), 0.5, 1.5) * MPC_COST_LAT.PATH # Heading cost is useful at low speed, otherwise end of plan can be off-heading - heading_cost = interp(v_ego, [5.0, 10.0], [MPC_COST_LAT.HEADING, 0.0]) - self.lat_mpc.set_weights(path_cost, heading_cost, self.steer_rate_cost) + heading_cost = interp(v_ego, [5.0, 10.0], [MPC_COST_LAT.HEADING, 0.15]) + self.lat_mpc.set_weights(MPC_COST_LAT.PATH, heading_cost, MPC_COST_LAT.STEER_RATE) y_pts = np.interp(v_ego * self.t_idxs[:LAT_MPC_N + 1], np.linalg.norm(d_path_xyz, axis=1), d_path_xyz[:, 1]) heading_pts = np.interp(v_ego * self.t_idxs[:LAT_MPC_N + 1], np.linalg.norm(self.path_xyz, axis=1), self.plan_yaw) @@ -80,6 +78,9 @@ class LateralPlanner: y_pts, heading_pts) # init state for next + # mpc.u_sol is the desired curvature rate given x0 curv state. + # with x0[3] = measured_curvature, this would be the actual desired rate. + # instead, interpolate x_sol so that x0[3] is the desired curvature for lat_control. self.x0[3] = interp(DT_MDL, self.t_idxs[:LAT_MPC_N + 1], self.lat_mpc.x_sol[:, 3]) # Check for infeasible MPC solution diff --git a/selfdrive/controls/lib/longcontrol.py b/selfdrive/controls/lib/longcontrol.py index f2cd282198..e9458607d5 100644 --- a/selfdrive/controls/lib/longcontrol.py +++ b/selfdrive/controls/lib/longcontrol.py @@ -1,7 +1,7 @@ from cereal import car from common.numpy_fast import clip, interp from common.realtime import DT_CTRL -from selfdrive.controls.lib.drive_helpers import CONTROL_N +from selfdrive.controls.lib.drive_helpers import CONTROL_N, apply_deadzone from selfdrive.controls.lib.pid import PIDController from selfdrive.modeld.constants import T_IDXS @@ -12,16 +12,6 @@ ACCEL_MIN_ISO = -3.5 # m/s^2 ACCEL_MAX_ISO = 2.0 # m/s^2 -def apply_deadzone(error, deadzone): - if error > deadzone: - error -= deadzone - elif error < - deadzone: - error += deadzone - else: - error = 0. - return error - - def long_control_state_trans(CP, active, long_control_state, v_ego, v_target, v_target_future, brake_pressed, cruise_standstill): """Update longitudinal control state machine""" diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py index b99ee9e9ac..bc0fc9fea6 100644 --- a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py +++ b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py @@ -4,7 +4,7 @@ import numpy as np from common.realtime import sec_since_boot from common.numpy_fast import clip, interp -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog from selfdrive.modeld.constants import index_function from selfdrive.controls.lib.radar_helpers import _LEAD_ACCEL_TAU diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/selfdrive/controls/lib/longitudinal_planner.py index 0d21c519a3..d4a6aaef8f 100755 --- a/selfdrive/controls/lib/longitudinal_planner.py +++ b/selfdrive/controls/lib/longitudinal_planner.py @@ -12,7 +12,7 @@ from selfdrive.controls.lib.longcontrol import LongCtrlState from selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import LongitudinalMpc from selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import T_IDXS as T_IDXS_MPC from selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX, CONTROL_N -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog LON_MPC_STEP = 0.2 # first step is 0.2s AWARENESS_DECEL = -0.2 # car smoothly decel at .2m/s^2 when user is distracted diff --git a/selfdrive/controls/lib/vehicle_model.py b/selfdrive/controls/lib/vehicle_model.py index 3f180d3252..0750384918 100755 --- a/selfdrive/controls/lib/vehicle_model.py +++ b/selfdrive/controls/lib/vehicle_model.py @@ -29,22 +29,22 @@ class VehicleModel: CP: Car Parameters """ # for math readability, convert long names car params into short names - self.m = CP.mass - self.j = CP.rotationalInertia - self.l = CP.wheelbase - self.aF = CP.centerToFront - self.aR = CP.wheelbase - CP.centerToFront - self.chi = CP.steerRatioRear - - self.cF_orig = CP.tireStiffnessFront - self.cR_orig = CP.tireStiffnessRear + self.m: float = CP.mass + self.j: float = CP.rotationalInertia + self.l: float = CP.wheelbase + self.aF: float = CP.centerToFront + self.aR: float = CP.wheelbase - CP.centerToFront + self.chi: float = CP.steerRatioRear + + self.cF_orig: float = CP.tireStiffnessFront + self.cR_orig: float = CP.tireStiffnessRear self.update_params(1.0, CP.steerRatio) def update_params(self, stiffness_factor: float, steer_ratio: float) -> None: """Update the vehicle model with a new stiffness factor and steer ratio""" - self.cF = stiffness_factor * self.cF_orig - self.cR = stiffness_factor * self.cR_orig - self.sR = steer_ratio + self.cF: float = stiffness_factor * self.cF_orig + self.cR: float = stiffness_factor * self.cR_orig + self.sR: float = steer_ratio def steady_state_sol(self, sa: float, u: float, roll: float) -> np.ndarray: """Returns the steady state solution. @@ -221,10 +221,10 @@ def dyn_ss_sol(sa: float, u: float, roll: float, VM: VehicleModel) -> np.ndarray """ A, B = create_dyn_state_matrices(u, VM) inp = np.array([[sa], [roll]]) - return -solve(A, B) @ inp + return -solve(A, B) @ inp # type: ignore -def calc_slip_factor(VM): +def calc_slip_factor(VM: VehicleModel) -> float: """The slip factor is a measure of how the curvature changes with speed it's positive for Oversteering vehicle, negative (usual case) otherwise. """ diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index 02f1c19a77..9356a55d84 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -2,28 +2,27 @@ from cereal import car from common.params import Params from common.realtime import Priority, config_realtime_process -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog from selfdrive.controls.lib.longitudinal_planner import Planner from selfdrive.controls.lib.lateral_planner import LateralPlanner -from selfdrive.hardware import TICI import cereal.messaging as messaging def plannerd_thread(sm=None, pm=None): - config_realtime_process(5 if TICI else 2, Priority.CTRL_LOW) + config_realtime_process(5, Priority.CTRL_LOW) cloudlog.info("plannerd is waiting for CarParams") params = Params() CP = car.CarParams.from_bytes(params.get("CarParams", block=True)) cloudlog.info("plannerd got CarParams: %s", CP.carName) - use_lanelines = not params.get_bool('EndToEndToggle') - wide_camera = params.get_bool('EnableWideCamera') if TICI else False + use_lanelines = False + wide_camera = params.get_bool('WideCameraOnly') cloudlog.event("e2e mode", on=use_lanelines) longitudinal_planner = Planner(CP) - lateral_planner = LateralPlanner(CP, use_lanelines=use_lanelines, wide_camera=wide_camera) + lateral_planner = LateralPlanner(use_lanelines=use_lanelines, wide_camera=wide_camera) if sm is None: sm = messaging.SubMaster(['carState', 'controlsState', 'radarState', 'modelV2'], diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index cae9474faf..b2c9914457 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -10,8 +10,7 @@ from common.params import Params from common.realtime import Ratekeeper, Priority, config_realtime_process from selfdrive.controls.lib.cluster.fastcluster_py import cluster_points_centroid from selfdrive.controls.lib.radar_helpers import Cluster, Track, RADAR_TO_CAMERA -from selfdrive.swaglog import cloudlog -from selfdrive.hardware import TICI +from system.swaglog import cloudlog class KalmanParams(): @@ -180,7 +179,7 @@ class RadarD(): # fuses camera and radar data for best lead detection def radard_thread(sm=None, pm=None, can_sock=None): - config_realtime_process(5 if TICI else 2, Priority.CTRL_LOW) + config_realtime_process(5, Priority.CTRL_LOW) # wait for stats about the car to come in from controls cloudlog.info("radard is waiting for CarParams") diff --git a/selfdrive/controls/tests/test_alerts.py b/selfdrive/controls/tests/test_alerts.py index 2502bed06b..2bd904b575 100755 --- a/selfdrive/controls/tests/test_alerts.py +++ b/selfdrive/controls/tests/test_alerts.py @@ -10,6 +10,7 @@ from common.basedir import BASEDIR from common.params import Params from selfdrive.controls.lib.events import Alert, EVENTS, ET from selfdrive.controls.lib.alertmanager import set_offroad_alert +from selfdrive.test.process_replay.process_replay import FakeSubMaster, CONFIGS AlertSize = log.ControlsState.AlertSize @@ -19,8 +20,7 @@ OFFROAD_ALERTS_PATH = os.path.join(BASEDIR, "selfdrive/controls/lib/alerts_offro ALERTS = [] for event_types in EVENTS.values(): for alert in event_types.values(): - if isinstance(alert, Alert): - ALERTS.append(alert) + ALERTS.append(alert) class TestAlerts(unittest.TestCase): @@ -30,6 +30,12 @@ class TestAlerts(unittest.TestCase): with open(OFFROAD_ALERTS_PATH) as f: cls.offroad_alerts = json.loads(f.read()) + # Create fake objects for callback + cls.CS = car.CarState.new_message() + cls.CP = car.CarParams.new_message() + cfg = [c for c in CONFIGS if c.proc_name == 'controlsd'][0] + cls.sm = FakeSubMaster(cfg.pub_sub.keys()) + def test_events_defined(self): # Ensure all events in capnp schema are defined in events.py events = car.CarEvent.EventName.schema.enumerants @@ -48,7 +54,7 @@ class TestAlerts(unittest.TestCase): max_text_width = 1920 - 300 # full screen width is useable, minus sidebar # TODO: get exact scale factor. found this empirically, works well enough - font_scale_factor = 1.85 # factor to scale from nanovg units to PIL + font_scale_factor = 1.55 # factor to scale from nanovg units to PIL draw = ImageDraw.Draw(Image.new('RGB', (0, 0))) @@ -59,6 +65,9 @@ class TestAlerts(unittest.TestCase): } for alert in ALERTS: + if not isinstance(alert, Alert): + alert = alert(self.CP, self.CS, self.sm, metric=False, soft_disable_time=100) + # for full size alerts, both text fields wrap the text, # so it's unlikely that they would go past the max width if alert.alert_size in (AlertSize.none, AlertSize.full): diff --git a/selfdrive/debug/can_printer.py b/selfdrive/debug/can_printer.py index 0aaaf1350b..3f991d4e6c 100755 --- a/selfdrive/debug/can_printer.py +++ b/selfdrive/debug/can_printer.py @@ -26,8 +26,9 @@ def can_printer(bus, max_msg, addr, ascii_decode): for addr in sorted(msgs.keys()): a = f"\"{msgs[addr][-1].decode('ascii', 'backslashreplace')}\"" if ascii_decode else "" x = binascii.hexlify(msgs[addr][-1]).decode('ascii') + freq = len(msgs[addr]) / (sec_since_boot() - start) if max_msg is None or addr < max_msg: - dd += "%04X(%4d)(%6d) %s %s\n" % (addr, addr, len(msgs[addr]), x.ljust(20), a) + dd += "%04X(%4d)(%6d)(%3dHz) %s %s\n" % (addr, addr, len(msgs[addr]), freq, x.ljust(20), a) print(dd) lp = sec_since_boot() diff --git a/selfdrive/debug/compare_fingerprints.py b/selfdrive/debug/compare_fingerprints.py deleted file mode 100755 index 5b7ba58b1e..0000000000 --- a/selfdrive/debug/compare_fingerprints.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python3 -# flake8: noqa - -# put 2 fingeprints and print the diffs -f1 = { -168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 701: 8, 703: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 746: 5, 752: 2, 754: 8, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 906: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 962: 8, 969: 4, 973: 8, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1537: 8, 1538: 8, 1562: 8 -} - -f2 = { -168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 515: 7, 516: 7, 517: 7, 518: 7, 520: 8, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 701: 8, 703: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 746: 5, 752: 2, 754: 8, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 906: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 962: 8, 969: 4, 973: 8, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8 -} - -for k in f1: - if k not in f2 or f1[k] != f2[k]: - print(k, "not in f2") - -for k in f2: - if k not in f1 or f2[k] != f1[k]: - print(k, "not in f1") diff --git a/selfdrive/debug/count_events.py b/selfdrive/debug/count_events.py index 8b32ce9d21..c3870e0f9e 100755 --- a/selfdrive/debug/count_events.py +++ b/selfdrive/debug/count_events.py @@ -4,6 +4,7 @@ from collections import Counter from pprint import pprint from tqdm import tqdm +from cereal.services import service_list from tools.lib.route import Route from tools.lib.logreader import LogReader @@ -13,6 +14,9 @@ if __name__ == "__main__": cnt_valid: Counter = Counter() cnt_events: Counter = Counter() + cams = [s for s in service_list if s.endswith('CameraState')] + cnt_cameras = dict.fromkeys(cams, 0) + for q in tqdm(r.qlog_paths()): if q is None: continue @@ -21,12 +25,21 @@ if __name__ == "__main__": if msg.which() == 'carEvents': for e in msg.carEvents: cnt_events[e.name] += 1 + elif msg.which() in cams: + cnt_cameras[msg.which()] += 1 + if not msg.valid: cnt_valid[msg.which()] += 1 + print("Events") pprint(cnt_events) - print("\n\n") + print("\n") print("Not valid") pprint(cnt_valid) + + print("\n") + print("Cameras") + for k, v in cnt_cameras.items(): + print(" ", k.ljust(20), v) diff --git a/selfdrive/debug/cycle_alerts.py b/selfdrive/debug/cycle_alerts.py index d097367474..b40c8e304c 100755 --- a/selfdrive/debug/cycle_alerts.py +++ b/selfdrive/debug/cycle_alerts.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 import time +import random from cereal import car, log import cereal.messaging as messaging @@ -7,9 +8,13 @@ from common.realtime import DT_CTRL from selfdrive.car.honda.interface import CarInterface from selfdrive.controls.lib.events import ET, Events from selfdrive.controls.lib.alertmanager import AlertManager +from selfdrive.manager.process_config import managed_processes EventName = car.CarEvent.EventName +def randperc() -> float: + return 100. * random.random() + def cycle_alerts(duration=200, is_metric=False): # all alerts #alerts = list(EVENTS.keys()) @@ -31,23 +36,25 @@ def cycle_alerts(duration=200, is_metric=False): # debug alerts alerts = [ - (EventName.highCpuUsage, ET.NO_ENTRY), - (EventName.lowMemory, ET.PERMANENT), - (EventName.overheat, ET.PERMANENT), - (EventName.outOfSpace, ET.PERMANENT), - (EventName.modeldLagging, ET.PERMANENT), + #(EventName.highCpuUsage, ET.NO_ENTRY), + #(EventName.lowMemory, ET.PERMANENT), + #(EventName.overheat, ET.PERMANENT), + #(EventName.outOfSpace, ET.PERMANENT), + #(EventName.modeldLagging, ET.PERMANENT), + #(EventName.processNotRunning, ET.NO_ENTRY), + #(EventName.commIssue, ET.NO_ENTRY), + #(EventName.calibrationInvalid, ET.PERMANENT), + (EventName.cameraMalfunction, ET.PERMANENT), + (EventName.cameraFrameRate, ET.PERMANENT), ] + cameras = ['roadCameraState', 'wideRoadCameraState', 'driverCameraState'] + + CS = car.CarState.new_message() CP = CarInterface.get_params("HONDA CIVIC 2016") sm = messaging.SubMaster(['deviceState', 'pandaStates', 'roadCameraState', 'modelV2', 'liveCalibration', - 'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman']) - - sm['deviceState'].freeSpacePercent = 55 - sm['deviceState'].memoryUsagePercent = 55 - sm['deviceState'].cpuTempC = [1, 2, 100] - sm['deviceState'].gpuTempC = [211, 2, 100] - sm['deviceState'].cpuUsagePercent = [23, 54] - sm['modelV2'].frameDropPerc = 20 + 'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman', + 'managerState'] + cameras) pm = messaging.PubMaster(['controlsState', 'pandaStates', 'deviceState']) @@ -60,7 +67,33 @@ def cycle_alerts(duration=200, is_metric=False): events.clear() events.add(alert) - a = events.create_alerts([et, ], [CP, sm, is_metric, 0]) + sm['deviceState'].freeSpacePercent = randperc() + sm['deviceState'].memoryUsagePercent = int(randperc()) + sm['deviceState'].cpuTempC = [randperc() for _ in range(3)] + sm['deviceState'].gpuTempC = [randperc() for _ in range(3)] + sm['deviceState'].cpuUsagePercent = [int(randperc()) for _ in range(8)] + sm['modelV2'].frameDropPerc = randperc() + + if random.random() > 0.25: + sm['modelV2'].velocity.x = [random.random(), ] + if random.random() > 0.25: + CS.vEgo = random.random() + + procs = [p.get_process_state_msg() for p in managed_processes.values()] + random.shuffle(procs) + for i in range(random.randint(0, 10)): + procs[i].shouldBeRunning = True + sm['managerState'].processes = procs + + sm['liveCalibration'].rpyCalib = [-1 * random.random() for _ in range(random.randint(0, 3))] + + for s in sm.data.keys(): + prob = 0.3 if s in cameras else 0.08 + sm.alive[s] = random.random() > prob + sm.valid[s] = random.random() > prob + sm.freq_ok[s] = random.random() > prob + + a = events.create_alerts([et, ], [CP, CS, sm, is_metric, 0]) AM.add_many(frame, a) alert = AM.process_alerts(frame, []) print(alert) diff --git a/selfdrive/debug/disable_ecu.py b/selfdrive/debug/disable_ecu.py index f0faf40017..af007207eb 100644 --- a/selfdrive/debug/disable_ecu.py +++ b/selfdrive/debug/disable_ecu.py @@ -3,7 +3,7 @@ import traceback import cereal.messaging as messaging from selfdrive.car.isotp_parallel_query import IsoTpParallelQuery -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog EXT_DIAG_REQUEST = b'\x10\x03' EXT_DIAG_RESPONSE = b'\x50\x03' diff --git a/selfdrive/debug/dump.py b/selfdrive/debug/dump.py index f208920f12..fdb825eead 100755 --- a/selfdrive/debug/dump.py +++ b/selfdrive/debug/dump.py @@ -13,7 +13,7 @@ from cereal.services import service_list if __name__ == "__main__": - parser = argparse.ArgumentParser(description='Dump communcation sockets. See cereal/services.py for a complete list of available sockets.') + parser = argparse.ArgumentParser(description='Dump communication sockets. See cereal/services.py for a complete list of available sockets.') parser.add_argument('--pipe', action='store_true') parser.add_argument('--raw', action='store_true') parser.add_argument('--json', action='store_true') diff --git a/selfdrive/debug/filter_log_message.py b/selfdrive/debug/filter_log_message.py index 452358cd5c..af52953936 100755 --- a/selfdrive/debug/filter_log_message.py +++ b/selfdrive/debug/filter_log_message.py @@ -1,9 +1,10 @@ #!/usr/bin/env python3 +import os import argparse import json import cereal.messaging as messaging -from tools.lib.robust_logreader import RobustLogReader as LogReader +from tools.lib.logreader import LogReader from tools.lib.route import Route LEVELS = { @@ -46,7 +47,6 @@ def print_androidlog(t, msg): if __name__ == "__main__": - parser = argparse.ArgumentParser() parser.add_argument('--level', default='DEBUG') parser.add_argument('--addr', default='127.0.0.1') @@ -55,8 +55,11 @@ if __name__ == "__main__": logs = None if len(args.route): - r = Route(args.route[0]) - logs = [q_log if r_log is None else r_log for (q_log, r_log) in zip(r.qlog_paths(), r.log_paths())] + if os.path.exists(args.route[0]): + logs = [args.route[0]] + else: + r = Route(args.route[0]) + logs = [q_log if r_log is None else r_log for (q_log, r_log) in zip(r.qlog_paths(), r.log_paths())] if len(args.route) == 2 and logs: n = int(args.route[1]) diff --git a/selfdrive/debug/internal/core_voltage_sweep.py b/selfdrive/debug/internal/core_voltage_sweep.py deleted file mode 100755 index c7c609560d..0000000000 --- a/selfdrive/debug/internal/core_voltage_sweep.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import time - -print("starting at") -os.system("cat /sys/kernel/debug/regulator/pm8994_s11/voltage") -print("volts") - -os.system("echo 99e8000.cpr3-ctrl > /sys/devices/soc/spm-regulator-10/regulator/regulator.56/99e8000.cpr3-ctrl-vdd/driver/unbind") -os.system("echo 1 > /sys/kernel/debug/regulator/pm8994_s11/enable") - -if len(sys.argv) > 1: - i = int(sys.argv[1]) - os.system("echo %d %d > /sys/kernel/debug/regulator/pm8994_s11/voltage" % (i,i)) - os.system("cat /sys/kernel/debug/regulator/pm8994_s11/voltage") -else: - for i in range(900000, 465000, -10000): - print("setting voltage to",i) - os.system("echo %d %d > /sys/kernel/debug/regulator/pm8994_s11/voltage" % (i,i)) - os.system("cat /sys/kernel/debug/regulator/pm8994_s11/voltage") - time.sleep(1) - diff --git a/selfdrive/debug/internal/measure_steering_accuracy.py b/selfdrive/debug/internal/measure_steering_accuracy.py deleted file mode 100755 index e06e43cdcf..0000000000 --- a/selfdrive/debug/internal/measure_steering_accuracy.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python3 -# type: ignore - -import os -import argparse -import signal -from collections import defaultdict - -import cereal.messaging as messaging - -def sigint_handler(signal, frame): - print("handler!") - exit(0) -signal.signal(signal.SIGINT, sigint_handler) - -if __name__ == "__main__": - - parser = argparse.ArgumentParser(description='Sniff a communication socket') - parser.add_argument('--addr', default='127.0.0.1') - args = parser.parse_args() - - if args.addr != "127.0.0.1": - os.environ["ZMQ"] = "1" - messaging.context = messaging.Context() - - carControl = messaging.sub_sock('carControl', addr=args.addr, conflate=True) - sm = messaging.SubMaster(['carState', 'carControl', 'controlsState'], addr=args.addr) - - msg_cnt = 0 - stats = defaultdict(lambda: {'err': 0, "cnt": 0, "=": 0, "+": 0, "-": 0}) - cnt = 0 - total_error = 0 - - while messaging.recv_one(carControl): - sm.update() - msg_cnt += 1 - - actual_speed = sm['carState'].vEgo - enabled = sm['controlsState'].enabled - steer_override = sm['controlsState'].steerOverride - - # must be above 10 m/s, engaged and not overriding steering - if actual_speed > 10.0 and enabled and not steer_override: - cnt += 1 - - # wait 5 seconds after engage/override - if cnt >= 500: - # calculate error before rounding - actual_angle = sm['controlsState'].angleSteers - desired_angle = sm['carControl'].actuators.steeringAngleDeg - angle_error = abs(desired_angle - actual_angle) - - # round numbers - actual_angle = round(actual_angle, 1) - desired_angle = round(desired_angle, 1) - angle_error = round(angle_error, 2) - angle_abs = int(abs(round(desired_angle, 0))) - - # collect stats - stats[angle_abs]["err"] += angle_error - stats[angle_abs]["cnt"] += 1 - if actual_angle == desired_angle: - stats[angle_abs]["="] += 1 - else: - if desired_angle == 0.: - overshoot = True - else: - overshoot = desired_angle < actual_angle if desired_angle > 0. else desired_angle > actual_angle - stats[angle_abs]["+" if overshoot else "-"] += 1 - else: - cnt = 0 - - if msg_cnt % 100 == 0: - print(chr(27) + "[2J") - if cnt != 0: - print("COLLECTING ...") - else: - print("DISABLED (speed too low, not engaged, or steer override)") - for k in sorted(stats.keys()): - v = stats[k] - print(f'angle: {k:#2} | error: {round(v["err"] / v["cnt"], 2):2.2f} | =:{int(v["="] / v["cnt"] * 100):#3}% | +:{int(v["+"] / v["cnt"] * 100):#4}% | -:{int(v["-"] / v["cnt"] * 100):#3}% | count: {v["cnt"]:#4}') diff --git a/selfdrive/debug/internal/sensor_test_bootloop.py b/selfdrive/debug/internal/sensor_test_bootloop.py deleted file mode 100755 index 36eb112e44..0000000000 --- a/selfdrive/debug/internal/sensor_test_bootloop.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/python3 -import sys -import os -import stat -import subprocess -import json -from common.text_window import TextWindow -import time - -# Required for sensord not to bus-error on startup -# commaai/cereal#22 -try: - os.mkdir("/dev/shm") -except FileExistsError: - pass -except PermissionError: - print("WARNING: failed to make /dev/shm") - -try: - with open('/tmp/sensor-test-results.json') as infile: - data = json.load(infile) -except Exception: - data = {'sensor-pass': 0, 'sensor-fail': 0} - -STARTUP_SCRIPT = "/data/data/com.termux/files/continue.sh" -try: - with open(STARTUP_SCRIPT, 'w') as startup_script: - startup_script.write("#!/usr/bin/bash\n\n/data/openpilot/selfdrive/debug/internal/sensor_test_bootloop.py\n") - os.chmod(STARTUP_SCRIPT, stat.S_IRWXU) -except Exception: - print("Failed to install new startup script -- aborting") - sys.exit(-1) - -sensord_env = {**os.environ, 'SENSOR_TEST': '1'} -process = subprocess.run("./sensord", cwd="/data/openpilot/selfdrive/sensord", env=sensord_env) # pylint: disable=subprocess-run-check - -if process.returncode == 40: - text = "Current run: SUCCESS\n" - data['sensor-pass'] += 1 -else: - text = "Current run: FAIL\n" - data['sensor-fail'] += 1 - - timestr = str(int(time.time())) - with open('/tmp/dmesg-' + timestr + '.log', 'w') as dmesg_out: - subprocess.call('dmesg', stdout=dmesg_out, shell=False) - with open("/tmp/logcat-" + timestr + '.log', 'w') as logcat_out: - subprocess.call(['logcat', '-d'], stdout=logcat_out, shell=False) - -text += "Sensor pass history: " + str(data['sensor-pass']) + "\n" -text += "Sensor fail history: " + str(data['sensor-fail']) + "\n" - -print(text) - -with open('/tmp/sensor-test-results.json', 'w') as outfile: - json.dump(data, outfile, indent=4) - -with TextWindow(text) as status: - for _ in range(100): - if status.get_status() == 1: - with open(STARTUP_SCRIPT, 'w') as startup_script: - startup_script.write("#!/usr/bin/bash\n\ncd /data/openpilot\nexec ./launch_openpilot.sh\n") - os.chmod(STARTUP_SCRIPT, stat.S_IRWXU) - break - time.sleep(0.1) - -subprocess.Popen("reboot") diff --git a/selfdrive/debug/live_cpu_and_temp.py b/selfdrive/debug/live_cpu_and_temp.py index b244f7cb0e..baeebb1c4c 100755 --- a/selfdrive/debug/live_cpu_and_temp.py +++ b/selfdrive/debug/live_cpu_and_temp.py @@ -88,7 +88,7 @@ if __name__ == "__main__": pass print("Top CPU usage:") - for k, v in sorted(procs.items(), key=lambda item: item[1], reverse=True)[:10]: + for k, v in sorted(procs.items(), key=lambda item: item[1], reverse=True)[:10]: # type: ignore print(f"{k.rjust(70)} {v:.2f} %") print() diff --git a/selfdrive/debug/profiling/ftrace.sh b/selfdrive/debug/profiling/ftrace.sh new file mode 100755 index 0000000000..fe91a3c0d9 --- /dev/null +++ b/selfdrive/debug/profiling/ftrace.sh @@ -0,0 +1,23 @@ +#!/usr/bin/bash +set -e + +cd /sys/kernel/tracing + +echo 1 > tracing_on +echo boot > trace_clock +echo 1000 > buffer_size_kb + +# /sys/kernel/tracing/available_events +echo 1 > events/irq/enable +echo 1 > events/sched/enable +echo 1 > events/kgsl/enable +echo 1 > events/camera/enable +echo 1 > events/workqueue/enable + +echo > trace +sleep 5 +echo 0 > tracing_on + +cp trace /tmp/trace +chown comma: /tmp/trace +echo /tmp/trace diff --git a/selfdrive/debug/run_process_on_route.py b/selfdrive/debug/run_process_on_route.py index a6e67d2b24..63b0733bba 100755 --- a/selfdrive/debug/run_process_on_route.py +++ b/selfdrive/debug/run_process_on_route.py @@ -25,7 +25,7 @@ if __name__ == "__main__": # Remove message generated by the process under test and merge in the new messages produces = {o.which() for o in outputs} inputs = [i for i in inputs if i.which() not in produces] - outputs = sorted(inputs + outputs, key=lambda x: x.logMonoTime) + outputs = sorted(inputs + outputs, key=lambda x: x.logMonoTime) # type: ignore fn = f"{args.route}_{args.process}.bz2" save_log(fn, outputs) diff --git a/selfdrive/debug/test_car_model.py b/selfdrive/debug/test_car_model.py new file mode 100755 index 0000000000..9082dbe3d6 --- /dev/null +++ b/selfdrive/debug/test_car_model.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +import argparse +import sys +from typing import List, Tuple +import unittest + +from selfdrive.car.tests.routes import TestRoute +from selfdrive.car.tests.test_models import TestCarModel + + +def create_test_models_suite(routes: List[Tuple[str, TestRoute]], ci=False) -> unittest.TestSuite: + test_suite = unittest.TestSuite() + for car_model, test_route in routes: + # create new test case and discover tests + test_case_args = {"car_model": car_model, "test_route": test_route, "ci": ci} + CarModelTestCase = type("CarModelTestCase", (TestCarModel,), test_case_args) + test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(CarModelTestCase)) + return test_suite + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Test any route against common issues with a new car port. " + + "Uses selfdrive/car/tests/test_models.py") + parser.add_argument("route", help="Specify route to run tests on") + parser.add_argument("--car", help="Specify car model for test route") + parser.add_argument("--segment", type=int, nargs="?", help="Specify segment of route to test") + parser.add_argument("--ci", action="store_true", help="Attempt to get logs using openpilotci, need to specify car") + args = parser.parse_args() + if len(sys.argv) == 1: + parser.print_help() + sys.exit() + + test_route = TestRoute(args.route, args.car, segment=args.segment) + test_suite = create_test_models_suite([(args.car, test_route)], ci=args.ci) + + unittest.TextTestRunner().run(test_suite) diff --git a/selfdrive/debug/test_fw_query_on_routes.py b/selfdrive/debug/test_fw_query_on_routes.py index 0f9e316cd0..011dd6c9a3 100755 --- a/selfdrive/debug/test_fw_query_on_routes.py +++ b/selfdrive/debug/test_fw_query_on_routes.py @@ -73,6 +73,7 @@ if __name__ == "__main__": lr = LogReader(qlog_path) dongles.append(dongle_id) + CP = None for msg in lr: if msg.which() == "pandaStates": if msg.pandaStates[0].pandaType not in ('uno', 'blackPanda', 'dos'): @@ -80,14 +81,13 @@ if __name__ == "__main__": break elif msg.which() == "carParams": - bts = msg.carParams.as_builder().to_bytes() - - car_fw = msg.carParams.carFw + CP = msg.carParams + car_fw = CP.carFw if len(car_fw) == 0: print("no fw") break - live_fingerprint = msg.carParams.carFingerprint + live_fingerprint = CP.carFingerprint live_fingerprint = migration.get(live_fingerprint, live_fingerprint) if args.car is not None: @@ -116,7 +116,7 @@ if __name__ == "__main__": break print(f"{dongle_id}|{time}") - print("Old style:", live_fingerprint, "Vin", msg.carParams.carVin) + print("Old style:", live_fingerprint, "Vin", CP.carVin) print("New style (exact):", exact_matches) print("New style (fuzzy):", fuzzy_matches) @@ -164,6 +164,9 @@ if __name__ == "__main__": print("Fuzzy match wrong! Fuzzy:", fuzzy_matches, "Live:", live_fingerprint) break + + if CP is None: + print("no CarParams in logs") except Exception: traceback.print_exc() except KeyboardInterrupt: diff --git a/selfdrive/hardware b/selfdrive/hardware new file mode 120000 index 0000000000..02a42c502f --- /dev/null +++ b/selfdrive/hardware @@ -0,0 +1 @@ +../system/hardware/ \ No newline at end of file diff --git a/selfdrive/locationd/calibrationd.py b/selfdrive/locationd/calibrationd.py index 51c84b847d..e092c939ae 100755 --- a/selfdrive/locationd/calibrationd.py +++ b/selfdrive/locationd/calibrationd.py @@ -20,8 +20,7 @@ from common.realtime import set_realtime_priority from common.transformations.model import model_height from common.transformations.camera import get_view_frame_from_road_frame from common.transformations.orientation import rot_from_euler, euler_from_rot -from selfdrive.hardware import TICI -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog MIN_SPEED_FILTER = 15 * CV.MPH_TO_MS MAX_VEL_ANGLE_STD = np.radians(0.25) @@ -48,7 +47,7 @@ class Calibration: def is_calibration_valid(rpy: np.ndarray) -> bool: - return (PITCH_LIMITS[0] < rpy[1] < PITCH_LIMITS[1]) and (YAW_LIMITS[0] < rpy[2] < YAW_LIMITS[1]) + return (PITCH_LIMITS[0] < rpy[1] < PITCH_LIMITS[1]) and (YAW_LIMITS[0] < rpy[2] < YAW_LIMITS[1]) # type: ignore def sanity_clip(rpy: np.ndarray) -> np.ndarray: @@ -68,7 +67,7 @@ class Calibrator: # Read saved calibration params = Params() calibration_params = params.get("CalibrationParams") - self.wide_camera = TICI and params.get_bool('EnableWideCamera') + self.wide_camera = params.get_bool('WideCameraOnly') rpy_init = RPY_INIT valid_blocks = 0 diff --git a/selfdrive/locationd/laikad.py b/selfdrive/locationd/laikad.py new file mode 100755 index 0000000000..8ec570e2be --- /dev/null +++ b/selfdrive/locationd/laikad.py @@ -0,0 +1,265 @@ +#!/usr/bin/env python3 +import json +import time +from collections import defaultdict +from concurrent.futures import Future, ProcessPoolExecutor +from enum import IntEnum +from typing import List, Optional + +import numpy as np + +from cereal import log, messaging +from common.params import Params, put_nonblocking +from laika import AstroDog +from laika.constants import SECS_IN_HR, SECS_IN_MIN +from laika.ephemeris import Ephemeris, EphemerisType, convert_ublox_ephem +from laika.gps_time import GPSTime +from laika.helpers import ConstellationId +from laika.raw_gnss import GNSSMeasurement, correct_measurements, process_measurements, read_raw_ublox +from selfdrive.locationd.laikad_helpers import calc_pos_fix_gauss_newton, get_posfix_sympy_fun +from selfdrive.locationd.models.constants import GENERATED_DIR, ObservationKind +from selfdrive.locationd.models.gnss_kf import GNSSKalman +from selfdrive.locationd.models.gnss_kf import States as GStates +from system.swaglog import cloudlog + +MAX_TIME_GAP = 10 +EPHEMERIS_CACHE = 'LaikadEphemeris' +CACHE_VERSION = 0.1 + + +class Laikad: + def __init__(self, valid_const=("GPS", "GLONASS"), auto_update=False, valid_ephem_types=(EphemerisType.ULTRA_RAPID_ORBIT, EphemerisType.NAV), + save_ephemeris=False, last_known_position=None): + self.astro_dog = AstroDog(valid_const=valid_const, auto_update=auto_update, valid_ephem_types=valid_ephem_types, clear_old_ephemeris=True) + self.gnss_kf = GNSSKalman(GENERATED_DIR) + self.orbit_fetch_executor = ProcessPoolExecutor() + self.orbit_fetch_future: Optional[Future] = None + self.last_fetch_orbits_t = None + self.last_cached_t = None + self.save_ephemeris = save_ephemeris + self.load_cache() + self.posfix_functions = {constellation: get_posfix_sympy_fun(constellation) for constellation in (ConstellationId.GPS, ConstellationId.GLONASS)} + self.last_pos_fix = last_known_position + + def load_cache(self): + cache = Params().get(EPHEMERIS_CACHE) + if not cache: + return + try: + cache = json.loads(cache, object_hook=deserialize_hook) + self.astro_dog.add_orbits(cache['orbits']) + self.astro_dog.add_navs(cache['nav']) + self.last_fetch_orbits_t = cache['last_fetch_orbits_t'] + except json.decoder.JSONDecodeError: + cloudlog.exception("Error parsing cache") + + def cache_ephemeris(self, t: GPSTime): + if self.save_ephemeris and (self.last_cached_t is None or t - self.last_cached_t > SECS_IN_MIN): + put_nonblocking(EPHEMERIS_CACHE, json.dumps( + {'version': CACHE_VERSION, 'last_fetch_orbits_t': self.last_fetch_orbits_t, 'orbits': self.astro_dog.orbits, 'nav': self.astro_dog.nav}, + cls=CacheSerializer)) + self.last_cached_t = t + + def process_ublox_msg(self, ublox_msg, ublox_mono_time: int, block=False): + if ublox_msg.which == 'measurementReport': + report = ublox_msg.measurementReport + if report.gpsWeek > 0: + latest_msg_t = GPSTime(report.gpsWeek, report.rcvTow) + self.fetch_orbits(latest_msg_t + SECS_IN_MIN, block) + new_meas = read_raw_ublox(report) + processed_measurements = process_measurements(new_meas, self.astro_dog) + + min_measurements = 5 if any(p.constellation_id == ConstellationId.GLONASS for p in processed_measurements) else 4 + pos_fix, pos_fix_residual = calc_pos_fix_gauss_newton(processed_measurements, self.posfix_functions, min_measurements=min_measurements) + if len(pos_fix) > 0: + self.last_pos_fix = pos_fix[:3] + est_pos = self.last_pos_fix + + corrected_measurements = correct_measurements(processed_measurements, est_pos, self.astro_dog) if est_pos is not None else [] + + t = ublox_mono_time * 1e-9 + self.update_localizer(est_pos, t, corrected_measurements) + kf_valid = all(self.kf_valid(t)) + ecef_pos = self.gnss_kf.x[GStates.ECEF_POS].tolist() + ecef_vel = self.gnss_kf.x[GStates.ECEF_VELOCITY].tolist() + + pos_std = np.sqrt(abs(self.gnss_kf.P[GStates.ECEF_POS].diagonal())).tolist() + vel_std = np.sqrt(abs(self.gnss_kf.P[GStates.ECEF_VELOCITY].diagonal())).tolist() + + meas_msgs = [create_measurement_msg(m) for m in corrected_measurements] + dat = messaging.new_message("gnssMeasurements") + measurement_msg = log.LiveLocationKalman.Measurement.new_message + dat.gnssMeasurements = { + "gpsWeek": report.gpsWeek, + "gpsTimeOfWeek": report.rcvTow, + "positionECEF": measurement_msg(value=ecef_pos, std=pos_std, valid=kf_valid), + "velocityECEF": measurement_msg(value=ecef_vel, std=vel_std, valid=kf_valid), + "positionFixECEF": measurement_msg(value=pos_fix, std=pos_fix_residual, valid=len(pos_fix) > 0), + "ubloxMonoTime": ublox_mono_time, + "correctedMeasurements": meas_msgs + } + return dat + elif ublox_msg.which == 'ephemeris': + ephem = convert_ublox_ephem(ublox_msg.ephemeris) + self.astro_dog.add_navs({ephem.prn: [ephem]}) + self.cache_ephemeris(t=ephem.epoch) + # elif ublox_msg.which == 'ionoData': + # todo add this. Needed to better correct messages offline. First fix ublox_msg.cc to sent them. + + def update_localizer(self, est_pos, t: float, measurements: List[GNSSMeasurement]): + # Check time and outputs are valid + valid = self.kf_valid(t) + if not all(valid): + if not valid[0]: + cloudlog.info("Init gnss kalman filter") + elif not valid[1]: + cloudlog.error("Time gap of over 10s detected, gnss kalman reset") + elif not valid[2]: + cloudlog.error("Gnss kalman filter state is nan") + if est_pos is not None: + cloudlog.info(f"Reset kalman filter with {est_pos}") + self.init_gnss_localizer(est_pos) + else: + cloudlog.info("Could not reset kalman filter") + return + if len(measurements) > 0: + kf_add_observations(self.gnss_kf, t, measurements) + else: + # Ensure gnss filter is updated even with no new measurements + self.gnss_kf.predict(t) + + def kf_valid(self, t: float): + filter_time = self.gnss_kf.filter.filter_time + return [filter_time is not None, + filter_time is not None and abs(t - filter_time) < MAX_TIME_GAP, + all(np.isfinite(self.gnss_kf.x[GStates.ECEF_POS]))] + + def init_gnss_localizer(self, est_pos): + x_initial, p_initial_diag = np.copy(GNSSKalman.x_initial), np.copy(np.diagonal(GNSSKalman.P_initial)) + x_initial[GStates.ECEF_POS] = est_pos + p_initial_diag[GStates.ECEF_POS] = 1000 ** 2 + self.gnss_kf.init_state(x_initial, covs_diag=p_initial_diag) + + def fetch_orbits(self, t: GPSTime, block): + if t not in self.astro_dog.orbit_fetched_times and (self.last_fetch_orbits_t is None or t - self.last_fetch_orbits_t > SECS_IN_HR): + astro_dog_vars = self.astro_dog.valid_const, self.astro_dog.auto_update, self.astro_dog.valid_ephem_types + if self.orbit_fetch_future is None: + self.orbit_fetch_future = self.orbit_fetch_executor.submit(get_orbit_data, t, *astro_dog_vars) + if block: + self.orbit_fetch_future.result() + if self.orbit_fetch_future.done(): + ret = self.orbit_fetch_future.result() + self.last_fetch_orbits_t = t + if ret: + self.astro_dog.orbits, self.astro_dog.orbit_fetched_times = ret + self.cache_ephemeris(t=t) + self.orbit_fetch_future = None + + +def get_orbit_data(t: GPSTime, valid_const, auto_update, valid_ephem_types): + astro_dog = AstroDog(valid_const=valid_const, auto_update=auto_update, valid_ephem_types=valid_ephem_types) + cloudlog.info(f"Start to download/parse orbits for time {t.as_datetime()}") + start_time = time.monotonic() + data = None + try: + astro_dog.get_orbit_data(t, only_predictions=True) + data = (astro_dog.orbits, astro_dog.orbit_fetched_times) + except RuntimeError as e: + cloudlog.info(f"No orbit data found. {e}") + cloudlog.info(f"Done parsing orbits. Took {time.monotonic() - start_time:.1f}s") + return data + + +def create_measurement_msg(meas: GNSSMeasurement): + c = log.GnssMeasurements.CorrectedMeasurement.new_message() + c.constellationId = meas.constellation_id.value + c.svId = meas.sv_id + c.glonassFrequency = meas.glonass_freq if meas.constellation_id == ConstellationId.GLONASS else 0 + c.pseudorange = float(meas.observables_final['C1C']) + c.pseudorangeStd = float(meas.observables_std['C1C']) + c.pseudorangeRate = float(meas.observables_final['D1C']) + c.pseudorangeRateStd = float(meas.observables_std['D1C']) + c.satPos = meas.sat_pos_final.tolist() + c.satVel = meas.sat_vel.tolist() + c.satVel = meas.sat_vel.tolist() + ephem = meas.sat_ephemeris + assert ephem is not None + if ephem.eph_type == EphemerisType.NAV: + source_type = EphemerisSourceType.nav + week, time_of_week = -1, -1 + else: + assert ephem.file_epoch is not None + week = ephem.file_epoch.week + time_of_week = ephem.file_epoch.tow + file_src = ephem.file_source + if file_src == 'igu': # example nasa: '2214/igu22144_00.sp3.Z' + source_type = EphemerisSourceType.nasaUltraRapid + elif file_src == 'Sta': # example nasa: '22166/ultra/Stark_1D_22061518.sp3' + source_type = EphemerisSourceType.glonassIacUltraRapid + else: + raise Exception(f"Didn't expect file source {file_src}") + + c.ephemerisSource.type = source_type.value + c.ephemerisSource.gpsWeek = week + c.ephemerisSource.gpsTimeOfWeek = time_of_week + return c + + +def kf_add_observations(gnss_kf: GNSSKalman, t: float, measurements: List[GNSSMeasurement]): + ekf_data = defaultdict(list) + for m in measurements: + m_arr = m.as_array() + if m.constellation_id == ConstellationId.GPS: + ekf_data[ObservationKind.PSEUDORANGE_GPS].append(m_arr) + ekf_data[ObservationKind.PSEUDORANGE_RATE_GPS].append(m_arr) + elif m.constellation_id == ConstellationId.GLONASS: + ekf_data[ObservationKind.PSEUDORANGE_GLONASS].append(m_arr) + ekf_data[ObservationKind.PSEUDORANGE_RATE_GLONASS].append(m_arr) + + for kind, data in ekf_data.items(): + gnss_kf.predict_and_observe(t, kind, data) + + +class CacheSerializer(json.JSONEncoder): + + def default(self, o): + if isinstance(o, Ephemeris): + return o.to_json() + if isinstance(o, GPSTime): + return o.__dict__ + if isinstance(o, np.ndarray): + return o.tolist() + return json.JSONEncoder.default(self, o) + + +def deserialize_hook(dct): + if 'ephemeris' in dct: + return Ephemeris.from_json(dct) + if 'week' in dct: + return GPSTime(dct['week'], dct['tow']) + return dct + + +class EphemerisSourceType(IntEnum): + nav = 0 + nasaUltraRapid = 1 + glonassIacUltraRapid = 2 + + +def main(): + sm = messaging.SubMaster(['ubloxGnss']) + pm = messaging.PubMaster(['gnssMeasurements']) + # todo get last_known_position + laikad = Laikad(save_ephemeris=True) + while True: + sm.update() + + if sm.updated['ubloxGnss']: + ublox_msg = sm['ubloxGnss'] + msg = laikad.process_ublox_msg(ublox_msg, sm.logMonoTime['ubloxGnss']) + if msg is not None: + pm.send('gnssMeasurements', msg) + + +if __name__ == "__main__": + main() diff --git a/selfdrive/locationd/laikad_helpers.py b/selfdrive/locationd/laikad_helpers.py new file mode 100644 index 0000000000..81f5ac3dd6 --- /dev/null +++ b/selfdrive/locationd/laikad_helpers.py @@ -0,0 +1,89 @@ +import numpy as np +import sympy + +from laika.constants import EARTH_ROTATION_RATE, SPEED_OF_LIGHT +from laika.helpers import ConstellationId + + +def calc_pos_fix_gauss_newton(measurements, posfix_functions, x0=None, signal='C1C', min_measurements=6): + ''' + Calculates gps fix using gauss newton method + To solve the problem a minimal of 4 measurements are required. + If Glonass is included 5 are required to solve for the additional free variable. + returns: + 0 -> list with positions + ''' + if x0 is None: + x0 = [0, 0, 0, 0, 0] + n = len(measurements) + if n < min_measurements: + return [], [] + + Fx_pos = pr_residual(measurements, posfix_functions, signal=signal) + x = gauss_newton(Fx_pos, x0) + residual, _ = Fx_pos(x, weight=1.0) + return x.tolist(), residual.tolist() + + +def pr_residual(measurements, posfix_functions, signal='C1C'): + def Fx_pos(inp, weight=None): + vals, gradients = [], [] + + for meas in measurements: + pr = meas.observables[signal] + pr += meas.sat_clock_err * SPEED_OF_LIGHT + + w = (1 / meas.observables_std[signal]) if weight is None else weight + + val, *gradient = posfix_functions[meas.constellation_id](*inp, pr, *meas.sat_pos, w) + vals.append(val) + gradients.append(gradient) + return np.asarray(vals), np.asarray(gradients) + + return Fx_pos + + +def gauss_newton(fun, b, xtol=1e-8, max_n=25): + for _ in range(max_n): + # Compute function and jacobian on current estimate + r, J = fun(b) + + # Update estimate + delta = np.linalg.pinv(J) @ r + b -= delta + + # Check step size for stopping condition + if np.linalg.norm(delta) < xtol: + break + return b + + +def get_posfix_sympy_fun(constellation): + # Unknowns + x, y, z = sympy.Symbol('x'), sympy.Symbol('y'), sympy.Symbol('z') + bc = sympy.Symbol('bc') + bg = sympy.Symbol('bg') + var = [x, y, z, bc, bg] + + # Knowns + pr = sympy.Symbol('pr') + sat_x, sat_y, sat_z = sympy.Symbol('sat_x'), sympy.Symbol('sat_y'), sympy.Symbol('sat_z') + weight = sympy.Symbol('weight') + + theta = EARTH_ROTATION_RATE * (pr - bc) / SPEED_OF_LIGHT + val = sympy.sqrt( + (sat_x * sympy.cos(theta) + sat_y * sympy.sin(theta) - x) ** 2 + + (sat_y * sympy.cos(theta) - sat_x * sympy.sin(theta) - y) ** 2 + + (sat_z - z) ** 2 + ) + + if constellation == ConstellationId.GLONASS: + res = weight * (val - (pr - bc - bg)) + elif constellation == ConstellationId.GPS: + res = weight * (val - (pr - bc)) + else: + raise NotImplementedError(f"Constellation {constellation} not supported") + + res = [res] + [sympy.diff(res, v) for v in var] + + return sympy.lambdify([x, y, z, bc, bg, pr, sat_x, sat_y, sat_z, weight], res) diff --git a/selfdrive/locationd/locationd.cc b/selfdrive/locationd/locationd.cc index 3875d969c5..c33ff6a497 100755 --- a/selfdrive/locationd/locationd.cc +++ b/selfdrive/locationd/locationd.cc @@ -250,12 +250,12 @@ void Localizer::input_fake_gps_observations(double current_time) { // Steps : first predict -> observe current obs with reasonable STD this->kf->predict(current_time); - VectorXd current_x = this->kf->get_x(); + VectorXd current_x = this->kf->get_x(); VectorXd ecef_pos = current_x.segment(STATE_ECEF_POS_START); VectorXd ecef_vel = current_x.segment(STATE_ECEF_VELOCITY_START); MatrixXdr ecef_pos_R = this->kf->get_fake_gps_pos_cov(); MatrixXdr ecef_vel_R = this->kf->get_fake_gps_vel_cov(); - + this->kf->predict_and_observe(current_time, OBSERVATION_ECEF_POS, { ecef_pos }, { ecef_pos_R }); this->kf->predict_and_observe(current_time, OBSERVATION_ECEF_VEL, { ecef_vel }, { ecef_vel_R }); } @@ -283,7 +283,7 @@ void Localizer::handle_gps(double current_time, const cereal::GpsLocationData::R VectorXd ecef_vel = this->converter->ned2ecef({ log.getVNED()[0], log.getVNED()[1], log.getVNED()[2] }).to_vector() - ecef_pos; MatrixXdr ecef_pos_R = Vector3d::Constant(std::pow(10.0 * log.getAccuracy(),2) + std::pow(10.0 * log.getVerticalAccuracy(),2)).asDiagonal(); MatrixXdr ecef_vel_R = Vector3d::Constant(std::pow(log.getSpeedAccuracy() * 10.0, 2)).asDiagonal(); - + this->unix_timestamp_millis = log.getTimestamp(); double gps_est_error = (this->kf->get_x().segment(STATE_ECEF_POS_START) - ecef_pos).norm(); @@ -419,7 +419,7 @@ void Localizer::reset_kalman(double current_time, VectorXd init_orient, VectorXd init_P.block(STATE_ECEF_ORIENTATION_ERR_START, STATE_ECEF_ORIENTATION_ERR_START).diagonal() = reset_orientation_P.diagonal(); init_P.block(STATE_ECEF_VELOCITY_ERR_START, STATE_ECEF_VELOCITY_ERR_START).diagonal() = init_vel_R.diagonal(); init_P.block(STATE_ANGULAR_VELOCITY_ERR_START, STATE_ANGULAR_VELOCITY_ERR_START, non_ecef_state_err_len, non_ecef_state_err_len).diagonal() = current_P.block(STATE_ANGULAR_VELOCITY_ERR_START, STATE_ANGULAR_VELOCITY_ERR_START, non_ecef_state_err_len, non_ecef_state_err_len).diagonal(); - + this->reset_kalman(current_time, current_x, init_P); } @@ -494,7 +494,7 @@ int Localizer::locationd_thread() { PubMaster pm({"liveLocationKalman"}); // TODO: remove carParams once we're always sending at 100Hz - SubMaster sm(service_list, nullptr, {"gpsLocationExternal", "carParams"}); + SubMaster sm(service_list, {}, nullptr, {"gpsLocationExternal", "carParams"}); uint64_t cnt = 0; bool filterInitialized = false; diff --git a/selfdrive/locationd/locationd.h b/selfdrive/locationd/locationd.h index 2ab3ba56ad..7c0cb6b7fe 100755 --- a/selfdrive/locationd/locationd.h +++ b/selfdrive/locationd/locationd.h @@ -8,10 +8,10 @@ #include "cereal/messaging/messaging.h" #include "common/transformations/coordinates.hpp" #include "common/transformations/orientation.hpp" -#include "selfdrive/common/params.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/timing.h" -#include "selfdrive/common/util.h" +#include "common/params.h" +#include "common/swaglog.h" +#include "common/timing.h" +#include "common/util.h" #include "selfdrive/sensord/sensors/constants.h" #define VISION_DECIMATION 2 diff --git a/selfdrive/locationd/models/car_kf.py b/selfdrive/locationd/models/car_kf.py index 75534efa5a..fe7d2e650b 100755 --- a/selfdrive/locationd/models/car_kf.py +++ b/selfdrive/locationd/models/car_kf.py @@ -7,7 +7,7 @@ import numpy as np from selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY from selfdrive.locationd.models.constants import ObservationKind -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog from rednose.helpers.kalmanfilter import KalmanFilter diff --git a/selfdrive/locationd/models/gnss_helpers.py b/selfdrive/locationd/models/gnss_helpers.py new file mode 100644 index 0000000000..a3bcbc0002 --- /dev/null +++ b/selfdrive/locationd/models/gnss_helpers.py @@ -0,0 +1,21 @@ +import numpy as np + +def parse_prr(m): + from laika.raw_gnss import GNSSMeasurement + sat_pos_vel_i = np.concatenate((m[GNSSMeasurement.SAT_POS], + m[GNSSMeasurement.SAT_VEL])) + R_i = np.atleast_2d(m[GNSSMeasurement.PRR_STD]**2) + z_i = m[GNSSMeasurement.PRR] + return z_i, R_i, sat_pos_vel_i + + +def parse_pr(m): + from laika.raw_gnss import GNSSMeasurement + pseudorange = m[GNSSMeasurement.PR] + pseudorange_stdev = m[GNSSMeasurement.PR_STD] + sat_pos_freq_i = np.concatenate((m[GNSSMeasurement.SAT_POS], + np.array([m[GNSSMeasurement.GLONASS_FREQ]]))) + z_i = np.atleast_1d(pseudorange) + R_i = np.atleast_2d(pseudorange_stdev**2) + return z_i, R_i, sat_pos_freq_i + diff --git a/selfdrive/locationd/models/gnss_kf.py b/selfdrive/locationd/models/gnss_kf.py index 3f4baab7b5..ce0ff84dc2 100755 --- a/selfdrive/locationd/models/gnss_kf.py +++ b/selfdrive/locationd/models/gnss_kf.py @@ -7,7 +7,7 @@ import sympy as sp from rednose.helpers.ekf_sym import EKF_sym, gen_code from selfdrive.locationd.models.constants import ObservationKind -from selfdrive.locationd.models.loc_kf import parse_pr, parse_prr +from selfdrive.locationd.models.gnss_helpers import parse_pr, parse_prr class States(): diff --git a/selfdrive/locationd/models/loc_kf.py b/selfdrive/locationd/models/loc_kf.py index 8391426dd1..6b08828695 100755 --- a/selfdrive/locationd/models/loc_kf.py +++ b/selfdrive/locationd/models/loc_kf.py @@ -5,33 +5,14 @@ import sys import numpy as np import sympy as sp -from selfdrive.locationd.models.constants import ObservationKind from rednose.helpers.ekf_sym import EKF_sym, gen_code from rednose.helpers.lst_sq_computer import LstSqComputer from rednose.helpers.sympy_helpers import euler_rotate, quat_matrix_r, quat_rotate -EARTH_GM = 3.986005e14 # m^3/s^2 (gravitational constant * mass of earth) - - -def parse_prr(m): - from laika.raw_gnss import GNSSMeasurement - sat_pos_vel_i = np.concatenate((m[GNSSMeasurement.SAT_POS], - m[GNSSMeasurement.SAT_VEL])) - R_i = np.atleast_2d(m[GNSSMeasurement.PRR_STD]**2) - z_i = m[GNSSMeasurement.PRR] - return z_i, R_i, sat_pos_vel_i - - -def parse_pr(m): - from laika.raw_gnss import GNSSMeasurement - pseudorange = m[GNSSMeasurement.PR] - pseudorange_stdev = m[GNSSMeasurement.PR_STD] - sat_pos_freq_i = np.concatenate((m[GNSSMeasurement.SAT_POS], - np.array([m[GNSSMeasurement.GLONASS_FREQ]]))) - z_i = np.atleast_1d(pseudorange) - R_i = np.atleast_2d(pseudorange_stdev**2) - return z_i, R_i, sat_pos_freq_i +from selfdrive.locationd.models.constants import ObservationKind +from selfdrive.locationd.models.gnss_helpers import parse_pr, parse_prr +EARTH_GM = 3.986005e14 # m^3/s^2 (gravitational constant * mass of earth) class States(): ECEF_POS = slice(0, 3) # x, y and z in ECEF in meters diff --git a/selfdrive/locationd/paramsd.py b/selfdrive/locationd/paramsd.py index 0e83728e5c..ae67dc28ab 100755 --- a/selfdrive/locationd/paramsd.py +++ b/selfdrive/locationd/paramsd.py @@ -10,7 +10,7 @@ from common.realtime import config_realtime_process, DT_MDL from common.numpy_fast import clip from selfdrive.locationd.models.car_kf import CarKalman, ObservationKind, States from selfdrive.locationd.models.constants import GENERATED_DIR -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog MAX_ANGLE_OFFSET_DELTA = 20 * DT_MDL # Max 20 deg/s diff --git a/selfdrive/locationd/test/test_laikad.py b/selfdrive/locationd/test/test_laikad.py new file mode 100755 index 0000000000..3a72303b0c --- /dev/null +++ b/selfdrive/locationd/test/test_laikad.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python3 +import time +import unittest +from collections import defaultdict +from datetime import datetime +from unittest import mock +from unittest.mock import Mock, patch + +from common.params import Params +from laika.ephemeris import EphemerisType, GPSEphemeris +from laika.gps_time import GPSTime +from laika.helpers import ConstellationId, TimeRangeHolder +from laika.raw_gnss import GNSSMeasurement, read_raw_ublox +from selfdrive.locationd.laikad import EPHEMERIS_CACHE, EphemerisSourceType, Laikad, create_measurement_msg +from selfdrive.test.openpilotci import get_url +from tools.lib.logreader import LogReader + + +def get_log(segs=range(0)): + logs = [] + for i in segs: + logs.extend(LogReader(get_url("4cf7a6ad03080c90|2021-09-29--13-46-36", i))) + return [m for m in logs if m.which() == 'ubloxGnss'] + + +def verify_messages(lr, laikad, return_one_success=False): + good_msgs = [] + for m in lr: + msg = laikad.process_ublox_msg(m.ubloxGnss, m.logMonoTime, block=True) + if msg is not None and len(msg.gnssMeasurements.correctedMeasurements) > 0: + good_msgs.append(msg) + if return_one_success: + return msg + return good_msgs + + +def get_first_gps_time(logs): + for m in logs: + if m.ubloxGnss.which == 'measurementReport': + new_meas = read_raw_ublox(m.ubloxGnss.measurementReport) + if len(new_meas) > 0: + return new_meas[0].recv_time + + +def get_measurement_mock(gpstime, sat_ephemeris): + meas = GNSSMeasurement(ConstellationId.GPS, 1, gpstime.week, gpstime.tow, {'C1C': 0., 'D1C': 0.}, {'C1C': 0., 'D1C': 0.}) + # Fake measurement being processed + meas.observables_final = meas.observables + meas.sat_ephemeris = sat_ephemeris + return meas + + +class TestLaikad(unittest.TestCase): + + @classmethod + def setUpClass(cls): + logs = get_log(range(1)) + cls.logs = logs + first_gps_time = get_first_gps_time(logs) + cls.first_gps_time = first_gps_time + + def setUp(self): + Params().delete(EPHEMERIS_CACHE) + + def test_ephemeris_source_in_msg(self): + data_mock = defaultdict(str) + data_mock['sv_id'] = 1 + + gpstime = GPSTime.from_datetime(datetime(2022, month=3, day=1)) + laikad = Laikad() + laikad.fetch_orbits(gpstime, block=True) + meas = get_measurement_mock(gpstime, laikad.astro_dog.orbits['R01'][0]) + msg = create_measurement_msg(meas) + self.assertEqual(msg.ephemerisSource.type.raw, EphemerisSourceType.glonassIacUltraRapid) + # Verify gps satellite returns same source + meas = get_measurement_mock(gpstime, laikad.astro_dog.orbits['R01'][0]) + msg = create_measurement_msg(meas) + self.assertEqual(msg.ephemerisSource.type.raw, EphemerisSourceType.glonassIacUltraRapid) + + # Test nasa source by using older date + gpstime = GPSTime.from_datetime(datetime(2021, month=3, day=1)) + laikad = Laikad() + laikad.fetch_orbits(gpstime, block=True) + meas = get_measurement_mock(gpstime, laikad.astro_dog.orbits['G01'][0]) + msg = create_measurement_msg(meas) + self.assertEqual(msg.ephemerisSource.type.raw, EphemerisSourceType.nasaUltraRapid) + + # Test nav source type + ephem = GPSEphemeris(data_mock, gpstime) + meas = get_measurement_mock(gpstime, ephem) + msg = create_measurement_msg(meas) + self.assertEqual(msg.ephemerisSource.type.raw, EphemerisSourceType.nav) + + def test_laika_online(self): + laikad = Laikad(auto_update=True, valid_ephem_types=EphemerisType.ULTRA_RAPID_ORBIT) + correct_msgs = verify_messages(self.logs, laikad) + + correct_msgs_expected = 560 + self.assertEqual(correct_msgs_expected, len(correct_msgs)) + self.assertEqual(correct_msgs_expected, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid])) + + def test_laika_online_nav_only(self): + laikad = Laikad(auto_update=True, valid_ephem_types=EphemerisType.NAV) + # Disable fetch_orbits to test NAV only + laikad.fetch_orbits = Mock() + correct_msgs = verify_messages(self.logs, laikad) + correct_msgs_expected = 560 + self.assertEqual(correct_msgs_expected, len(correct_msgs)) + self.assertEqual(correct_msgs_expected, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid])) + + @mock.patch('laika.downloader.download_and_cache_file') + def test_laika_offline(self, downloader_mock): + downloader_mock.side_effect = IOError + laikad = Laikad(auto_update=False) + correct_msgs = verify_messages(self.logs, laikad) + self.assertEqual(256, len(correct_msgs)) + self.assertEqual(256, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid])) + + def test_laika_get_orbits(self): + laikad = Laikad(auto_update=False) + # Pretend process has loaded the orbits on startup by using the time of the first gps message. + laikad.fetch_orbits(self.first_gps_time, block=True) + self.dict_has_values(laikad.astro_dog.orbits) + + @unittest.skip("Use to debug live data") + def test_laika_get_orbits_now(self): + laikad = Laikad(auto_update=False) + laikad.fetch_orbits(GPSTime.from_datetime(datetime.utcnow()), block=True) + prn = "G01" + self.assertGreater(len(laikad.astro_dog.orbits[prn]), 0) + prn = "R01" + self.assertGreater(len(laikad.astro_dog.orbits[prn]), 0) + print(min(laikad.astro_dog.orbits[prn], key=lambda e: e.epoch).epoch.as_datetime()) + + def test_get_orbits_in_process(self): + laikad = Laikad(auto_update=False) + has_orbits = False + for m in self.logs: + laikad.process_ublox_msg(m.ubloxGnss, m.logMonoTime, block=False) + if laikad.orbit_fetch_future is not None: + laikad.orbit_fetch_future.result() + vals = laikad.astro_dog.orbits.values() + has_orbits = len(vals) > 0 and max([len(v) for v in vals]) > 0 + if has_orbits: + break + self.assertTrue(has_orbits) + self.assertGreater(len(laikad.astro_dog.orbit_fetched_times._ranges), 0) + self.assertEqual(None, laikad.orbit_fetch_future) + + def test_cache(self): + laikad = Laikad(auto_update=True, save_ephemeris=True) + + def wait_for_cache(): + max_time = 2 + while Params().get(EPHEMERIS_CACHE) is None: + time.sleep(0.1) + max_time -= 0.1 + if max_time == 0: + self.fail("Cache has not been written after 2 seconds") + + # Test cache with no ephemeris + laikad.cache_ephemeris(t=GPSTime(0, 0)) + wait_for_cache() + Params().delete(EPHEMERIS_CACHE) + + laikad.astro_dog.get_navs(self.first_gps_time) + laikad.fetch_orbits(self.first_gps_time, block=True) + + # Wait for cache to save + wait_for_cache() + + # Check both nav and orbits separate + laikad = Laikad(auto_update=False, valid_ephem_types=EphemerisType.NAV) + # Verify orbits and nav are loaded from cache + self.dict_has_values(laikad.astro_dog.orbits) + self.dict_has_values(laikad.astro_dog.nav) + # Verify cache is working for only nav by running a segment + msg = verify_messages(self.logs, laikad, return_one_success=True) + self.assertIsNotNone(msg) + + with patch('selfdrive.locationd.laikad.get_orbit_data', return_value=None) as mock_method: + # Verify no orbit downloads even if orbit fetch times is reset since the cache has recently been saved and we don't want to download high frequently + laikad.astro_dog.orbit_fetched_times = TimeRangeHolder() + laikad.fetch_orbits(self.first_gps_time, block=False) + mock_method.assert_not_called() + + # Verify cache is working for only orbits by running a segment + laikad = Laikad(auto_update=False, valid_ephem_types=EphemerisType.ULTRA_RAPID_ORBIT) + msg = verify_messages(self.logs, laikad, return_one_success=True) + self.assertIsNotNone(msg) + # Verify orbit data is not downloaded + mock_method.assert_not_called() + + def dict_has_values(self, dct): + self.assertGreater(len(dct), 0) + self.assertGreater(min([len(v) for v in dct.values()]), 0) + + +if __name__ == "__main__": + unittest.main() diff --git a/selfdrive/locationd/test/test_locationd.py b/selfdrive/locationd/test/test_locationd.py index 5c0143bdbf..7f5d752100 100755 --- a/selfdrive/locationd/test/test_locationd.py +++ b/selfdrive/locationd/test/test_locationd.py @@ -108,7 +108,7 @@ void localizer_handle_msg_bytes(Localizer_t localizer, const char *data, size_t class TestLocationdProc(unittest.TestCase): MAX_WAITS = 1000 - LLD_MSGS = {'gpsLocationExternal', 'cameraOdometry', 'carState', 'sensorEvents', 'liveCalibration'} + LLD_MSGS = ['gpsLocationExternal', 'cameraOdometry', 'carState', 'sensorEvents', 'liveCalibration'] def setUp(self): random.seed(123489234) diff --git a/selfdrive/locationd/test/test_ublox_processing.py b/selfdrive/locationd/test/test_ublox_processing.py new file mode 100755 index 0000000000..427003b24c --- /dev/null +++ b/selfdrive/locationd/test/test_ublox_processing.py @@ -0,0 +1,80 @@ +import unittest + +import numpy as np + +from laika import AstroDog +from laika.helpers import ConstellationId +from laika.raw_gnss import calc_pos_fix, correct_measurements, process_measurements, read_raw_ublox +from selfdrive.test.openpilotci import get_url +from tools.lib.logreader import LogReader + + +def get_gnss_measurements(log_reader): + gnss_measurements = [] + for msg in log_reader: + if msg.which() == "ubloxGnss": + ublox_msg = msg.ubloxGnss + if ublox_msg.which == 'measurementReport': + report = ublox_msg.measurementReport + if len(report.measurements) > 0: + gnss_measurements.append(read_raw_ublox(report)) + return gnss_measurements + + +class TestUbloxProcessing(unittest.TestCase): + NUM_TEST_PROCESS_MEAS = 10 + + @classmethod + def setUpClass(cls): + lr = LogReader(get_url("4cf7a6ad03080c90|2021-09-29--13-46-36", 0)) + cls.gnss_measurements = get_gnss_measurements(lr) + + def test_read_ublox_raw(self): + count_gps = 0 + count_glonass = 0 + for measurements in self.gnss_measurements: + for m in measurements: + if m.constellation_id == ConstellationId.GPS: + count_gps += 1 + elif m.constellation_id == ConstellationId.GLONASS: + count_glonass += 1 + + self.assertEqual(count_gps, 5036) + self.assertEqual(count_glonass, 3651) + + def test_get_fix(self): + dog = AstroDog() + position_fix_found = 0 + count_processed_measurements = 0 + count_corrected_measurements = 0 + position_fix_found_after_correcting = 0 + + pos_ests = [] + for measurements in self.gnss_measurements[:self.NUM_TEST_PROCESS_MEAS]: + processed_meas = process_measurements(measurements, dog) + count_processed_measurements += len(processed_meas) + pos_fix = calc_pos_fix(processed_meas) + if len(pos_fix) > 0 and all(pos_fix[0] != 0): + position_fix_found += 1 + + corrected_meas = correct_measurements(processed_meas, pos_fix[0][:3], dog) + count_corrected_measurements += len(corrected_meas) + + pos_fix = calc_pos_fix(corrected_meas) + if len(pos_fix) > 0 and all(pos_fix[0] != 0): + pos_ests.append(pos_fix[0]) + position_fix_found_after_correcting += 1 + + mean_fix = np.mean(np.array(pos_ests)[:, :3], axis=0) + np.testing.assert_allclose(mean_fix, [-2452306.662377, -4778343.136806, 3428550.090557], rtol=0, atol=1) + + # Note that can happen that there are less corrected measurements compared to processed when they are invalid. + # However, not for the current segment + self.assertEqual(position_fix_found, self.NUM_TEST_PROCESS_MEAS) + self.assertEqual(position_fix_found_after_correcting, self.NUM_TEST_PROCESS_MEAS) + self.assertEqual(count_processed_measurements, 69) + self.assertEqual(count_corrected_measurements, 69) + + +if __name__ == "__main__": + unittest.main() diff --git a/selfdrive/locationd/ublox_msg.cc b/selfdrive/locationd/ublox_msg.cc index 9e32c7b070..c9833410e7 100644 --- a/selfdrive/locationd/ublox_msg.cc +++ b/selfdrive/locationd/ublox_msg.cc @@ -10,7 +10,7 @@ #include #include -#include "selfdrive/common/swaglog.h" +#include "common/swaglog.h" const double gpsPi = 3.1415926535898; #define UBLOX_MSG_SIZE(hdr) (*(uint16_t *)&hdr[4]) diff --git a/selfdrive/locationd/ublox_msg.h b/selfdrive/locationd/ublox_msg.h index da1c180c0b..542e72816b 100644 --- a/selfdrive/locationd/ublox_msg.h +++ b/selfdrive/locationd/ublox_msg.h @@ -8,7 +8,7 @@ #include #include "cereal/messaging/messaging.h" -#include "selfdrive/common/util.h" +#include "common/util.h" #include "selfdrive/locationd/generated/gps.h" #include "selfdrive/locationd/generated/ubx.h" diff --git a/selfdrive/locationd/ubloxd.cc b/selfdrive/locationd/ubloxd.cc index ae07284c8e..d9b3e7647d 100644 --- a/selfdrive/locationd/ubloxd.cc +++ b/selfdrive/locationd/ubloxd.cc @@ -3,8 +3,8 @@ #include #include "cereal/messaging/messaging.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" +#include "common/swaglog.h" +#include "common/util.h" #include "selfdrive/locationd/ublox_msg.h" ExitHandler do_exit; diff --git a/selfdrive/loggerd/.gitignore b/selfdrive/loggerd/.gitignore index 4a8755b956..6437be5e38 100644 --- a/selfdrive/loggerd/.gitignore +++ b/selfdrive/loggerd/.gitignore @@ -1,2 +1,3 @@ loggerd +encoderd tests/test_logger diff --git a/selfdrive/loggerd/SConscript b/selfdrive/loggerd/SConscript index 92cc37a5fb..a15aac380d 100644 --- a/selfdrive/loggerd/SConscript +++ b/selfdrive/loggerd/SConscript @@ -1,17 +1,15 @@ -Import('env', 'arch', 'cereal', 'messaging', 'common', 'visionipc', 'gpucommon') - +Import('env', 'arch', 'cereal', 'messaging', 'common', 'visionipc') libs = [common, cereal, messaging, visionipc, 'zmq', 'capnp', 'kj', 'z', 'avformat', 'avcodec', 'swscale', 'avutil', - 'yuv', 'bz2', 'OpenCL', 'pthread'] + 'yuv', 'OpenCL', 'pthread'] -src = ['logger.cc', 'loggerd.cc', 'video_writer.cc'] +src = ['logger.cc', 'video_writer.cc', 'encoder/encoder.cc'] if arch == "larch64": - src += ['omx_encoder.cc'] - libs += ['OmxCore', 'gsl', 'CB'] + gpucommon + src += ['encoder/v4l_encoder.cc'] else: - src += ['raw_logger.cc'] + src += ['encoder/ffmpeg_encoder.cc'] if arch == "Darwin": # fix OpenCL @@ -21,8 +19,9 @@ if arch == "Darwin": logger_lib = env.Library('logger', src) libs.insert(0, logger_lib) -env.Program('loggerd', ['main.cc'], LIBS=libs) +env.Program('loggerd', ['loggerd.cc'], LIBS=libs) +env.Program('encoderd', ['encoderd.cc'], LIBS=libs) env.Program('bootlog.cc', LIBS=libs) if GetOption('test'): - env.Program('tests/test_logger', ['tests/test_runner.cc', 'tests/test_loggerd.cc', 'tests/test_logger.cc', env.Object('logger_util', '#/selfdrive/ui/replay/util.cc')], LIBS=libs + ['curl', 'crypto']) + env.Program('tests/test_logger', ['tests/test_runner.cc', 'tests/test_logger.cc'], LIBS=libs + ['curl', 'crypto']) diff --git a/selfdrive/loggerd/bootlog.cc b/selfdrive/loggerd/bootlog.cc index e7ce308cec..882b749fe9 100644 --- a/selfdrive/loggerd/bootlog.cc +++ b/selfdrive/loggerd/bootlog.cc @@ -2,13 +2,13 @@ #include #include "cereal/messaging/messaging.h" -#include "selfdrive/common/swaglog.h" +#include "common/swaglog.h" #include "selfdrive/loggerd/logger.h" static kj::Array build_boot_log() { std::vector bootlog_commands; - if (Hardware::TICI()) { + if (Hardware::AGNOS()) { bootlog_commands.push_back("journalctl"); bootlog_commands.push_back("sudo nvme smart-log --output-format=json /dev/nvme0"); } @@ -49,14 +49,14 @@ static kj::Array build_boot_log() { } int main(int argc, char** argv) { - const std::string path = LOG_ROOT + "/boot/" + logger_get_route_name() + ".bz2"; + const std::string path = LOG_ROOT + "/boot/" + logger_get_route_name(); LOGW("bootlog to %s", path.c_str()); // Open bootlog bool r = util::create_directories(LOG_ROOT + "/boot/", 0775); assert(r); - BZFile bz_file(path.c_str()); + RawFile bz_file(path.c_str()); // Write initdata bz_file.write(logger_build_init_data().asBytes()); diff --git a/selfdrive/loggerd/config.py b/selfdrive/loggerd/config.py index 6cd20a68ab..168c9fba91 100644 --- a/selfdrive/loggerd/config.py +++ b/selfdrive/loggerd/config.py @@ -1,6 +1,6 @@ import os from pathlib import Path -from selfdrive.hardware import PC +from system.hardware import PC if os.environ.get('LOG_ROOT', False): ROOT = os.environ['LOG_ROOT'] diff --git a/selfdrive/loggerd/deleter.py b/selfdrive/loggerd/deleter.py index d745e91fb5..5606288024 100644 --- a/selfdrive/loggerd/deleter.py +++ b/selfdrive/loggerd/deleter.py @@ -2,7 +2,7 @@ import os import shutil import threading -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog from selfdrive.loggerd.config import ROOT, get_available_bytes, get_available_percent from selfdrive.loggerd.uploader import listdir_by_creation diff --git a/selfdrive/loggerd/encoder.h b/selfdrive/loggerd/encoder.h deleted file mode 100644 index 3d9f957d9f..0000000000 --- a/selfdrive/loggerd/encoder.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include -#include "selfdrive/loggerd/loggerd.h" - -class VideoEncoder { -public: - virtual ~VideoEncoder() {} - virtual int encode_frame(const uint8_t *y_ptr, const uint8_t *u_ptr, const uint8_t *v_ptr, - int in_width, int in_height, uint64_t ts) = 0; - virtual void encoder_open(const char* path) = 0; - virtual void encoder_close() = 0; -}; diff --git a/selfdrive/loggerd/encoder/encoder.cc b/selfdrive/loggerd/encoder/encoder.cc new file mode 100644 index 0000000000..943f37803d --- /dev/null +++ b/selfdrive/loggerd/encoder/encoder.cc @@ -0,0 +1,82 @@ +#include +#include "selfdrive/loggerd/encoder/encoder.h" + +VideoEncoder::~VideoEncoder() {} + +void VideoEncoder::publisher_init() { + // publish + service_name = this->type == DriverCam ? "driverEncodeData" : + (this->type == WideRoadCam ? "wideRoadEncodeData" : + (this->in_width == this->out_width ? "roadEncodeData" : "qRoadEncodeData")); + pm.reset(new PubMaster({service_name})); +} + +void VideoEncoder::publisher_publish(VideoEncoder *e, int segment_num, uint32_t idx, VisionIpcBufExtra &extra, + unsigned int flags, kj::ArrayPtr header, kj::ArrayPtr dat) { + // broadcast packet + MessageBuilder msg; + auto event = msg.initEvent(true); + auto edat = (e->type == DriverCam) ? event.initDriverEncodeData() : + ((e->type == WideRoadCam) ? event.initWideRoadEncodeData() : + (e->in_width == e->out_width ? event.initRoadEncodeData() : event.initQRoadEncodeData())); + auto edata = edat.initIdx(); + struct timespec ts; + timespec_get(&ts, TIME_UTC); + edat.setUnixTimestampNanos((uint64_t)ts.tv_sec*1000000000 + ts.tv_nsec); + edata.setFrameId(extra.frame_id); + edata.setTimestampSof(extra.timestamp_sof); + edata.setTimestampEof(extra.timestamp_eof); + edata.setType(e->codec); + edata.setEncodeId(e->cnt++); + edata.setSegmentNum(segment_num); + edata.setSegmentId(idx); + edata.setFlags(flags); + edata.setLen(dat.size()); + edat.setData(dat); + if (flags & V4L2_BUF_FLAG_KEYFRAME) edat.setHeader(header); + + auto words = new kj::Array(capnp::messageToFlatArray(msg)); + auto bytes = words->asBytes(); + e->pm->send(e->service_name, bytes.begin(), bytes.size()); + if (e->write) { + e->to_write.push(words); + } else { + delete words; + } +} + +// TODO: writing should be moved to loggerd +void VideoEncoder::write_handler(VideoEncoder *e, const char *path) { + VideoWriter writer(path, e->filename, e->codec != cereal::EncodeIndex::Type::FULL_H_E_V_C, e->out_width, e->out_height, e->fps, e->codec); + + bool first = true; + kj::Array* out_buf; + while ((out_buf = e->to_write.pop())) { + capnp::FlatArrayMessageReader cmsg(*out_buf); + cereal::Event::Reader event = cmsg.getRoot(); + + auto edata = (e->type == DriverCam) ? event.getDriverEncodeData() : + ((e->type == WideRoadCam) ? event.getWideRoadEncodeData() : + (e->in_width == e->out_width ? event.getRoadEncodeData() : event.getQRoadEncodeData())); + auto idx = edata.getIdx(); + auto flags = idx.getFlags(); + + if (first) { + assert(flags & V4L2_BUF_FLAG_KEYFRAME); + auto header = edata.getHeader(); + writer.write((uint8_t *)header.begin(), header.size(), idx.getTimestampEof()/1000, true, false); + first = false; + } + + // dangerous cast from const, but should be fine + auto data = edata.getData(); + if (data.size() > 0) { + writer.write((uint8_t *)data.begin(), data.size(), idx.getTimestampEof()/1000, false, flags & V4L2_BUF_FLAG_KEYFRAME); + } + + // free the data + delete out_buf; + } + + // VideoWriter is freed on out of scope +} diff --git a/selfdrive/loggerd/encoder/encoder.h b/selfdrive/loggerd/encoder/encoder.h new file mode 100644 index 0000000000..312b68ba19 --- /dev/null +++ b/selfdrive/loggerd/encoder/encoder.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include +#include + +#include "cereal/messaging/messaging.h" +#include "cereal/visionipc/visionipc.h" +#include "common/queue.h" +#include "selfdrive/loggerd/video_writer.h" +#include "selfdrive/camerad/cameras/camera_common.h" + +#define V4L2_BUF_FLAG_KEYFRAME 8 + +class VideoEncoder { +public: + VideoEncoder(const char* filename, CameraType type, int in_width, int in_height, int fps, + int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height, bool write) + : filename(filename), type(type), in_width(in_width), in_height(in_height), fps(fps), + bitrate(bitrate), codec(codec), out_width(out_width), out_height(out_height), write(write) { } + virtual ~VideoEncoder(); + virtual int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) = 0; + virtual void encoder_open(const char* path) = 0; + virtual void encoder_close() = 0; + + void publisher_init(); + static void publisher_publish(VideoEncoder *e, int segment_num, uint32_t idx, VisionIpcBufExtra &extra, unsigned int flags, kj::ArrayPtr header, kj::ArrayPtr dat); + + void writer_open(const char* path) { + if (this->write) write_handler_thread = std::thread(VideoEncoder::write_handler, this, path); + } + + void writer_close() { + if (this->write) { + to_write.push(NULL); + write_handler_thread.join(); + } + assert(to_write.empty()); + } + +protected: + bool write; + const char* filename; + int in_width, in_height; + int out_width, out_height, fps; + int bitrate; + cereal::EncodeIndex::Type codec; + CameraType type; + +private: + // total frames encoded + int cnt = 0; + + // publishing + std::unique_ptr pm; + const char *service_name; + + // writing support + static void write_handler(VideoEncoder *e, const char *path); + std::thread write_handler_thread; + SafeQueue* > to_write; +}; diff --git a/selfdrive/loggerd/encoder/ffmpeg_encoder.cc b/selfdrive/loggerd/encoder/ffmpeg_encoder.cc new file mode 100644 index 0000000000..22587819a4 --- /dev/null +++ b/selfdrive/loggerd/encoder/ffmpeg_encoder.cc @@ -0,0 +1,151 @@ +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +#include "selfdrive/loggerd/encoder/ffmpeg_encoder.h" + +#include +#include + +#include +#include +#include + +#define __STDC_CONSTANT_MACROS + +#include "libyuv.h" + +extern "C" { +#include +#include +#include +} + +#include "common/swaglog.h" +#include "common/util.h" + +const int env_debug_encoder = (getenv("DEBUG_ENCODER") != NULL) ? atoi(getenv("DEBUG_ENCODER")) : 0; + +void FfmpegEncoder::encoder_init() { + frame = av_frame_alloc(); + assert(frame); + frame->format = AV_PIX_FMT_YUV420P; + frame->width = out_width; + frame->height = out_height; + frame->linesize[0] = out_width; + frame->linesize[1] = out_width/2; + frame->linesize[2] = out_width/2; + + convert_buf.resize(in_width * in_height * 3 / 2); + + if (in_width != out_width || in_height != out_height) { + downscale_buf.resize(out_width * out_height * 3 / 2); + } + + publisher_init(); +} + +FfmpegEncoder::~FfmpegEncoder() { + encoder_close(); + av_frame_free(&frame); +} + +void FfmpegEncoder::encoder_open(const char* path) { + const AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_FFVHUFF); + + this->codec_ctx = avcodec_alloc_context3(codec); + assert(this->codec_ctx); + this->codec_ctx->width = frame->width; + this->codec_ctx->height = frame->height; + this->codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P; + this->codec_ctx->time_base = (AVRational){ 1, fps }; + int err = avcodec_open2(this->codec_ctx, codec, NULL); + assert(err >= 0); + + writer_open(path); + is_open = true; + segment_num++; + counter = 0; +} + +void FfmpegEncoder::encoder_close() { + if (!is_open) return; + writer_close(); + is_open = false; +} + +int FfmpegEncoder::encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) { + assert(buf->width == this->in_width); + assert(buf->height == this->in_height); + + uint8_t *cy = convert_buf.data(); + uint8_t *cu = cy + in_width * in_height; + uint8_t *cv = cu + (in_width / 2) * (in_height / 2); + libyuv::NV12ToI420(buf->y, buf->stride, + buf->uv, buf->stride, + cy, in_width, + cu, in_width/2, + cv, in_width/2, + in_width, in_height); + + if (downscale_buf.size() > 0) { + uint8_t *out_y = downscale_buf.data(); + uint8_t *out_u = out_y + frame->width * frame->height; + uint8_t *out_v = out_u + (frame->width / 2) * (frame->height / 2); + libyuv::I420Scale(cy, in_width, + cu, in_width/2, + cv, in_width/2, + in_width, in_height, + out_y, frame->width, + out_u, frame->width/2, + out_v, frame->width/2, + frame->width, frame->height, + libyuv::kFilterNone); + frame->data[0] = out_y; + frame->data[1] = out_u; + frame->data[2] = out_v; + } else { + frame->data[0] = cy; + frame->data[1] = cu; + frame->data[2] = cv; + } + frame->pts = counter*50*1000; // 50ms per frame + + int ret = counter; + + int err = avcodec_send_frame(this->codec_ctx, frame); + if (err < 0) { + LOGE("avcodec_send_frame error %d", err); + ret = -1; + } + + AVPacket pkt; + av_init_packet(&pkt); + pkt.data = NULL; + pkt.size = 0; + while (ret >= 0) { + err = avcodec_receive_packet(this->codec_ctx, &pkt); + if (err == AVERROR_EOF) { + break; + } else if (err == AVERROR(EAGAIN)) { + // Encoder might need a few frames on startup to get started. Keep going + ret = 0; + break; + } else if (err < 0) { + LOGE("avcodec_receive_packet error %d", err); + ret = -1; + break; + } + + if (env_debug_encoder) { + printf("%20s got %8d bytes flags %8x idx %4d id %8d\n", this->filename, pkt.size, pkt.flags, counter, extra->frame_id); + } + + publisher_publish(this, segment_num, counter, *extra, + (pkt.flags & AV_PKT_FLAG_KEY) ? V4L2_BUF_FLAG_KEYFRAME : 0, + kj::arrayPtr(pkt.data, (size_t)0), // TODO: get the header + kj::arrayPtr(pkt.data, pkt.size)); + + counter++; + } + av_packet_unref(&pkt); + return ret; +} diff --git a/selfdrive/loggerd/encoder/ffmpeg_encoder.h b/selfdrive/loggerd/encoder/ffmpeg_encoder.h new file mode 100644 index 0000000000..497a28b651 --- /dev/null +++ b/selfdrive/loggerd/encoder/ffmpeg_encoder.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include +#include + +extern "C" { +#include +#include +#include +} + +#include "selfdrive/loggerd/encoder/encoder.h" +#include "selfdrive/loggerd/loggerd.h" + +class FfmpegEncoder : public VideoEncoder { + public: + FfmpegEncoder(const char* filename, CameraType type, int in_width, int in_height, int fps, + int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height, bool write) : + VideoEncoder(filename, type, in_width, in_height, fps, bitrate, cereal::EncodeIndex::Type::BIG_BOX_LOSSLESS, out_width, out_height, write) { encoder_init(); } + ~FfmpegEncoder(); + void encoder_init(); + int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra); + void encoder_open(const char* path); + void encoder_close(); + +private: + int segment_num = -1; + int counter = 0; + bool is_open = false; + + AVCodecContext *codec_ctx; + AVFrame *frame = NULL; + std::vector convert_buf; + std::vector downscale_buf; +}; diff --git a/selfdrive/loggerd/encoder/v4l_encoder.cc b/selfdrive/loggerd/encoder/v4l_encoder.cc new file mode 100644 index 0000000000..b3bd692b16 --- /dev/null +++ b/selfdrive/loggerd/encoder/v4l_encoder.cc @@ -0,0 +1,306 @@ +#include +#include +#include + +#include "selfdrive/loggerd/encoder/v4l_encoder.h" +#include "common/util.h" +#include "common/timing.h" + +#include "libyuv.h" +#include "msm_media_info.h" + +// has to be in this order +#include "v4l2-controls.h" +#include +#define V4L2_QCOM_BUF_FLAG_CODECCONFIG 0x00020000 +#define V4L2_QCOM_BUF_FLAG_EOS 0x02000000 + +// echo 0x7fffffff > /sys/kernel/debug/msm_vidc/debug_level +const int env_debug_encoder = (getenv("DEBUG_ENCODER") != NULL) ? atoi(getenv("DEBUG_ENCODER")) : 0; + +#define checked_ioctl(x,y,z) { int _ret = HANDLE_EINTR(ioctl(x,y,z)); if (_ret!=0) { LOGE("checked_ioctl failed %d %lx %p", x, y, z); } assert(_ret==0); } + +static void dequeue_buffer(int fd, v4l2_buf_type buf_type, unsigned int *index=NULL, unsigned int *bytesused=NULL, unsigned int *flags=NULL, struct timeval *timestamp=NULL) { + v4l2_plane plane = {0}; + v4l2_buffer v4l_buf = { + .type = buf_type, + .memory = V4L2_MEMORY_USERPTR, + .m = { .planes = &plane, }, + .length = 1, + }; + checked_ioctl(fd, VIDIOC_DQBUF, &v4l_buf); + + if (index) *index = v4l_buf.index; + if (bytesused) *bytesused = v4l_buf.m.planes[0].bytesused; + if (flags) *flags = v4l_buf.flags; + if (timestamp) *timestamp = v4l_buf.timestamp; + assert(v4l_buf.m.planes[0].data_offset == 0); +} + +static void queue_buffer(int fd, v4l2_buf_type buf_type, unsigned int index, VisionBuf *buf, struct timeval timestamp={0}, unsigned int bytesused=0) { + v4l2_plane plane = { + .length = (unsigned int)buf->len, + .m = { .userptr = (unsigned long)buf->addr, }, + .bytesused = bytesused, + .reserved = {(unsigned int)buf->fd} + }; + + v4l2_buffer v4l_buf = { + .type = buf_type, + .index = index, + .memory = V4L2_MEMORY_USERPTR, + .m = { .planes = &plane, }, + .length = 1, + .bytesused = 0, + .flags = V4L2_BUF_FLAG_TIMESTAMP_COPY, + .timestamp = timestamp + }; + + checked_ioctl(fd, VIDIOC_QBUF, &v4l_buf); +} + +static void request_buffers(int fd, v4l2_buf_type buf_type, unsigned int count) { + struct v4l2_requestbuffers reqbuf = { + .type = buf_type, + .memory = V4L2_MEMORY_USERPTR, + .count = count + }; + checked_ioctl(fd, VIDIOC_REQBUFS, &reqbuf); +} + +void V4LEncoder::dequeue_handler(V4LEncoder *e) { + std::string dequeue_thread_name = "dq-"+std::string(e->filename); + util::set_thread_name(dequeue_thread_name.c_str()); + + e->segment_num++; + uint32_t idx = -1; + bool exit = false; + + // POLLIN is capture, POLLOUT is frame + struct pollfd pfd; + pfd.events = POLLIN | POLLOUT; + pfd.fd = e->fd; + + // save the header + kj::Array header; + + while (!exit) { + int rc = poll(&pfd, 1, 1000); + if (!rc) { LOGE("encoder dequeue poll timeout"); continue; } + + if (env_debug_encoder >= 2) { + printf("%20s poll %x at %.2f ms\n", e->filename, pfd.revents, millis_since_boot()); + } + + int frame_id = -1; + if (pfd.revents & POLLIN) { + unsigned int bytesused, flags, index; + struct timeval timestamp; + dequeue_buffer(e->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, &index, &bytesused, &flags, ×tamp); + e->buf_out[index].sync(VISIONBUF_SYNC_FROM_DEVICE); + uint8_t *buf = (uint8_t*)e->buf_out[index].addr; + int64_t ts = timestamp.tv_sec * 1000000 + timestamp.tv_usec; + + // eof packet, we exit + if (flags & V4L2_QCOM_BUF_FLAG_EOS) { + exit = true; + } else if (flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG) { + // save header + header = kj::heapArray(buf, bytesused); + } else { + VisionIpcBufExtra extra = e->extras.pop(); + assert(extra.timestamp_eof/1000 == ts); // stay in sync + frame_id = extra.frame_id; + ++idx; + e->publisher_publish(e, e->segment_num, idx, extra, flags, header, kj::arrayPtr(buf, bytesused)); + } + + if (env_debug_encoder) { + printf("%20s got(%d) %6d bytes flags %8x idx %3d/%4d id %8d ts %ld lat %.2f ms (%lu frames free)\n", + e->filename, index, bytesused, flags, e->segment_num, idx, frame_id, ts, millis_since_boot()-(ts/1000.), e->free_buf_in.size()); + } + + // requeue the buffer + queue_buffer(e->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, index, &e->buf_out[index]); + } + + if (pfd.revents & POLLOUT) { + unsigned int index; + dequeue_buffer(e->fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, &index); + e->free_buf_in.push(index); + } + } +} + +void V4LEncoder::encoder_init() { + fd = open("/dev/v4l/by-path/platform-aa00000.qcom_vidc-video-index1", O_RDWR|O_NONBLOCK); + assert(fd >= 0); + + struct v4l2_capability cap; + checked_ioctl(fd, VIDIOC_QUERYCAP, &cap); + LOGD("opened encoder device %s %s = %d", cap.driver, cap.card, fd); + assert(strcmp((const char *)cap.driver, "msm_vidc_driver") == 0); + assert(strcmp((const char *)cap.card, "msm_vidc_venc") == 0); + + struct v4l2_format fmt_out = { + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + .fmt = { + .pix_mp = { + // downscales are free with v4l + .width = (unsigned int)out_width, + .height = (unsigned int)out_height, + .pixelformat = (codec == cereal::EncodeIndex::Type::FULL_H_E_V_C) ? V4L2_PIX_FMT_HEVC : V4L2_PIX_FMT_H264, + .field = V4L2_FIELD_ANY, + .colorspace = V4L2_COLORSPACE_DEFAULT, + } + } + }; + checked_ioctl(fd, VIDIOC_S_FMT, &fmt_out); + + v4l2_streamparm streamparm = { + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .parm = { + .output = { + // TODO: more stuff here? we don't know + .timeperframe = { + .numerator = 1, + .denominator = 20 + } + } + } + }; + checked_ioctl(fd, VIDIOC_S_PARM, &streamparm); + + struct v4l2_format fmt_in = { + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .fmt = { + .pix_mp = { + .width = (unsigned int)in_width, + .height = (unsigned int)in_height, + .pixelformat = V4L2_PIX_FMT_NV12, + .field = V4L2_FIELD_ANY, + .colorspace = V4L2_COLORSPACE_470_SYSTEM_BG, + } + } + }; + checked_ioctl(fd, VIDIOC_S_FMT, &fmt_in); + + LOGD("in buffer size %d, out buffer size %d", + fmt_in.fmt.pix_mp.plane_fmt[0].sizeimage, + fmt_out.fmt.pix_mp.plane_fmt[0].sizeimage); + + // shared ctrls + { + struct v4l2_control ctrls[] = { + { .id = V4L2_CID_MPEG_VIDEO_HEADER_MODE, .value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE}, + { .id = V4L2_CID_MPEG_VIDEO_BITRATE, .value = bitrate}, + { .id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL, .value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR}, + { .id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY, .value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE}, + { .id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD, .value = 1}, + }; + for (auto ctrl : ctrls) { + checked_ioctl(fd, VIDIOC_S_CTRL, &ctrl); + } + } + + if (codec == cereal::EncodeIndex::Type::FULL_H_E_V_C) { + struct v4l2_control ctrls[] = { + { .id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE, .value = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN}, + { .id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL, .value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5}, + { .id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES, .value = 29}, + { .id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES, .value = 0}, + }; + for (auto ctrl : ctrls) { + checked_ioctl(fd, VIDIOC_S_CTRL, &ctrl); + } + } else { + struct v4l2_control ctrls[] = { + { .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE, .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH}, + { .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL, .value = V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN}, + { .id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES, .value = 14}, + { .id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES, .value = 0}, + { .id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, .value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC}, + { .id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL, .value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0}, + { .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, .value = 0}, + { .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, .value = 0}, + { .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, .value = 0}, + { .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, .value = 0}, + }; + for (auto ctrl : ctrls) { + checked_ioctl(fd, VIDIOC_S_CTRL, &ctrl); + } + } + + // allocate buffers + request_buffers(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, BUF_OUT_COUNT); + request_buffers(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, BUF_IN_COUNT); + + // start encoder + v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + checked_ioctl(fd, VIDIOC_STREAMON, &buf_type); + buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + checked_ioctl(fd, VIDIOC_STREAMON, &buf_type); + + // queue up output buffers + for (unsigned int i = 0; i < BUF_OUT_COUNT; i++) { + buf_out[i].allocate(fmt_out.fmt.pix_mp.plane_fmt[0].sizeimage); + queue_buffer(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, i, &buf_out[i]); + } + // queue up input buffers + for (unsigned int i = 0; i < BUF_IN_COUNT; i++) { + free_buf_in.push(i); + } + + publisher_init(); +} + +void V4LEncoder::encoder_open(const char* path) { + dequeue_handler_thread = std::thread(V4LEncoder::dequeue_handler, this); + writer_open(path); + this->is_open = true; + this->counter = 0; +} + +int V4LEncoder::encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) { + struct timeval timestamp { + .tv_sec = (long)(extra->timestamp_eof/1000000000), + .tv_usec = (long)((extra->timestamp_eof/1000) % 1000000), + }; + + // reserve buffer + int buffer_in = free_buf_in.pop(); + + // push buffer + extras.push(*extra); + //buf->sync(VISIONBUF_SYNC_TO_DEVICE); + queue_buffer(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, buffer_in, buf, timestamp); + + return this->counter++; +} + +void V4LEncoder::encoder_close() { + if (this->is_open) { + // pop all the frames before closing, then put the buffers back + for (int i = 0; i < BUF_IN_COUNT; i++) free_buf_in.pop(); + for (int i = 0; i < BUF_IN_COUNT; i++) free_buf_in.push(i); + // no frames, stop the encoder + struct v4l2_encoder_cmd encoder_cmd = { .cmd = V4L2_ENC_CMD_STOP }; + checked_ioctl(fd, VIDIOC_ENCODER_CMD, &encoder_cmd); + // join waits for V4L2_QCOM_BUF_FLAG_EOS + dequeue_handler_thread.join(); + assert(extras.empty()); + writer_close(); + } + this->is_open = false; +} + +V4LEncoder::~V4LEncoder() { + encoder_close(); + v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + checked_ioctl(fd, VIDIOC_STREAMOFF, &buf_type); + request_buffers(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 0); + buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + checked_ioctl(fd, VIDIOC_STREAMOFF, &buf_type); + request_buffers(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 0); + close(fd); +} diff --git a/selfdrive/loggerd/encoder/v4l_encoder.h b/selfdrive/loggerd/encoder/v4l_encoder.h new file mode 100644 index 0000000000..b7c378be85 --- /dev/null +++ b/selfdrive/loggerd/encoder/v4l_encoder.h @@ -0,0 +1,34 @@ +#pragma once + +#include "common/queue.h" +#include "selfdrive/loggerd/encoder/encoder.h" + +#define BUF_IN_COUNT 7 +#define BUF_OUT_COUNT 6 + +class V4LEncoder : public VideoEncoder { +public: + V4LEncoder(const char* filename, CameraType type, int in_width, int in_height, int fps, + int bitrate, cereal::EncodeIndex::Type codec, int out_width, int out_height, bool write) : + VideoEncoder(filename, type, in_width, in_height, fps, bitrate, codec, out_width, out_height, write) { encoder_init(); } + ~V4LEncoder(); + void encoder_init(); + int encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra); + void encoder_open(const char* path); + void encoder_close(); +private: + int fd; + + bool is_open = false; + int segment_num = -1; + int counter = 0; + + SafeQueue extras; + + static void dequeue_handler(V4LEncoder *e); + std::thread dequeue_handler_thread; + + VisionBuf buf_in[BUF_IN_COUNT]; + VisionBuf buf_out[BUF_OUT_COUNT]; + SafeQueue free_buf_in; +}; diff --git a/selfdrive/loggerd/encoderd.cc b/selfdrive/loggerd/encoderd.cc new file mode 100644 index 0000000000..87cf4a492f --- /dev/null +++ b/selfdrive/loggerd/encoderd.cc @@ -0,0 +1,145 @@ +#include "selfdrive/loggerd/loggerd.h" + +ExitHandler do_exit; + +struct EncoderdState { + int max_waiting = 0; + + // Sync logic for startup + std::atomic encoders_ready = 0; + std::atomic start_frame_id = 0; + bool camera_ready[WideRoadCam + 1] = {}; + bool camera_synced[WideRoadCam + 1] = {}; +}; + +// Handle initial encoder syncing by waiting for all encoders to reach the same frame id +bool sync_encoders(EncoderdState *s, CameraType cam_type, uint32_t frame_id) { + if (s->camera_synced[cam_type]) return true; + + if (s->max_waiting > 1 && s->encoders_ready != s->max_waiting) { + // add a small margin to the start frame id in case one of the encoders already dropped the next frame + update_max_atomic(s->start_frame_id, frame_id + 2); + if (std::exchange(s->camera_ready[cam_type], true) == false) { + ++s->encoders_ready; + LOGD("camera %d encoder ready", cam_type); + } + return false; + } else { + if (s->max_waiting == 1) update_max_atomic(s->start_frame_id, frame_id); + bool synced = frame_id >= s->start_frame_id; + s->camera_synced[cam_type] = synced; + if (!synced) LOGD("camera %d waiting for frame %d, cur %d", cam_type, (int)s->start_frame_id, frame_id); + return synced; + } +} + + +void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) { + util::set_thread_name(cam_info.filename); + + std::vector encoders; + VisionIpcClient vipc_client = VisionIpcClient("camerad", cam_info.stream_type, false); + + int cur_seg = 0; + while (!do_exit) { + if (!vipc_client.connect(false)) { + util::sleep_for(5); + continue; + } + + // init encoders + if (encoders.empty()) { + VisionBuf buf_info = vipc_client.buffers[0]; + LOGW("encoder %s init %dx%d", cam_info.filename, buf_info.width, buf_info.height); + + // main encoder + encoders.push_back(new Encoder(cam_info.filename, cam_info.type, buf_info.width, buf_info.height, + cam_info.fps, cam_info.bitrate, + cam_info.is_h265 ? cereal::EncodeIndex::Type::FULL_H_E_V_C : cereal::EncodeIndex::Type::QCAMERA_H264, + buf_info.width, buf_info.height, false)); + // qcamera encoder + if (cam_info.has_qcamera) { + encoders.push_back(new Encoder(qcam_info.filename, cam_info.type, buf_info.width, buf_info.height, + qcam_info.fps, qcam_info.bitrate, + qcam_info.is_h265 ? cereal::EncodeIndex::Type::FULL_H_E_V_C : cereal::EncodeIndex::Type::QCAMERA_H264, + qcam_info.frame_width, qcam_info.frame_height, false)); + } + } + + for (int i = 0; i < encoders.size(); ++i) { + encoders[i]->encoder_open(NULL); + } + + bool lagging = false; + while (!do_exit) { + VisionIpcBufExtra extra; + VisionBuf* buf = vipc_client.recv(&extra); + if (buf == nullptr) continue; + + // detect loop around and drop the frames + if (buf->get_frame_id() != extra.frame_id) { + if (!lagging) { + LOGE("encoder %s lag buffer id: %d extra id: %d", cam_info.filename, buf->get_frame_id(), extra.frame_id); + lagging = true; + } + continue; + } + lagging = false; + + if (!sync_encoders(s, cam_info.type, extra.frame_id)) { + continue; + } + if (do_exit) break; + + // do rotation if required + const int frames_per_seg = SEGMENT_LENGTH * MAIN_FPS; + if (cur_seg >= 0 && extra.frame_id >= ((cur_seg + 1) * frames_per_seg) + s->start_frame_id) { + for (auto &e : encoders) { + e->encoder_close(); + e->encoder_open(NULL); + } + ++cur_seg; + } + + // encode a frame + for (int i = 0; i < encoders.size(); ++i) { + int out_id = encoders[i]->encode_frame(buf, &extra); + + if (out_id == -1) { + LOGE("Failed to encode frame. frame_id: %d", extra.frame_id); + } + } + } + } + + LOG("encoder destroy"); + for(auto &e : encoders) { + e->encoder_close(); + delete e; + } +} + +void encoderd_thread() { + EncoderdState s; + + std::vector encoder_threads; + for (const auto &cam : cameras_logged) { + if (cam.enable) { + encoder_threads.push_back(std::thread(encoder_thread, &s, cam)); + s.max_waiting++; + } + } + for (auto &t : encoder_threads) t.join(); +} + +int main() { + if (!Hardware::PC()) { + int ret; + ret = util::set_realtime_priority(52); + assert(ret == 0); + ret = util::set_core_affinity({3}); + assert(ret == 0); + } + encoderd_thread(); + return 0; +} diff --git a/selfdrive/loggerd/logger.cc b/selfdrive/loggerd/logger.cc index f2c34554e3..5aed47e291 100644 --- a/selfdrive/loggerd/logger.cc +++ b/selfdrive/loggerd/logger.cc @@ -15,9 +15,9 @@ #include #include -#include "selfdrive/common/params.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/version.h" +#include "common/params.h" +#include "common/swaglog.h" +#include "common/version.h" // ***** logging helpers ***** @@ -33,12 +33,7 @@ kj::Array logger_build_init_data() { MessageBuilder msg; auto init = msg.initEvent().initInitData(); - if (Hardware::TICI()) { - init.setDeviceType(cereal::InitData::DeviceType::TICI); - } else { - init.setDeviceType(cereal::InitData::DeviceType::PC); - } - + init.setDeviceType(Hardware::get_device_type()); init.setVersion(COMMA_VERSION); std::ifstream cmdline_stream("/proc/cmdline"); @@ -109,13 +104,12 @@ static void lh_log_sentinel(LoggerHandle *h, SentinelType type) { // ***** logging functions ***** -void logger_init(LoggerState *s, const char* log_name, bool has_qlog) { +void logger_init(LoggerState *s, bool has_qlog) { pthread_mutex_init(&s->lock, NULL); s->part = -1; s->has_qlog = has_qlog; s->route_name = logger_get_route_name(); - snprintf(s->log_name, sizeof(s->log_name), "%s", log_name); s->init_data = logger_build_init_data(); } @@ -132,8 +126,8 @@ static LoggerHandle* logger_open(LoggerState *s, const char* root_path) { snprintf(h->segment_path, sizeof(h->segment_path), "%s/%s--%d", root_path, s->route_name.c_str(), s->part); - snprintf(h->log_path, sizeof(h->log_path), "%s/%s.bz2", h->segment_path, s->log_name); - snprintf(h->qlog_path, sizeof(h->qlog_path), "%s/qlog.bz2", h->segment_path); + snprintf(h->log_path, sizeof(h->log_path), "%s/rlog", h->segment_path); + snprintf(h->qlog_path, sizeof(h->qlog_path), "%s/qlog", h->segment_path); snprintf(h->lock_path, sizeof(h->lock_path), "%s.lock", h->log_path); h->end_sentinel_type = SentinelType::END_OF_SEGMENT; h->exit_signal = 0; @@ -144,9 +138,9 @@ static LoggerHandle* logger_open(LoggerState *s, const char* root_path) { if (lock_file == NULL) return NULL; fclose(lock_file); - h->log = std::make_unique(h->log_path); + h->log = std::make_unique(h->log_path); if (s->has_qlog) { - h->q_log = std::make_unique(h->qlog_path); + h->q_log = std::make_unique(h->qlog_path); } pthread_mutex_init(&h->lock, NULL); diff --git a/selfdrive/loggerd/logger.h b/selfdrive/loggerd/logger.h index bdda9d6917..e7594cee88 100644 --- a/selfdrive/loggerd/logger.h +++ b/selfdrive/loggerd/logger.h @@ -7,55 +7,37 @@ #include #include -#include #include #include #include "cereal/messaging/messaging.h" -#include "selfdrive/common/util.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/hardware/hw.h" +#include "common/util.h" +#include "common/swaglog.h" +#include "system/hardware/hw.h" const std::string LOG_ROOT = Path::log_root(); #define LOGGER_MAX_HANDLES 16 -class BZFile { +class RawFile { public: - BZFile(const char* path) { + RawFile(const char* path) { file = util::safe_fopen(path, "wb"); assert(file != nullptr); - int bzerror; - bz_file = BZ2_bzWriteOpen(&bzerror, file, 9, 0, 30); - assert(bzerror == BZ_OK); } - ~BZFile() { - int bzerror; - BZ2_bzWriteClose(&bzerror, bz_file, 0, nullptr, nullptr); - if (bzerror != BZ_OK) { - LOGE("BZ2_bzWriteClose error, bzerror=%d", bzerror); - } + ~RawFile() { util::safe_fflush(file); int err = fclose(file); assert(err == 0); } inline void write(void* data, size_t size) { - int bzerror; - do { - BZ2_bzWrite(&bzerror, bz_file, data, size); - } while (bzerror == BZ_IO_ERROR && errno == EINTR); - - if (bzerror != BZ_OK && !error_logged) { - LOGE("BZ2_bzWrite error, bzerror=%d", bzerror); - error_logged = true; - } + int written = util::safe_fwrite(data, 1, size, file); + assert(written == size); } inline void write(kj::ArrayPtr array) { write(array.begin(), array.size()); } private: - bool error_logged = false; FILE* file = nullptr; - BZFILE* bz_file = nullptr; }; typedef cereal::Sentinel::SentinelType SentinelType; @@ -69,7 +51,7 @@ typedef struct LoggerHandle { char log_path[4096]; char qlog_path[4096]; char lock_path[4096]; - std::unique_ptr log, q_log; + std::unique_ptr log, q_log; } LoggerHandle; typedef struct LoggerState { @@ -86,7 +68,7 @@ typedef struct LoggerState { kj::Array logger_build_init_data(); std::string logger_get_route_name(); -void logger_init(LoggerState *s, const char* log_name, bool has_qlog); +void logger_init(LoggerState *s, bool has_qlog); int logger_next(LoggerState *s, const char* root_path, char* out_segment_path, size_t out_segment_path_len, int* out_part); diff --git a/selfdrive/loggerd/loggerd.cc b/selfdrive/loggerd/loggerd.cc index a2c2b45a2b..4086f4991e 100644 --- a/selfdrive/loggerd/loggerd.cc +++ b/selfdrive/loggerd/loggerd.cc @@ -1,159 +1,18 @@ #include "selfdrive/loggerd/loggerd.h" +#include "selfdrive/loggerd/video_writer.h" ExitHandler do_exit; -// Handle initial encoder syncing by waiting for all encoders to reach the same frame id -bool sync_encoders(LoggerdState *s, CameraType cam_type, uint32_t frame_id) { - if (s->camera_synced[cam_type]) return true; - - if (s->max_waiting > 1 && s->encoders_ready != s->max_waiting) { - // add a small margin to the start frame id in case one of the encoders already dropped the next frame - update_max_atomic(s->start_frame_id, frame_id + 2); - if (std::exchange(s->camera_ready[cam_type], true) == false) { - ++s->encoders_ready; - LOGD("camera %d encoder ready", cam_type); - } - return false; - } else { - if (s->max_waiting == 1) update_max_atomic(s->start_frame_id, frame_id); - bool synced = frame_id >= s->start_frame_id; - s->camera_synced[cam_type] = synced; - if (!synced) LOGD("camera %d waiting for frame %d, cur %d", cam_type, (int)s->start_frame_id, frame_id); - return synced; - } -} - -bool trigger_rotate_if_needed(LoggerdState *s, int cur_seg, uint32_t frame_id) { - const int frames_per_seg = SEGMENT_LENGTH * MAIN_FPS; - if (cur_seg >= 0 && frame_id >= ((cur_seg + 1) * frames_per_seg) + s->start_frame_id) { - // trigger rotate and wait until the main logger has rotated to the new segment - ++s->ready_to_rotate; - std::unique_lock lk(s->rotate_lock); - s->rotate_cv.wait(lk, [&] { - return s->rotate_segment > cur_seg || do_exit; - }); - return !do_exit; - } - return false; -} - -void encoder_thread(LoggerdState *s, const LogCameraInfo &cam_info) { - util::set_thread_name(cam_info.filename); - - int cur_seg = -1; - int encode_idx = 0; - LoggerHandle *lh = NULL; - std::vector encoders; - VisionIpcClient vipc_client = VisionIpcClient("camerad", cam_info.stream_type, false); - - // While we write them right to the log for sync, we also publish the encode idx to the socket - const char *service_name = cam_info.type == DriverCam ? "driverEncodeIdx" : (cam_info.type == WideRoadCam ? "wideRoadEncodeIdx" : "roadEncodeIdx"); - PubMaster pm({service_name}); - - while (!do_exit) { - if (!vipc_client.connect(false)) { - util::sleep_for(5); - continue; - } - - // init encoders - if (encoders.empty()) { - VisionBuf buf_info = vipc_client.buffers[0]; - LOGD("encoder init %dx%d", buf_info.width, buf_info.height); - - // main encoder - encoders.push_back(new Encoder(cam_info.filename, cam_info.type, buf_info.width, buf_info.height, - cam_info.fps, cam_info.bitrate, cam_info.is_h265, - buf_info.width, buf_info.height, cam_info.record)); - // qcamera encoder - if (cam_info.has_qcamera) { - encoders.push_back(new Encoder(qcam_info.filename, cam_info.type, buf_info.width, buf_info.height, - qcam_info.fps, qcam_info.bitrate, qcam_info.is_h265, - qcam_info.frame_width, qcam_info.frame_height)); - } - } - - while (!do_exit) { - VisionIpcBufExtra extra; - VisionBuf* buf = vipc_client.recv(&extra); - if (buf == nullptr) continue; - - if (cam_info.trigger_rotate) { - s->last_camera_seen_tms = millis_since_boot(); - if (!sync_encoders(s, cam_info.type, extra.frame_id)) { - continue; - } - - // check if we're ready to rotate - trigger_rotate_if_needed(s, cur_seg, extra.frame_id); - if (do_exit) break; - } - - // rotate the encoder if the logger is on a newer segment - if (s->rotate_segment > cur_seg) { - cur_seg = s->rotate_segment; - - LOGW("camera %d rotate encoder to %s", cam_info.type, s->segment_path); - for (auto &e : encoders) { - e->encoder_close(); - e->encoder_open(s->segment_path); - } - if (lh) { - lh_close(lh); - } - lh = logger_get_handle(&s->logger); - } - - // encode a frame - for (int i = 0; i < encoders.size(); ++i) { - int out_id = encoders[i]->encode_frame(buf->y, buf->u, buf->v, - buf->width, buf->height, extra.timestamp_eof); - - if (out_id == -1) { - LOGE("Failed to encode frame. frame_id: %d encode_id: %d", extra.frame_id, encode_idx); - } - - // publish encode index - if (i == 0 && out_id != -1) { - MessageBuilder msg; - // this is really ugly - bool valid = (buf->get_frame_id() == extra.frame_id); - auto eidx = cam_info.type == DriverCam ? msg.initEvent(valid).initDriverEncodeIdx() : - (cam_info.type == WideRoadCam ? msg.initEvent(valid).initWideRoadEncodeIdx() : msg.initEvent(valid).initRoadEncodeIdx()); - eidx.setFrameId(extra.frame_id); - eidx.setTimestampSof(extra.timestamp_sof); - eidx.setTimestampEof(extra.timestamp_eof); - if (Hardware::TICI()) { - eidx.setType(cereal::EncodeIndex::Type::FULL_H_E_V_C); - } else { - eidx.setType(cam_info.type == DriverCam ? cereal::EncodeIndex::Type::FRONT : cereal::EncodeIndex::Type::FULL_H_E_V_C); - } - eidx.setEncodeId(encode_idx); - eidx.setSegmentNum(cur_seg); - eidx.setSegmentId(out_id); - if (lh) { - auto bytes = msg.toBytes(); - lh_log(lh, bytes.begin(), bytes.size(), true); - } - pm.send(service_name, msg); - } - } - - encode_idx++; - } - - if (lh) { - lh_close(lh); - lh = NULL; - } - } - - LOG("encoder destroy"); - for(auto &e : encoders) { - e->encoder_close(); - delete e; - } -} +struct LoggerdState { + LoggerState logger = {}; + char segment_path[4096]; + std::mutex rotate_lock; + std::atomic rotate_segment; + std::atomic last_camera_seen_tms; + std::atomic ready_to_rotate; // count of encoders ready to rotate + int max_waiting = 0; + double last_rotate_tms = 0.; // last rotate time in ms +}; void logger_rotate(LoggerdState *s) { { @@ -165,7 +24,6 @@ void logger_rotate(LoggerdState *s) { s->ready_to_rotate = 0; s->last_rotate_tms = millis_since_boot(); } - s->rotate_cv.notify_all(); LOGW((s->logger.part == 0) ? "logging to %s" : "rotated to %s", s->segment_path); } @@ -183,20 +41,151 @@ void rotate_if_needed(LoggerdState *s) { } } +struct RemoteEncoder { + std::unique_ptr writer; + int encoderd_segment_offset; + int current_segment = -1; + std::vector q; + int dropped_frames = 0; + bool recording = false; + bool marked_ready_to_rotate = false; + bool seen_first_packet = false; +}; + +int handle_encoder_msg(LoggerdState *s, Message *msg, std::string &name, struct RemoteEncoder &re) { + const LogCameraInfo &cam_info = (name == "driverEncodeData") ? cameras_logged[1] : + ((name == "wideRoadEncodeData") ? cameras_logged[2] : + ((name == "qRoadEncodeData") ? qcam_info : cameras_logged[0])); + int bytes_count = 0; + + // extract the message + capnp::FlatArrayMessageReader cmsg(kj::ArrayPtr((capnp::word *)msg->getData(), msg->getSize())); + auto event = cmsg.getRoot(); + auto edata = (name == "driverEncodeData") ? event.getDriverEncodeData() : + ((name == "wideRoadEncodeData") ? event.getWideRoadEncodeData() : + ((name == "qRoadEncodeData") ? event.getQRoadEncodeData() : event.getRoadEncodeData())); + auto idx = edata.getIdx(); + auto flags = idx.getFlags(); + + // encoderd can have started long before loggerd + if (!re.seen_first_packet) { + re.seen_first_packet = true; + re.encoderd_segment_offset = idx.getSegmentNum(); + LOGD("%s: has encoderd offset %d", name.c_str(), re.encoderd_segment_offset); + } + int offset_segment_num = idx.getSegmentNum() - re.encoderd_segment_offset; + + if (offset_segment_num == s->rotate_segment) { + // loggerd is now on the segment that matches this packet + + // if this is a new segment, we close any possible old segments, move to the new, and process any queued packets + if (re.current_segment != s->rotate_segment) { + if (re.recording) { + re.writer.reset(); + re.recording = false; + } + re.current_segment = s->rotate_segment; + re.marked_ready_to_rotate = false; + // we are in this segment now, process any queued messages before this one + if (!re.q.empty()) { + for (auto &qmsg: re.q) { + bytes_count += handle_encoder_msg(s, qmsg, name, re); + } + re.q.clear(); + } + } + + // if we aren't recording yet, try to start, since we are in the correct segment + if (!re.recording) { + if (flags & V4L2_BUF_FLAG_KEYFRAME) { + // only create on iframe + if (re.dropped_frames) { + // this should only happen for the first segment, maybe + LOGW("%s: dropped %d non iframe packets before init", name.c_str(), re.dropped_frames); + re.dropped_frames = 0; + } + // if we aren't actually recording, don't create the writer + if (cam_info.record) { + re.writer.reset(new VideoWriter(s->segment_path, + cam_info.filename, idx.getType() != cereal::EncodeIndex::Type::FULL_H_E_V_C, + cam_info.frame_width, cam_info.frame_height, cam_info.fps, idx.getType())); + // write the header + auto header = edata.getHeader(); + re.writer->write((uint8_t *)header.begin(), header.size(), idx.getTimestampEof()/1000, true, false); + } + re.recording = true; + } else { + // this is a sad case when we aren't recording, but don't have an iframe + // nothing we can do but drop the frame + delete msg; + ++re.dropped_frames; + return bytes_count; + } + } + + // we have to be recording if we are here + assert(re.recording); + + // if we are actually writing the video file, do so + if (re.writer) { + auto data = edata.getData(); + re.writer->write((uint8_t *)data.begin(), data.size(), idx.getTimestampEof()/1000, false, flags & V4L2_BUF_FLAG_KEYFRAME); + } + + // put it in log stream as the idx packet + MessageBuilder bmsg; + auto evt = bmsg.initEvent(event.getValid()); + evt.setLogMonoTime(event.getLogMonoTime()); + if (name == "driverEncodeData") { evt.setDriverEncodeIdx(idx); } + if (name == "wideRoadEncodeData") { evt.setWideRoadEncodeIdx(idx); } + if (name == "qRoadEncodeData") { evt.setQRoadEncodeIdx(idx); } + if (name == "roadEncodeData") { evt.setRoadEncodeIdx(idx); } + auto new_msg = bmsg.toBytes(); + logger_log(&s->logger, (uint8_t *)new_msg.begin(), new_msg.size(), true); // always in qlog? + bytes_count += new_msg.size(); + + // free the message, we used it + delete msg; + } else if (offset_segment_num > s->rotate_segment) { + // encoderd packet has a newer segment, this means encoderd has rolled over + if (!re.marked_ready_to_rotate) { + re.marked_ready_to_rotate = true; + ++s->ready_to_rotate; + LOGD("rotate %d -> %d ready %d/%d for %s", + s->rotate_segment.load(), offset_segment_num, + s->ready_to_rotate.load(), s->max_waiting, name.c_str()); + } + // queue up all the new segment messages, they go in after the rotate + re.q.push_back(msg); + } else { + LOGE("%s: encoderd packet has a older segment!!! idx.getSegmentNum():%d s->rotate_segment:%d re.encoderd_segment_offset:%d", + name.c_str(), idx.getSegmentNum(), s->rotate_segment.load(), re.encoderd_segment_offset); + // free the message, it's useless. this should never happen + // actually, this can happen if you restart encoderd + re.encoderd_segment_offset = -s->rotate_segment.load(); + delete msg; + } + + return bytes_count; +} + void loggerd_thread() { // setup messaging typedef struct QlogState { std::string name; int counter, freq; + bool encoder; } QlogState; std::unordered_map qlog_states; + std::unordered_map remote_encoders; std::unique_ptr ctx(Context::create()); std::unique_ptr poller(Poller::create()); // subscribe to all socks for (const auto& it : services) { - if (!it.should_log) continue; + const bool encoder = strcmp(it.name+strlen(it.name)-strlen("EncodeData"), "EncodeData") == 0; + if (!it.should_log && !encoder) continue; LOGD("logging %s (on port %d)", it.name, it.port); SubSocket * sock = SubSocket::create(ctx.get(), it.name); @@ -206,22 +195,22 @@ void loggerd_thread() { .name = it.name, .counter = 0, .freq = it.decimation, + .encoder = encoder, }; } LoggerdState s; // init logger - logger_init(&s.logger, "rlog", true); + logger_init(&s.logger, true); logger_rotate(&s); Params().put("CurrentRoute", s.logger.route_name); // init encoders s.last_camera_seen_tms = millis_since_boot(); - std::vector encoder_threads; for (const auto &cam : cameras_logged) { if (cam.enable) { - encoder_threads.push_back(std::thread(encoder_thread, &s, cam)); - if (cam.trigger_rotate) s.max_waiting++; + s.max_waiting++; + if (cam.has_qcamera) { s.max_waiting++; } } } @@ -238,9 +227,15 @@ void loggerd_thread() { Message *msg = nullptr; while (!do_exit && (msg = sock->receive(true))) { const bool in_qlog = qs.freq != -1 && (qs.counter++ % qs.freq == 0); - logger_log(&s.logger, (uint8_t *)msg->getData(), msg->getSize(), in_qlog); - bytes_count += msg->getSize(); - delete msg; + + if (qs.encoder) { + s.last_camera_seen_tms = millis_since_boot(); + bytes_count += handle_encoder_msg(&s, msg, qs.name, remote_encoders[sock]); + } else { + logger_log(&s.logger, (uint8_t *)msg->getData(), msg->getSize(), in_qlog); + bytes_count += msg->getSize(); + delete msg; + } rotate_if_needed(&s); @@ -258,10 +253,6 @@ void loggerd_thread() { } } - LOGW("closing encoders"); - s.rotate_cv.notify_all(); - for (auto &t : encoder_threads) t.join(); - LOGW("closing logger"); logger_close(&s.logger, &do_exit); @@ -274,3 +265,18 @@ void loggerd_thread() { // messaging cleanup for (auto &[sock, qs] : qlog_states) delete sock; } + +int main(int argc, char** argv) { + if (!Hardware::PC()) { + int ret; + ret = util::set_core_affinity({0, 1, 2, 3}); + assert(ret == 0); + // TODO: why does this impact camerad timings? + //ret = util::set_realtime_priority(1); + //assert(ret == 0); + } + + loggerd_thread(); + + return 0; +} diff --git a/selfdrive/loggerd/loggerd.h b/selfdrive/loggerd/loggerd.h index 761ff5507a..7e13e90e63 100644 --- a/selfdrive/loggerd/loggerd.h +++ b/selfdrive/loggerd/loggerd.h @@ -16,25 +16,25 @@ #include "cereal/visionipc/visionipc.h" #include "cereal/visionipc/visionipc_client.h" #include "selfdrive/camerad/cameras/camera_common.h" -#include "selfdrive/common/params.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/timing.h" -#include "selfdrive/common/util.h" -#include "selfdrive/hardware/hw.h" +#include "common/params.h" +#include "common/swaglog.h" +#include "common/timing.h" +#include "common/util.h" +#include "system/hardware/hw.h" -#include "selfdrive/loggerd/encoder.h" +#include "selfdrive/loggerd/encoder/encoder.h" #include "selfdrive/loggerd/logger.h" #ifdef QCOM2 -#include "selfdrive/loggerd/omx_encoder.h" -#define Encoder OmxEncoder +#include "selfdrive/loggerd/encoder/v4l_encoder.h" +#define Encoder V4LEncoder #else -#include "selfdrive/loggerd/raw_logger.h" -#define Encoder RawLogger +#include "selfdrive/loggerd/encoder/ffmpeg_encoder.h" +#define Encoder FfmpegEncoder #endif constexpr int MAIN_FPS = 20; -const int MAIN_BITRATE = Hardware::TICI() ? 10000000 : 5000000; -const int DCAM_BITRATE = Hardware::TICI() ? MAIN_BITRATE : 2500000; +const int MAIN_BITRATE = 10000000; +const int DCAM_BITRATE = MAIN_BITRATE; #define NO_CAMERA_PATIENCE 500 // fall back to time-based rotation if all cameras are dead @@ -50,7 +50,6 @@ struct LogCameraInfo { int bitrate; bool is_h265; bool has_qcamera; - bool trigger_rotate; bool enable; bool record; }; @@ -64,9 +63,10 @@ const LogCameraInfo cameras_logged[] = { .bitrate = MAIN_BITRATE, .is_h265 = true, .has_qcamera = true, - .trigger_rotate = true, .enable = true, .record = true, + .frame_width = 1928, + .frame_height = 1208, }, { .type = DriverCam, @@ -76,9 +76,10 @@ const LogCameraInfo cameras_logged[] = { .bitrate = DCAM_BITRATE, .is_h265 = true, .has_qcamera = false, - .trigger_rotate = true, .enable = true, .record = Params().getBool("RecordFront"), + .frame_width = 1928, + .frame_height = 1208, }, { .type = WideRoadCam, @@ -88,9 +89,10 @@ const LogCameraInfo cameras_logged[] = { .bitrate = MAIN_BITRATE, .is_h265 = true, .has_qcamera = false, - .trigger_rotate = true, - .enable = Hardware::TICI(), - .record = Hardware::TICI(), + .enable = true, + .record = true, + .frame_width = 1928, + .frame_height = 1208, }, }; const LogCameraInfo qcam_info = { @@ -98,29 +100,8 @@ const LogCameraInfo qcam_info = { .fps = MAIN_FPS, .bitrate = 256000, .is_h265 = false, - .frame_width = Hardware::TICI() ? 526 : 480, - .frame_height = Hardware::TICI() ? 330 : 360 // keep pixel count the same? -}; - -struct LoggerdState { - LoggerState logger = {}; - char segment_path[4096]; - std::mutex rotate_lock; - std::condition_variable rotate_cv; - std::atomic rotate_segment; - std::atomic last_camera_seen_tms; - std::atomic ready_to_rotate; // count of encoders ready to rotate - int max_waiting = 0; - double last_rotate_tms = 0.; // last rotate time in ms - - // Sync logic for startup - std::atomic encoders_ready = 0; - std::atomic start_frame_id = 0; - bool camera_ready[WideRoadCam + 1] = {}; - bool camera_synced[WideRoadCam + 1] = {}; + .enable = true, + .record = true, + .frame_width = 526, + .frame_height = 330, }; - -bool sync_encoders(LoggerdState *s, CameraType cam_type, uint32_t frame_id); -bool trigger_rotate_if_needed(LoggerdState *s, int cur_seg, uint32_t frame_id); -void rotate_if_needed(LoggerdState *s); -void loggerd_thread(); diff --git a/selfdrive/loggerd/main.cc b/selfdrive/loggerd/main.cc deleted file mode 100644 index c9bb35bfdb..0000000000 --- a/selfdrive/loggerd/main.cc +++ /dev/null @@ -1,18 +0,0 @@ -#include "selfdrive/loggerd/loggerd.h" - -#include - -int main(int argc, char** argv) { - if (Hardware::TICI()) { - int ret; - ret = util::set_core_affinity({0, 1, 2, 3}); - assert(ret == 0); - // TODO: why does this impact camerad timings? - //ret = util::set_realtime_priority(1); - //assert(ret == 0); - } - - loggerd_thread(); - - return 0; -} diff --git a/selfdrive/loggerd/omx_encoder.cc b/selfdrive/loggerd/omx_encoder.cc deleted file mode 100644 index 31e035955a..0000000000 --- a/selfdrive/loggerd/omx_encoder.cc +++ /dev/null @@ -1,547 +0,0 @@ -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -#include "selfdrive/loggerd/omx_encoder.h" -#include "cereal/messaging/messaging.h" - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include "libyuv.h" - -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" -#include "selfdrive/loggerd/include/msm_media_info.h" - -// Check the OMX error code and assert if an error occurred. -#define OMX_CHECK(_expr) \ - do { \ - assert(OMX_ErrorNone == (_expr)); \ - } while (0) - -extern ExitHandler do_exit; - -// ***** OMX callback functions ***** - -void OmxEncoder::wait_for_state(OMX_STATETYPE state_) { - std::unique_lock lk(this->state_lock); - while (this->state != state_) { - this->state_cv.wait(lk); - } -} - -static OMX_CALLBACKTYPE omx_callbacks = { - .EventHandler = OmxEncoder::event_handler, - .EmptyBufferDone = OmxEncoder::empty_buffer_done, - .FillBufferDone = OmxEncoder::fill_buffer_done, -}; - -OMX_ERRORTYPE OmxEncoder::event_handler(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_EVENTTYPE event, - OMX_U32 data1, OMX_U32 data2, OMX_PTR event_data) { - OmxEncoder *e = (OmxEncoder*)app_data; - if (event == OMX_EventCmdComplete) { - assert(data1 == OMX_CommandStateSet); - LOG("set state event 0x%x", data2); - { - std::unique_lock lk(e->state_lock); - e->state = (OMX_STATETYPE)data2; - } - e->state_cv.notify_all(); - } else if (event == OMX_EventError) { - LOGE("OMX error 0x%08x", data1); - } else { - LOGE("OMX unhandled event %d", event); - assert(false); - } - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE OmxEncoder::empty_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, - OMX_BUFFERHEADERTYPE *buffer) { - OmxEncoder *e = (OmxEncoder*)app_data; - e->free_in.push(buffer); - return OMX_ErrorNone; -} - -OMX_ERRORTYPE OmxEncoder::fill_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, - OMX_BUFFERHEADERTYPE *buffer) { - OmxEncoder *e = (OmxEncoder*)app_data; - e->done_out.push(buffer); - return OMX_ErrorNone; -} - -#define PORT_INDEX_IN 0 -#define PORT_INDEX_OUT 1 - -static const char* omx_color_fomat_name(uint32_t format) __attribute__((unused)); -static const char* omx_color_fomat_name(uint32_t format) { - switch (format) { - case OMX_COLOR_FormatUnused: return "OMX_COLOR_FormatUnused"; - case OMX_COLOR_FormatMonochrome: return "OMX_COLOR_FormatMonochrome"; - case OMX_COLOR_Format8bitRGB332: return "OMX_COLOR_Format8bitRGB332"; - case OMX_COLOR_Format12bitRGB444: return "OMX_COLOR_Format12bitRGB444"; - case OMX_COLOR_Format16bitARGB4444: return "OMX_COLOR_Format16bitARGB4444"; - case OMX_COLOR_Format16bitARGB1555: return "OMX_COLOR_Format16bitARGB1555"; - case OMX_COLOR_Format16bitRGB565: return "OMX_COLOR_Format16bitRGB565"; - case OMX_COLOR_Format16bitBGR565: return "OMX_COLOR_Format16bitBGR565"; - case OMX_COLOR_Format18bitRGB666: return "OMX_COLOR_Format18bitRGB666"; - case OMX_COLOR_Format18bitARGB1665: return "OMX_COLOR_Format18bitARGB1665"; - case OMX_COLOR_Format19bitARGB1666: return "OMX_COLOR_Format19bitARGB1666"; - case OMX_COLOR_Format24bitRGB888: return "OMX_COLOR_Format24bitRGB888"; - case OMX_COLOR_Format24bitBGR888: return "OMX_COLOR_Format24bitBGR888"; - case OMX_COLOR_Format24bitARGB1887: return "OMX_COLOR_Format24bitARGB1887"; - case OMX_COLOR_Format25bitARGB1888: return "OMX_COLOR_Format25bitARGB1888"; - case OMX_COLOR_Format32bitBGRA8888: return "OMX_COLOR_Format32bitBGRA8888"; - case OMX_COLOR_Format32bitARGB8888: return "OMX_COLOR_Format32bitARGB8888"; - case OMX_COLOR_FormatYUV411Planar: return "OMX_COLOR_FormatYUV411Planar"; - case OMX_COLOR_FormatYUV411PackedPlanar: return "OMX_COLOR_FormatYUV411PackedPlanar"; - case OMX_COLOR_FormatYUV420Planar: return "OMX_COLOR_FormatYUV420Planar"; - case OMX_COLOR_FormatYUV420PackedPlanar: return "OMX_COLOR_FormatYUV420PackedPlanar"; - case OMX_COLOR_FormatYUV420SemiPlanar: return "OMX_COLOR_FormatYUV420SemiPlanar"; - case OMX_COLOR_FormatYUV422Planar: return "OMX_COLOR_FormatYUV422Planar"; - case OMX_COLOR_FormatYUV422PackedPlanar: return "OMX_COLOR_FormatYUV422PackedPlanar"; - case OMX_COLOR_FormatYUV422SemiPlanar: return "OMX_COLOR_FormatYUV422SemiPlanar"; - case OMX_COLOR_FormatYCbYCr: return "OMX_COLOR_FormatYCbYCr"; - case OMX_COLOR_FormatYCrYCb: return "OMX_COLOR_FormatYCrYCb"; - case OMX_COLOR_FormatCbYCrY: return "OMX_COLOR_FormatCbYCrY"; - case OMX_COLOR_FormatCrYCbY: return "OMX_COLOR_FormatCrYCbY"; - case OMX_COLOR_FormatYUV444Interleaved: return "OMX_COLOR_FormatYUV444Interleaved"; - case OMX_COLOR_FormatRawBayer8bit: return "OMX_COLOR_FormatRawBayer8bit"; - case OMX_COLOR_FormatRawBayer10bit: return "OMX_COLOR_FormatRawBayer10bit"; - case OMX_COLOR_FormatRawBayer8bitcompressed: return "OMX_COLOR_FormatRawBayer8bitcompressed"; - case OMX_COLOR_FormatL2: return "OMX_COLOR_FormatL2"; - case OMX_COLOR_FormatL4: return "OMX_COLOR_FormatL4"; - case OMX_COLOR_FormatL8: return "OMX_COLOR_FormatL8"; - case OMX_COLOR_FormatL16: return "OMX_COLOR_FormatL16"; - case OMX_COLOR_FormatL24: return "OMX_COLOR_FormatL24"; - case OMX_COLOR_FormatL32: return "OMX_COLOR_FormatL32"; - case OMX_COLOR_FormatYUV420PackedSemiPlanar: return "OMX_COLOR_FormatYUV420PackedSemiPlanar"; - case OMX_COLOR_FormatYUV422PackedSemiPlanar: return "OMX_COLOR_FormatYUV422PackedSemiPlanar"; - case OMX_COLOR_Format18BitBGR666: return "OMX_COLOR_Format18BitBGR666"; - case OMX_COLOR_Format24BitARGB6666: return "OMX_COLOR_Format24BitARGB6666"; - case OMX_COLOR_Format24BitABGR6666: return "OMX_COLOR_Format24BitABGR6666"; - - case OMX_COLOR_FormatAndroidOpaque: return "OMX_COLOR_FormatAndroidOpaque"; - case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar"; - case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; - case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka: return "OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka"; - case OMX_SEC_COLOR_FormatNV12Tiled: return "OMX_SEC_COLOR_FormatNV12Tiled"; - case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m: return "OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m"; - - // case QOMX_COLOR_FormatYVU420SemiPlanar: return "QOMX_COLOR_FormatYVU420SemiPlanar"; - case QOMX_COLOR_FormatYVU420PackedSemiPlanar32m4ka: return "QOMX_COLOR_FormatYVU420PackedSemiPlanar32m4ka"; - case QOMX_COLOR_FormatYUV420PackedSemiPlanar16m2ka: return "QOMX_COLOR_FormatYUV420PackedSemiPlanar16m2ka"; - // case QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka: return "QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka"; - // case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m: return "QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m"; - case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView: return "QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView"; - case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed: return "QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed"; - case QOMX_COLOR_Format32bitRGBA8888: return "QOMX_COLOR_Format32bitRGBA8888"; - case QOMX_COLOR_Format32bitRGBA8888Compressed: return "QOMX_COLOR_Format32bitRGBA8888Compressed"; - - default: - return "unkn"; - } -} - - -// ***** encoder functions ***** -OmxEncoder::OmxEncoder(const char* filename, CameraType type, int in_width, int in_height, int fps, int bitrate, bool h265, int out_width, int out_height, bool write) - : in_width_(in_width), in_height_(in_height), width(out_width), height(out_height) { - this->filename = filename; - this->type = type; - this->write = write; - this->fps = fps; - this->remuxing = !h265; - - this->downscale = in_width != out_width || in_height != out_height; - if (this->downscale) { - this->y_ptr2 = (uint8_t *)malloc(this->width*this->height); - this->u_ptr2 = (uint8_t *)malloc(this->width*this->height/4); - this->v_ptr2 = (uint8_t *)malloc(this->width*this->height/4); - } - - auto component = (OMX_STRING)(h265 ? "OMX.qcom.video.encoder.hevc" : "OMX.qcom.video.encoder.avc"); - int err = OMX_GetHandle(&this->handle, component, this, &omx_callbacks); - if (err != OMX_ErrorNone) { - LOGE("error getting codec: %x", err); - } - assert(err == OMX_ErrorNone); - // printf("handle: %p\n", this->handle); - - // setup input port - - OMX_PARAM_PORTDEFINITIONTYPE in_port = {0}; - in_port.nSize = sizeof(in_port); - in_port.nPortIndex = (OMX_U32) PORT_INDEX_IN; - OMX_CHECK(OMX_GetParameter(this->handle, OMX_IndexParamPortDefinition, (OMX_PTR) &in_port)); - - in_port.format.video.nFrameWidth = this->width; - in_port.format.video.nFrameHeight = this->height; - in_port.format.video.nStride = VENUS_Y_STRIDE(COLOR_FMT_NV12, this->width); - in_port.format.video.nSliceHeight = this->height; - // in_port.nBufferSize = (this->width * this->height * 3) / 2; - in_port.nBufferSize = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, this->width, this->height); - in_port.format.video.xFramerate = (this->fps * 65536); - in_port.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - // in_port.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; - in_port.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; - - OMX_CHECK(OMX_SetParameter(this->handle, OMX_IndexParamPortDefinition, (OMX_PTR) &in_port)); - OMX_CHECK(OMX_GetParameter(this->handle, OMX_IndexParamPortDefinition, (OMX_PTR) &in_port)); - this->in_buf_headers.resize(in_port.nBufferCountActual); - - // setup output port - - OMX_PARAM_PORTDEFINITIONTYPE out_port = {0}; - out_port.nSize = sizeof(out_port); - out_port.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - OMX_CHECK(OMX_GetParameter(this->handle, OMX_IndexParamPortDefinition, (OMX_PTR)&out_port)); - out_port.format.video.nFrameWidth = this->width; - out_port.format.video.nFrameHeight = this->height; - out_port.format.video.xFramerate = 0; - out_port.format.video.nBitrate = bitrate; - if (h265) { - out_port.format.video.eCompressionFormat = OMX_VIDEO_CodingHEVC; - } else { - out_port.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; - } - out_port.format.video.eColorFormat = OMX_COLOR_FormatUnused; - - OMX_CHECK(OMX_SetParameter(this->handle, OMX_IndexParamPortDefinition, (OMX_PTR) &out_port)); - - OMX_CHECK(OMX_GetParameter(this->handle, OMX_IndexParamPortDefinition, (OMX_PTR) &out_port)); - this->out_buf_headers.resize(out_port.nBufferCountActual); - - OMX_VIDEO_PARAM_BITRATETYPE bitrate_type = {0}; - bitrate_type.nSize = sizeof(bitrate_type); - bitrate_type.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - OMX_CHECK(OMX_GetParameter(this->handle, OMX_IndexParamVideoBitrate, (OMX_PTR) &bitrate_type)); - bitrate_type.eControlRate = OMX_Video_ControlRateVariable; - bitrate_type.nTargetBitrate = bitrate; - - OMX_CHECK(OMX_SetParameter(this->handle, OMX_IndexParamVideoBitrate, (OMX_PTR) &bitrate_type)); - - if (h265) { - // setup HEVC - OMX_VIDEO_PARAM_PROFILELEVELTYPE hevc_type = {0}; - OMX_INDEXTYPE index_type = OMX_IndexParamVideoProfileLevelCurrent; - hevc_type.nSize = sizeof(hevc_type); - hevc_type.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - OMX_CHECK(OMX_GetParameter(this->handle, index_type, (OMX_PTR) &hevc_type)); - - hevc_type.eProfile = OMX_VIDEO_HEVCProfileMain; - hevc_type.eLevel = OMX_VIDEO_HEVCHighTierLevel5; - - OMX_CHECK(OMX_SetParameter(this->handle, index_type, (OMX_PTR) &hevc_type)); - } else { - // setup h264 - OMX_VIDEO_PARAM_AVCTYPE avc = { 0 }; - avc.nSize = sizeof(avc); - avc.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - OMX_CHECK(OMX_GetParameter(this->handle, OMX_IndexParamVideoAvc, &avc)); - - avc.nBFrames = 0; - avc.nPFrames = 15; - - avc.eProfile = OMX_VIDEO_AVCProfileHigh; - avc.eLevel = OMX_VIDEO_AVCLevel31; - - avc.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; - avc.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; - - avc.nRefFrames = 1; - avc.bUseHadamard = OMX_TRUE; - avc.bEntropyCodingCABAC = OMX_TRUE; - avc.bWeightedPPrediction = OMX_TRUE; - avc.bconstIpred = OMX_TRUE; - - OMX_CHECK(OMX_SetParameter(this->handle, OMX_IndexParamVideoAvc, &avc)); - } - - - // for (int i = 0; ; i++) { - // OMX_VIDEO_PARAM_PORTFORMATTYPE video_port_format = {0}; - // video_port_format.nSize = sizeof(video_port_format); - // video_port_format.nIndex = i; - // video_port_format.nPortIndex = PORT_INDEX_IN; - // if (OMX_GetParameter(this->handle, OMX_IndexParamVideoPortFormat, &video_port_format) != OMX_ErrorNone) - // break; - // printf("in %d: compression 0x%x format 0x%x %s\n", i, - // video_port_format.eCompressionFormat, video_port_format.eColorFormat, - // omx_color_fomat_name(video_port_format.eColorFormat)); - // } - - // for (int i=0; i<32; i++) { - // OMX_VIDEO_PARAM_PROFILELEVELTYPE params = {0}; - // params.nSize = sizeof(params); - // params.nPortIndex = PORT_INDEX_OUT; - // params.nProfileIndex = i; - // if (OMX_GetParameter(this->handle, OMX_IndexParamVideoProfileLevelQuerySupported, ¶ms) != OMX_ErrorNone) - // break; - // printf("profile %d level 0x%x\n", params.eProfile, params.eLevel); - // } - - OMX_CHECK(OMX_SendCommand(this->handle, OMX_CommandStateSet, OMX_StateIdle, NULL)); - - for (auto &buf : this->in_buf_headers) { - OMX_CHECK(OMX_AllocateBuffer(this->handle, &buf, PORT_INDEX_IN, this, - in_port.nBufferSize)); - } - - for (auto &buf : this->out_buf_headers) { - OMX_CHECK(OMX_AllocateBuffer(this->handle, &buf, PORT_INDEX_OUT, this, - out_port.nBufferSize)); - } - - wait_for_state(OMX_StateIdle); - - OMX_CHECK(OMX_SendCommand(this->handle, OMX_CommandStateSet, OMX_StateExecuting, NULL)); - - wait_for_state(OMX_StateExecuting); - - // give omx all the output buffers - for (auto &buf : this->out_buf_headers) { - // printf("fill %p\n", this->out_buf_headers[i]); - OMX_CHECK(OMX_FillThisBuffer(this->handle, buf)); - } - - // fill the input free queue - for (auto &buf : this->in_buf_headers) { - this->free_in.push(buf); - } - - LOGE("omx initialized - in: %d - out %d", this->in_buf_headers.size(), this->out_buf_headers.size()); - - service_name = this->type == DriverCam ? "driverEncodeData" : - (this->type == WideRoadCam ? "wideRoadEncodeData" : - (this->remuxing ? "qRoadEncodeData" : "roadEncodeData")); - pm.reset(new PubMaster({service_name})); -} - -void OmxEncoder::callback_handler(OmxEncoder *e) { - // OMX documentation specifies to not empty the buffer from the callback function - // so we use this intermediate handler to copy the buffer for further writing - // and give it back to OMX. We could also send the data over msgq from here. - bool exit = false; - - while (!exit) { - OMX_BUFFERHEADERTYPE *buffer = e->done_out.pop(); - OmxBuffer *new_buffer = (OmxBuffer*)malloc(sizeof(OmxBuffer) + buffer->nFilledLen); - assert(new_buffer); - - new_buffer->header = *buffer; - memcpy(new_buffer->data, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen); - - e->to_write.push(new_buffer); - -#ifdef QCOM2 - if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { - buffer->nTimeStamp = 0; - } - - if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { - buffer->nTimeStamp = 0; - } -#endif - - if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { - exit = true; - } - - // give omx back the buffer - // TOOD: fails when shutting down - OMX_CHECK(OMX_FillThisBuffer(e->handle, buffer)); - } -} - -void OmxEncoder::write_and_broadcast_handler(OmxEncoder *e){ - bool exit = false; - - e->segment_num++; - uint32_t idx = 0; - while (!exit) { - OmxBuffer *out_buf = e->to_write.pop(); - - MessageBuilder msg; - auto edata = (e->type == DriverCam) ? msg.initEvent(true).initDriverEncodeData() : - ((e->type == WideRoadCam) ? msg.initEvent(true).initWideRoadEncodeData() : - (e->remuxing ? msg.initEvent(true).initQRoadEncodeData() : msg.initEvent(true).initRoadEncodeData())); - edata.setData(kj::heapArray(out_buf->data, out_buf->header.nFilledLen)); - edata.setTimestampEof(out_buf->header.nTimeStamp); - edata.setIdx(idx++); - edata.setSegmentNum(e->segment_num); - edata.setFlags(out_buf->header.nFlags); - e->pm->send(e->service_name, msg); - - OmxEncoder::handle_out_buf(e, out_buf); - if (out_buf->header.nFlags & OMX_BUFFERFLAG_EOS) { - exit = true; - } - - free(out_buf); - } -} - - -void OmxEncoder::handle_out_buf(OmxEncoder *e, OmxBuffer *out_buf) { - if (!(out_buf->header.nFlags & OMX_BUFFERFLAG_EOS) && e->writer) { - e->writer->write(out_buf->data, - out_buf->header.nFilledLen, - out_buf->header.nTimeStamp, - out_buf->header.nFlags & OMX_BUFFERFLAG_CODECCONFIG, - out_buf->header.nFlags & OMX_BUFFERFLAG_SYNCFRAME); - } -} - -int OmxEncoder::encode_frame(const uint8_t *y_ptr, const uint8_t *u_ptr, const uint8_t *v_ptr, - int in_width, int in_height, uint64_t ts) { - assert(in_width == this->in_width_); - assert(in_height == this->in_height_); - int err; - if (!this->is_open) { - return -1; - } - - // this sometimes freezes... put it outside the encoder lock so we can still trigger rotates... - // THIS IS A REALLY BAD IDEA, but apparently the race has to happen 30 times to trigger this - //pthread_mutex_unlock(&this->lock); - OMX_BUFFERHEADERTYPE* in_buf = nullptr; - while (!this->free_in.try_pop(in_buf, 20)) { - if (do_exit) { - return -1; - } - } - - //pthread_mutex_lock(&this->lock); - - int ret = this->counter; - - uint8_t *in_buf_ptr = in_buf->pBuffer; - // printf("in_buf ptr %p\n", in_buf_ptr); - - uint8_t *in_y_ptr = in_buf_ptr; - int in_y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, this->width); - int in_uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, this->width); - // uint8_t *in_uv_ptr = in_buf_ptr + (this->width * this->height); - uint8_t *in_uv_ptr = in_buf_ptr + (in_y_stride * VENUS_Y_SCANLINES(COLOR_FMT_NV12, this->height)); - - if (this->downscale) { - I420Scale(y_ptr, in_width, - u_ptr, in_width/2, - v_ptr, in_width/2, - in_width, in_height, - this->y_ptr2, this->width, - this->u_ptr2, this->width/2, - this->v_ptr2, this->width/2, - this->width, this->height, - libyuv::kFilterNone); - y_ptr = this->y_ptr2; - u_ptr = this->u_ptr2; - v_ptr = this->v_ptr2; - } - err = libyuv::I420ToNV12(y_ptr, this->width, - u_ptr, this->width/2, - v_ptr, this->width/2, - in_y_ptr, in_y_stride, - in_uv_ptr, in_uv_stride, - this->width, this->height); - assert(err == 0); - - // in_buf->nFilledLen = (this->width*this->height) + (this->width*this->height/2); - in_buf->nFilledLen = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, this->width, this->height); - in_buf->nFlags = OMX_BUFFERFLAG_ENDOFFRAME; - in_buf->nOffset = 0; - in_buf->nTimeStamp = ts/1000LL; // OMX_TICKS, in microseconds - this->last_t = in_buf->nTimeStamp; - - OMX_CHECK(OMX_EmptyThisBuffer(this->handle, in_buf)); - - this->dirty = true; - - this->counter++; - - return ret; -} - -void OmxEncoder::encoder_open(const char* path) { - if (this->write) { - writer.reset(new VideoWriter(path, this->filename, this->remuxing, this->width, this->height, this->fps, !this->remuxing, false)); - } - - // start writer threads - callback_handler_thread = std::thread(OmxEncoder::callback_handler, this); - write_handler_thread = std::thread(OmxEncoder::write_and_broadcast_handler, this); - - this->is_open = true; - this->counter = 0; -} - -void OmxEncoder::encoder_close() { - if (this->is_open) { - if (this->dirty) { - // drain output only if there could be frames in the encoder - - OMX_BUFFERHEADERTYPE* in_buf = this->free_in.pop(); - in_buf->nFilledLen = 0; - in_buf->nOffset = 0; - in_buf->nFlags = OMX_BUFFERFLAG_EOS; - in_buf->nTimeStamp = this->last_t + 1000000LL/this->fps; - - OMX_CHECK(OMX_EmptyThisBuffer(this->handle, in_buf)); - - this->dirty = false; - } - - callback_handler_thread.join(); - write_handler_thread.join(); - - writer.reset(); - } - this->is_open = false; -} - -OmxEncoder::~OmxEncoder() { - assert(!this->is_open); - - OMX_CHECK(OMX_SendCommand(this->handle, OMX_CommandStateSet, OMX_StateIdle, NULL)); - - wait_for_state(OMX_StateIdle); - - OMX_CHECK(OMX_SendCommand(this->handle, OMX_CommandStateSet, OMX_StateLoaded, NULL)); - - for (auto &buf : this->in_buf_headers) { - OMX_CHECK(OMX_FreeBuffer(this->handle, PORT_INDEX_IN, buf)); - } - - for (auto &buf : this->out_buf_headers) { - OMX_CHECK(OMX_FreeBuffer(this->handle, PORT_INDEX_OUT, buf)); - } - - wait_for_state(OMX_StateLoaded); - - OMX_CHECK(OMX_FreeHandle(this->handle)); - - OMX_BUFFERHEADERTYPE *buf; - while (this->free_in.try_pop(buf)); - while (this->done_out.try_pop(buf)); - - OmxBuffer *write_buf; - while (this->to_write.try_pop(write_buf)) { - free(write_buf); - }; - - if (this->downscale) { - free(this->y_ptr2); - free(this->u_ptr2); - free(this->v_ptr2); - } -} diff --git a/selfdrive/loggerd/omx_encoder.h b/selfdrive/loggerd/omx_encoder.h deleted file mode 100644 index e57dccbe11..0000000000 --- a/selfdrive/loggerd/omx_encoder.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include - -#include "selfdrive/common/queue.h" -#include "selfdrive/loggerd/encoder.h" -#include "selfdrive/loggerd/video_writer.h" - -struct OmxBuffer { - OMX_BUFFERHEADERTYPE header; - OMX_U8 data[]; -}; - - -// OmxEncoder, lossey codec using hardware hevc -class OmxEncoder : public VideoEncoder { -public: - OmxEncoder(const char* filename, CameraType type, int width, int height, int fps, int bitrate, bool h265, int out_width, int out_height, bool write = true); - ~OmxEncoder(); - int encode_frame(const uint8_t *y_ptr, const uint8_t *u_ptr, const uint8_t *v_ptr, - int in_width, int in_height, uint64_t ts); - void encoder_open(const char* path); - void encoder_close(); - - // OMX callbacks - static OMX_ERRORTYPE event_handler(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_EVENTTYPE event, - OMX_U32 data1, OMX_U32 data2, OMX_PTR event_data); - static OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, - OMX_BUFFERHEADERTYPE *buffer); - static OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, - OMX_BUFFERHEADERTYPE *buffer); - -private: - void wait_for_state(OMX_STATETYPE state); - static void callback_handler(OmxEncoder *e); - static void write_and_broadcast_handler(OmxEncoder *e); - static void handle_out_buf(OmxEncoder *e, OmxBuffer *out_buf); - - int in_width_, in_height_; - int width, height, fps; - bool is_open = false; - bool dirty = false; - bool write = false; - int counter = 0; - std::thread callback_handler_thread; - std::thread write_handler_thread; - int segment_num = -1; - std::unique_ptr pm; - const char *service_name; - - const char* filename; - CameraType type; - - std::mutex state_lock; - std::condition_variable state_cv; - OMX_STATETYPE state = OMX_StateLoaded; - - OMX_HANDLETYPE handle; - - std::vector in_buf_headers; - std::vector out_buf_headers; - - uint64_t last_t; - - SafeQueue free_in; - SafeQueue done_out; - SafeQueue to_write; - - bool remuxing; - std::unique_ptr writer; - - bool downscale; - uint8_t *y_ptr2, *u_ptr2, *v_ptr2; -}; diff --git a/selfdrive/loggerd/raw_logger.cc b/selfdrive/loggerd/raw_logger.cc deleted file mode 100644 index 29d421a881..0000000000 --- a/selfdrive/loggerd/raw_logger.cc +++ /dev/null @@ -1,120 +0,0 @@ -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -#include "selfdrive/loggerd/raw_logger.h" - -#include -#include - -#include -#include -#include - -#define __STDC_CONSTANT_MACROS - -#include "libyuv.h" - -extern "C" { -#include -#include -#include -} - -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" - -RawLogger::RawLogger(const char* filename, CameraType type, int in_width, int in_height, int fps, - int bitrate, bool h265, int out_width, int out_height, bool write) - : in_width_(in_width), in_height_(in_height), filename(filename), fps(fps) { - // TODO: respect write arg - frame = av_frame_alloc(); - assert(frame); - frame->format = AV_PIX_FMT_YUV420P; - frame->width = out_width; - frame->height = out_height; - frame->linesize[0] = out_width; - frame->linesize[1] = out_width/2; - frame->linesize[2] = out_width/2; - - if (in_width != out_width || in_height != out_height) { - downscale_buf.resize(out_width * out_height * 3 / 2); - } -} - -RawLogger::~RawLogger() { - encoder_close(); - av_frame_free(&frame); -} - -void RawLogger::encoder_open(const char* path) { - writer = new VideoWriter(path, this->filename, true, frame->width, frame->height, this->fps, false, true); - // write the header - writer->write(NULL, 0, 0, true, false); - is_open = true; -} - -void RawLogger::encoder_close() { - if (!is_open) return; - delete writer; - is_open = false; -} - -int RawLogger::encode_frame(const uint8_t *y_ptr, const uint8_t *u_ptr, const uint8_t *v_ptr, - int in_width, int in_height, uint64_t ts) { - assert(in_width == this->in_width_); - assert(in_height == this->in_height_); - - if (downscale_buf.size() > 0) { - uint8_t *out_y = downscale_buf.data(); - uint8_t *out_u = out_y + frame->width * frame->height; - uint8_t *out_v = out_u + (frame->width / 2) * (frame->height / 2); - libyuv::I420Scale(y_ptr, in_width, - u_ptr, in_width/2, - v_ptr, in_width/2, - in_width, in_height, - out_y, frame->width, - out_u, frame->width/2, - out_v, frame->width/2, - frame->width, frame->height, - libyuv::kFilterNone); - frame->data[0] = out_y; - frame->data[1] = out_u; - frame->data[2] = out_v; - } else { - frame->data[0] = (uint8_t*)y_ptr; - frame->data[1] = (uint8_t*)u_ptr; - frame->data[2] = (uint8_t*)v_ptr; - } - frame->pts = counter*50*1000; // 50ms per frame - - int ret = counter; - - int err = avcodec_send_frame(writer->codec_ctx, frame); - if (err < 0) { - LOGE("avcodec_send_frame error %d", err); - ret = -1; - } - - AVPacket pkt; - av_init_packet(&pkt); - pkt.data = NULL; - pkt.size = 0; - while (ret >= 0) { - err = avcodec_receive_packet(writer->codec_ctx, &pkt); - if (err == AVERROR_EOF) { - break; - } else if (err == AVERROR(EAGAIN)) { - // Encoder might need a few frames on startup to get started. Keep going - ret = 0; - break; - } else if (err < 0) { - LOGE("avcodec_receive_packet error %d", err); - ret = -1; - break; - } - - writer->write(pkt.data, pkt.size, pkt.pts, false, pkt.flags & AV_PKT_FLAG_KEY); - counter++; - } - av_packet_unref(&pkt); - return ret; -} diff --git a/selfdrive/loggerd/raw_logger.h b/selfdrive/loggerd/raw_logger.h deleted file mode 100644 index 56bd08ff1f..0000000000 --- a/selfdrive/loggerd/raw_logger.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -extern "C" { -#include -#include -#include -} - -#include "selfdrive/loggerd/encoder.h" -#include "selfdrive/loggerd/video_writer.h" - -class RawLogger : public VideoEncoder { - public: - RawLogger(const char* filename, CameraType type, int in_width, int in_height, int fps, - int bitrate, bool h265, int out_width, int out_height, bool write = true); - ~RawLogger(); - int encode_frame(const uint8_t *y_ptr, const uint8_t *u_ptr, const uint8_t *v_ptr, - int in_width, int in_height, uint64_t ts); - void encoder_open(const char* path); - void encoder_close(); - -private: - const char* filename; - //bool write; - int fps; - int counter = 0; - bool is_open = false; - - int in_width_, in_height_; - - AVFrame *frame = NULL; - std::vector downscale_buf; - - VideoWriter *writer = NULL; -}; diff --git a/selfdrive/loggerd/tests/test_deleter.py b/selfdrive/loggerd/tests/test_deleter.py old mode 100644 new mode 100755 index e0a063bd43..80fb5c997f --- a/selfdrive/loggerd/tests/test_deleter.py +++ b/selfdrive/loggerd/tests/test_deleter.py @@ -1,12 +1,12 @@ +#!/usr/bin/env python3 import os import time import threading import unittest from collections import namedtuple -import selfdrive.loggerd.deleter as deleter from common.timeout import Timeout, TimeoutException - +import selfdrive.loggerd.deleter as deleter from selfdrive.loggerd.tests.loggerd_tests_common import UploaderTestCase Stats = namedtuple("Stats", ['f_bavail', 'f_blocks', 'f_frsize']) diff --git a/selfdrive/loggerd/tests/test_encoder.py b/selfdrive/loggerd/tests/test_encoder.py index 9479b6256a..1b9bcef2d7 100755 --- a/selfdrive/loggerd/tests/test_encoder.py +++ b/selfdrive/loggerd/tests/test_encoder.py @@ -13,7 +13,7 @@ from tqdm import trange from common.params import Params from common.timeout import Timeout -from selfdrive.hardware import TICI +from system.hardware import TICI from selfdrive.loggerd.config import ROOT from selfdrive.manager.process_config import managed_processes from tools.lib.logreader import LogReader @@ -24,7 +24,7 @@ CAMERAS = [ ("fcamera.hevc", 20, FULL_SIZE, "roadEncodeIdx"), ("dcamera.hevc", 20, FULL_SIZE, "driverEncodeIdx"), ("ecamera.hevc", 20, FULL_SIZE, "wideRoadEncodeIdx"), - ("qcamera.ts", 20, 77066, None), + ("qcamera.ts", 20, 130000, None), ] # we check frame count, so we don't have to be too strict on size @@ -62,6 +62,7 @@ class TestEncoder(unittest.TestCase): managed_processes['sensord'].start() managed_processes['loggerd'].start() + managed_processes['encoderd'].start() time.sleep(1.0) managed_processes['camerad'].start() @@ -97,21 +98,21 @@ class TestEncoder(unittest.TestCase): cmd = "LD_LIBRARY_PATH=/usr/local/lib " + cmd expected_frames = fps * SEGMENT_LENGTH - frame_tolerance = 0 probe = subprocess.check_output(cmd, shell=True, encoding='utf8') frame_count = int(probe.split('\n')[0].strip()) counts.append(frame_count) - self.assertTrue(abs(expected_frames - frame_count) <= frame_tolerance, - f"segment #{i}: {camera} failed frame count check: expected {expected_frames}, got {frame_count}") + self.assertEqual(frame_count, expected_frames, + f"segment #{i}: {camera} failed frame count check: expected {expected_frames}, got {frame_count}") # sanity check file size file_size = os.path.getsize(file_path) - self.assertTrue(math.isclose(file_size, size, rel_tol=FILE_SIZE_TOLERANCE)) + self.assertTrue(math.isclose(file_size, size, rel_tol=FILE_SIZE_TOLERANCE), + f"{file_path} size {file_size} isn't close to target size {size}") # Check encodeIdx if encode_idx_name is not None: - rlog_path = f"{route_prefix_path}--{i}/rlog.bz2" + rlog_path = f"{route_prefix_path}--{i}/rlog" msgs = [m for m in LogReader(rlog_path) if m.which() == encode_idx_name] encode_msgs = [getattr(m, encode_idx_name) for m in msgs] @@ -142,19 +143,18 @@ class TestEncoder(unittest.TestCase): shutil.rmtree(f"{route_prefix_path}--{i}") try: - for i in trange(num_segments + 1): + for i in trange(num_segments): # poll for next segment with Timeout(int(SEGMENT_LENGTH*10), error_msg=f"timed out waiting for segment {i}"): - while Path(f"{route_prefix_path}--{i}") not in Path(ROOT).iterdir(): + while Path(f"{route_prefix_path}--{i+1}") not in Path(ROOT).iterdir(): time.sleep(0.1) + check_seg(i) finally: managed_processes['loggerd'].stop() + managed_processes['encoderd'].stop() managed_processes['camerad'].stop() managed_processes['sensord'].stop() - for i in trange(num_segments): - check_seg(i) - if __name__ == "__main__": unittest.main() diff --git a/selfdrive/loggerd/tests/test_logger.cc b/selfdrive/loggerd/tests/test_logger.cc index 21b1d711d8..11a50fa2e7 100644 --- a/selfdrive/loggerd/tests/test_logger.cc +++ b/selfdrive/loggerd/tests/test_logger.cc @@ -7,7 +7,7 @@ #include "catch2/catch.hpp" #include "cereal/messaging/messaging.h" -#include "selfdrive/common/util.h" +#include "common/util.h" #include "selfdrive/loggerd/logger.h" #include "selfdrive/ui/replay/util.h" @@ -18,10 +18,10 @@ void verify_segment(const std::string &route_path, int segment, int max_segment, SentinelType begin_sentinel = segment == 0 ? SentinelType::START_OF_ROUTE : SentinelType::START_OF_SEGMENT; SentinelType end_sentinel = segment == max_segment - 1 ? SentinelType::END_OF_ROUTE : SentinelType::END_OF_SEGMENT; - REQUIRE(!util::file_exists(segment_path + "/rlog.bz2.lock")); - for (const char *fn : {"/rlog.bz2", "/qlog.bz2"}) { + REQUIRE(!util::file_exists(segment_path + "/rlog.lock")); + for (const char *fn : {"/rlog", "/qlog"}) { const std::string log_file = segment_path + fn; - std::string log = decompressBZ2(util::read_file(log_file)); + std::string log = util::read_file(log_file); REQUIRE(!log.empty()); int event_cnt = 0, i = 0; kj::ArrayPtr words((capnp::word *)log.data(), log.size() / sizeof(capnp::word)); @@ -70,7 +70,7 @@ TEST_CASE("logger") { ExitHandler do_exit; LoggerState logger = {}; - logger_init(&logger, "rlog", true); + logger_init(&logger, true); char segment_path[PATH_MAX] = {}; int segment = -1; @@ -78,7 +78,7 @@ TEST_CASE("logger") { const int segment_cnt = 100; for (int i = 0; i < segment_cnt; ++i) { REQUIRE(logger_next(&logger, log_root.c_str(), segment_path, sizeof(segment_path), &segment) == 0); - REQUIRE(util::file_exists(std::string(segment_path) + "/rlog.bz2.lock")); + REQUIRE(util::file_exists(std::string(segment_path) + "/rlog.lock")); REQUIRE(segment == i); write_msg(logger.cur_handle); } diff --git a/selfdrive/loggerd/tests/test_loggerd.cc b/selfdrive/loggerd/tests/test_loggerd.cc deleted file mode 100644 index d84185cbba..0000000000 --- a/selfdrive/loggerd/tests/test_loggerd.cc +++ /dev/null @@ -1,93 +0,0 @@ -#include - -#include "catch2/catch.hpp" -#include "selfdrive/loggerd/loggerd.h" - -int random_int(int min, int max) { - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(min, max); - return dist(rng); -} - -int get_synced_frame_id(LoggerdState *s, CameraType cam_type, int start_frame_id) { - int frame_id = start_frame_id; - while (!sync_encoders(s, cam_type, frame_id)) { - ++frame_id; - usleep(0); - } - return frame_id; -}; - -TEST_CASE("sync_encoders") { - const int max_waiting = GENERATE(1, 2, 3); - - for (int test_cnt = 0; test_cnt < 10; ++test_cnt) { - LoggerdState s{.max_waiting = max_waiting}; - std::vector start_frames; - std::vector> futures; - - for (int i = 0; i < max_waiting; ++i) { - int start_frame_id = random_int(0, 20); - start_frames.push_back(start_frame_id); - futures.emplace_back(std::async(std::launch::async, get_synced_frame_id, &s, (CameraType)i, start_frame_id)); - } - - // get results - int synced_frame_id = 0; - for (int i = 0; i < max_waiting; ++i) { - if (i == 0) { - synced_frame_id = futures[i].get(); - // require synced_frame_id equal start_frame_id if max_waiting == 1 - if (max_waiting == 1) { - REQUIRE(synced_frame_id == start_frames[0]); - } - } else { - REQUIRE(futures[i].get() == synced_frame_id); - } - } - } -} - -const int MAX_SEGMENT_CNT = 100; - -std::pair encoder_thread(LoggerdState *s) { - int cur_seg = 0; - uint32_t frame_id = s->start_frame_id; - - while (cur_seg < MAX_SEGMENT_CNT) { - ++frame_id; - if (trigger_rotate_if_needed(s, cur_seg, frame_id)) { - cur_seg = s->rotate_segment; - } - util::sleep_for(0); - } - - return {cur_seg, frame_id}; -} - -TEST_CASE("trigger_rotate") { - const int encoders = GENERATE(1, 2, 3); - const int start_frame_id = random_int(0, 20); - - LoggerdState s{ - .max_waiting = encoders, - .start_frame_id = start_frame_id, - }; - - std::vector>> futures; - for (int i = 0; i < encoders; ++i) { - futures.emplace_back(std::async(std::launch::async, encoder_thread, &s)); - } - - while (s.rotate_segment < MAX_SEGMENT_CNT) { - rotate_if_needed(&s); - util::sleep_for(10); - } - - for (auto &f : futures) { - auto [encoder_seg, frame_id] = f.get(); - REQUIRE(encoder_seg == MAX_SEGMENT_CNT); - REQUIRE(frame_id == start_frame_id + encoder_seg * (SEGMENT_LENGTH * MAIN_FPS)); - } -} diff --git a/selfdrive/loggerd/tests/test_loggerd.py b/selfdrive/loggerd/tests/test_loggerd.py index 13e0b720d8..9dbc7ac332 100755 --- a/selfdrive/loggerd/tests/test_loggerd.py +++ b/selfdrive/loggerd/tests/test_loggerd.py @@ -15,14 +15,12 @@ from cereal.services import service_list from common.basedir import BASEDIR from common.params import Params from common.timeout import Timeout -from selfdrive.hardware import TICI from selfdrive.loggerd.config import ROOT from selfdrive.manager.process_config import managed_processes -from selfdrive.version import get_version +from system.version import get_version from tools.lib.logreader import LogReader -from cereal.visionipc.visionipc_pyx import VisionIpcServer, VisionStreamType # pylint: disable=no-name-in-module, import-error -from common.transformations.camera import eon_f_frame_size, tici_f_frame_size, \ - eon_d_frame_size, tici_d_frame_size, tici_e_frame_size +from cereal.visionipc import VisionIpcServer, VisionStreamType +from common.transformations.camera import tici_f_frame_size, tici_d_frame_size, tici_e_frame_size SentinelType = log.Sentinel.SentinelType @@ -108,17 +106,15 @@ class TestLoggerd(unittest.TestCase): os.environ["LOGGERD_TEST"] = "1" Params().put("RecordFront", "1") - expected_files = {"rlog.bz2", "qlog.bz2", "qcamera.ts", "fcamera.hevc", "dcamera.hevc"} - streams = [(VisionStreamType.VISION_STREAM_ROAD, tici_f_frame_size if TICI else eon_f_frame_size, "roadCameraState"), - (VisionStreamType.VISION_STREAM_DRIVER, tici_d_frame_size if TICI else eon_d_frame_size, "driverCameraState")] - if TICI: - expected_files.add("ecamera.hevc") - streams.append((VisionStreamType.VISION_STREAM_WIDE_ROAD, tici_e_frame_size, "wideRoadCameraState")) + expected_files = {"rlog", "qlog", "qcamera.ts", "fcamera.hevc", "dcamera.hevc", "ecamera.hevc"} + streams = [(VisionStreamType.VISION_STREAM_ROAD, (*tici_f_frame_size, 2048*2346, 2048, 2048*1216), "roadCameraState"), + (VisionStreamType.VISION_STREAM_DRIVER, (*tici_d_frame_size, 2048*2346, 2048, 2048*1216), "driverCameraState"), + (VisionStreamType.VISION_STREAM_WIDE_ROAD, (*tici_e_frame_size, 2048*2346, 2048, 2048*1216), "wideRoadCameraState")] pm = messaging.PubMaster(["roadCameraState", "driverCameraState", "wideRoadCameraState"]) vipc_server = VisionIpcServer("camerad") - for stream_type, frame_size, _ in streams: - vipc_server.create_buffers(stream_type, 40, False, *(frame_size)) + for stream_type, frame_spec, _ in streams: + vipc_server.create_buffers_with_sizes(stream_type, 40, False, *(frame_spec)) vipc_server.start_listener() for _ in range(5): @@ -126,11 +122,12 @@ class TestLoggerd(unittest.TestCase): length = random.randint(1, 3) os.environ["LOGGERD_SEGMENT_LENGTH"] = str(length) managed_processes["loggerd"].start() + managed_processes["encoderd"].start() fps = 20.0 for n in range(1, int(num_segs*length*fps)+1): - for stream_type, frame_size, state in streams: - dat = np.empty(int(frame_size[0]*frame_size[1]*3/2), dtype=np.uint8) + for stream_type, frame_spec, state in streams: + dat = np.empty(frame_spec[2], dtype=np.uint8) vipc_server.send(stream_type, dat[:].flatten().tobytes(), n, n/fps, n/fps) camera_state = messaging.new_message(state) @@ -140,6 +137,7 @@ class TestLoggerd(unittest.TestCase): time.sleep(1.0/fps) managed_processes["loggerd"].stop() + managed_processes["encoderd"].stop() route_path = str(self._get_latest_log_dir()).rsplit("--", 1)[0] for n in range(num_segs): @@ -208,7 +206,7 @@ class TestLoggerd(unittest.TestCase): time.sleep(1) managed_processes["loggerd"].stop() - qlog_path = os.path.join(self._get_latest_log_dir(), "qlog.bz2") + qlog_path = os.path.join(self._get_latest_log_dir(), "qlog") lr = list(LogReader(qlog_path)) # check initData and sentinel @@ -254,7 +252,7 @@ class TestLoggerd(unittest.TestCase): time.sleep(2) managed_processes["loggerd"].stop() - lr = list(LogReader(os.path.join(self._get_latest_log_dir(), "rlog.bz2"))) + lr = list(LogReader(os.path.join(self._get_latest_log_dir(), "rlog"))) # check initData and sentinel self._check_init_data(lr) diff --git a/selfdrive/loggerd/tests/test_uploader.py b/selfdrive/loggerd/tests/test_uploader.py index 01b529468b..6090bbe2aa 100755 --- a/selfdrive/loggerd/tests/test_uploader.py +++ b/selfdrive/loggerd/tests/test_uploader.py @@ -6,11 +6,9 @@ import unittest import logging import json -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog import selfdrive.loggerd.uploader as uploader -from common.xattr import getxattr - from selfdrive.loggerd.tests.loggerd_tests_common import UploaderTestCase @@ -54,11 +52,11 @@ class TestUploader(UploaderTestCase): def gen_files(self, lock=False, boot=True): f_paths = list() - for t in ["qlog.bz2", "rlog.bz2", "dcamera.hevc", "fcamera.hevc"]: + for t in ["qlog", "rlog", "dcamera.hevc", "fcamera.hevc"]: f_paths.append(self.make_file_with_data(self.seg_dir, t, 1, lock=lock)) if boot: - f_paths.append(self.make_file_with_data("boot", f"{self.seg_dir}.bz2", 1, lock=lock)) + f_paths.append(self.make_file_with_data("boot", f"{self.seg_dir}", 1, lock=lock)) return f_paths def gen_order(self, seg1, seg2, boot=True): @@ -84,7 +82,7 @@ class TestUploader(UploaderTestCase): self.assertFalse(len(log_handler.upload_order) < len(exp_order), "Some files failed to upload") self.assertFalse(len(log_handler.upload_order) > len(exp_order), "Some files were uploaded twice") for f_path in exp_order: - self.assertTrue(getxattr(os.path.join(self.root, f_path), uploader.UPLOAD_ATTR_NAME), "All files not uploaded") + self.assertTrue(os.getxattr(os.path.join(self.root, f_path.replace('.bz2', '')), uploader.UPLOAD_ATTR_NAME), "All files not uploaded") self.assertTrue(log_handler.upload_order == exp_order, "Files uploaded in wrong order") @@ -103,7 +101,7 @@ class TestUploader(UploaderTestCase): self.assertFalse(len(log_handler.upload_ignored) < len(exp_order), "Some files failed to ignore") self.assertFalse(len(log_handler.upload_ignored) > len(exp_order), "Some files were ignored twice") for f_path in exp_order: - self.assertTrue(getxattr(os.path.join(self.root, f_path), uploader.UPLOAD_ATTR_NAME), "All files not ignored") + self.assertTrue(os.getxattr(os.path.join(self.root, f_path.replace('.bz2', '')), uploader.UPLOAD_ATTR_NAME), "All files not ignored") self.assertTrue(log_handler.upload_ignored == exp_order, "Files ignored in wrong order") @@ -128,7 +126,7 @@ class TestUploader(UploaderTestCase): self.assertFalse(len(log_handler.upload_order) < len(exp_order), "Some files failed to upload") self.assertFalse(len(log_handler.upload_order) > len(exp_order), "Some files were uploaded twice") for f_path in exp_order: - self.assertTrue(getxattr(os.path.join(self.root, f_path), uploader.UPLOAD_ATTR_NAME), "All files not uploaded") + self.assertTrue(os.getxattr(os.path.join(self.root, f_path.replace('.bz2', '')), uploader.UPLOAD_ATTR_NAME), "All files not uploaded") self.assertTrue(log_handler.upload_order == exp_order, "Files uploaded in wrong order") @@ -143,8 +141,8 @@ class TestUploader(UploaderTestCase): self.join_thread() for f_path in f_paths: - self.assertFalse(getxattr(f_path, uploader.UPLOAD_ATTR_NAME), "File upload when locked") - + uploaded = uploader.UPLOAD_ATTR_NAME in os.listxattr(f_path.replace('.bz2', '')) + self.assertFalse(uploaded, "File upload when locked") def test_clear_locks_on_startup(self): f_paths = self.gen_files(lock=True, boot=False) @@ -157,4 +155,4 @@ class TestUploader(UploaderTestCase): if __name__ == "__main__": - unittest.main(failfast=True) + unittest.main() diff --git a/selfdrive/loggerd/tools/mark_all_uploaded.py b/selfdrive/loggerd/tools/mark_all_uploaded.py index ff6e3c1f17..e60e6cfa2c 100644 --- a/selfdrive/loggerd/tools/mark_all_uploaded.py +++ b/selfdrive/loggerd/tools/mark_all_uploaded.py @@ -1,9 +1,8 @@ import os -from common.xattr import setxattr from selfdrive.loggerd.uploader import UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE from selfdrive.loggerd.config import ROOT for folder in os.walk(ROOT): for file1 in folder[2]: full_path = os.path.join(folder[0], file1) - setxattr(full_path, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE) + os.setxattr(full_path, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE) diff --git a/selfdrive/loggerd/tools/mark_unuploaded.py b/selfdrive/loggerd/tools/mark_unuploaded.py index 0d3f765af4..343805d5fc 100755 --- a/selfdrive/loggerd/tools/mark_unuploaded.py +++ b/selfdrive/loggerd/tools/mark_unuploaded.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 +import os import sys -from common.xattr import removexattr from selfdrive.loggerd.uploader import UPLOAD_ATTR_NAME for fn in sys.argv[1:]: print(f"unmarking {fn}") - removexattr(fn, UPLOAD_ATTR_NAME) + os.removexattr(fn, UPLOAD_ATTR_NAME) diff --git a/selfdrive/loggerd/uploader.py b/selfdrive/loggerd/uploader.py index 9e9dd0c79e..f97bafecb9 100644 --- a/selfdrive/loggerd/uploader.py +++ b/selfdrive/loggerd/uploader.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +import bz2 +import io import json import os import random @@ -12,15 +14,18 @@ from cereal import log import cereal.messaging as messaging from common.api import Api from common.params import Params -from selfdrive.hardware import TICI +from common.realtime import set_core_affinity +from system.hardware import TICI from selfdrive.loggerd.xattr_cache import getxattr, setxattr from selfdrive.loggerd.config import ROOT -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog NetworkType = log.DeviceState.NetworkType UPLOAD_ATTR_NAME = 'user.upload' UPLOAD_ATTR_VALUE = b'1' +UPLOAD_QLOG_QCAM_MAX_SIZE = 100 * 1e6 # MB + allow_sleep = bool(os.getenv("UPLOADER_SLEEP", "1")) force_wifi = os.getenv("FORCEWIFI") is not None fake_upload = os.getenv("FAKEUPLOAD") is not None @@ -64,12 +69,12 @@ class Uploader(): self.immediate_count = 0 # stats for last successfully uploaded file - self.last_time = 0 - self.last_speed = 0 + self.last_time = 0.0 + self.last_speed = 0.0 self.last_filename = "" self.immediate_folders = ["crash/", "boot/"] - self.immediate_priority = {"qlog.bz2": 0, "qcamera.ts": 1} + self.immediate_priority = {"qlog": 0, "qlog.bz2": 0, "qcamera.ts": 1} def get_upload_sort(self, name): if name in self.immediate_priority: @@ -119,11 +124,11 @@ class Uploader(): for name, key, fn in upload_files: if any(f in fn for f in self.immediate_folders): - return (key, fn) + return (name, key, fn) for name, key, fn in upload_files: if name in self.immediate_priority: - return (key, fn) + return (name, key, fn) return None @@ -149,7 +154,13 @@ class Uploader(): self.last_resp = FakeResponse() else: with open(fn, "rb") as f: - self.last_resp = requests.put(url, data=f, headers=headers, timeout=10) + if key.endswith('.bz2') and not fn.endswith('.bz2'): + data = bz2.compress(f.read()) + data = io.BytesIO(data) + else: + data = f + + self.last_resp = requests.put(url, data=data, headers=headers, timeout=10) except Exception as e: self.last_exc = (e, traceback.format_exc()) raise @@ -165,7 +176,7 @@ class Uploader(): return self.last_resp - def upload(self, key, fn, network_type, metered): + def upload(self, name, key, fn, network_type, metered): try: sz = os.path.getsize(fn) except OSError: @@ -175,22 +186,15 @@ class Uploader(): cloudlog.event("upload_start", key=key, fn=fn, sz=sz, network_type=network_type, metered=metered) if sz == 0: - try: - # tag files of 0 size as uploaded - setxattr(fn, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE) - except OSError: - cloudlog.event("uploader_setxattr_failed", exc=self.last_exc, key=key, fn=fn, sz=sz) + # tag files of 0 size as uploaded + success = True + elif name in self.immediate_priority and sz > UPLOAD_QLOG_QCAM_MAX_SIZE: + cloudlog.event("uploader_too_large", key=key, fn=fn, sz=sz) success = True else: start_time = time.monotonic() stat = self.normal_upload(key, fn) if stat is not None and stat.status_code in (200, 201, 401, 403, 412): - try: - # tag file as uploaded - setxattr(fn, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE) - except OSError: - cloudlog.event("uploader_setxattr_failed", exc=self.last_exc, key=key, fn=fn, sz=sz) - self.last_filename = fn self.last_time = time.monotonic() - start_time self.last_speed = (sz / 1e6) / self.last_time @@ -200,6 +204,13 @@ class Uploader(): success = False cloudlog.event("upload_failed", stat=stat, exc=self.last_exc, key=key, fn=fn, sz=sz, network_type=network_type, metered=metered) + if success: + # tag file as uploaded + try: + setxattr(fn, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE) + except OSError: + cloudlog.event("uploader_setxattr_failed", exc=self.last_exc, key=key, fn=fn, sz=sz) + return success def get_msg(self): @@ -212,7 +223,13 @@ class Uploader(): us.lastFilename = self.last_filename return msg + def uploader_fn(exit_event): + try: + set_core_affinity([0, 1, 2, 3]) + except Exception: + cloudlog.exception("failed to set core affinity") + clear_locks(ROOT) params = Params() @@ -245,9 +262,13 @@ def uploader_fn(exit_event): time.sleep(60 if offroad else 5) continue - key, fn = d + name, key, fn = d + + # qlogs and bootlogs need to be compressed before uploading + if key.endswith(('qlog', 'rlog')) or (key.startswith('boot/') and not key.endswith('.bz2')): + key += ".bz2" - success = uploader.upload(key, fn, sm['deviceState'].networkType.raw, sm['deviceState'].networkMetered) + success = uploader.upload(name, key, fn, sm['deviceState'].networkType.raw, sm['deviceState'].networkMetered) if success: backoff = 0.1 elif allow_sleep: diff --git a/selfdrive/loggerd/video_writer.cc b/selfdrive/loggerd/video_writer.cc index f9034f6912..4f79ccafc8 100644 --- a/selfdrive/loggerd/video_writer.cc +++ b/selfdrive/loggerd/video_writer.cc @@ -1,14 +1,14 @@ #pragma clang diagnostic ignored "-Wdeprecated-declarations" - #include #include #include "selfdrive/loggerd/video_writer.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" +#include "common/swaglog.h" +#include "common/util.h" -VideoWriter::VideoWriter(const char *path, const char *filename, bool remuxing, int width, int height, int fps, bool h265, bool raw) - : remuxing(remuxing), raw(raw) { +VideoWriter::VideoWriter(const char *path, const char *filename, bool remuxing, int width, int height, int fps, cereal::EncodeIndex::Type codec) + : remuxing(remuxing) { + raw = codec == cereal::EncodeIndex::Type::BIG_BOX_LOSSLESS; vid_path = util::string_format("%s/%s", path, filename); lock_path = util::string_format("%s/%s.lock", path, filename); @@ -22,33 +22,29 @@ VideoWriter::VideoWriter(const char *path, const char *filename, bool remuxing, assert(this->ofmt_ctx); // set codec correctly. needed? - av_register_all(); - - AVCodec *codec = NULL; - assert(!h265); - codec = avcodec_find_encoder(raw ? AV_CODEC_ID_FFVHUFF : AV_CODEC_ID_H264); - assert(codec); + assert(codec != cereal::EncodeIndex::Type::FULL_H_E_V_C); + const AVCodec *avcodec = avcodec_find_encoder(raw ? AV_CODEC_ID_FFVHUFF : AV_CODEC_ID_H264); + assert(avcodec); - this->codec_ctx = avcodec_alloc_context3(codec); + this->codec_ctx = avcodec_alloc_context3(avcodec); assert(this->codec_ctx); this->codec_ctx->width = width; this->codec_ctx->height = height; this->codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P; this->codec_ctx->time_base = (AVRational){ 1, fps }; - if (raw) { - // since the codec is actually used, we open it - int err = avcodec_open2(this->codec_ctx, codec, NULL); + if (codec == cereal::EncodeIndex::Type::BIG_BOX_LOSSLESS) { + // without this, there's just noise + int err = avcodec_open2(this->codec_ctx, avcodec, NULL); assert(err >= 0); } - this->out_stream = avformat_new_stream(this->ofmt_ctx, raw ? codec : NULL); + this->out_stream = avformat_new_stream(this->ofmt_ctx, raw ? avcodec : NULL); assert(this->out_stream); int err = avio_open(&this->ofmt_ctx->pb, this->vid_path.c_str(), AVIO_FLAG_WRITE); assert(err >= 0); - this->wrote_codec_config = false; } else { this->of = util::safe_fopen(this->vid_path.c_str(), "wb"); assert(this->of); @@ -65,7 +61,7 @@ void VideoWriter::write(uint8_t *data, int len, long long timestamp, bool codecc if (remuxing) { if (codecconfig) { - if (data) { + if (len > 0) { codec_ctx->extradata = (uint8_t*)av_mallocz(len + AV_INPUT_BUFFER_PADDING_SIZE); codec_ctx->extradata_size = len; memcpy(codec_ctx->extradata, data, len); @@ -93,9 +89,9 @@ void VideoWriter::write(uint8_t *data, int len, long long timestamp, bool codecc // TODO: can use av_write_frame for non raw? int err = av_interleaved_write_frame(ofmt_ctx, &pkt); - if (err < 0) { LOGW("ts encoder write issue"); } + if (err < 0) { LOGW("ts encoder write issue len: %d ts: %lu", len, timestamp); } - av_free_packet(&pkt); + av_packet_unref(&pkt); } } } diff --git a/selfdrive/loggerd/video_writer.h b/selfdrive/loggerd/video_writer.h index 8217b859bf..01a243904c 100644 --- a/selfdrive/loggerd/video_writer.h +++ b/selfdrive/loggerd/video_writer.h @@ -4,22 +4,23 @@ extern "C" { #include +#include } +#include "cereal/messaging/messaging.h" + class VideoWriter { public: - VideoWriter(const char *path, const char *filename, bool remuxing, int width, int height, int fps, bool h265, bool raw); + VideoWriter(const char *path, const char *filename, bool remuxing, int width, int height, int fps, cereal::EncodeIndex::Type codec); void write(uint8_t *data, int len, long long timestamp, bool codecconfig, bool keyframe); ~VideoWriter(); - AVCodecContext *codec_ctx; private: std::string vid_path, lock_path; FILE *of = nullptr; + AVCodecContext *codec_ctx; AVFormatContext *ofmt_ctx; AVStream *out_stream; bool remuxing, raw; - - bool wrote_codec_config; }; \ No newline at end of file diff --git a/selfdrive/loggerd/xattr_cache.py b/selfdrive/loggerd/xattr_cache.py index e721692500..95e39f2032 100644 --- a/selfdrive/loggerd/xattr_cache.py +++ b/selfdrive/loggerd/xattr_cache.py @@ -1,15 +1,23 @@ -from typing import Dict, Tuple +import os +import errno +from typing import Dict, Tuple, Optional -from common.xattr import getxattr as getattr1 -from common.xattr import setxattr as setattr1 +_cached_attributes: Dict[Tuple, Optional[bytes]] = {} -cached_attributes: Dict[Tuple, bytes] = {} -def getxattr(path: str, attr_name: bytes) -> bytes: - if (path, attr_name) not in cached_attributes: - response = getattr1(path, attr_name) - cached_attributes[(path, attr_name)] = response - return cached_attributes[(path, attr_name)] +def getxattr(path: str, attr_name: str) -> Optional[bytes]: + key = (path, attr_name) + if key not in _cached_attributes: + try: + response = os.getxattr(path, attr_name) + except OSError as e: + # ENODATA means attribute hasn't been set + if e.errno == errno.ENODATA: + response = None + else: + raise + _cached_attributes[key] = response + return _cached_attributes[key] def setxattr(path: str, attr_name: str, attr_value: bytes) -> None: - cached_attributes.pop((path, attr_name), None) - return setattr1(path, attr_name, attr_value) + _cached_attributes.pop((path, attr_name), None) + return os.setxattr(path, attr_name, attr_value) diff --git a/selfdrive/manager/build.py b/selfdrive/manager/build.py index 806aa58bb7..10b4c0a4b8 100755 --- a/selfdrive/manager/build.py +++ b/selfdrive/manager/build.py @@ -10,14 +10,14 @@ from pathlib import Path from common.basedir import BASEDIR from common.spinner import Spinner from common.text_window import TextWindow -from selfdrive.hardware import TICI -from selfdrive.swaglog import cloudlog, add_file_handler -from selfdrive.version import is_dirty +from system.hardware import AGNOS +from system.swaglog import cloudlog, add_file_handler +from system.version import is_dirty MAX_CACHE_SIZE = 4e9 if "CI" in os.environ else 2e9 -CACHE_DIR = Path("/data/scons_cache" if TICI else "/tmp/scons_cache") +CACHE_DIR = Path("/data/scons_cache" if AGNOS else "/tmp/scons_cache") -TOTAL_SCONS_NODES = 2405 +TOTAL_SCONS_NODES = 2035 MAX_BUILD_PROGRESS = 100 PREBUILT = os.path.exists(os.path.join(BASEDIR, 'prebuilt')) diff --git a/selfdrive/manager/manager.py b/selfdrive/manager/manager.py index 1934da6701..140c7f1d44 100755 --- a/selfdrive/manager/manager.py +++ b/selfdrive/manager/manager.py @@ -13,13 +13,13 @@ from common.basedir import BASEDIR from common.params import Params, ParamKeyType from common.text_window import TextWindow from selfdrive.boardd.set_time import set_time -from selfdrive.hardware import HARDWARE, PC +from system.hardware import HARDWARE, PC from selfdrive.manager.helpers import unblock_stdout from selfdrive.manager.process import ensure_running from selfdrive.manager.process_config import managed_processes from selfdrive.athena.registration import register, UNREGISTERED_DONGLE_ID -from selfdrive.swaglog import cloudlog, add_file_handler -from selfdrive.version import is_dirty, get_commit, get_version, get_origin, get_short_branch, \ +from system.swaglog import cloudlog, add_file_handler +from system.version import is_dirty, get_commit, get_version, get_origin, get_short_branch, \ terms_version, training_version @@ -128,17 +128,16 @@ def manager_thread() -> None: ignore.append("pandad") ignore += [x for x in os.getenv("BLOCK", "").split(",") if len(x) > 0] - ensure_running(managed_processes.values(), started=False, not_run=ignore) - sm = messaging.SubMaster(['deviceState', 'carParams'], poll=['deviceState']) pm = messaging.PubMaster(['managerState']) + ensure_running(managed_processes.values(), False, params=params, CP=sm['carParams'], not_run=ignore) + while True: sm.update() started = sm['deviceState'].started - driverview = params.get_bool("IsDriverViewEnabled") - ensure_running(managed_processes.values(), started=started, driverview=driverview, notcar=sm['carParams'].notCar, not_run=ignore) + ensure_running(managed_processes.values(), started, params=params, CP=sm['carParams'], not_run=ignore) running = ' '.join("%s%s\u001b[0m" % ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name) for p in managed_processes.values() if p.proc) diff --git a/selfdrive/manager/process.py b/selfdrive/manager/process.py index 8bb160961f..dabfbe4ee0 100644 --- a/selfdrive/manager/process.py +++ b/selfdrive/manager/process.py @@ -4,7 +4,7 @@ import signal import struct import time import subprocess -from typing import Optional, List, ValuesView +from typing import Optional, Callable, List, ValuesView from abc import ABC, abstractmethod from multiprocessing import Process @@ -12,11 +12,12 @@ from setproctitle import setproctitle # pylint: disable=no-name-in-module import cereal.messaging as messaging import selfdrive.sentry as sentry +from cereal import car from common.basedir import BASEDIR from common.params import Params from common.realtime import sec_since_boot -from selfdrive.swaglog import cloudlog -from selfdrive.hardware import HARDWARE +from system.swaglog import cloudlog +from system.hardware import HARDWARE from cereal import log WATCHDOG_FN = "/dev/shm/wd_" @@ -71,8 +72,7 @@ class ManagerProcess(ABC): sigkill = False onroad = True offroad = False - driverview = False - notcar = False + callback: Optional[Callable[[bool, Params, car.CarParams], bool]] = None proc: Optional[Process] = None enabled = True name = "" @@ -184,15 +184,14 @@ class ManagerProcess(ABC): class NativeProcess(ManagerProcess): - def __init__(self, name, cwd, cmdline, enabled=True, onroad=True, offroad=False, driverview=False, notcar=False, unkillable=False, sigkill=False, watchdog_max_dt=None): + def __init__(self, name, cwd, cmdline, enabled=True, onroad=True, offroad=False, callback=None, unkillable=False, sigkill=False, watchdog_max_dt=None): self.name = name self.cwd = cwd self.cmdline = cmdline self.enabled = enabled self.onroad = onroad self.offroad = offroad - self.driverview = driverview - self.notcar = notcar + self.callback = callback self.unkillable = unkillable self.sigkill = sigkill self.watchdog_max_dt = watchdog_max_dt @@ -217,14 +216,13 @@ class NativeProcess(ManagerProcess): class PythonProcess(ManagerProcess): - def __init__(self, name, module, enabled=True, onroad=True, offroad=False, driverview=False, notcar=False, unkillable=False, sigkill=False, watchdog_max_dt=None): + def __init__(self, name, module, enabled=True, onroad=True, offroad=False, callback=None, unkillable=False, sigkill=False, watchdog_max_dt=None): self.name = name self.module = module self.enabled = enabled self.onroad = onroad self.offroad = offroad - self.driverview = driverview - self.notcar = notcar + self.callback = callback self.unkillable = unkillable self.sigkill = sigkill self.watchdog_max_dt = watchdog_max_dt @@ -291,7 +289,7 @@ class DaemonProcess(ManagerProcess): pass -def ensure_running(procs: ValuesView[ManagerProcess], started: bool, driverview: bool=False, notcar: bool=False, +def ensure_running(procs: ValuesView[ManagerProcess], started: bool, params=None, CP: car.CarParams=None, not_run: Optional[List[str]]=None) -> None: if not_run is None: not_run = [] @@ -301,9 +299,9 @@ def ensure_running(procs: ValuesView[ManagerProcess], started: bool, driverview: run = any(( p.offroad and not started, p.onroad and started, - p.driverview and driverview, - p.notcar and notcar, )) + if p.callback is not None and None not in (params, CP): + run = run or p.callback(started, params, CP) # Conditions that block a process from starting run = run and not any(( diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index 2e2747fecc..a9a5c78a7f 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -1,48 +1,63 @@ import os -from selfdrive.hardware import TICI, PC +from cereal import car +from common.params import Params +from system.hardware import PC from selfdrive.manager.process import PythonProcess, NativeProcess, DaemonProcess WEBCAM = os.getenv("USE_WEBCAM") is not None +def driverview(started: bool, params: Params, CP: car.CarParams) -> bool: + return params.get_bool("IsDriverViewEnabled") # type: ignore + +def notcar(started: bool, params: Params, CP: car.CarParams) -> bool: + return CP.notCar # type: ignore + +def logging(started, params, CP: car.CarParams) -> bool: + run = (not CP.notCar) or not params.get_bool("DisableLogging") + return started and run + procs = [ + NativeProcess("clocksd", "system/clocksd", ["./clocksd"]), + NativeProcess("logcatd", "system/logcatd", ["./logcatd"]), + NativeProcess("proclogd", "system/proclogd", ["./proclogd"]), + PythonProcess("logmessaged", "system.logmessaged", offroad=True), + PythonProcess("timezoned", "system.timezoned", enabled=not PC, offroad=True), + DaemonProcess("manage_athenad", "selfdrive.athena.manage_athenad", "AthenadPid"), # due to qualcomm kernel bugs SIGKILLing camerad sometimes causes page table corruption - NativeProcess("camerad", "selfdrive/camerad", ["./camerad"], unkillable=True, driverview=True), - NativeProcess("clocksd", "selfdrive/clocksd", ["./clocksd"]), - NativeProcess("dmonitoringmodeld", "selfdrive/modeld", ["./dmonitoringmodeld"], enabled=(not PC or WEBCAM), driverview=True), - NativeProcess("logcatd", "selfdrive/logcatd", ["./logcatd"]), - NativeProcess("loggerd", "selfdrive/loggerd", ["./loggerd"]), + NativeProcess("camerad", "selfdrive/camerad", ["./camerad"], unkillable=True, callback=driverview), + NativeProcess("dmonitoringmodeld", "selfdrive/modeld", ["./dmonitoringmodeld"], enabled=(not PC or WEBCAM), callback=driverview), + NativeProcess("encoderd", "selfdrive/loggerd", ["./encoderd"]), + NativeProcess("loggerd", "selfdrive/loggerd", ["./loggerd"], onroad=False, callback=logging), NativeProcess("modeld", "selfdrive/modeld", ["./modeld"]), - NativeProcess("navd", "selfdrive/ui/navd", ["./navd"], offroad=True), - NativeProcess("proclogd", "selfdrive/proclogd", ["./proclogd"]), NativeProcess("sensord", "selfdrive/sensord", ["./sensord"], enabled=not PC), NativeProcess("ubloxd", "selfdrive/locationd", ["./ubloxd"], enabled=(not PC or WEBCAM)), - NativeProcess("ui", "selfdrive/ui", ["./ui"], offroad=True, watchdog_max_dt=(5 if TICI else None)), + NativeProcess("ui", "selfdrive/ui", ["./ui"], offroad=True, watchdog_max_dt=(5 if not PC else None)), NativeProcess("soundd", "selfdrive/ui/soundd", ["./soundd"], offroad=True), NativeProcess("locationd", "selfdrive/locationd", ["./locationd"]), NativeProcess("boardd", "selfdrive/boardd", ["./boardd"], enabled=False), PythonProcess("calibrationd", "selfdrive.locationd.calibrationd"), PythonProcess("controlsd", "selfdrive.controls.controlsd"), PythonProcess("deleter", "selfdrive.loggerd.deleter", offroad=True), - PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", enabled=(not PC or WEBCAM), driverview=True), - PythonProcess("logmessaged", "selfdrive.logmessaged", offroad=True), + PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", enabled=(not PC or WEBCAM), callback=driverview), + PythonProcess("navd", "selfdrive.navd.navd"), PythonProcess("pandad", "selfdrive.boardd.pandad", offroad=True), PythonProcess("paramsd", "selfdrive.locationd.paramsd"), PythonProcess("plannerd", "selfdrive.controls.plannerd"), PythonProcess("radard", "selfdrive.controls.radard"), PythonProcess("thermald", "selfdrive.thermald.thermald", offroad=True), - PythonProcess("timezoned", "selfdrive.timezoned", enabled=TICI, offroad=True), PythonProcess("tombstoned", "selfdrive.tombstoned", enabled=not PC, offroad=True), PythonProcess("updated", "selfdrive.updated", enabled=not PC, onroad=False, offroad=True), PythonProcess("uploader", "selfdrive.loggerd.uploader", offroad=True), PythonProcess("statsd", "selfdrive.statsd", offroad=True), - NativeProcess("bridge", "cereal/messaging", ["./bridge"], onroad=False, notcar=True), - PythonProcess("webjoystick", "tools.joystick.web", onroad=False, notcar=True), + NativeProcess("bridge", "cereal/messaging", ["./bridge"], onroad=False, callback=notcar), + PythonProcess("webjoystick", "tools.joystick.web", onroad=False, callback=notcar), # Experimental PythonProcess("rawgpsd", "selfdrive.sensord.rawgps.rawgpsd", enabled=os.path.isfile("/persist/comma/use-quectel-rawgps")), + PythonProcess("laikad", "selfdrive.locationd.laikad", enabled=os.path.isfile("/persist/comma/use-laikad")), ] managed_processes = {p.name: p for p in procs} diff --git a/selfdrive/manager/test/test_manager.py b/selfdrive/manager/test/test_manager.py index 1750c81b2e..a84ff264d2 100755 --- a/selfdrive/manager/test/test_manager.py +++ b/selfdrive/manager/test/test_manager.py @@ -5,14 +5,13 @@ import time import unittest import selfdrive.manager.manager as manager -from selfdrive.hardware import TICI, HARDWARE from selfdrive.manager.process import DaemonProcess from selfdrive.manager.process_config import managed_processes +from system.hardware import AGNOS, HARDWARE os.environ['FAKEUPLOAD'] = "1" -# TODO: make eon fast -MAX_STARTUP_TIME = 15 +MAX_STARTUP_TIME = 3 ALL_PROCESSES = [p.name for p in managed_processes.values() if (type(p) is not DaemonProcess) and p.enabled and (p.name not in ['updated', 'pandad'])] @@ -50,13 +49,10 @@ class TestManager(unittest.TestCase): self.assertTrue(state.running, f"{p} not running") exit_code = managed_processes[p].stop(retry=False) - if (TICI and p in ['ui', 'navd']): + if (AGNOS and p in ['ui',]): # TODO: make Qt UI exit gracefully continue - # Make sure the process is actually dead - managed_processes[p].stop() - # TODO: interrupted blocking read exits with 1 in cereal. use a more unique return code exit_codes = [0, 1] if managed_processes[p].sigkill: diff --git a/selfdrive/modeld/SConscript b/selfdrive/modeld/SConscript index c6855e8c38..3e9738d864 100644 --- a/selfdrive/modeld/SConscript +++ b/selfdrive/modeld/SConscript @@ -63,24 +63,16 @@ common_model = lenv.Object(common_src) # build thneed model if use_thneed and arch == "larch64": - fn = File("#models/supercombo").abspath + fn = File("models/supercombo").abspath compiler = lenv.Program('thneed/compile', ["thneed/compile.cc"]+common_model, LIBS=libs) - cmd = f"cd {Dir('.').abspath} && {compiler[0].abspath} {fn}.dlc {fn}_badweights.thneed --binary" + cmd = f"cd {Dir('.').abspath} && {compiler[0].abspath} --in {fn}.dlc --out {fn}.thneed --binary --optimize" lib_paths = ':'.join(Dir(p).abspath for p in lenv["LIBPATH"]) kernel_path = os.path.join(Dir('.').abspath, "thneed", "kernels") cenv = Environment(ENV={'LD_LIBRARY_PATH': f"{lib_paths}:{lenv['ENV']['LD_LIBRARY_PATH']}", 'KERNEL_PATH': kernel_path}) kernels = [os.path.join(kernel_path, x) for x in os.listdir(kernel_path) if x.endswith(".cl")] - cenv.Command(fn + "_badweights.thneed", [fn + ".dlc", kernels, compiler], cmd) - - from selfdrive.modeld.thneed.weights_fixup import weights_fixup - def weights_fixup_action(target, source, env): - weights_fixup(target[0].abspath, source[0].abspath, source[1].abspath) - - env = Environment(BUILDERS = {'WeightFixup' : Builder(action = weights_fixup_action)}) - env.WeightFixup(target=fn + ".thneed", source=[fn+"_badweights.thneed", fn+".dlc"]) - + cenv.Command(fn + ".thneed", [fn + ".dlc", kernels, compiler], cmd) lenv.Program('_dmonitoringmodeld', [ "dmonitoringmodeld.cc", diff --git a/selfdrive/modeld/dmonitoringmodeld.cc b/selfdrive/modeld/dmonitoringmodeld.cc index 8016180f40..68c49572e6 100644 --- a/selfdrive/modeld/dmonitoringmodeld.cc +++ b/selfdrive/modeld/dmonitoringmodeld.cc @@ -5,8 +5,8 @@ #include #include "cereal/visionipc/visionipc_client.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" +#include "common/swaglog.h" +#include "common/util.h" #include "selfdrive/modeld/models/dmonitoring.h" ExitHandler do_exit; @@ -31,7 +31,7 @@ void run_model(DMonitoringModelState &model, VisionIpcClient &vipc_client) { } double t1 = millis_since_boot(); - DMonitoringResult res = dmonitoring_eval_frame(&model, buf->addr, buf->width, buf->height, calib); + DMonitoringResult res = dmonitoring_eval_frame(&model, buf->addr, buf->width, buf->height, buf->stride, buf->uv_offset, calib); double t2 = millis_since_boot(); // send dm packet diff --git a/selfdrive/modeld/modeld.cc b/selfdrive/modeld/modeld.cc index 6ee07b3d02..0aac9b3c4a 100644 --- a/selfdrive/modeld/modeld.cc +++ b/selfdrive/modeld/modeld.cc @@ -7,11 +7,11 @@ #include "cereal/messaging/messaging.h" #include "cereal/visionipc/visionipc_client.h" -#include "selfdrive/common/clutil.h" -#include "selfdrive/common/params.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" -#include "selfdrive/hardware/hw.h" +#include "common/clutil.h" +#include "common/params.h" +#include "common/swaglog.h" +#include "common/util.h" +#include "system/hardware/hw.h" #include "selfdrive/modeld/models/driving.h" ExitHandler do_exit; @@ -163,7 +163,7 @@ void run_model(ModelState &model, VisionIpcClient &vipc_client_main, VisionIpcCl } int main(int argc, char **argv) { - if (Hardware::TICI()) { + if (!Hardware::PC()) { int ret; ret = util::set_realtime_priority(54); assert(ret == 0); @@ -171,7 +171,7 @@ int main(int argc, char **argv) { assert(ret == 0); } - bool main_wide_camera = Params().getBool("EnableWideCamera"); + bool main_wide_camera = Params().getBool("WideCameraOnly"); bool use_extra_client = !main_wide_camera; // set for single camera mode // cl init diff --git a/selfdrive/modeld/models/README.md b/selfdrive/modeld/models/README.md new file mode 100644 index 0000000000..6b704cbfa8 --- /dev/null +++ b/selfdrive/modeld/models/README.md @@ -0,0 +1,59 @@ +## Neural networks in openpilot +To view the architecture of the ONNX networks, you can use [netron](https://netron.app/) + +## Supercombo +### Supercombo input format (Full size: 393738 x float32) +* **image stream** + * Two consecutive images (256 * 512 * 3 in RGB) recorded at 20 Hz : 393216 = 2 * 6 * 128 * 256 + * Each 256 * 512 image is represented in YUV420 with 6 channels : 6 * 128 * 256 + * Channels 0,1,2,3 represent the full-res Y channel and are represented in numpy as Y[::2, ::2], Y[::2, 1::2], Y[1::2, ::2], and Y[1::2, 1::2] + * Channel 4 represents the half-res U channel + * Channel 5 represents the half-res V channel +* **wide image stream** + * Two consecutive images (256 * 512 * 3 in RGB) recorded at 20 Hz : 393216 = 2 * 6 * 128 * 256 + * Each 256 * 512 image is represented in YUV420 with 6 channels : 6 * 128 * 256 + * Channels 0,1,2,3 represent the full-res Y channel and are represented in numpy as Y[::2, ::2], Y[::2, 1::2], Y[1::2, ::2], and Y[1::2, 1::2] + * Channel 4 represents the half-res U channel + * Channel 5 represents the half-res V channel +* **desire** + * one-hot encoded vector to command model to execute certain actions, bit only needs to be sent for 1 frame : 8 +* **traffic convention** + * one-hot encoded vector to tell model whether traffic is right-hand or left-hand traffic : 2 +* **recurrent state** + * The recurrent state vector that is fed back into the GRU for temporal context : 512 + + +### Supercombo output format (Full size: XXX x float32) +Read [here](https://github.com/commaai/openpilot/blob/90af436a121164a51da9fa48d093c29f738adf6a/selfdrive/modeld/models/driving.h#L236) for more. + + +## Driver Monitoring Model +* .onnx model can be run with onnx runtimes +* .dlc file is a pre-quantized model and only runs on qualcomm DSPs + +### input format +* single image (640 * 320 * 3 in RGB): + * full input size is 6 * 640/2 * 320/2 = 307200 + * represented in YUV420 with 6 channels: + * Channels 0,1,2,3 represent the full-res Y channel and are represented in numpy as Y[::2, ::2], Y[::2, 1::2], Y[1::2, ::2], and Y[1::2, 1::2] + * Channel 4 represents the half-res U channel + * Channel 5 represents the half-res V channel + * normalized, ranging from -1.0 to 1.0 + +### output format +* 39 x float32 outputs ([parsing example](https://github.com/commaai/openpilot/blob/master/selfdrive/modeld/models/dmonitoring.cc#L165)) + * face pose: 12 = 6 + 6 + * face orientation [pitch, yaw, roll] in camera frame: 3 + * face position [dx, dy] relative to image center: 2 + * normalized face size: 1 + * standard deviations for above outputs: 6 + * face visible probability: 1 + * eyes: 20 = (8 + 1) + (8 + 1) + 1 + 1 + * eye position and size, and their standard deviations: 8 + * eye visible probability: 1 + * eye closed probability: 1 + * wearing sunglasses probability: 1 + * poor camera vision probability: 1 + * face partially out-of-frame probability: 1 + * (deprecated) distracted probabilities: 2 + * face covered probability: 1 diff --git a/selfdrive/modeld/models/commonmodel.cc b/selfdrive/modeld/models/commonmodel.cc index a075c08deb..b7c9051c6e 100644 --- a/selfdrive/modeld/models/commonmodel.cc +++ b/selfdrive/modeld/models/commonmodel.cc @@ -5,9 +5,9 @@ #include #include -#include "selfdrive/common/clutil.h" -#include "selfdrive/common/mat.h" -#include "selfdrive/common/timing.h" +#include "common/clutil.h" +#include "common/mat.h" +#include "common/timing.h" ModelFrame::ModelFrame(cl_device_id device_id, cl_context context) { input_frames = std::make_unique(buf_size); @@ -22,9 +22,9 @@ ModelFrame::ModelFrame(cl_device_id device_id, cl_context context) { loadyuv_init(&loadyuv, context, device_id, MODEL_WIDTH, MODEL_HEIGHT); } -float* ModelFrame::prepare(cl_mem yuv_cl, int frame_width, int frame_height, const mat3 &projection, cl_mem *output) { +float* ModelFrame::prepare(cl_mem yuv_cl, int frame_width, int frame_height, int frame_stride, int frame_uv_offset, const mat3 &projection, cl_mem *output) { transform_queue(&this->transform, q, - yuv_cl, frame_width, frame_height, + yuv_cl, frame_width, frame_height, frame_stride, frame_uv_offset, y_cl, u_cl, v_cl, MODEL_WIDTH, MODEL_HEIGHT, projection); if (output == NULL) { diff --git a/selfdrive/modeld/models/commonmodel.h b/selfdrive/modeld/models/commonmodel.h index 182e8978b7..40c82a8c21 100644 --- a/selfdrive/modeld/models/commonmodel.h +++ b/selfdrive/modeld/models/commonmodel.h @@ -12,7 +12,7 @@ #include #endif -#include "selfdrive/common/mat.h" +#include "common/mat.h" #include "selfdrive/modeld/transforms/loadyuv.h" #include "selfdrive/modeld/transforms/transform.h" @@ -25,7 +25,7 @@ class ModelFrame { public: ModelFrame(cl_device_id device_id, cl_context context); ~ModelFrame(); - float* prepare(cl_mem yuv_cl, int width, int height, const mat3& transform, cl_mem *output); + float* prepare(cl_mem yuv_cl, int width, int height, int frame_stride, int frame_uv_offset, const mat3& transform, cl_mem *output); const int MODEL_WIDTH = 512; const int MODEL_HEIGHT = 256; diff --git a/selfdrive/modeld/models/dmonitoring.cc b/selfdrive/modeld/models/dmonitoring.cc index 40f4220c0f..71da8dad53 100644 --- a/selfdrive/modeld/models/dmonitoring.cc +++ b/selfdrive/modeld/models/dmonitoring.cc @@ -2,11 +2,11 @@ #include "libyuv.h" -#include "selfdrive/common/mat.h" -#include "selfdrive/common/modeldata.h" -#include "selfdrive/common/params.h" -#include "selfdrive/common/timing.h" -#include "selfdrive/hardware/hw.h" +#include "common/mat.h" +#include "common/modeldata.h" +#include "common/params.h" +#include "common/timing.h" +#include "system/hardware/hw.h" #include "selfdrive/modeld/models/dmonitoring.h" @@ -39,9 +39,9 @@ void dmonitoring_init(DMonitoringModelState* s) { init_yuv_buf(s->resized_buf, MODEL_WIDTH, MODEL_HEIGHT); #ifdef USE_ONNX_MODEL - s->m = new ONNXModel("../../models/dmonitoring_model.onnx", &s->output[0], OUTPUT_SIZE, USE_DSP_RUNTIME); + s->m = new ONNXModel("models/dmonitoring_model.onnx", &s->output[0], OUTPUT_SIZE, USE_DSP_RUNTIME); #else - s->m = new SNPEModel("../../models/dmonitoring_model_q.dlc", &s->output[0], OUTPUT_SIZE, USE_DSP_RUNTIME); + s->m = new SNPEModel("models/dmonitoring_model_q.dlc", &s->output[0], OUTPUT_SIZE, USE_DSP_RUNTIME); #endif s->m->addCalib(s->calib, CALIB_LEN); @@ -55,35 +55,27 @@ static inline auto get_yuv_buf(std::vector &buf, const int width, int h } struct Rect {int x, y, w, h;}; -void crop_yuv(uint8_t *raw, int width, int height, uint8_t *y, uint8_t *u, uint8_t *v, const Rect &rect) { +void crop_nv12_to_yuv(uint8_t *raw, int stride, int uv_offset, uint8_t *y, uint8_t *u, uint8_t *v, const Rect &rect) { uint8_t *raw_y = raw; - uint8_t *raw_u = raw_y + (width * height); - uint8_t *raw_v = raw_u + ((width / 2) * (height / 2)); + uint8_t *raw_uv = raw_y + uv_offset; for (int r = 0; r < rect.h / 2; r++) { - memcpy(y + 2 * r * rect.w, raw_y + (2 * r + rect.y) * width + rect.x, rect.w); - memcpy(y + (2 * r + 1) * rect.w, raw_y + (2 * r + rect.y + 1) * width + rect.x, rect.w); - memcpy(u + r * (rect.w / 2), raw_u + (r + (rect.y / 2)) * width / 2 + (rect.x / 2), rect.w / 2); - memcpy(v + r * (rect.w / 2), raw_v + (r + (rect.y / 2)) * width / 2 + (rect.x / 2), rect.w / 2); + memcpy(y + 2 * r * rect.w, raw_y + (2 * r + rect.y) * stride + rect.x, rect.w); + memcpy(y + (2 * r + 1) * rect.w, raw_y + (2 * r + rect.y + 1) * stride + rect.x, rect.w); + for (int h = 0; h < rect.w / 2; h++) { + u[r * rect.w/2 + h] = raw_uv[(r + (rect.y/2)) * stride + (rect.x/2 + h)*2]; + v[r * rect.w/2 + h] = raw_uv[(r + (rect.y/2)) * stride + (rect.x/2 + h)*2 + 1]; + } } } -DMonitoringResult dmonitoring_eval_frame(DMonitoringModelState* s, void* stream_buf, int width, int height, float *calib) { - Rect crop_rect; - if (width == TICI_CAM_WIDTH) { - const int cropped_height = tici_dm_crop::width / 1.33; - crop_rect = {width / 2 - tici_dm_crop::width / 2 + tici_dm_crop::x_offset, - height / 2 - cropped_height / 2 + tici_dm_crop::y_offset, - cropped_height / 2, - cropped_height}; - if (!s->is_rhd) { - crop_rect.x += tici_dm_crop::width - crop_rect.w; - } - } else { - const int adapt_width = 372; - crop_rect = {0, 0, adapt_width, height}; - if (!s->is_rhd) { - crop_rect.x += width - crop_rect.w; - } +DMonitoringResult dmonitoring_eval_frame(DMonitoringModelState* s, void* stream_buf, int width, int height, int stride, int uv_offset, float *calib) { + const int cropped_height = tici_dm_crop::width / 1.33; + Rect crop_rect = {width / 2 - tici_dm_crop::width / 2 + tici_dm_crop::x_offset, + height / 2 - cropped_height / 2 + tici_dm_crop::y_offset, + cropped_height / 2, + cropped_height}; + if (!s->is_rhd) { + crop_rect.x += tici_dm_crop::width - crop_rect.w; } int resized_width = MODEL_WIDTH; @@ -91,10 +83,10 @@ DMonitoringResult dmonitoring_eval_frame(DMonitoringModelState* s, void* stream_ auto [cropped_y, cropped_u, cropped_v] = get_yuv_buf(s->cropped_buf, crop_rect.w, crop_rect.h); if (!s->is_rhd) { - crop_yuv((uint8_t *)stream_buf, width, height, cropped_y, cropped_u, cropped_v, crop_rect); + crop_nv12_to_yuv((uint8_t *)stream_buf, stride, uv_offset, cropped_y, cropped_u, cropped_v, crop_rect); } else { auto [mirror_y, mirror_u, mirror_v] = get_yuv_buf(s->premirror_cropped_buf, crop_rect.w, crop_rect.h); - crop_yuv((uint8_t *)stream_buf, width, height, mirror_y, mirror_u, mirror_v, crop_rect); + crop_nv12_to_yuv((uint8_t *)stream_buf, stride, uv_offset, mirror_y, mirror_u, mirror_v, crop_rect); libyuv::I420Mirror(mirror_y, crop_rect.w, mirror_u, crop_rect.w / 2, mirror_v, crop_rect.w / 2, @@ -107,31 +99,16 @@ DMonitoringResult dmonitoring_eval_frame(DMonitoringModelState* s, void* stream_ auto [resized_buf, resized_u, resized_v] = get_yuv_buf(s->resized_buf, resized_width, resized_height); uint8_t *resized_y = resized_buf; libyuv::FilterMode mode = libyuv::FilterModeEnum::kFilterBilinear; - if (Hardware::TICI()) { - libyuv::I420Scale(cropped_y, crop_rect.w, - cropped_u, crop_rect.w / 2, - cropped_v, crop_rect.w / 2, - crop_rect.w, crop_rect.h, - resized_y, resized_width, - resized_u, resized_width / 2, - resized_v, resized_width / 2, - resized_width, resized_height, - mode); - } else { - const int source_height = 0.7*resized_height; - const int extra_height = (resized_height - source_height) / 2; - const int extra_width = (resized_width - source_height / 2) / 2; - const int source_width = source_height / 2 + extra_width; - libyuv::I420Scale(cropped_y, crop_rect.w, - cropped_u, crop_rect.w / 2, - cropped_v, crop_rect.w / 2, - crop_rect.w, crop_rect.h, - resized_y + extra_height * resized_width, resized_width, - resized_u + extra_height / 2 * resized_width / 2, resized_width / 2, - resized_v + extra_height / 2 * resized_width / 2, resized_width / 2, - source_width, source_height, - mode); - } + libyuv::I420Scale(cropped_y, crop_rect.w, + cropped_u, crop_rect.w / 2, + cropped_v, crop_rect.w / 2, + crop_rect.w, crop_rect.h, + resized_y, resized_width, + resized_u, resized_width / 2, + resized_v, resized_width / 2, + resized_width, resized_height, + mode); + int yuv_buf_len = (MODEL_WIDTH/2) * (MODEL_HEIGHT/2) * 6; // Y|u|v -> y|y|y|y|u|v float *net_input_buf = get_buffer(s->net_input_buf, yuv_buf_len); diff --git a/selfdrive/modeld/models/dmonitoring.h b/selfdrive/modeld/models/dmonitoring.h index b233056862..a1be91e3bb 100644 --- a/selfdrive/modeld/models/dmonitoring.h +++ b/selfdrive/modeld/models/dmonitoring.h @@ -3,7 +3,7 @@ #include #include "cereal/messaging/messaging.h" -#include "selfdrive/common/util.h" +#include "common/util.h" #include "selfdrive/modeld/models/commonmodel.h" #include "selfdrive/modeld/runners/run.h" @@ -46,7 +46,7 @@ typedef struct DMonitoringModelState { } DMonitoringModelState; void dmonitoring_init(DMonitoringModelState* s); -DMonitoringResult dmonitoring_eval_frame(DMonitoringModelState* s, void* stream_buf, int width, int height, float *calib); +DMonitoringResult dmonitoring_eval_frame(DMonitoringModelState* s, void* stream_buf, int width, int height, int stride, int uv_offset, float *calib); void dmonitoring_publish(PubMaster &pm, uint32_t frame_id, const DMonitoringResult &res, float execution_time, kj::ArrayPtr raw_pred); void dmonitoring_free(DMonitoringModelState* s); diff --git a/models/dmonitoring_model.current b/selfdrive/modeld/models/dmonitoring_model.current similarity index 100% rename from models/dmonitoring_model.current rename to selfdrive/modeld/models/dmonitoring_model.current diff --git a/models/dmonitoring_model.onnx b/selfdrive/modeld/models/dmonitoring_model.onnx similarity index 100% rename from models/dmonitoring_model.onnx rename to selfdrive/modeld/models/dmonitoring_model.onnx diff --git a/models/dmonitoring_model_q.dlc b/selfdrive/modeld/models/dmonitoring_model_q.dlc similarity index 100% rename from models/dmonitoring_model_q.dlc rename to selfdrive/modeld/models/dmonitoring_model_q.dlc diff --git a/selfdrive/modeld/models/driving.cc b/selfdrive/modeld/models/driving.cc index e14411df78..59c0b249d9 100644 --- a/selfdrive/modeld/models/driving.cc +++ b/selfdrive/modeld/models/driving.cc @@ -8,10 +8,10 @@ #include -#include "selfdrive/common/clutil.h" -#include "selfdrive/common/params.h" -#include "selfdrive/common/timing.h" -#include "selfdrive/common/swaglog.h" +#include "common/clutil.h" +#include "common/params.h" +#include "common/timing.h" +#include "common/swaglog.h" constexpr float FCW_THRESHOLD_5MS2_HIGH = 0.15; constexpr float FCW_THRESHOLD_5MS2_LOW = 0.05; @@ -32,11 +32,11 @@ void model_init(ModelState* s, cl_device_id device_id, cl_context context) { s->wide_frame = new ModelFrame(device_id, context); #ifdef USE_THNEED - s->m = std::make_unique("../../models/supercombo.thneed", + s->m = std::make_unique("models/supercombo.thneed", #elif USE_ONNX_MODEL - s->m = std::make_unique("../../models/supercombo.onnx", + s->m = std::make_unique("models/supercombo.onnx", #else - s->m = std::make_unique("../../models/supercombo.dlc", + s->m = std::make_unique("models/supercombo.dlc", #endif &s->output[0], NET_OUTPUT_SIZE, USE_GPU_RUNTIME, true); @@ -73,12 +73,12 @@ ModelOutput* model_eval_frame(ModelState* s, VisionBuf* buf, VisionBuf* wbuf, #endif // if getInputBuf is not NULL, net_input_buf will be - auto net_input_buf = s->frame->prepare(buf->buf_cl, buf->width, buf->height, transform, static_cast(s->m->getInputBuf())); + auto net_input_buf = s->frame->prepare(buf->buf_cl, buf->width, buf->height, buf->stride, buf->uv_offset, transform, static_cast(s->m->getInputBuf())); s->m->addImage(net_input_buf, s->frame->buf_size); LOGT("Image added"); if (wbuf != nullptr) { - auto net_extra_buf = s->wide_frame->prepare(wbuf->buf_cl, wbuf->width, wbuf->height, transform_wide, static_cast(s->m->getExtraBuf())); + auto net_extra_buf = s->wide_frame->prepare(wbuf->buf_cl, wbuf->width, wbuf->height, wbuf->stride, wbuf->uv_offset, transform_wide, static_cast(s->m->getExtraBuf())); s->m->addExtra(net_extra_buf, s->wide_frame->buf_size); LOGT("Extra image added"); } diff --git a/selfdrive/modeld/models/driving.h b/selfdrive/modeld/models/driving.h index 47dec0d9d7..a691051636 100644 --- a/selfdrive/modeld/models/driving.h +++ b/selfdrive/modeld/models/driving.h @@ -10,9 +10,9 @@ #include "cereal/messaging/messaging.h" #include "cereal/visionipc/visionipc_client.h" -#include "selfdrive/common/mat.h" -#include "selfdrive/common/modeldata.h" -#include "selfdrive/common/util.h" +#include "common/mat.h" +#include "common/modeldata.h" +#include "common/util.h" #include "selfdrive/modeld/models/commonmodel.h" #include "selfdrive/modeld/runners/run.h" @@ -245,7 +245,7 @@ struct ModelOutput { constexpr int OUTPUT_SIZE = sizeof(ModelOutput) / sizeof(float); #ifdef TEMPORAL - constexpr int TEMPORAL_SIZE = 512; + constexpr int TEMPORAL_SIZE = 512+256; #else constexpr int TEMPORAL_SIZE = 0; #endif diff --git a/selfdrive/modeld/models/supercombo.dlc b/selfdrive/modeld/models/supercombo.dlc new file mode 100644 index 0000000000..90f7a2e65b --- /dev/null +++ b/selfdrive/modeld/models/supercombo.dlc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c2cb3a3054f3292bbe538d6b793908dc2e234c200802d41b6766d3cb51b0b44 +size 101662751 diff --git a/selfdrive/modeld/models/supercombo.onnx b/selfdrive/modeld/models/supercombo.onnx new file mode 100644 index 0000000000..0493398560 --- /dev/null +++ b/selfdrive/modeld/models/supercombo.onnx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96b60d0bfd1386c93b4f79195aa1c5e77b23e0250578a308ee2c58857ed5eb49 +size 102570834 diff --git a/selfdrive/modeld/runners/onnx_runner.py b/selfdrive/modeld/runners/onnx_runner.py index 2a6238c1d2..e282a66b66 100755 --- a/selfdrive/modeld/runners/onnx_runner.py +++ b/selfdrive/modeld/runners/onnx_runner.py @@ -59,7 +59,10 @@ if __name__ == "__main__": options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL provider = 'CPUExecutionProvider' - print("Onnx selected provider: ", [provider], file=sys.stderr) - ort_session = ort.InferenceSession(sys.argv[1], options, providers=[provider]) - print("Onnx using ", ort_session.get_providers(), file=sys.stderr) - run_loop(ort_session) + try: + print("Onnx selected provider: ", [provider], file=sys.stderr) + ort_session = ort.InferenceSession(sys.argv[1], options, providers=[provider]) + print("Onnx using ", ort_session.get_providers(), file=sys.stderr) + run_loop(ort_session) + except KeyboardInterrupt: + pass diff --git a/selfdrive/modeld/runners/onnxmodel.cc b/selfdrive/modeld/runners/onnxmodel.cc index 9ba08570e3..9b4d6fd015 100644 --- a/selfdrive/modeld/runners/onnxmodel.cc +++ b/selfdrive/modeld/runners/onnxmodel.cc @@ -11,8 +11,8 @@ #include #include -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" +#include "common/swaglog.h" +#include "common/util.h" ONNXModel::ONNXModel(const char *path, float *_output, size_t _output_size, int runtime, bool _use_extra) { LOGD("loading model %s", path); diff --git a/selfdrive/modeld/runners/snpemodel.cc b/selfdrive/modeld/runners/snpemodel.cc index 44fa6ce298..1861494d59 100644 --- a/selfdrive/modeld/runners/snpemodel.cc +++ b/selfdrive/modeld/runners/snpemodel.cc @@ -6,8 +6,8 @@ #include #include -#include "selfdrive/common/util.h" -#include "selfdrive/common/timing.h" +#include "common/util.h" +#include "common/timing.h" void PrintErrorStringAndExit() { std::cerr << zdl::DlSystem::getLastErrorString() << std::endl; @@ -123,6 +123,12 @@ SNPEModel::SNPEModel(const char *path, float *loutput, size_t loutput_size, int outputBuffer = ubFactory.createUserBuffer(output, output_size * sizeof(float), outputStrides, &userBufferEncodingFloat); outputMap.add(output_tensor_name, outputBuffer.get()); } + +#ifdef USE_THNEED + if (Runtime == zdl::DlSystem::Runtime_t::GPU) { + thneed.reset(new Thneed()); + } +#endif } void SNPEModel::addRecurrent(float *state, int state_size) { @@ -176,7 +182,7 @@ std::unique_ptr SNPEModel::addExtra(float *state, in void SNPEModel::execute() { #ifdef USE_THNEED if (Runtime == zdl::DlSystem::Runtime_t::GPU) { - if (thneed == NULL) { + if (!thneed_recorded) { bool ret = inputBuffer->setBufferAddress(input); assert(ret == true); if (use_extra) { @@ -188,7 +194,7 @@ void SNPEModel::execute() { PrintErrorStringAndExit(); } memset(recurrent, 0, recurrent_size*sizeof(float)); - thneed = new Thneed(); + thneed->record = true; if (!snpe->execute(inputMap, outputMap)) { PrintErrorStringAndExit(); } @@ -220,6 +226,7 @@ void SNPEModel::execute() { assert(false); } free(outputs_golden); + thneed_recorded = true; } else { if (use_extra) { float *inputs[5] = {recurrent, trafficConvention, desire, extra, input}; diff --git a/selfdrive/modeld/runners/snpemodel.h b/selfdrive/modeld/runners/snpemodel.h index 6e9c33f89c..ba51fdced0 100644 --- a/selfdrive/modeld/runners/snpemodel.h +++ b/selfdrive/modeld/runners/snpemodel.h @@ -1,4 +1,5 @@ #pragma once +#pragma clang diagnostic ignored "-Wdeprecated-declarations" #include #include @@ -32,7 +33,8 @@ public: void execute(); #ifdef USE_THNEED - Thneed *thneed = NULL; + std::unique_ptr thneed; + bool thneed_recorded = false; #endif private: diff --git a/selfdrive/modeld/runners/thneedmodel.cc b/selfdrive/modeld/runners/thneedmodel.cc index edc091bda9..dbe80a9463 100644 --- a/selfdrive/modeld/runners/thneedmodel.cc +++ b/selfdrive/modeld/runners/thneedmodel.cc @@ -4,7 +4,6 @@ ThneedModel::ThneedModel(const char *path, float *loutput, size_t loutput_size, int runtime, bool luse_extra) { thneed = new Thneed(true); - thneed->record = 0; thneed->load(path); thneed->clexec(); thneed->find_inputs_outputs(); diff --git a/selfdrive/modeld/test/test_modeld.py b/selfdrive/modeld/test/test_modeld.py index f09aec578c..2fcff785a9 100755 --- a/selfdrive/modeld/test/test_modeld.py +++ b/selfdrive/modeld/test/test_modeld.py @@ -5,7 +5,7 @@ import numpy as np import random import cereal.messaging as messaging -from cereal.visionipc.visionipc_pyx import VisionIpcServer, VisionStreamType # pylint: disable=no-name-in-module, import-error +from cereal.visionipc import VisionIpcServer, VisionStreamType from common.transformations.camera import tici_f_frame_size from common.realtime import DT_MDL from selfdrive.manager.process_config import managed_processes diff --git a/selfdrive/modeld/thneed/compile.cc b/selfdrive/modeld/thneed/compile.cc index c22156d2c9..a2f55ffd97 100644 --- a/selfdrive/modeld/thneed/compile.cc +++ b/selfdrive/modeld/thneed/compile.cc @@ -1,19 +1,46 @@ #include +#include #include "selfdrive/modeld/runners/snpemodel.h" #include "selfdrive/modeld/thneed/thneed.h" -#include "selfdrive/hardware/hw.h" +#include "system/hardware/hw.h" -#define TEMPORAL_SIZE 512 +#define TEMPORAL_SIZE 512+256 #define DESIRE_LEN 8 #define TRAFFIC_CONVENTION_LEN 2 // TODO: This should probably use SNPE directly. int main(int argc, char* argv[]) { + bool run_optimizer = false, save_binaries = false; + const char *input_file = NULL, *output_file = NULL; + static struct option long_options[] = { + {"in", required_argument, 0, 'i' }, + {"out", required_argument, 0, 'o' }, + {"binary", no_argument, 0, 'b' }, + {"optimize", no_argument, 0, 'f' }, + {0, 0, 0, 0 } + }; + int long_index = 0, opt = 0; + while ((opt = getopt_long_only(argc, argv,"", long_options, &long_index)) != -1) { + switch (opt) { + case 'i': input_file = optarg; break; + case 'o': output_file = optarg; break; + case 'b': save_binaries = true; break; + case 'f': run_optimizer = true; break; + } + } + + // no input? + if (!input_file) { + printf("usage: -i -o --binary --optimize\n"); + return -1; + } + #define OUTPUT_SIZE 0x10000 float *output = (float*)calloc(OUTPUT_SIZE, sizeof(float)); - SNPEModel mdl(argv[1], output, 0, USE_GPU_RUNTIME, true); + SNPEModel mdl(input_file, output, 0, USE_GPU_RUNTIME, true); + mdl.thneed->run_optimizer = run_optimizer; float state[TEMPORAL_SIZE] = {0}; float desire[DESIRE_LEN] = {0}; @@ -32,14 +59,20 @@ int main(int argc, char* argv[]) { memset(output, 0, OUTPUT_SIZE * sizeof(float)); mdl.execute(); + // don't save? + if (!output_file) { + printf("no output file, exiting\n"); + return 0; + } + // save model - bool save_binaries = (argc > 3) && (strcmp(argv[3], "--binary") == 0); - mdl.thneed->save(argv[2], save_binaries); + printf("saving %s with binary %d\n", output_file, save_binaries); + mdl.thneed->save(output_file, save_binaries); // test model auto thneed = new Thneed(true); thneed->record = false; - thneed->load(argv[2]); + thneed->load(output_file); thneed->clexec(); thneed->find_inputs_outputs(); diff --git a/selfdrive/modeld/thneed/lib.py b/selfdrive/modeld/thneed/lib.py index dccdfb10ac..38ef3f4262 100644 --- a/selfdrive/modeld/thneed/lib.py +++ b/selfdrive/modeld/thneed/lib.py @@ -23,9 +23,9 @@ def save_thneed(jdat, fn): if 'data' in o: new_weights.append(o['data']) del o['data'] - new_weights = b''.join(new_weights) + new_weights_bytes = b''.join(new_weights) with open(fn, "wb") as f: j = json.dumps(jdat, ensure_ascii=False).encode('latin_1') f.write(struct.pack("I", len(j))) f.write(j) - f.write(new_weights) + f.write(new_weights_bytes) diff --git a/selfdrive/modeld/thneed/optimizer.cc b/selfdrive/modeld/thneed/optimizer.cc index b516b5fa50..39737d3d76 100644 --- a/selfdrive/modeld/thneed/optimizer.cc +++ b/selfdrive/modeld/thneed/optimizer.cc @@ -4,12 +4,12 @@ #include #include "thneed.h" -#include "selfdrive/common/util.h" -#include "selfdrive/common/clutil.h" +#include "common/util.h" +#include "common/clutil.h" extern map g_program_source; -static int is_same_size_image(cl_mem a, cl_mem b) { +/*static int is_same_size_image(cl_mem a, cl_mem b) { size_t a_width, a_height, a_depth, a_array_size, a_row_pitch, a_slice_pitch; clGetImageInfo(a, CL_IMAGE_WIDTH, sizeof(a_width), &a_width, NULL); clGetImageInfo(a, CL_IMAGE_HEIGHT, sizeof(a_height), &a_height, NULL); @@ -29,7 +29,7 @@ static int is_same_size_image(cl_mem a, cl_mem b) { return (a_width == b_width) && (a_height == b_height) && (a_depth == b_depth) && (a_array_size == b_array_size) && (a_row_pitch == b_row_pitch) && (a_slice_pitch == b_slice_pitch); -} +}*/ static cl_mem make_image_like(cl_context context, cl_mem val) { cl_image_format format; @@ -138,7 +138,7 @@ int Thneed::optimize() { // delete useless copy layers // saves ~0.7 ms - if (kq[i]->name == "concatenation" || kq[i]->name == "flatten") { + /*if (kq[i]->name == "concatenation" || kq[i]->name == "flatten") { string in = kq[i]->args[kq[i]->get_arg_num("input")]; string out = kq[i]->args[kq[i]->get_arg_num("output")]; if (is_same_size_image(*(cl_mem*)in.data(), *(cl_mem*)out.data())) { @@ -148,7 +148,7 @@ int Thneed::optimize() { kq.erase(kq.begin()+i); --i; } - } + }*/ // NOTE: if activations/accumulation are done in the wrong order, this will be wrong diff --git a/selfdrive/modeld/thneed/serialize.cc b/selfdrive/modeld/thneed/serialize.cc index 89b761b9d2..136576fe1c 100644 --- a/selfdrive/modeld/thneed/serialize.cc +++ b/selfdrive/modeld/thneed/serialize.cc @@ -2,8 +2,8 @@ #include #include "json11.hpp" -#include "selfdrive/common/util.h" -#include "selfdrive/common/clutil.h" +#include "common/util.h" +#include "common/clutil.h" #include "selfdrive/modeld/thneed/thneed.h" using namespace json11; diff --git a/selfdrive/modeld/thneed/thneed.cc b/selfdrive/modeld/thneed/thneed.cc index 470ff219b0..d673c4f56f 100644 --- a/selfdrive/modeld/thneed/thneed.cc +++ b/selfdrive/modeld/thneed/thneed.cc @@ -9,10 +9,8 @@ #include #include -#include "selfdrive/common/clutil.h" -#include "selfdrive/common/timing.h" -//#define RUN_DISASSEMBLER -#define RUN_OPTIMIZER +#include "common/clutil.h" +#include "common/timing.h" Thneed *g_thneed = NULL; int g_fd = -1; @@ -203,11 +201,6 @@ void CachedCommand::exec() { for (auto &it : kq) { it->debug_print(false); } - #ifdef RUN_DISASSEMBLER - // assuming 2 commands - disassemble(0); - disassemble(1); - #endif } assert(ret == 0); @@ -220,7 +213,6 @@ Thneed::Thneed(bool do_clinit) { assert(g_fd != -1); fd = g_fd; ram = make_unique(0x80000, fd); - record = true; timestamp = -1; g_thneed = this; char *thneed_debug_env = getenv("THNEED_DEBUG"); @@ -230,7 +222,7 @@ Thneed::Thneed(bool do_clinit) { void Thneed::stop() { find_inputs_outputs(); printf("Thneed::stop: recorded %lu commands\n", cmds.size()); - record = 0; + record = false; } void Thneed::find_inputs_outputs() { @@ -416,9 +408,7 @@ cl_int thneed_clFinish(cl_command_queue command_queue) { Thneed *thneed = g_thneed; if (thneed != NULL && thneed->record) { - #ifdef RUN_OPTIMIZER - thneed->optimize(); - #endif + if (thneed->run_optimizer) thneed->optimize(); return thneed->clexec(); } else { return clFinish(command_queue); diff --git a/selfdrive/modeld/thneed/thneed.h b/selfdrive/modeld/thneed/thneed.h index b09d32b0ef..0ccea59a3c 100644 --- a/selfdrive/modeld/thneed/thneed.h +++ b/selfdrive/modeld/thneed/thneed.h @@ -94,6 +94,7 @@ class Thneed { void execute(float **finputs, float *foutput, bool slow=false); void wait(); int optimize(); + bool run_optimizer = false; vector input_clmem; vector inputs; @@ -106,7 +107,7 @@ class Thneed { int context_id; // protected? - bool record; + bool record = false; int debug; int timestamp; unique_ptr ram; diff --git a/selfdrive/modeld/thneed/weights_fixup.py b/selfdrive/modeld/thneed/weights_fixup.py index 47875a9ee0..539b1b5d32 100755 --- a/selfdrive/modeld/thneed/weights_fixup.py +++ b/selfdrive/modeld/thneed/weights_fixup.py @@ -140,6 +140,7 @@ def weights_fixup(target, source_thneed, dlc): save_thneed(jdat, target) if __name__ == "__main__": - weights_fixup(os.path.join(BASEDIR, "models/supercombo_fixed.thneed"), - os.path.join(BASEDIR, "models/supercombo.thneed"), - os.path.join(BASEDIR, "models/supercombo.dlc")) + model_dir = os.path.join(BASEDIR, "selfdrive/modeld/models/") + weights_fixup(os.path.join(model_dir, "supercombo_fixed.thneed"), + os.path.join(model_dir, "supercombo.thneed"), + os.path.join(model_dir, "supercombo.dlc")) diff --git a/selfdrive/modeld/transforms/loadyuv.h b/selfdrive/modeld/transforms/loadyuv.h index a3161b2935..7d27ef5d46 100644 --- a/selfdrive/modeld/transforms/loadyuv.h +++ b/selfdrive/modeld/transforms/loadyuv.h @@ -1,6 +1,6 @@ #pragma once -#include "selfdrive/common/clutil.h" +#include "common/clutil.h" typedef struct { int width, height; diff --git a/selfdrive/modeld/transforms/transform.cc b/selfdrive/modeld/transforms/transform.cc index 5f4929bab3..cabc58a46d 100644 --- a/selfdrive/modeld/transforms/transform.cc +++ b/selfdrive/modeld/transforms/transform.cc @@ -3,7 +3,7 @@ #include #include -#include "selfdrive/common/clutil.h" +#include "common/clutil.h" void transform_init(Transform* s, cl_context ctx, cl_device_id device_id) { memset(s, 0, sizeof(*s)); @@ -25,7 +25,7 @@ void transform_destroy(Transform* s) { void transform_queue(Transform* s, cl_command_queue q, - cl_mem in_yuv, int in_width, int in_height, + cl_mem in_yuv, int in_width, int in_height, int in_stride, int in_uv_offset, cl_mem out_y, cl_mem out_u, cl_mem out_v, int out_width, int out_height, const mat3& projection) { @@ -44,28 +44,30 @@ void transform_queue(Transform* s, const int in_y_width = in_width; const int in_y_height = in_height; + const int in_y_px_stride = 1; const int in_uv_width = in_width/2; const int in_uv_height = in_height/2; - const int in_y_offset = 0; - const int in_u_offset = in_y_offset + in_y_width*in_y_height; - const int in_v_offset = in_u_offset + in_uv_width*in_uv_height; + const int in_uv_px_stride = 2; + const int in_u_offset = in_uv_offset; + const int in_v_offset = in_uv_offset + 1; const int out_y_width = out_width; const int out_y_height = out_height; const int out_uv_width = out_width/2; const int out_uv_height = out_height/2; - CL_CHECK(clSetKernelArg(s->krnl, 0, sizeof(cl_mem), &in_yuv)); - CL_CHECK(clSetKernelArg(s->krnl, 1, sizeof(cl_int), &in_y_width)); - CL_CHECK(clSetKernelArg(s->krnl, 2, sizeof(cl_int), &in_y_offset)); - CL_CHECK(clSetKernelArg(s->krnl, 3, sizeof(cl_int), &in_y_height)); - CL_CHECK(clSetKernelArg(s->krnl, 4, sizeof(cl_int), &in_y_width)); - CL_CHECK(clSetKernelArg(s->krnl, 5, sizeof(cl_mem), &out_y)); - CL_CHECK(clSetKernelArg(s->krnl, 6, sizeof(cl_int), &out_y_width)); - CL_CHECK(clSetKernelArg(s->krnl, 7, sizeof(cl_int), &zero)); - CL_CHECK(clSetKernelArg(s->krnl, 8, sizeof(cl_int), &out_y_height)); - CL_CHECK(clSetKernelArg(s->krnl, 9, sizeof(cl_int), &out_y_width)); - CL_CHECK(clSetKernelArg(s->krnl, 10, sizeof(cl_mem), &s->m_y_cl)); + CL_CHECK(clSetKernelArg(s->krnl, 0, sizeof(cl_mem), &in_yuv)); // src + CL_CHECK(clSetKernelArg(s->krnl, 1, sizeof(cl_int), &in_stride)); // src_row_stride + CL_CHECK(clSetKernelArg(s->krnl, 2, sizeof(cl_int), &in_y_px_stride)); // src_px_stride + CL_CHECK(clSetKernelArg(s->krnl, 3, sizeof(cl_int), &zero)); // src_offset + CL_CHECK(clSetKernelArg(s->krnl, 4, sizeof(cl_int), &in_y_height)); // src_rows + CL_CHECK(clSetKernelArg(s->krnl, 5, sizeof(cl_int), &in_y_width)); // src_cols + CL_CHECK(clSetKernelArg(s->krnl, 6, sizeof(cl_mem), &out_y)); // dst + CL_CHECK(clSetKernelArg(s->krnl, 7, sizeof(cl_int), &out_y_width)); // dst_row_stride + CL_CHECK(clSetKernelArg(s->krnl, 8, sizeof(cl_int), &zero)); // dst_offset + CL_CHECK(clSetKernelArg(s->krnl, 9, sizeof(cl_int), &out_y_height)); // dst_rows + CL_CHECK(clSetKernelArg(s->krnl, 10, sizeof(cl_int), &out_y_width)); // dst_cols + CL_CHECK(clSetKernelArg(s->krnl, 11, sizeof(cl_mem), &s->m_y_cl)); // M const size_t work_size_y[2] = {(size_t)out_y_width, (size_t)out_y_height}; @@ -74,21 +76,21 @@ void transform_queue(Transform* s, const size_t work_size_uv[2] = {(size_t)out_uv_width, (size_t)out_uv_height}; - CL_CHECK(clSetKernelArg(s->krnl, 1, sizeof(cl_int), &in_uv_width)); - CL_CHECK(clSetKernelArg(s->krnl, 2, sizeof(cl_int), &in_u_offset)); - CL_CHECK(clSetKernelArg(s->krnl, 3, sizeof(cl_int), &in_uv_height)); - CL_CHECK(clSetKernelArg(s->krnl, 4, sizeof(cl_int), &in_uv_width)); - CL_CHECK(clSetKernelArg(s->krnl, 5, sizeof(cl_mem), &out_u)); - CL_CHECK(clSetKernelArg(s->krnl, 6, sizeof(cl_int), &out_uv_width)); - CL_CHECK(clSetKernelArg(s->krnl, 7, sizeof(cl_int), &zero)); - CL_CHECK(clSetKernelArg(s->krnl, 8, sizeof(cl_int), &out_uv_height)); - CL_CHECK(clSetKernelArg(s->krnl, 9, sizeof(cl_int), &out_uv_width)); - CL_CHECK(clSetKernelArg(s->krnl, 10, sizeof(cl_mem), &s->m_uv_cl)); - + CL_CHECK(clSetKernelArg(s->krnl, 2, sizeof(cl_int), &in_uv_px_stride)); // src_px_stride + CL_CHECK(clSetKernelArg(s->krnl, 3, sizeof(cl_int), &in_u_offset)); // src_offset + CL_CHECK(clSetKernelArg(s->krnl, 4, sizeof(cl_int), &in_uv_height)); // src_rows + CL_CHECK(clSetKernelArg(s->krnl, 5, sizeof(cl_int), &in_uv_width)); // src_cols + CL_CHECK(clSetKernelArg(s->krnl, 6, sizeof(cl_mem), &out_u)); // dst + CL_CHECK(clSetKernelArg(s->krnl, 7, sizeof(cl_int), &out_uv_width)); // dst_row_stride + CL_CHECK(clSetKernelArg(s->krnl, 8, sizeof(cl_int), &zero)); // dst_offset + CL_CHECK(clSetKernelArg(s->krnl, 9, sizeof(cl_int), &out_uv_height)); // dst_rows + CL_CHECK(clSetKernelArg(s->krnl, 10, sizeof(cl_int), &out_uv_width)); // dst_cols + CL_CHECK(clSetKernelArg(s->krnl, 11, sizeof(cl_mem), &s->m_uv_cl)); // M + CL_CHECK(clEnqueueNDRangeKernel(q, s->krnl, 2, NULL, (const size_t*)&work_size_uv, NULL, 0, 0, NULL)); - CL_CHECK(clSetKernelArg(s->krnl, 2, sizeof(cl_int), &in_v_offset)); - CL_CHECK(clSetKernelArg(s->krnl, 5, sizeof(cl_mem), &out_v)); + CL_CHECK(clSetKernelArg(s->krnl, 3, sizeof(cl_int), &in_v_offset)); // src_ofset + CL_CHECK(clSetKernelArg(s->krnl, 6, sizeof(cl_mem), &out_v)); // dst CL_CHECK(clEnqueueNDRangeKernel(q, s->krnl, 2, NULL, (const size_t*)&work_size_uv, NULL, 0, 0, NULL)); diff --git a/selfdrive/modeld/transforms/transform.cl b/selfdrive/modeld/transforms/transform.cl index 8ad1869351..357ef87321 100644 --- a/selfdrive/modeld/transforms/transform.cl +++ b/selfdrive/modeld/transforms/transform.cl @@ -6,9 +6,9 @@ #define INTER_REMAP_COEF_SCALE (1 << INTER_REMAP_COEF_BITS) __kernel void warpPerspective(__global const uchar * src, - int src_step, int src_offset, int src_rows, int src_cols, + int src_row_stride, int src_px_stride, int src_offset, int src_rows, int src_cols, __global uchar * dst, - int dst_step, int dst_offset, int dst_rows, int dst_cols, + int dst_row_stride, int dst_offset, int dst_rows, int dst_cols, __constant float * M) { int dx = get_global_id(0); @@ -28,18 +28,18 @@ __kernel void warpPerspective(__global const uchar * src, short ax = (short)(X & (INTER_TAB_SIZE - 1)); int v0 = (sx >= 0 && sx < src_cols && sy >= 0 && sy < src_rows) ? - convert_int(src[mad24(sy, src_step, src_offset + sx)]) : 0; + convert_int(src[mad24(sy, src_row_stride, src_offset + sx*src_px_stride)]) : 0; int v1 = (sx+1 >= 0 && sx+1 < src_cols && sy >= 0 && sy < src_rows) ? - convert_int(src[mad24(sy, src_step, src_offset + (sx+1))]) : 0; + convert_int(src[mad24(sy, src_row_stride, src_offset + (sx+1)*src_px_stride)]) : 0; int v2 = (sx >= 0 && sx < src_cols && sy+1 >= 0 && sy+1 < src_rows) ? - convert_int(src[mad24(sy+1, src_step, src_offset + sx)]) : 0; + convert_int(src[mad24(sy+1, src_row_stride, src_offset + sx*src_px_stride)]) : 0; int v3 = (sx+1 >= 0 && sx+1 < src_cols && sy+1 >= 0 && sy+1 < src_rows) ? - convert_int(src[mad24(sy+1, src_step, src_offset + (sx+1))]) : 0; + convert_int(src[mad24(sy+1, src_row_stride, src_offset + (sx+1)*src_px_stride)]) : 0; float taby = 1.f/INTER_TAB_SIZE*ay; float tabx = 1.f/INTER_TAB_SIZE*ax; - int dst_index = mad24(dy, dst_step, dst_offset + dx); + int dst_index = mad24(dy, dst_row_stride, dst_offset + dx); int itab0 = convert_short_sat_rte( (1.0f-taby)*(1.0f-tabx) * INTER_REMAP_COEF_SCALE ); int itab1 = convert_short_sat_rte( (1.0f-taby)*tabx * INTER_REMAP_COEF_SCALE ); diff --git a/selfdrive/modeld/transforms/transform.h b/selfdrive/modeld/transforms/transform.h index f34613684c..771a7054b3 100644 --- a/selfdrive/modeld/transforms/transform.h +++ b/selfdrive/modeld/transforms/transform.h @@ -7,7 +7,7 @@ #include #endif -#include "selfdrive/common/mat.h" +#include "common/mat.h" typedef struct { cl_kernel krnl; @@ -19,7 +19,7 @@ void transform_init(Transform* s, cl_context ctx, cl_device_id device_id); void transform_destroy(Transform* transform); void transform_queue(Transform* s, cl_command_queue q, - cl_mem yuv, int in_width, int in_height, + cl_mem yuv, int in_width, int in_height, int in_stride, int in_uv_offset, cl_mem out_y, cl_mem out_u, cl_mem out_v, int out_width, int out_height, const mat3& projection); diff --git a/selfdrive/monitoring/driver_monitor.py b/selfdrive/monitoring/driver_monitor.py index 66b28c39b7..662e0d76ce 100644 --- a/selfdrive/monitoring/driver_monitor.py +++ b/selfdrive/monitoring/driver_monitor.py @@ -3,7 +3,6 @@ from math import atan2 from cereal import car from common.numpy_fast import interp from common.realtime import DT_DMON -from selfdrive.hardware import TICI from common.filter_simple import FirstOrderFilter from common.stat_live import RunningStatFilter @@ -16,7 +15,7 @@ EventName = car.CarEvent.EventName # ****************************************************************************************** class DRIVER_MONITOR_SETTINGS(): - def __init__(self, TICI=TICI, DT_DMON=DT_DMON): + def __init__(self): self._DT_DMON = DT_DMON # ref (page15-16): https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:42018X1947&rid=2 self._AWARENESS_TIME = 30. # passive wheeltouch total timeout @@ -27,15 +26,15 @@ class DRIVER_MONITOR_SETTINGS(): self._DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 6. self._FACE_THRESHOLD = 0.5 - self._PARTIAL_FACE_THRESHOLD = 0.8 if TICI else 0.45 - self._EYE_THRESHOLD = 0.65 if TICI else 0.6 - self._SG_THRESHOLD = 0.925 if TICI else 0.91 - self._BLINK_THRESHOLD = 0.8 if TICI else 0.55 - self._BLINK_THRESHOLD_SLACK = 0.9 if TICI else 0.7 + self._PARTIAL_FACE_THRESHOLD = 0.8 + self._EYE_THRESHOLD = 0.65 + self._SG_THRESHOLD = 0.925 + self._BLINK_THRESHOLD = 0.8 + self._BLINK_THRESHOLD_SLACK = 0.9 self._BLINK_THRESHOLD_STRICT = self._BLINK_THRESHOLD - self._EE_THRESH11 = 0.75 if TICI else 0.4 - self._EE_THRESH12 = 3.25 if TICI else 2.45 + self._EE_THRESH11 = 0.75 + self._EE_THRESH12 = 3.25 self._EE_THRESH21 = 0.01 self._EE_THRESH22 = 0.35 diff --git a/selfdrive/hardware/pc/__init__.py b/selfdrive/navd/__init__.py similarity index 100% rename from selfdrive/hardware/pc/__init__.py rename to selfdrive/navd/__init__.py diff --git a/selfdrive/navd/helpers.py b/selfdrive/navd/helpers.py new file mode 100644 index 0000000000..eda813154a --- /dev/null +++ b/selfdrive/navd/helpers.py @@ -0,0 +1,174 @@ +from __future__ import annotations + +import json +import math +from typing import Any, Dict, List, Optional, Tuple, Union, cast + +from common.conversions import Conversions +from common.numpy_fast import clip +from common.params import Params + +EARTH_MEAN_RADIUS = 6371007.2 +SPEED_CONVERSIONS = { + 'km/h': Conversions.KPH_TO_MS, + 'mph': Conversions.MPH_TO_MS, + } + + +class Coordinate: + def __init__(self, latitude: float, longitude: float) -> None: + self.latitude = latitude + self.longitude = longitude + self.annotations: Dict[str, float] = {} + + @classmethod + def from_mapbox_tuple(cls, t: Tuple[float, float]) -> Coordinate: + return cls(t[1], t[0]) + + def as_dict(self) -> Dict[str, float]: + return {'latitude': self.latitude, 'longitude': self.longitude} + + def __str__(self) -> str: + return f"({self.latitude}, {self.longitude})" + + def __eq__(self, other) -> bool: + if not isinstance(other, Coordinate): + return False + return (self.latitude == other.latitude) and (self.longitude == other.longitude) + + def __sub__(self, other: Coordinate) -> Coordinate: + return Coordinate(self.latitude - other.latitude, self.longitude - other.longitude) + + def __add__(self, other: Coordinate) -> Coordinate: + return Coordinate(self.latitude + other.latitude, self.longitude + other.longitude) + + def __mul__(self, c: float) -> Coordinate: + return Coordinate(self.latitude * c, self.longitude * c) + + def dot(self, other: Coordinate) -> float: + return self.latitude * other.latitude + self.longitude * other.longitude + + def distance_to(self, other: Coordinate) -> float: + # Haversine formula + dlat = math.radians(other.latitude - self.latitude) + dlon = math.radians(other.longitude - self.longitude) + + haversine_dlat = math.sin(dlat / 2.0) + haversine_dlat *= haversine_dlat + haversine_dlon = math.sin(dlon / 2.0) + haversine_dlon *= haversine_dlon + + y = haversine_dlat \ + + math.cos(math.radians(self.latitude)) \ + * math.cos(math.radians(other.latitude)) \ + * haversine_dlon + x = 2 * math.asin(math.sqrt(y)) + return x * EARTH_MEAN_RADIUS + + +def minimum_distance(a: Coordinate, b: Coordinate, p: Coordinate): + if a.distance_to(b) < 0.01: + return a.distance_to(p) + + ap = p - a + ab = b - a + t = clip(ap.dot(ab) / ab.dot(ab), 0.0, 1.0) + projection = a + ab * t + return projection.distance_to(p) + + +def distance_along_geometry(geometry: List[Coordinate], pos: Coordinate) -> float: + if len(geometry) <= 2: + return geometry[0].distance_to(pos) + + # 1. Find segment that is closest to current position + # 2. Total distance is sum of distance to start of closest segment + # + all previous segments + total_distance = 0.0 + total_distance_closest = 0.0 + closest_distance = 1e9 + + for i in range(len(geometry) - 1): + d = minimum_distance(geometry[i], geometry[i + 1], pos) + + if d < closest_distance: + closest_distance = d + total_distance_closest = total_distance + geometry[i].distance_to(pos) + + total_distance += geometry[i].distance_to(geometry[i + 1]) + + return total_distance_closest + + +def coordinate_from_param(param: str, params: Optional[Params] = None) -> Optional[Coordinate]: + if params is None: + params = Params() + + json_str = params.get(param) + if json_str is None: + return None + + pos = json.loads(json_str) + if 'latitude' not in pos or 'longitude' not in pos: + return None + + return Coordinate(pos['latitude'], pos['longitude']) + + +def string_to_direction(direction: str) -> str: + for d in ['left', 'right', 'straight']: + if d in direction: + return d + return 'none' + + +def maxspeed_to_ms(maxspeed: Dict[str, Union[str, float]]) -> float: + unit = cast(str, maxspeed['unit']) + speed = cast(float, maxspeed['speed']) + return SPEED_CONVERSIONS[unit] * speed + + +def parse_banner_instructions(instruction: Any, banners: Any, distance_to_maneuver: float = 0.0) -> None: + if not len(banners): + return + + current_banner = banners[0] + + # A segment can contain multiple banners, find one that we need to show now + for banner in banners: + if distance_to_maneuver < banner['distanceAlongGeometry']: + current_banner = banner + + # Only show banner when close enough to maneuver + instruction.showFull = distance_to_maneuver < current_banner['distanceAlongGeometry'] + + # Primary + p = current_banner['primary'] + if 'text' in p: + instruction.maneuverPrimaryText = p['text'] + if 'type' in p: + instruction.maneuverType = p['type'] + if 'modifier' in p: + instruction.maneuverModifier = p['modifier'] + + # Secondary + if 'secondary' in current_banner: + instruction.maneuverSecondaryText = current_banner['secondary']['text'] + + # Lane lines + if 'sub' in current_banner: + lanes = [] + for component in current_banner['sub']['components']: + if component['type'] != 'lane': + continue + + lane = { + 'active': component['active'], + 'directions': [string_to_direction(d) for d in component['directions']], + } + + if 'active_direction' in component: + lane['activeDirection'] = string_to_direction(component['active_direction']) + + lanes.append(lane) + instruction.lanes = lanes diff --git a/selfdrive/navd/navd.py b/selfdrive/navd/navd.py new file mode 100755 index 0000000000..f02de43c7b --- /dev/null +++ b/selfdrive/navd/navd.py @@ -0,0 +1,291 @@ +#!/usr/bin/env python3 +import math +import os +import threading + +import requests + +import cereal.messaging as messaging +from cereal import log +from common.api import Api +from common.params import Params +from common.realtime import Ratekeeper +from selfdrive.navd.helpers import (Coordinate, coordinate_from_param, + distance_along_geometry, maxspeed_to_ms, + minimum_distance, + parse_banner_instructions) +from system.swaglog import cloudlog + +REROUTE_DISTANCE = 25 +MANEUVER_TRANSITION_THRESHOLD = 10 + + +class RouteEngine: + def __init__(self, sm, pm): + self.sm = sm + self.pm = pm + + self.params = Params() + + # Get last gps position from params + self.last_position = coordinate_from_param("LastGPSPosition", self.params) + self.last_bearing = None + + self.gps_ok = False + self.localizer_valid = False + + self.nav_destination = None + self.step_idx = None + self.route = None + self.route_geometry = None + + self.recompute_backoff = 0 + self.recompute_countdown = 0 + + self.ui_pid = None + + if "MAPBOX_TOKEN" in os.environ: + self.mapbox_token = os.environ["MAPBOX_TOKEN"] + self.mapbox_host = "https://api.mapbox.com" + else: + try: + self.mapbox_token = Api(self.params.get("DongleId", encoding='utf8')).get_token(expiry_hours=4 * 7 * 24) + except FileNotFoundError: + cloudlog.exception("Failed to generate mapbox token due to missing private key. Ensure device is registered.") + self.mapbox_token = "" + self.mapbox_host = "https://maps.comma.ai" + + def update(self): + self.sm.update(0) + + if self.sm.updated["managerState"]: + ui_pid = [p.pid for p in self.sm["managerState"].processes if p.name == "ui" and p.running] + if ui_pid: + if self.ui_pid and self.ui_pid != ui_pid[0]: + cloudlog.warning("UI restarting, sending route") + threading.Timer(5.0, self.send_route).start() + self.ui_pid = ui_pid[0] + + self.update_location() + self.recompute_route() + self.send_instruction() + + def update_location(self): + location = self.sm['liveLocationKalman'] + self.gps_ok = location.gpsOK + + self.localizer_valid = (location.status == log.LiveLocationKalman.Status.valid) and location.positionGeodetic.valid + + if self.localizer_valid: + self.last_bearing = math.degrees(location.calibratedOrientationNED.value[2]) + self.last_position = Coordinate(location.positionGeodetic.value[0], location.positionGeodetic.value[1]) + + def recompute_route(self): + if self.last_position is None: + return + + new_destination = coordinate_from_param("NavDestination", self.params) + if new_destination is None: + self.clear_route() + return + + should_recompute = self.should_recompute() + if new_destination != self.nav_destination: + cloudlog.warning(f"Got new destination from NavDestination param {new_destination}") + should_recompute = True + + # Don't recompute when GPS drifts in tunnels + if not self.gps_ok and self.step_idx is not None: + return + + if self.recompute_countdown == 0 and should_recompute: + self.recompute_countdown = 2**self.recompute_backoff + self.recompute_backoff = min(6, self.recompute_backoff + 1) + self.calculate_route(new_destination) + else: + self.recompute_countdown = max(0, self.recompute_countdown - 1) + + def calculate_route(self, destination): + cloudlog.warning(f"Calculating route {self.last_position} -> {destination}") + self.nav_destination = destination + + params = { + 'access_token': self.mapbox_token, + 'annotations': 'maxspeed', + 'geometries': 'geojson', + 'overview': 'full', + 'steps': 'true', + 'banner_instructions': 'true', + 'alternatives': 'false', + } + + if self.last_bearing is not None: + params['bearings'] = f"{(self.last_bearing + 360) % 360:.0f},90;" + + url = self.mapbox_host + f'/directions/v5/mapbox/driving-traffic/{self.last_position.longitude},{self.last_position.latitude};{destination.longitude},{destination.latitude}' + try: + resp = requests.get(url, params=params) + resp.raise_for_status() + + r = resp.json() + if len(r['routes']): + self.route = r['routes'][0]['legs'][0]['steps'] + self.route_geometry = [] + + maxspeed_idx = 0 + maxspeeds = r['routes'][0]['legs'][0]['annotation']['maxspeed'] + + # Convert coordinates + for step in self.route: + coords = [] + + for c in step['geometry']['coordinates']: + coord = Coordinate.from_mapbox_tuple(c) + + # Last step does not have maxspeed + if (maxspeed_idx < len(maxspeeds)): + maxspeed = maxspeeds[maxspeed_idx] + if ('unknown' not in maxspeed) and ('none' not in maxspeed): + coord.annotations['maxspeed'] = maxspeed_to_ms(maxspeed) + + coords.append(coord) + maxspeed_idx += 1 + + self.route_geometry.append(coords) + maxspeed_idx -= 1 # Every segment ends with the same coordinate as the start of the next + + self.step_idx = 0 + else: + cloudlog.warning("Got empty route response") + self.clear_route() + + except requests.exceptions.RequestException: + cloudlog.exception("failed to get route") + self.clear_route() + + self.send_route() + + def send_instruction(self): + msg = messaging.new_message('navInstruction') + + if self.step_idx is None: + msg.valid = False + self.pm.send('navInstruction', msg) + return + + step = self.route[self.step_idx] + geometry = self.route_geometry[self.step_idx] + along_geometry = distance_along_geometry(geometry, self.last_position) + distance_to_maneuver_along_geometry = step['distance'] - along_geometry + + # Current instruction + msg.navInstruction.maneuverDistance = distance_to_maneuver_along_geometry + parse_banner_instructions(msg.navInstruction, step['bannerInstructions'], distance_to_maneuver_along_geometry) + + # Compute total remaining time and distance + remaning = 1.0 - along_geometry / max(step['distance'], 1) + total_distance = step['distance'] * remaning + total_time = step['duration'] * remaning + total_time_typical = step['duration_typical'] * remaning + + # Add up totals for future steps + for i in range(self.step_idx + 1, len(self.route)): + total_distance += self.route[i]['distance'] + total_time += self.route[i]['duration'] + total_time_typical += self.route[i]['duration_typical'] + + msg.navInstruction.distanceRemaining = total_distance + msg.navInstruction.timeRemaining = total_time + msg.navInstruction.timeRemainingTypical = total_time_typical + + # Speed limit + closest_idx, closest = min(enumerate(geometry), key=lambda p: p[1].distance_to(self.last_position)) + if closest_idx > 0: + # If we are not past the closest point, show previous + if along_geometry < distance_along_geometry(geometry, geometry[closest_idx]): + closest = geometry[closest_idx - 1] + + if ('maxspeed' in closest.annotations) and self.localizer_valid: + msg.navInstruction.speedLimit = closest.annotations['maxspeed'] + + # Speed limit sign type + if 'speedLimitSign' in step: + if step['speedLimitSign'] == 'mutcd': + msg.navInstruction.speedLimitSign = log.NavInstruction.SpeedLimitSign.mutcd + elif step['speedLimitSign'] == 'vienna': + msg.navInstruction.speedLimitSign = log.NavInstruction.SpeedLimitSign.vienna + + self.pm.send('navInstruction', msg) + + # Transition to next route segment + if distance_to_maneuver_along_geometry < -MANEUVER_TRANSITION_THRESHOLD: + if self.step_idx + 1 < len(self.route): + self.step_idx += 1 + self.recompute_backoff = 0 + self.recompute_countdown = 0 + else: + cloudlog.warning("Destination reached") + Params().delete("NavDestination") + + # Clear route if driving away from destination + dist = self.nav_destination.distance_to(self.last_position) + if dist > REROUTE_DISTANCE: + self.clear_route() + + def send_route(self): + coords = [] + + if self.route is not None: + for path in self.route_geometry: + coords += [c.as_dict() for c in path] + + msg = messaging.new_message('navRoute') + msg.navRoute.coordinates = coords + self.pm.send('navRoute', msg) + + def clear_route(self): + self.route = None + self.route_geometry = None + self.step_idx = None + self.nav_destination = None + + def should_recompute(self): + if self.step_idx is None or self.route is None: + return True + + # Don't recompute in last segment, assume destination is reached + if self.step_idx == len(self.route) - 1: + return False + + # Compute closest distance to all line segments in the current path + min_d = REROUTE_DISTANCE + 1 + path = self.route_geometry[self.step_idx] + for i in range(len(path) - 1): + a = path[i] + b = path[i + 1] + + if a.distance_to(b) < 1.0: + continue + + min_d = min(min_d, minimum_distance(a, b, self.last_position)) + + return min_d > REROUTE_DISTANCE + + # TODO: Check for going wrong way in segment + + +def main(sm=None, pm=None): + if sm is None: + sm = messaging.SubMaster(['liveLocationKalman', 'managerState']) + if pm is None: + pm = messaging.PubMaster(['navInstruction', 'navRoute']) + + rk = Ratekeeper(1.0) + route_engine = RouteEngine(sm, pm) + while True: + route_engine.update() + rk.keep_time() + + +if __name__ == "__main__": + main() diff --git a/selfdrive/sensord/rawgps/compare.py b/selfdrive/sensord/rawgps/compare.py index 073647499b..0ec15b81fb 100755 --- a/selfdrive/sensord/rawgps/compare.py +++ b/selfdrive/sensord/rawgps/compare.py @@ -31,7 +31,7 @@ if __name__ == "__main__": tm = m if tm is None: continue - + if not i.measurementStatus.measurementNotUsable and i.measurementStatus.satelliteTimeIsKnown: sat_time = (i.unfilteredMeasurementIntegral + i.unfilteredMeasurementFraction + i.latency) / 1000 ublox_psuedorange = tm.pseudorange @@ -56,7 +56,7 @@ if __name__ == "__main__": pr_err /= len(car) speed_err /= len(car) print("avg psuedorange err %f avg speed err %f" % (pr_err, speed_err)) - for c in sorted(car, key=lambda x: abs(x[1] - x[3] - pr_err)): + for c in sorted(car, key=lambda x: abs(x[1] - x[3] - pr_err)): # type: ignore svid, ublox_psuedorange, ublox_speed, qcom_psuedorange, qcom_speed, cno = c print("svid: %3d pseudorange: %10.2f m speed: %8.2f m/s meas: %12.2f speed: %10.2f meas_err: %10.3f speed_err: %8.3f cno: %d" % (svid, ublox_psuedorange, ublox_speed, qcom_psuedorange, qcom_speed, diff --git a/selfdrive/sensord/rawgps/rawgpsd.py b/selfdrive/sensord/rawgps/rawgpsd.py index e0861c0d9a..3aa6d4b072 100755 --- a/selfdrive/sensord/rawgps/rawgpsd.py +++ b/selfdrive/sensord/rawgps/rawgpsd.py @@ -10,7 +10,7 @@ from struct import unpack_from, calcsize, pack import cereal.messaging as messaging from cereal import log -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog from selfdrive.sensord.rawgps.modemdiag import ModemDiag, DIAG_LOG_F, setup_logs, send_recv from selfdrive.sensord.rawgps.structs import dict_unpacker diff --git a/selfdrive/sensord/sensors/bmx055_accel.cc b/selfdrive/sensord/sensors/bmx055_accel.cc index f5d68bdee5..d17e3fe617 100644 --- a/selfdrive/sensord/sensors/bmx055_accel.cc +++ b/selfdrive/sensord/sensors/bmx055_accel.cc @@ -2,8 +2,8 @@ #include -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/timing.h" +#include "common/swaglog.h" +#include "common/timing.h" BMX055_Accel::BMX055_Accel(I2CBus *bus) : I2CSensor(bus) {} diff --git a/selfdrive/sensord/sensors/bmx055_gyro.cc b/selfdrive/sensord/sensors/bmx055_gyro.cc index f0e3034e3f..74b22d8fef 100644 --- a/selfdrive/sensord/sensors/bmx055_gyro.cc +++ b/selfdrive/sensord/sensors/bmx055_gyro.cc @@ -3,7 +3,7 @@ #include #include -#include "selfdrive/common/swaglog.h" +#include "common/swaglog.h" #define DEG2RAD(x) ((x) * M_PI / 180.0) diff --git a/selfdrive/sensord/sensors/bmx055_magn.cc b/selfdrive/sensord/sensors/bmx055_magn.cc index 29e0d809d8..a2c793eff6 100644 --- a/selfdrive/sensord/sensors/bmx055_magn.cc +++ b/selfdrive/sensord/sensors/bmx055_magn.cc @@ -6,8 +6,8 @@ #include #include -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" +#include "common/swaglog.h" +#include "common/util.h" static int16_t compensate_x(trim_data_t trim_data, int16_t mag_data_x, uint16_t data_rhall) { uint16_t process_comp_x0 = data_rhall; diff --git a/selfdrive/sensord/sensors/bmx055_temp.cc b/selfdrive/sensord/sensors/bmx055_temp.cc index 339a987ce0..85bdea9e61 100644 --- a/selfdrive/sensord/sensors/bmx055_temp.cc +++ b/selfdrive/sensord/sensors/bmx055_temp.cc @@ -3,8 +3,8 @@ #include #include "selfdrive/sensord/sensors/bmx055_accel.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/timing.h" +#include "common/swaglog.h" +#include "common/timing.h" BMX055_Temp::BMX055_Temp(I2CBus *bus) : I2CSensor(bus) {} diff --git a/selfdrive/sensord/sensors/i2c_sensor.h b/selfdrive/sensord/sensors/i2c_sensor.h index 83c66eac87..7832475a98 100644 --- a/selfdrive/sensord/sensors/i2c_sensor.h +++ b/selfdrive/sensord/sensors/i2c_sensor.h @@ -3,7 +3,7 @@ #include #include "cereal/gen/cpp/log.capnp.h" -#include "selfdrive/common/i2c.h" +#include "common/i2c.h" #include "selfdrive/sensord/sensors/constants.h" #include "selfdrive/sensord/sensors/sensor.h" diff --git a/selfdrive/sensord/sensors/light_sensor.cc b/selfdrive/sensord/sensors/light_sensor.cc index 4d00d37bda..4497343684 100644 --- a/selfdrive/sensord/sensors/light_sensor.cc +++ b/selfdrive/sensord/sensors/light_sensor.cc @@ -2,7 +2,7 @@ #include -#include "selfdrive/common/timing.h" +#include "common/timing.h" #include "selfdrive/sensord/sensors/constants.h" void LightSensor::get_event(cereal::SensorEventData::Builder &event) { diff --git a/selfdrive/sensord/sensors/lsm6ds3_accel.cc b/selfdrive/sensord/sensors/lsm6ds3_accel.cc index 83222858e7..bcac7de9f7 100644 --- a/selfdrive/sensord/sensors/lsm6ds3_accel.cc +++ b/selfdrive/sensord/sensors/lsm6ds3_accel.cc @@ -2,8 +2,8 @@ #include -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/timing.h" +#include "common/swaglog.h" +#include "common/timing.h" LSM6DS3_Accel::LSM6DS3_Accel(I2CBus *bus) : I2CSensor(bus) {} diff --git a/selfdrive/sensord/sensors/lsm6ds3_gyro.cc b/selfdrive/sensord/sensors/lsm6ds3_gyro.cc index 6732ead0f1..c7711d34e3 100644 --- a/selfdrive/sensord/sensors/lsm6ds3_gyro.cc +++ b/selfdrive/sensord/sensors/lsm6ds3_gyro.cc @@ -3,8 +3,8 @@ #include #include -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/timing.h" +#include "common/swaglog.h" +#include "common/timing.h" #define DEG2RAD(x) ((x) * M_PI / 180.0) diff --git a/selfdrive/sensord/sensors/lsm6ds3_temp.cc b/selfdrive/sensord/sensors/lsm6ds3_temp.cc index 6b093fce05..1dd179d69e 100644 --- a/selfdrive/sensord/sensors/lsm6ds3_temp.cc +++ b/selfdrive/sensord/sensors/lsm6ds3_temp.cc @@ -2,8 +2,8 @@ #include -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/timing.h" +#include "common/swaglog.h" +#include "common/timing.h" LSM6DS3_Temp::LSM6DS3_Temp(I2CBus *bus) : I2CSensor(bus) {} diff --git a/selfdrive/sensord/sensors/mmc5603nj_magn.cc b/selfdrive/sensord/sensors/mmc5603nj_magn.cc index 68878867e4..7c654ce7a3 100644 --- a/selfdrive/sensord/sensors/mmc5603nj_magn.cc +++ b/selfdrive/sensord/sensors/mmc5603nj_magn.cc @@ -2,8 +2,8 @@ #include -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/timing.h" +#include "common/swaglog.h" +#include "common/timing.h" MMC5603NJ_Magn::MMC5603NJ_Magn(I2CBus *bus) : I2CSensor(bus) {} diff --git a/selfdrive/sensord/sensors_qcom2.cc b/selfdrive/sensord/sensors_qcom2.cc index c3e5bbcdfa..65fe43f65f 100644 --- a/selfdrive/sensord/sensors_qcom2.cc +++ b/selfdrive/sensord/sensors_qcom2.cc @@ -5,10 +5,10 @@ #include #include "cereal/messaging/messaging.h" -#include "selfdrive/common/i2c.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/timing.h" -#include "selfdrive/common/util.h" +#include "common/i2c.h" +#include "common/swaglog.h" +#include "common/timing.h" +#include "common/util.h" #include "selfdrive/sensord/sensors/bmx055_accel.h" #include "selfdrive/sensord/sensors/bmx055_gyro.h" #include "selfdrive/sensord/sensors/bmx055_magn.h" diff --git a/selfdrive/hardware/tici/__init__.py b/selfdrive/sensord/test/__init__.py similarity index 100% rename from selfdrive/hardware/tici/__init__.py rename to selfdrive/sensord/test/__init__.py diff --git a/selfdrive/sensord/test/test_sensord.py b/selfdrive/sensord/test/test_sensord.py new file mode 100755 index 0000000000..9fd918c971 --- /dev/null +++ b/selfdrive/sensord/test/test_sensord.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +import time +import unittest + +import cereal.messaging as messaging +from system.hardware import TICI +from selfdrive.test.helpers import with_processes + +TEST_TIMESPAN = 10 + +SENSOR_CONFIGURATIONS = ( + { + ('bmx055', 'acceleration'), + ('bmx055', 'gyroUncalibrated'), + ('bmx055', 'magneticUncalibrated'), + ('bmx055', 'temperature'), + ('lsm6ds3', 'acceleration'), + ('lsm6ds3', 'gyroUncalibrated'), + ('lsm6ds3', 'temperature'), + ('rpr0521', 'light'), + }, + { + ('lsm6ds3', 'acceleration'), + ('lsm6ds3', 'gyroUncalibrated'), + ('lsm6ds3', 'temperature'), + ('mmc5603nj', 'magneticUncalibrated'), + ('rpr0521', 'light'), + }, + { + ('bmx055', 'acceleration'), + ('bmx055', 'gyroUncalibrated'), + ('bmx055', 'magneticUncalibrated'), + ('bmx055', 'temperature'), + ('lsm6ds3trc', 'acceleration'), + ('lsm6ds3trc', 'gyroUncalibrated'), + ('lsm6ds3trc', 'temperature'), + ('rpr0521', 'light'), + }, + { + ('lsm6ds3trc', 'acceleration'), + ('lsm6ds3trc', 'gyroUncalibrated'), + ('lsm6ds3trc', 'temperature'), + ('mmc5603nj', 'magneticUncalibrated'), + ('rpr0521', 'light'), + }, +) + + +class TestSensord(unittest.TestCase): + @classmethod + def setUpClass(cls): + if not TICI: + raise unittest.SkipTest + + @with_processes(['sensord']) + def test_sensors_present(self): + sensor_events = messaging.sub_sock("sensorEvents", timeout=0.1) + + start_time_sec = time.time() + events = [] + while time.time() - start_time_sec < TEST_TIMESPAN: + events += messaging.drain_sock(sensor_events) + time.sleep(0.01) + + seen = set() + for event in events: + for measurement in event.sensorEvents: + # Filter out unset events + if measurement.version == 0: + continue + seen.add((str(measurement.source), measurement.which())) + + self.assertIn(seen, SENSOR_CONFIGURATIONS) + + +if __name__ == "__main__": + unittest.main() diff --git a/selfdrive/sentry.py b/selfdrive/sentry.py index 5f22bf18e0..aa409ea394 100644 --- a/selfdrive/sentry.py +++ b/selfdrive/sentry.py @@ -5,9 +5,9 @@ from sentry_sdk.integrations.threading import ThreadingIntegration from common.params import Params from selfdrive.athena.registration import is_registered_device -from selfdrive.hardware import HARDWARE, PC -from selfdrive.swaglog import cloudlog -from selfdrive.version import get_branch, get_commit, get_origin, get_version, \ +from system.hardware import HARDWARE, PC +from system.swaglog import cloudlog +from system.version import get_branch, get_commit, get_origin, get_version, \ is_comma_remote, is_dirty, is_tested_branch diff --git a/selfdrive/statsd.py b/selfdrive/statsd.py index b880c4110a..7dc002727e 100755 --- a/selfdrive/statsd.py +++ b/selfdrive/statsd.py @@ -9,10 +9,10 @@ from typing import NoReturn, Union, List, Dict from common.params import Params from cereal.messaging import SubMaster -from selfdrive.swaglog import cloudlog -from selfdrive.hardware import HARDWARE +from system.swaglog import cloudlog +from system.hardware import HARDWARE from common.file_helpers import atomic_write_in_dir -from selfdrive.version import get_normalized_origin, get_short_branch, get_short_version, is_dirty +from system.version import get_normalized_origin, get_short_branch, get_short_version, is_dirty from selfdrive.loggerd.config import STATS_DIR, STATS_DIR_FILE_LIMIT, STATS_SOCKET, STATS_FLUSH_TIME_S @@ -88,6 +88,7 @@ def main() -> NoReturn: # subscribe to deviceState for started state sm = SubMaster(['deviceState']) + idx = 0 last_flush_time = time.monotonic() gauges = {} samples: Dict[str, List[float]] = defaultdict(list) @@ -149,9 +150,10 @@ def main() -> NoReturn: # check that we aren't filling up the drive if len(os.listdir(STATS_DIR)) < STATS_DIR_FILE_LIMIT: if len(result) > 0: - stats_path = os.path.join(STATS_DIR, str(int(current_time.timestamp()))) + stats_path = os.path.join(STATS_DIR, f"{current_time.timestamp():.0f}_{idx}") with atomic_write_in_dir(stats_path) as f: f.write(result) + idx += 1 else: cloudlog.error("stats dir full") diff --git a/selfdrive/test/helpers.py b/selfdrive/test/helpers.py index 5abc0d964f..8cc996c28d 100644 --- a/selfdrive/test/helpers.py +++ b/selfdrive/test/helpers.py @@ -2,9 +2,9 @@ import os import time from functools import wraps -from selfdrive.hardware import PC +from system.hardware import PC from selfdrive.manager.process_config import managed_processes -from selfdrive.version import training_version, terms_version +from system.version import training_version, terms_version def set_params_enabled(): diff --git a/selfdrive/test/openpilotci.py b/selfdrive/test/openpilotci.py index 6483b6717f..1d1b6ec423 100755 --- a/selfdrive/test/openpilotci.py +++ b/selfdrive/test/openpilotci.py @@ -4,17 +4,18 @@ import sys import subprocess BASE_URL = "https://commadataci.blob.core.windows.net/openpilotci/" - TOKEN_PATH = "/data/azure_token" + def get_url(route_name, segment_num, log_type="rlog"): ext = "hevc" if log_type.endswith('camera') else "bz2" return BASE_URL + f"{route_name.replace('|', '/')}/{segment_num}/{log_type}.{ext}" + def upload_file(path, name): from azure.storage.blob import BlockBlobService # pylint: disable=import-error - sas_token = None + sas_token = os.environ.get("AZURE_TOKEN", None) if os.path.isfile(TOKEN_PATH): sas_token = open(TOKEN_PATH).read().strip() @@ -25,6 +26,7 @@ def upload_file(path, name): service.create_blob_from_path("openpilotci", name, path) return "https://commadataci.blob.core.windows.net/openpilotci/" + name + if __name__ == "__main__": for f in sys.argv[1:]: name = os.path.basename(f) diff --git a/selfdrive/test/process_replay/.gitignore b/selfdrive/test/process_replay/.gitignore index a35cd58d41..63c37e64e1 100644 --- a/selfdrive/test/process_replay/.gitignore +++ b/selfdrive/test/process_replay/.gitignore @@ -1 +1,2 @@ fakedata/ +debayer_diff.txt diff --git a/selfdrive/test/process_replay/README.md b/selfdrive/test/process_replay/README.md index 3add95f0a0..9fa4ca644a 100644 --- a/selfdrive/test/process_replay/README.md +++ b/selfdrive/test/process_replay/README.md @@ -1,10 +1,11 @@ -# process replay +# Process replay Process replay is a regression test designed to identify any changes in the output of a process. This test replays a segment through individual processes and compares the output to a known good replay. Each make is represented in the test with a segment. If the test fails, make sure that you didn't unintentionally change anything. If there are intentional changes, the reference logs will be updated. Use `test_processes.py` to run the test locally. +Use `FILEREADER_CACHE='1' test_processes.py` to cache log files. Currently the following processes are tested: @@ -12,14 +13,34 @@ Currently the following processes are tested: * radard * plannerd * calibrationd +* dmonitoringd +* locationd +* paramsd * ubloxd +### Usage +``` +Usage: test_processes.py [-h] [--whitelist-procs PROCS] [--whitelist-cars CARS] [--blacklist-procs PROCS] + [--blacklist-cars CARS] [--ignore-fields FIELDS] [--ignore-msgs MSGS] [--update-refs] [--upload-only] +Regression test to identify changes in a process's output +optional arguments: + -h, --help show this help message and exit + --whitelist-procs PROCS Whitelist given processes from the test (e.g. controlsd) + --whitelist-cars WHITELIST_CARS Whitelist given cars from the test (e.g. HONDA) + --blacklist-procs BLACKLIST_PROCS Blacklist given processes from the test (e.g. controlsd) + --blacklist-cars BLACKLIST_CARS Blacklist given cars from the test (e.g. HONDA) + --ignore-fields IGNORE_FIELDS Extra fields or msgs to ignore (e.g. carState.events) + --ignore-msgs IGNORE_MSGS Msgs to ignore (e.g. carEvents) + --update-refs Updates reference logs using current commit + --upload-only Skips testing processes and uploads logs from previous test run +``` + ## Forks -openpilot forks can use this test with their own reference logs +openpilot forks can use this test with their own reference logs, by default `test_proccess.py` saves logs locally. To generate new logs: -`./update_refs.py --no-upload` +`./test_processes.py` -Then, check in the new logs using git-lfs. Make sure to also include the updated `ref_commit` file. +Then, check in the new logs using git-lfs. Make sure to also update the `ref_commit` file to the current commit. diff --git a/selfdrive/test/process_replay/compare_logs.py b/selfdrive/test/process_replay/compare_logs.py index f1ca69987c..057e46cd9c 100755 --- a/selfdrive/test/process_replay/compare_logs.py +++ b/selfdrive/test/process_replay/compare_logs.py @@ -1,25 +1,18 @@ #!/usr/bin/env python3 import bz2 -import os import sys import math import numbers import dictdiffer from collections import Counter -if "CI" in os.environ: - def tqdm(x): - return x -else: - from tqdm import tqdm # type: ignore - from tools.lib.logreader import LogReader EPSILON = sys.float_info.epsilon def save_log(dest, log_msgs, compress=True): - dat = b"".join(msg.as_builder().to_bytes() for msg in tqdm(log_msgs)) + dat = b"".join(msg.as_builder().to_bytes() for msg in log_msgs) if compress: dat = bz2.compress(dat) @@ -67,7 +60,7 @@ def compare_logs(log1, log2, ignore_fields=None, ignore_msgs=None, tolerance=Non raise Exception(f"logs are not same length: {len(log1)} VS {len(log2)}\n\t\t{cnt1}\n\t\t{cnt2}") diff = [] - for msg1, msg2 in tqdm(zip(log1, log2)): + for msg1, msg2 in zip(log1, log2): if msg1.which() != msg2.which(): print(msg1, msg2) raise Exception("msgs not aligned between logs") diff --git a/selfdrive/test/process_replay/debayer_replay_ref_commit b/selfdrive/test/process_replay/debayer_replay_ref_commit new file mode 100644 index 0000000000..551fc680ba --- /dev/null +++ b/selfdrive/test/process_replay/debayer_replay_ref_commit @@ -0,0 +1 @@ +8f9ba7540b4549b4a57312129b8ff678d045f70f \ No newline at end of file diff --git a/selfdrive/test/process_replay/helpers.py b/selfdrive/test/process_replay/helpers.py new file mode 100644 index 0000000000..8571f36c36 --- /dev/null +++ b/selfdrive/test/process_replay/helpers.py @@ -0,0 +1,26 @@ +import os +import shutil +import uuid + +from common.params import Params + +class OpenpilotPrefix(object): + def __init__(self, prefix: str = None) -> None: + self.prefix = prefix if prefix else str(uuid.uuid4()) + self.msgq_path = os.path.join('/dev/shm', self.prefix) + + def __enter__(self): + os.environ['OPENPILOT_PREFIX'] = self.prefix + try: + os.mkdir(self.msgq_path) + except FileExistsError: + pass + + def __exit__(self, exc_type, exc_obj, exc_tb): + symlink_path = Params().get_param_path() + if os.path.exists(symlink_path): + shutil.rmtree(os.path.realpath(symlink_path), ignore_errors=True) + os.remove(symlink_path) + shutil.rmtree(self.msgq_path, ignore_errors=True) + del os.environ['OPENPILOT_PREFIX'] + return False diff --git a/selfdrive/test/process_replay/model_replay.py b/selfdrive/test/process_replay/model_replay.py index 1befb69aa4..f3bb286635 100755 --- a/selfdrive/test/process_replay/model_replay.py +++ b/selfdrive/test/process_replay/model_replay.py @@ -7,30 +7,29 @@ from typing import Any from itertools import zip_longest import cereal.messaging as messaging -from cereal.visionipc.visionipc_pyx import VisionIpcServer, VisionStreamType # pylint: disable=no-name-in-module, import-error +from cereal.visionipc import VisionIpcServer, VisionStreamType from common.spinner import Spinner from common.timeout import Timeout -from common.transformations.camera import get_view_frame_from_road_frame, eon_f_frame_size, tici_f_frame_size, \ - eon_d_frame_size, tici_d_frame_size -from selfdrive.hardware import PC, TICI +from common.transformations.camera import get_view_frame_from_road_frame, tici_f_frame_size, tici_d_frame_size +from system.hardware import PC from selfdrive.manager.process_config import managed_processes from selfdrive.test.openpilotci import BASE_URL, get_url from selfdrive.test.process_replay.compare_logs import compare_logs, save_log from selfdrive.test.process_replay.test_processes import format_diff -from selfdrive.version import get_commit +from system.version import get_commit from tools.lib.framereader import FrameReader from tools.lib.logreader import LogReader TEST_ROUTE = "4cf7a6ad03080c90|2021-09-29--13-46-36" SEGMENT = 0 +MAX_FRAMES = 20 if PC else 1300 SEND_EXTRA_INPUTS = bool(os.getenv("SEND_EXTRA_INPUTS", "0")) VIPC_STREAM = {"roadCameraState": VisionStreamType.VISION_STREAM_ROAD, "driverCameraState": VisionStreamType.VISION_STREAM_DRIVER, "wideRoadCameraState": VisionStreamType.VISION_STREAM_WIDE_ROAD} - -def get_log_fn(ref_commit, test_route, tici=True): - return f"{test_route}_{'model_tici' if tici else 'model'}_{ref_commit}.bz2" +def get_log_fn(ref_commit, test_route): + return f"{test_route}_model_tici_{ref_commit}.bz2" def replace_calib(msg, calib): @@ -41,12 +40,15 @@ def replace_calib(msg, calib): def model_replay(lr, frs): - spinner = Spinner() - spinner.update("starting model replay") + if not PC: + spinner = Spinner() + spinner.update("starting model replay") + else: + spinner = None vipc_server = VisionIpcServer("camerad") - vipc_server.create_buffers(VisionStreamType.VISION_STREAM_ROAD, 40, False, *(tici_f_frame_size if TICI else eon_f_frame_size)) - vipc_server.create_buffers(VisionStreamType.VISION_STREAM_DRIVER, 40, False, *(tici_d_frame_size if TICI else eon_d_frame_size)) + vipc_server.create_buffers(VisionStreamType.VISION_STREAM_ROAD, 40, False, *(tici_f_frame_size)) + vipc_server.create_buffers(VisionStreamType.VISION_STREAM_DRIVER, 40, False, *(tici_d_frame_size)) vipc_server.create_buffers(VisionStreamType.VISION_STREAM_WIDE_ROAD, 40, False, *(tici_f_frame_size)) vipc_server.start_listener() @@ -61,8 +63,8 @@ def model_replay(lr, frs): log_msgs = [] last_desire = None - recv_cnt = defaultdict(lambda: 0) - frame_idxs = defaultdict(lambda: 0) + recv_cnt = defaultdict(int) + frame_idxs = defaultdict(int) # init modeld with valid calibration cal_msgs = [msg for msg in lr if msg.which() == "liveCalibration"] @@ -76,7 +78,7 @@ def model_replay(lr, frs): for cam_msgs in zip_longest(msgs['roadCameraState'], msgs['wideRoadCameraState'], msgs['driverCameraState']): # need a pair of road/wide msgs - if TICI and None in (cam_msgs[0], cam_msgs[1]): + if None in (cam_msgs[0], cam_msgs[1]): break for msg in cam_msgs: @@ -96,7 +98,7 @@ def model_replay(lr, frs): if msg.which() in VIPC_STREAM: msg = msg.as_builder() camera_state = getattr(msg, msg.which()) - img = frs[msg.which()].get(frame_idxs[msg.which()], pix_fmt="yuv420p")[0] + img = frs[msg.which()].get(frame_idxs[msg.which()], pix_fmt="nv12")[0] frame_idxs[msg.which()] += 1 # send camera state and frame @@ -107,7 +109,7 @@ def model_replay(lr, frs): recv = None if msg.which() in ('roadCameraState', 'wideRoadCameraState'): - if not TICI or min(frame_idxs['roadCameraState'], frame_idxs['wideRoadCameraState']) > recv_cnt['modelV2']: + if min(frame_idxs['roadCameraState'], frame_idxs['wideRoadCameraState']) > recv_cnt['modelV2']: recv = "modelV2" elif msg.which() == 'driverCameraState': recv = "driverState" @@ -118,14 +120,19 @@ def model_replay(lr, frs): recv_cnt[recv] += 1 log_msgs.append(messaging.recv_one(sm.sock[recv])) - spinner.update("replaying models: road %d/%d, driver %d/%d" % (frame_idxs['roadCameraState'], - frs['roadCameraState'].frame_count, frame_idxs['driverCameraState'], frs['driverCameraState'].frame_count)) + if spinner: + spinner.update("replaying models: road %d/%d, driver %d/%d" % (frame_idxs['roadCameraState'], + frs['roadCameraState'].frame_count, frame_idxs['driverCameraState'], frs['driverCameraState'].frame_count)) + - if any(frame_idxs[c] >= frs[c].frame_count for c in frame_idxs.keys()): + if any(frame_idxs[c] >= frs[c].frame_count for c in frame_idxs.keys()) or frame_idxs['roadCameraState'] == MAX_FRAMES: break + else: + print(f'Received {frame_idxs["roadCameraState"]} frames') finally: - spinner.close() + if spinner: + spinner.close() managed_processes['modeld'].stop() managed_processes['dmonitoringmodeld'].stop() @@ -144,9 +151,8 @@ if __name__ == "__main__": frs = { 'roadCameraState': FrameReader(get_url(TEST_ROUTE, SEGMENT, log_type="fcamera")), 'driverCameraState': FrameReader(get_url(TEST_ROUTE, SEGMENT, log_type="dcamera")), + 'wideRoadCameraState': FrameReader(get_url(TEST_ROUTE, SEGMENT, log_type="ecamera")) } - if TICI: - frs['wideRoadCameraState'] = FrameReader(get_url(TEST_ROUTE, SEGMENT, log_type="ecamera")) # run replay log_msgs = model_replay(lr, frs) @@ -156,9 +162,9 @@ if __name__ == "__main__": if not update: with open(ref_commit_fn) as f: ref_commit = f.read().strip() - log_fn = get_log_fn(ref_commit, TEST_ROUTE, tici=TICI) + log_fn = get_log_fn(ref_commit, TEST_ROUTE) try: - cmp_log = LogReader(BASE_URL + log_fn) + cmp_log = list(LogReader(BASE_URL + log_fn))[:2*MAX_FRAMES] ignore = [ 'logMonoTime', @@ -167,7 +173,8 @@ if __name__ == "__main__": 'driverState.modelExecutionTime', 'driverState.dspExecutionTime' ] - tolerance = None if not PC else 1e-3 + # TODO this tolerence is absurdly large + tolerance = 5e-1 if PC else None results: Any = {TEST_ROUTE: {}} results[TEST_ROUTE]["models"] = compare_logs(cmp_log, log_msgs, tolerance=tolerance, ignore_fields=ignore) diff1, diff2, failed = format_diff(results, ref_commit) @@ -182,13 +189,13 @@ if __name__ == "__main__": failed = True # upload new refs - if update or failed: + if (update or failed) and not PC: from selfdrive.test.openpilotci import upload_file print("Uploading new refs") new_commit = get_commit() - log_fn = get_log_fn(new_commit, TEST_ROUTE, tici=TICI) + log_fn = get_log_fn(new_commit, TEST_ROUTE) save_log(log_fn, log_msgs) try: upload_file(log_fn, os.path.basename(log_fn)) diff --git a/selfdrive/test/process_replay/model_replay_ref_commit b/selfdrive/test/process_replay/model_replay_ref_commit index bf4e1eadb8..54c2ed54ad 100644 --- a/selfdrive/test/process_replay/model_replay_ref_commit +++ b/selfdrive/test/process_replay/model_replay_ref_commit @@ -1 +1 @@ -5fb5cd71a6e878cf45593ecea22c93e932f70c31 \ No newline at end of file +629eaa7b26d1721a71547f9de880f99732cb27f3 diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index e06d8198e4..b016eb1c9f 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -8,15 +8,16 @@ import signal from collections import namedtuple import capnp -from tqdm import tqdm import cereal.messaging as messaging from cereal import car, log from cereal.services import service_list from common.params import Params from common.timeout import Timeout +from panda.python import ALTERNATIVE_EXPERIENCE from selfdrive.car.fingerprints import FW_VERSIONS from selfdrive.car.car_helpers import get_car, interfaces +from selfdrive.test.process_replay.helpers import OpenpilotPrefix from selfdrive.manager.process import PythonProcess from selfdrive.manager.process_config import managed_processes @@ -24,6 +25,8 @@ from selfdrive.manager.process_config import managed_processes NUMPY_TOLERANCE = 1e-7 CI = "CI" in os.environ TIMEOUT = 15 +PROC_REPLAY_DIR = os.path.dirname(os.path.abspath(__file__)) +FAKEDATA = os.path.join(PROC_REPLAY_DIR, "fakedata/") ProcessConfig = namedtuple('ProcessConfig', ['proc_name', 'pub_sub', 'ignore', 'init_callback', 'should_recv_callback', 'tolerance', 'fake_pubsubmaster', 'submaster_config'], defaults=({},)) @@ -240,14 +243,17 @@ CONFIGS = [ pub_sub={ "can": ["controlsState", "carState", "carControl", "sendcan", "carEvents", "carParams"], "deviceState": [], "pandaStates": [], "peripheralState": [], "liveCalibration": [], "driverMonitoringState": [], "longitudinalPlan": [], "lateralPlan": [], "liveLocationKalman": [], "liveParameters": [], "radarState": [], - "modelV2": [], "driverCameraState": [], "roadCameraState": [], "managerState": [], + "modelV2": [], "driverCameraState": [], "roadCameraState": [], "wideRoadCameraState": [], "managerState": [], "testJoystick": [], }, ignore=["logMonoTime", "valid", "controlsState.startMonoTime", "controlsState.cumLagMs"], init_callback=fingerprint, should_recv_callback=controlsd_rcv_callback, tolerance=NUMPY_TOLERANCE, fake_pubsubmaster=True, - submaster_config={'ignore_avg_freq': ['radarState', 'longitudinalPlan']} + submaster_config={ + 'ignore_avg_freq': ['radarState', 'longitudinalPlan', 'driverCameraState', 'driverMonitoringState'], # dcam is expected at 20 Hz + 'ignore_alive': ['wideRoadCameraState'], # TODO: Add to regen + } ), ProcessConfig( proc_name="radard", @@ -336,27 +342,42 @@ CONFIGS = [ def replay_process(cfg, lr, fingerprint=None): - if cfg.fake_pubsubmaster: - return python_replay_process(cfg, lr, fingerprint) - else: - return cpp_replay_process(cfg, lr, fingerprint) + with OpenpilotPrefix(): + if cfg.fake_pubsubmaster: + return python_replay_process(cfg, lr, fingerprint) + else: + return cpp_replay_process(cfg, lr, fingerprint) -def setup_env(simulation=False): +def setup_env(simulation=False, CP=None): params = Params() params.clear_all() params.put_bool("OpenpilotEnabledToggle", True) params.put_bool("Passive", False) params.put_bool("DisengageOnAccelerator", True) - params.put_bool("EnableWideCamera", False) + params.put_bool("WideCameraOnly", False) + params.put_bool("DisableLogging", False) os.environ["NO_RADAR_SLEEP"] = "1" os.environ["REPLAY"] = "1" + os.environ['SKIP_FW_QUERY'] = "" + os.environ['FINGERPRINT'] = "" if simulation: os.environ["SIMULATION"] = "1" elif "SIMULATION" in os.environ: del os.environ["SIMULATION"] + # Regen or python process + if CP is not None: + if CP.alternativeExperience == ALTERNATIVE_EXPERIENCE.DISABLE_DISENGAGE_ON_GAS: + params.put_bool("DisengageOnAccelerator", False) + + if CP.fingerprintSource == "fw" and CP.carFingerprint in FW_VERSIONS: + params.put("CarParamsCache", CP.as_builder().to_bytes()) + else: + os.environ['SKIP_FW_QUERY'] = "1" + os.environ['FINGERPRINT'] = CP.carFingerprint + def python_replay_process(cfg, lr, fingerprint=None): sub_sockets = [s for _, sub in cfg.pub_sub.items() for s in sub] pub_sockets = [s for s in cfg.pub_sub.keys() if s != 'can'] @@ -371,30 +392,13 @@ def python_replay_process(cfg, lr, fingerprint=None): all_msgs = sorted(lr, key=lambda msg: msg.logMonoTime) pub_msgs = [msg for msg in all_msgs if msg.which() in list(cfg.pub_sub.keys())] - setup_env() - - # TODO: remove after getting new route for civic & accord - migration = { - "HONDA CIVIC 2016 TOURING": "HONDA CIVIC 2016", - "HONDA ACCORD 2018 SPORT 2T": "HONDA ACCORD 2018", - "HONDA ACCORD 2T 2018": "HONDA ACCORD 2018", - "Mazda CX-9 2021": "MAZDA CX-9 2021", - } - if fingerprint is not None: os.environ['SKIP_FW_QUERY'] = "1" os.environ['FINGERPRINT'] = fingerprint + setup_env() else: - os.environ['SKIP_FW_QUERY'] = "" - os.environ['FINGERPRINT'] = "" - for msg in lr: - if msg.which() == 'carParams': - car_fingerprint = migration.get(msg.carParams.carFingerprint, msg.carParams.carFingerprint) - if msg.carParams.fingerprintSource == "fw" and (car_fingerprint in FW_VERSIONS): - Params().put("CarParamsCache", msg.carParams.as_builder().to_bytes()) - else: - os.environ['SKIP_FW_QUERY'] = "1" - os.environ['FINGERPRINT'] = car_fingerprint + CP = [m for m in lr if m.which() == 'carParams'][0].carParams + setup_env(CP=CP) assert(type(managed_processes[cfg.proc_name]) is PythonProcess) managed_processes[cfg.proc_name].prepare() @@ -418,7 +422,7 @@ def python_replay_process(cfg, lr, fingerprint=None): fsm.wait_for_update() log_msgs, msg_queue = [], [] - for msg in tqdm(pub_msgs, disable=CI): + for msg in pub_msgs: if cfg.should_recv_callback is not None: recv_socks, should_recv = cfg.should_recv_callback(msg, CP, cfg, fsm) else: @@ -470,7 +474,7 @@ def cpp_replay_process(cfg, lr, fingerprint=None): for s in sub_sockets: messaging.recv_one_or_none(sockets[s]) - for i, msg in enumerate(tqdm(pub_msgs, disable=False)): + for i, msg in enumerate(pub_msgs): pm.send(msg.which(), msg.as_builder()) resp_sockets = cfg.pub_sub[msg.which()] if cfg.should_recv_callback is None else cfg.should_recv_callback(msg) diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index b870f98460..8ed68d5bdd 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -d17ecea1f071007193a8a1e1ececf78c96b9deac \ No newline at end of file +ed1dfb8b155ebcd8fdad4e06462b3bb7869fc67b diff --git a/selfdrive/test/process_replay/regen.py b/selfdrive/test/process_replay/regen.py index 5084a40060..dfc62a4558 100755 --- a/selfdrive/test/process_replay/regen.py +++ b/selfdrive/test/process_replay/regen.py @@ -1,40 +1,44 @@ #!/usr/bin/env python3 +import bz2 import os import time import multiprocessing -from tqdm import tqdm import argparse +from tqdm import tqdm # run DM procs os.environ["USE_WEBCAM"] = "1" import cereal.messaging as messaging +from cereal import car from cereal.services import service_list -from cereal.visionipc.visionipc_pyx import VisionIpcServer, VisionStreamType # pylint: disable=no-name-in-module, import-error +from cereal.visionipc import VisionIpcServer, VisionStreamType from common.params import Params from common.realtime import Ratekeeper, DT_MDL, DT_DMON, sec_since_boot from common.transformations.camera import eon_f_frame_size, eon_d_frame_size, tici_f_frame_size, tici_d_frame_size -from selfdrive.car.fingerprints import FW_VERSIONS from selfdrive.manager.process import ensure_running from selfdrive.manager.process_config import managed_processes -from selfdrive.test.process_replay.process_replay import setup_env, check_enabled +from selfdrive.test.process_replay.process_replay import FAKEDATA, setup_env, check_enabled from selfdrive.test.update_ci_routes import upload_route from tools.lib.route import Route from tools.lib.framereader import FrameReader from tools.lib.logreader import LogReader - -process_replay_dir = os.path.dirname(os.path.abspath(__file__)) -FAKEDATA = os.path.join(process_replay_dir, "fakedata/") - - def replay_panda_states(s, msgs): pm = messaging.PubMaster([s, 'peripheralState']) rk = Ratekeeper(service_list[s].frequency, print_delay_threshold=None) smsgs = [m for m in msgs if m.which() in ['pandaStates', 'pandaStateDEPRECATED']] + # TODO: new safety params from flags, remove after getting new routes for Toyota + safety_param_migration = { + "TOYOTA PRIUS 2017": 578, + "TOYOTA RAV4 2017": 329 + } + # Migrate safety param base on carState cp = [m for m in msgs if m.which() == 'carParams'][0].carParams - if len(cp.safetyConfigs): + if cp.carFingerprint in safety_param_migration: + safety_param = safety_param_migration[cp.carFingerprint] + elif len(cp.safetyConfigs): safety_param = cp.safetyConfigs[0].safetyParam if cp.safetyConfigs[0].safetyParamDEPRECATED != 0: safety_param = cp.safetyConfigs[0].safetyParamDEPRECATED @@ -112,7 +116,7 @@ def replay_service(s, msgs): rk.keep_time() -def replay_cameras(lr, frs): +def replay_cameras(lr, frs, disable_tqdm=False): eon_cameras = [ ("roadCameraState", DT_MDL, eon_f_frame_size, VisionStreamType.VISION_STREAM_ROAD, True), ("driverCameraState", DT_DMON, eon_d_frame_size, VisionStreamType.VISION_STREAM_DRIVER, False), @@ -157,8 +161,8 @@ def replay_cameras(lr, frs): if fr is not None: print(f"Decompressing frames {s}") frames = [] - for i in tqdm(range(fr.frame_count)): - img = fr.get(i, pix_fmt='yuv420p')[0] + for i in tqdm(range(fr.frame_count), disable=disable_tqdm): + img = fr.get(i, pix_fmt='nv12')[0] frames.append(img.flatten().tobytes()) vs.create_buffers(stream, 40, False, size[0], size[1]) @@ -167,41 +171,25 @@ def replay_cameras(lr, frs): p.append(multiprocessing.Process(target=replay_camera, args=(s, stream, dt, vs, frames, size, use_extra_client))) - # hack to make UI work - vs.create_buffers(VisionStreamType.VISION_STREAM_RGB_ROAD, 4, True, eon_f_frame_size[0], eon_f_frame_size[1]) vs.start_listener() return vs, p -def regen_segment(lr, frs=None, outdir=FAKEDATA): +def regen_segment(lr, frs=None, outdir=FAKEDATA, disable_tqdm=False): lr = list(lr) if frs is None: frs = dict() - setup_env() params = Params() - os.environ["LOG_ROOT"] = outdir - os.environ['SKIP_FW_QUERY'] = "" - os.environ['FINGERPRINT'] = "" - - # TODO: remove after getting new route for mazda - migration = { - "Mazda CX-9 2021": "MAZDA CX-9 2021", - } for msg in lr: if msg.which() == 'carParams': - car_fingerprint = migration.get(msg.carParams.carFingerprint, msg.carParams.carFingerprint) - if len(msg.carParams.carFw) and (car_fingerprint in FW_VERSIONS): - params.put("CarParamsCache", msg.carParams.as_builder().to_bytes()) - else: - os.environ['SKIP_FW_QUERY'] = "1" - os.environ['FINGERPRINT'] = car_fingerprint + setup_env(CP=msg.carParams) elif msg.which() == 'liveCalibration': params.put("CalibrationParams", msg.as_builder().to_bytes()) - vs, cam_procs = replay_cameras(lr, frs) + vs, cam_procs = replay_cameras(lr, frs, disable_tqdm=disable_tqdm) fake_daemons = { 'sensord': [ @@ -213,7 +201,7 @@ def regen_segment(lr, frs=None, outdir=FAKEDATA): multiprocessing.Process(target=replay_panda_states, args=('pandaStates', lr)), ], 'managerState': [ - multiprocessing.Process(target=replay_manager_state, args=('managerState', lr)), + multiprocessing.Process(target=replay_manager_state, args=('managerState', lr)), ], 'thermald': [ multiprocessing.Process(target=replay_device_state, args=('deviceState', lr)), @@ -230,13 +218,13 @@ def regen_segment(lr, frs=None, outdir=FAKEDATA): time.sleep(5) # start procs up - ignore = list(fake_daemons.keys()) + ['ui', 'manage_athenad', 'uploader'] - ensure_running(managed_processes.values(), started=True, not_run=ignore) + ignore = list(fake_daemons.keys()) + ['ui', 'manage_athenad', 'uploader', 'soundd'] + ensure_running(managed_processes.values(), started=True, params=Params(), CP=car.CarParams(), not_run=ignore) for procs in fake_daemons.values(): for p in procs: p.start() - for _ in tqdm(range(60)): + for _ in tqdm(range(60), disable=disable_tqdm): # ensure all procs are running for d, procs in fake_daemons.items(): for p in procs: @@ -256,13 +244,13 @@ def regen_segment(lr, frs=None, outdir=FAKEDATA): segment = params.get("CurrentRoute", encoding='utf-8') + "--0" seg_path = os.path.join(outdir, segment) # check to make sure openpilot is engaged in the route - if not check_enabled(LogReader(os.path.join(seg_path, "rlog.bz2"))): + if not check_enabled(LogReader(os.path.join(seg_path, "rlog"))): raise Exception(f"Route never enabled: {segment}") return seg_path -def regen_and_save(route, sidx, upload=False, use_route_meta=False): +def regen_and_save(route, sidx, upload=False, use_route_meta=False, outdir=FAKEDATA, disable_tqdm=False): if use_route_meta: r = Route(args.route) lr = LogReader(r.log_paths()[args.seg]) @@ -270,7 +258,14 @@ def regen_and_save(route, sidx, upload=False, use_route_meta=False): else: lr = LogReader(f"cd:/{route.replace('|', '/')}/{sidx}/rlog.bz2") fr = FrameReader(f"cd:/{route.replace('|', '/')}/{sidx}/fcamera.hevc") - rpath = regen_segment(lr, {'roadCameraState': fr}) + rpath = regen_segment(lr, {'roadCameraState': fr}, outdir=outdir, disable_tqdm=disable_tqdm) + + # compress raw rlog before uploading + with open(os.path.join(rpath, "rlog"), "rb") as f: + data = bz2.compress(f.read()) + with open(os.path.join(rpath, "rlog.bz2"), "wb") as f: + f.write(data) + os.remove(os.path.join(rpath, "rlog")) lr = LogReader(os.path.join(rpath, 'rlog.bz2')) controls_state_active = [m.controlsState.active for m in lr if m.which() == 'controlsState'] @@ -281,7 +276,7 @@ def regen_and_save(route, sidx, upload=False, use_route_meta=False): print("\n\n", "*"*30, "\n\n") print("New route:", relr, "\n") if upload: - upload_route(relr) + upload_route(relr, exclude_patterns=['*.hevc', ]) return relr diff --git a/selfdrive/test/process_replay/regen_all.py b/selfdrive/test/process_replay/regen_all.py index 4f057bbf50..c3ea1d41e1 100755 --- a/selfdrive/test/process_replay/regen_all.py +++ b/selfdrive/test/process_replay/regen_all.py @@ -1,22 +1,38 @@ #!/usr/bin/env python3 +import argparse +import concurrent.futures +import os +import random +from tqdm import tqdm + +from selfdrive.test.process_replay.helpers import OpenpilotPrefix from selfdrive.test.process_replay.regen import regen_and_save -from selfdrive.test.process_replay.test_processes import original_segments as segments +from selfdrive.test.process_replay.test_processes import FAKEDATA, original_segments as segments +from tools.lib.route import SegmentName + + +def regen_job(segment, disable_tqdm): + with OpenpilotPrefix(): + sn = SegmentName(segment[1]) + fake_dongle_id = 'regen' + ''.join(random.choice('0123456789ABCDEF') for _ in range(11)) + try: + relr = regen_and_save(sn.route_name.canonical_name, sn.segment_num, upload=True, use_route_meta=False, outdir=os.path.join(FAKEDATA, fake_dongle_id), disable_tqdm=disable_tqdm) + relr = '|'.join(relr.split('/')[-2:]) + return f' ("{segment[0]}", "{relr}"), ' + except Exception as e: + return f" {segment} failed: {str(e)}" + if __name__ == "__main__": - new_segments = [] - for segment in segments: - route = segment[1].rsplit('--', 1)[0] - sidx = int(segment[1].rsplit('--', 1)[1]) - print("Regen", route, sidx) - relr = regen_and_save(route, sidx, upload=True, use_route_meta=False) + parser = argparse.ArgumentParser(description="Generate new segments from old ones") + parser.add_argument("-j", "--jobs", type=int, default=1) + args = parser.parse_args() - print("\n\n", "*"*30, "\n\n") - print("New route:", relr, "\n") - relr = relr.replace('/', '|') - new_segments.append(f' ("{segment[0]}", "{relr}"), ') - print() - print() - print() - print('COPY THIS INTO test_processes.py') - for seg in new_segments: - print(seg) + with concurrent.futures.ProcessPoolExecutor(max_workers=args.jobs) as pool: + p = list(pool.map(regen_job, segments, [args.jobs > 1] * args.jobs)) + msg = "Copy these new segments into test_processes.py:" + for seg in tqdm(p, desc="Generating segments"): + msg += "\n" + str(seg) + print() + print() + print(msg) diff --git a/selfdrive/test/process_replay/test_debayer.py b/selfdrive/test/process_replay/test_debayer.py new file mode 100755 index 0000000000..eff77fc479 --- /dev/null +++ b/selfdrive/test/process_replay/test_debayer.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python3 +import os +import sys +import bz2 +import numpy as np + +import pyopencl as cl # install with `PYOPENCL_CL_PRETEND_VERSION=2.0 pip install pyopencl` + +from system.hardware import PC, TICI +from common.basedir import BASEDIR +from selfdrive.test.openpilotci import BASE_URL, get_url +from system.version import get_commit +from selfdrive.camerad.snapshot.snapshot import yuv_to_rgb +from tools.lib.logreader import LogReader +from tools.lib.filereader import FileReader + +TEST_ROUTE = "8345e3b82948d454|2022-05-04--13-45-33" +SEGMENT = 0 + +FRAME_WIDTH = 1928 +FRAME_HEIGHT = 1208 +FRAME_STRIDE = 2896 + +UV_WIDTH = FRAME_WIDTH // 2 +UV_HEIGHT = FRAME_HEIGHT // 2 +UV_SIZE = UV_WIDTH * UV_HEIGHT + + +def get_frame_fn(ref_commit, test_route, tici=True): + return f"{test_route}_debayer{'_tici' if tici else ''}_{ref_commit}.bz2" + + +def bzip_frames(frames): + data = bytes() + for y, u, v in frames: + data += y.tobytes() + data += u.tobytes() + data += v.tobytes() + return bz2.compress(data) + + +def unbzip_frames(url): + with FileReader(url) as f: + dat = f.read() + + data = bz2.decompress(dat) + + res = [] + for y_start in range(0, len(data), FRAME_WIDTH * FRAME_HEIGHT + UV_SIZE * 2): + u_start = y_start + FRAME_WIDTH * FRAME_HEIGHT + v_start = u_start + UV_SIZE + + y = np.frombuffer(data[y_start: u_start], dtype=np.uint8).reshape((FRAME_HEIGHT, FRAME_WIDTH)) + u = np.frombuffer(data[u_start: v_start], dtype=np.uint8).reshape((UV_HEIGHT, UV_WIDTH)) + v = np.frombuffer(data[v_start: v_start + UV_SIZE], dtype=np.uint8).reshape((UV_HEIGHT, UV_WIDTH)) + + res.append((y, u, v)) + + return res + + +def init_kernels(frame_offset=0): + ctx = cl.create_some_context(interactive=False) + + with open(os.path.join(BASEDIR, 'selfdrive/camerad/cameras/real_debayer.cl')) as f: + build_args = ' -cl-fast-relaxed-math -cl-denorms-are-zero -cl-single-precision-constant' + \ + f' -DFRAME_STRIDE={FRAME_STRIDE} -DRGB_WIDTH={FRAME_WIDTH} -DRGB_HEIGHT={FRAME_HEIGHT} -DFRAME_OFFSET={frame_offset} -DCAM_NUM=0' + if PC: + build_args += ' -DHALF_AS_FLOAT=1 -cl-std=CL2.0' + debayer_prg = cl.Program(ctx, f.read()).build(options=build_args) + + return ctx, debayer_prg + +def debayer_frame(ctx, debayer_prg, data, rgb=False): + q = cl.CommandQueue(ctx) + + yuv_buff = np.empty(FRAME_WIDTH * FRAME_HEIGHT + UV_SIZE * 2, dtype=np.uint8) + + cam_g = cl.Buffer(ctx, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=data) + yuv_g = cl.Buffer(ctx, cl.mem_flags.WRITE_ONLY, FRAME_WIDTH * FRAME_HEIGHT + UV_SIZE * 2) + + local_worksize = (20, 20) if TICI else (4, 4) + ev1 = debayer_prg.debayer10(q, (UV_WIDTH, UV_HEIGHT), local_worksize, cam_g, yuv_g) + cl.enqueue_copy(q, yuv_buff, yuv_g, wait_for=[ev1]).wait() + cl.enqueue_barrier(q) + + y = yuv_buff[:FRAME_WIDTH*FRAME_HEIGHT].reshape((FRAME_HEIGHT, FRAME_WIDTH)) + u = yuv_buff[FRAME_WIDTH*FRAME_HEIGHT:FRAME_WIDTH*FRAME_HEIGHT+UV_SIZE].reshape((UV_HEIGHT, UV_WIDTH)) + v = yuv_buff[FRAME_WIDTH*FRAME_HEIGHT+UV_SIZE:].reshape((UV_HEIGHT, UV_WIDTH)) + + if rgb: + return yuv_to_rgb(y, u, v) + else: + return y, u, v + + +def debayer_replay(lr): + ctx, debayer_prg = init_kernels() + + frames = [] + for m in lr: + if m.which() == 'roadCameraState': + cs = m.roadCameraState + if cs.image: + data = np.frombuffer(cs.image, dtype=np.uint8) + img = debayer_frame(ctx, debayer_prg, data) + + frames.append(img) + + return frames + + +if __name__ == "__main__": + update = "--update" in sys.argv + replay_dir = os.path.dirname(os.path.abspath(__file__)) + ref_commit_fn = os.path.join(replay_dir, "debayer_replay_ref_commit") + + # load logs + lr = list(LogReader(get_url(TEST_ROUTE, SEGMENT))) + + # run replay + frames = debayer_replay(lr) + + # get diff + failed = False + diff = '' + yuv_i = ['y', 'u', 'v'] + if not update: + with open(ref_commit_fn) as f: + ref_commit = f.read().strip() + frame_fn = get_frame_fn(ref_commit, TEST_ROUTE, tici=TICI) + + try: + cmp_frames = unbzip_frames(BASE_URL + frame_fn) + + if len(frames) != len(cmp_frames): + failed = True + diff += 'amount of frames not equal\n' + + for i, (frame, cmp_frame) in enumerate(zip(frames, cmp_frames)): + for j in range(3): + fr = frame[j] + cmp_f = cmp_frame[j] + if fr.shape != cmp_f.shape: + failed = True + diff += f'frame shapes not equal for ({i}, {yuv_i[j]})\n' + diff += f'{ref_commit}: {cmp_f.shape}\n' + diff += f'HEAD: {fr.shape}\n' + elif not np.array_equal(fr, cmp_f): + failed = True + if np.allclose(fr, cmp_f, atol=1): + diff += f'frames not equal for ({i}, {yuv_i[j]}), but are all close\n' + else: + diff += f'frames not equal for ({i}, {yuv_i[j]})\n' + + frame_diff = np.abs(np.subtract(fr, cmp_f)) + diff_len = len(np.nonzero(frame_diff)[0]) + if diff_len > 10000: + diff += f'different at a large amount of pixels ({diff_len})\n' + else: + diff += 'different at (frame, yuv, pixel, ref, HEAD):\n' + for k in zip(*np.nonzero(frame_diff)): + diff += f'{i}, {yuv_i[j]}, {k}, {cmp_f[k]}, {fr[k]}\n' + + if failed: + print(diff) + with open("debayer_diff.txt", "w") as f: + f.write(diff) + except Exception as e: + print(str(e)) + failed = True + + # upload new refs + if update or (failed and TICI): + from selfdrive.test.openpilotci import upload_file + + print("Uploading new refs") + + frames_bzip = bzip_frames(frames) + + new_commit = get_commit() + frame_fn = os.path.join(replay_dir, get_frame_fn(new_commit, TEST_ROUTE, tici=TICI)) + with open(frame_fn, "wb") as f2: + f2.write(frames_bzip) + + try: + upload_file(frame_fn, os.path.basename(frame_fn)) + except Exception as e: + print("failed to upload", e) + + if update: + with open(ref_commit_fn, 'w') as f: + f.write(str(new_commit)) + + print("\nNew ref commit: ", new_commit) + + sys.exit(int(failed)) diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index c59fe197a4..25fbd210cc 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -1,18 +1,22 @@ #!/usr/bin/env python3 import argparse +import concurrent.futures import os import sys -from typing import Any +from collections import defaultdict +from tqdm import tqdm +from typing import Any, Dict from selfdrive.car.car_helpers import interface_names -from selfdrive.test.openpilotci import get_url -from selfdrive.test.process_replay.compare_logs import compare_logs -from selfdrive.test.process_replay.process_replay import CONFIGS, replay_process, check_enabled +from selfdrive.test.openpilotci import get_url, upload_file +from selfdrive.test.process_replay.compare_logs import compare_logs, save_log +from selfdrive.test.process_replay.process_replay import CONFIGS, PROC_REPLAY_DIR, FAKEDATA, check_enabled, replay_process +from system.version import get_commit +from tools.lib.filereader import FileReader from tools.lib.logreader import LogReader - original_segments = [ - ("BODY", "bd6a637565e91581|2022-04-04--22-05-08--0"), # COMMA.BODY + ("BODY", "937ccb7243511b65|2022-05-24--16-03-09--1"), # COMMA.BODY ("HYUNDAI", "02c45f73a2e5c6e9|2021-01-01--19-08-22--1"), # HYUNDAI.SONATA ("TOYOTA", "0982d79ebb0de295|2021-01-04--17-13-21--13"), # TOYOTA.PRIUS (INDI) ("TOYOTA2", "0982d79ebb0de295|2021-01-03--20-03-36--6"), # TOYOTA.RAV4 (LQR) @@ -33,11 +37,11 @@ original_segments = [ segments = [ ("BODY", "bd6a637565e91581|2022-04-04--22-05-08--0"), ("HYUNDAI", "fakedata|2022-01-20--17-49-04--0"), - ("TOYOTA", "fakedata|2022-04-28--18-59-34--0"), - ("TOYOTA2", "fakedata|2022-04-28--15-52-38--0"), - ("TOYOTA3", "fakedata|2022-04-13--19-09-53--0"), + ("TOYOTA", "fakedata|2022-04-29--15-57-12--0"), + ("TOYOTA2", "fakedata|2022-04-29--16-08-01--0"), + ("TOYOTA3", "fakedata|2022-04-29--16-17-39--0"), ("HONDA", "fakedata|2022-01-20--17-56-40--0"), - ("HONDA2", "fakedata|2022-04-13--19-23-30--0"), + ("HONDA2", "fakedata|2022-04-29--16-31-55--0"), ("CHRYSLER", "fakedata|2022-01-20--18-00-11--0"), ("SUBARU", "fakedata|2022-01-20--18-01-57--0"), ("GM", "fakedata|2022-01-20--18-03-41--0"), @@ -50,32 +54,52 @@ segments = [ excluded_interfaces = ["mock", "ford", "mazda", "tesla"] BASE_URL = "https://commadataci.blob.core.windows.net/openpilotci/" +REF_COMMIT_FN = os.path.join(PROC_REPLAY_DIR, "ref_commit") + + +def run_test_process(data): + segment, cfg, args, cur_log_fn, ref_log_path, lr_dat = data + res = None + if not args.upload_only: + lr = LogReader.from_bytes(lr_dat) + res, log_msgs = test_process(cfg, lr, ref_log_path, args.ignore_fields, args.ignore_msgs) + # save logs so we can upload when updating refs + save_log(cur_log_fn, log_msgs) + + if args.update_refs or args.upload_only: + print(f'Uploading: {os.path.basename(cur_log_fn)}') + assert os.path.exists(cur_log_fn), f"Cannot find log to upload: {cur_log_fn}" + upload_file(cur_log_fn, os.path.basename(cur_log_fn)) + os.remove(cur_log_fn) + return (segment, cfg.proc_name, res) -# run the full test (including checks) when no args given -FULL_TEST = len(sys.argv) <= 1 +def get_log_data(segment): + r, n = segment.rsplit("--", 1) + with FileReader(get_url(r, n)) as f: + return (segment, f.read()) -def test_process(cfg, lr, cmp_log_fn, ignore_fields=None, ignore_msgs=None): + +def test_process(cfg, lr, ref_log_path, ignore_fields=None, ignore_msgs=None): if ignore_fields is None: ignore_fields = [] if ignore_msgs is None: ignore_msgs = [] - cmp_log_path = cmp_log_fn if os.path.exists(cmp_log_fn) else BASE_URL + os.path.basename(cmp_log_fn) - cmp_log_msgs = list(LogReader(cmp_log_path)) + ref_log_msgs = list(LogReader(ref_log_path)) log_msgs = replay_process(cfg, lr) # check to make sure openpilot is engaged in the route if cfg.proc_name == "controlsd": if not check_enabled(log_msgs): - segment = cmp_log_fn.split("/")[-1].split("_")[0] - raise Exception(f"Route never enabled: {segment}") + raise Exception(f"Route never enabled: {ref_log_path}") try: - return compare_logs(cmp_log_msgs, log_msgs, ignore_fields+cfg.ignore, ignore_msgs, cfg.tolerance) + return compare_logs(ref_log_msgs, log_msgs, ignore_fields + cfg.ignore, ignore_msgs, cfg.tolerance), log_msgs except Exception as e: - return str(e) + return str(e), log_msgs + def format_diff(results, ref_commit): diff1, diff2 = "", "" @@ -94,7 +118,7 @@ def format_diff(results, ref_commit): diff1 += f"\t\t{diff}\n" failed = True elif len(diff): - cnt = {} + cnt: Dict[str, int] = {} for d in diff: diff2 += f"\t{str(d)}\n" @@ -106,74 +130,108 @@ def format_diff(results, ref_commit): failed = True return diff1, diff2, failed + if __name__ == "__main__": + all_cars = {car for car, _ in segments} + all_procs = {cfg.proc_name for cfg in CONFIGS} parser = argparse.ArgumentParser(description="Regression test to identify changes in a process's output") - - # whitelist has precedence over blacklist in case both are defined - parser.add_argument("--whitelist-procs", type=str, nargs="*", default=[], - help="Whitelist given processes from the test (e.g. controlsd)") - parser.add_argument("--whitelist-cars", type=str, nargs="*", default=[], - help="Whitelist given cars from the test (e.g. HONDA)") + parser.add_argument("--whitelist-procs", type=str, nargs="*", default=all_procs, + help="Whitelist given processes from the test (e.g. controlsd)") + parser.add_argument("--whitelist-cars", type=str, nargs="*", default=all_cars, + help="Whitelist given cars from the test (e.g. HONDA)") parser.add_argument("--blacklist-procs", type=str, nargs="*", default=[], - help="Blacklist given processes from the test (e.g. controlsd)") + help="Blacklist given processes from the test (e.g. controlsd)") parser.add_argument("--blacklist-cars", type=str, nargs="*", default=[], - help="Blacklist given cars from the test (e.g. HONDA)") + help="Blacklist given cars from the test (e.g. HONDA)") parser.add_argument("--ignore-fields", type=str, nargs="*", default=[], - help="Extra fields or msgs to ignore (e.g. carState.events)") + help="Extra fields or msgs to ignore (e.g. carState.events)") parser.add_argument("--ignore-msgs", type=str, nargs="*", default=[], - help="Msgs to ignore (e.g. carEvents)") + help="Msgs to ignore (e.g. carEvents)") + parser.add_argument("--update-refs", action="store_true", + help="Updates reference logs using current commit") + parser.add_argument("--upload-only", action="store_true", + help="Skips testing processes and uploads logs from previous test run") + parser.add_argument("-j", "--jobs", type=int, default=1) args = parser.parse_args() - cars_whitelisted = len(args.whitelist_cars) > 0 - procs_whitelisted = len(args.whitelist_procs) > 0 + tested_procs = set(args.whitelist_procs) - set(args.blacklist_procs) + tested_cars = set(args.whitelist_cars) - set(args.blacklist_cars) + tested_cars = {c.upper() for c in tested_cars} + + full_test = (tested_procs == all_procs) and (tested_cars == all_cars) and all(len(x) == 0 for x in (args.ignore_fields, args.ignore_msgs)) + upload = args.update_refs or args.upload_only + os.makedirs(os.path.dirname(FAKEDATA), exist_ok=True) + + if upload: + assert full_test, "Need to run full test when updating refs" - process_replay_dir = os.path.dirname(os.path.abspath(__file__)) try: - ref_commit = open(os.path.join(process_replay_dir, "ref_commit")).read().strip() + ref_commit = open(REF_COMMIT_FN).read().strip() except FileNotFoundError: - print("couldn't find reference commit") + print("Couldn't find reference commit") sys.exit(1) + cur_commit = get_commit() + if cur_commit is None: + raise Exception("Couldn't get current commit") + print(f"***** testing against commit {ref_commit} *****") # check to make sure all car brands are tested - if FULL_TEST: - tested_cars = {c.lower() for c, _ in segments} - untested = (set(interface_names) - set(excluded_interfaces)) - tested_cars + if full_test: + untested = (set(interface_names) - set(excluded_interfaces)) - {c.lower() for c in tested_cars} assert len(untested) == 0, f"Cars missing routes: {str(untested)}" - results: Any = {} - for car_brand, segment in segments: - if (cars_whitelisted and car_brand.upper() not in args.whitelist_cars) or \ - (not cars_whitelisted and car_brand.upper() in args.blacklist_cars): - continue - - print(f"***** testing route segment {segment} *****\n") + with concurrent.futures.ProcessPoolExecutor(max_workers=args.jobs) as pool: + if not args.upload_only: + download_segments = [seg for car, seg in segments if car in tested_cars] + log_data: Dict[str, LogReader] = {} + p1 = pool.map(get_log_data, download_segments) + for segment, lr in tqdm(p1, desc="Getting Logs", total=len(download_segments)): + log_data[segment] = lr + + pool_args: Any = [] + for car_brand, segment in segments: + if car_brand not in tested_cars: + continue - results[segment] = {} + for cfg in CONFIGS: + if cfg.proc_name not in tested_procs: + continue - r, n = segment.rsplit("--", 1) - lr = LogReader(get_url(r, n)) + cur_log_fn = os.path.join(FAKEDATA, f"{segment}_{cfg.proc_name}_{cur_commit}.bz2") + if args.update_refs: # reference logs will not exist if routes were just regenerated + ref_log_path = get_url(*segment.rsplit("--", 1)) + else: + ref_log_fn = os.path.join(FAKEDATA, f"{segment}_{cfg.proc_name}_{ref_commit}.bz2") + ref_log_path = ref_log_fn if os.path.exists(ref_log_fn) else BASE_URL + os.path.basename(ref_log_fn) - for cfg in CONFIGS: - if (procs_whitelisted and cfg.proc_name not in args.whitelist_procs) or \ - (not procs_whitelisted and cfg.proc_name in args.blacklist_procs): - continue + dat = None if args.upload_only else log_data[segment] + pool_args.append((segment, cfg, args, cur_log_fn, ref_log_path, dat)) - cmp_log_fn = os.path.join(process_replay_dir, f"{segment}_{cfg.proc_name}_{ref_commit}.bz2") - results[segment][cfg.proc_name] = test_process(cfg, lr, cmp_log_fn, args.ignore_fields, args.ignore_msgs) + results: Any = defaultdict(dict) + p2 = pool.map(run_test_process, pool_args) + for (segment, proc, result) in tqdm(p2, desc="Running Tests", total=len(pool_args)): + if isinstance(result, list): + results[segment][proc] = result diff1, diff2, failed = format_diff(results, ref_commit) - with open(os.path.join(process_replay_dir, "diff.txt"), "w") as f: - f.write(diff2) - print(diff1) - - if failed: - print("TEST FAILED") - print("\n\nTo update the reference logs for this test run:") - print("./update_refs.py") + if not upload: + with open(os.path.join(PROC_REPLAY_DIR, "diff.txt"), "w") as f: + f.write(diff2) + print(diff1) + + if failed: + print("TEST FAILED") + print("\n\nTo push the new reference logs for this commit run:") + print("./test_processes.py --upload-only") + else: + print("TEST SUCCEEDED") + else: - print("TEST SUCCEEDED") + with open(REF_COMMIT_FN, "w") as f: + f.write(cur_commit) + print(f"\n\nUpdated reference logs for commit: {cur_commit}") sys.exit(int(failed)) diff --git a/selfdrive/test/process_replay/update_refs.py b/selfdrive/test/process_replay/update_refs.py deleted file mode 100755 index 0a3d95e714..0000000000 --- a/selfdrive/test/process_replay/update_refs.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys - -from selfdrive.test.openpilotci import upload_file, get_url -from selfdrive.test.process_replay.compare_logs import save_log -from selfdrive.test.process_replay.process_replay import replay_process, CONFIGS -from selfdrive.test.process_replay.test_processes import segments -from selfdrive.version import get_commit -from tools.lib.logreader import LogReader - -if __name__ == "__main__": - - no_upload = "--no-upload" in sys.argv - - process_replay_dir = os.path.dirname(os.path.abspath(__file__)) - ref_commit_fn = os.path.join(process_replay_dir, "ref_commit") - - ref_commit = get_commit() - if ref_commit is None: - raise Exception("couldn't get ref commit") - with open(ref_commit_fn, "w") as f: - f.write(ref_commit) - - for car_brand, segment in segments: - r, n = segment.rsplit("--", 1) - lr = LogReader(get_url(r, n)) - - for cfg in CONFIGS: - log_msgs = replay_process(cfg, lr) - log_fn = os.path.join(process_replay_dir, f"{segment}_{cfg.proc_name}_{ref_commit}.bz2") - save_log(log_fn, log_msgs) - - if not no_upload: - upload_file(log_fn, os.path.basename(log_fn)) - os.remove(log_fn) - - print("done") diff --git a/selfdrive/test/setup_device_ci.sh b/selfdrive/test/setup_device_ci.sh index 1b518ddb21..99acc050ea 100755 --- a/selfdrive/test/setup_device_ci.sh +++ b/selfdrive/test/setup_device_ci.sh @@ -19,6 +19,7 @@ fi umount /data/safe_staging/merged/ || true sudo umount /data/safe_staging/merged/ || true +rm -rf /data/safe_staging/* || true export KEYS_PARAM_PATH="/data/params/d/GithubSshKeys" export KEYS_PATH="/usr/comma/setup_keys" @@ -54,15 +55,17 @@ cd $SOURCE_DIR rm -f .git/index.lock git reset --hard -git fetch -find . -maxdepth 1 -not -path './.git' -not -name '.' -not -name '..' -exec rm -rf '{}' \; git fetch --verbose origin $GIT_COMMIT +find . -maxdepth 1 -not -path './.git' -not -name '.' -not -name '..' -exec rm -rf '{}' \; git reset --hard $GIT_COMMIT git checkout $GIT_COMMIT git clean -xdf git submodule update --init --recursive git submodule foreach --recursive "git reset --hard && git clean -xdf" +git lfs pull +(ulimit -n 65535 && git lfs prune) + echo "git checkout done, t=$SECONDS" rsync -a --delete $SOURCE_DIR $TEST_DIR diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 0fea95d0f5..3586f86f12 100755 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -21,12 +21,13 @@ from tools.lib.logreader import LogReader # Baseline CPU usage by process PROCS = { - "selfdrive.controls.controlsd": 31.0, - "./loggerd": 70.0, - "./camerad": 26.0, + "selfdrive.controls.controlsd": 35.0, + "./loggerd": 10.0, + "./encoderd": 12.5, + "./camerad": 16.5, "./locationd": 9.1, "selfdrive.controls.plannerd": 11.7, - "./_ui": 21.0, + "./_ui": 19.2, "selfdrive.locationd.paramsd": 9.0, "./_sensord": 6.17, "selfdrive.controls.radard": 4.5, @@ -38,7 +39,7 @@ PROCS = { "./_soundd": 1.0, "selfdrive.monitoring.dmonitoringd": 1.90, "./proclogd": 1.54, - "selfdrive.logmessaged": 0.2, + "system.logmessaged": 0.2, "./clocksd": 0.02, "./ubloxd": 0.02, "selfdrive.tombstoned": 0, @@ -59,7 +60,7 @@ TIMINGS = { "roadCameraState": [2.5, 0.35], "driverCameraState": [2.5, 0.35], "modelV2": [2.5, 0.35], - "driverState": [2.5, 0.35], + "driverState": [2.5, 0.40], "liveLocationKalman": [2.5, 0.35], "wideRoadCameraState": [1.5, 0.35], } @@ -108,9 +109,9 @@ class TestOnroad(unittest.TestCase): @classmethod def setUpClass(cls): if "DEBUG" in os.environ: - segs = filter(lambda x: os.path.exists(os.path.join(x, "rlog.bz2")), Path(ROOT).iterdir()) + segs = filter(lambda x: os.path.exists(os.path.join(x, "rlog")), Path(ROOT).iterdir()) segs = sorted(segs, key=lambda x: x.stat().st_mtime) - cls.lr = list(LogReader(os.path.join(segs[-1], "rlog.bz2"))) + cls.lr = list(LogReader(os.path.join(segs[-1], "rlog"))) return # setup env @@ -160,10 +161,10 @@ class TestOnroad(unittest.TestCase): if proc.wait(60) is None: proc.kill() - cls.lrs = [list(LogReader(os.path.join(str(s), "rlog.bz2"))) for s in cls.segments] + cls.lrs = [list(LogReader(os.path.join(str(s), "rlog"))) for s in cls.segments] # use the second segment by default as it's the first full segment - cls.lr = list(LogReader(os.path.join(str(cls.segments[1]), "rlog.bz2"))) + cls.lr = list(LogReader(os.path.join(str(cls.segments[1]), "rlog"))) def test_cloudlog_size(self): msgs = [m for m in self.lr if m.which() == 'logMessage'] @@ -181,6 +182,20 @@ class TestOnroad(unittest.TestCase): cpu_ok = check_cpu_usage(proclogs[0], proclogs[-1]) self.assertTrue(cpu_ok) + def test_camera_processing_time(self): + result = "\n" + result += "------------------------------------------------\n" + result += "-------------- Debayer Timing ------------------\n" + result += "------------------------------------------------\n" + + ts = [getattr(getattr(m, m.which()), "processingTime") for m in self.lr if 'CameraState' in m.which()] + self.assertLess(min(ts), 0.025, f"high execution time: {min(ts)}") + result += f"execution time: min {min(ts):.5f}s\n" + result += f"execution time: max {max(ts):.5f}s\n" + result += f"execution time: mean {np.mean(ts):.5f}s\n" + result += "------------------------------------------------\n" + print(result) + def test_mpc_execution_timings(self): result = "\n" result += "------------------------------------------------\n" diff --git a/selfdrive/test/update_ci_routes.py b/selfdrive/test/update_ci_routes.py index b388e599f7..99a63b8dfd 100755 --- a/selfdrive/test/update_ci_routes.py +++ b/selfdrive/test/update_ci_routes.py @@ -18,8 +18,12 @@ DEST_KEY = azureutil.get_user_token(_DATA_ACCOUNT_CI, "openpilotci") SOURCE_KEYS = [azureutil.get_user_token(account, bucket) for account, bucket in SOURCES] SERVICE = BlockBlobService(_DATA_ACCOUNT_CI, sas_token=DEST_KEY) -def upload_route(path): +def upload_route(path, exclude_patterns=None): + if exclude_patterns is None: + exclude_patterns = ['*/dcamera.hevc'] + r, n = path.rsplit("--", 1) + r = '/'.join(r.split('/')[-2:]) # strip out anything extra in the path destpath = f"{r}/{n}" cmd = [ "azcopy", @@ -28,9 +32,7 @@ def upload_route(path): f"https://{_DATA_ACCOUNT_CI}.blob.core.windows.net/openpilotci/{destpath}?{DEST_KEY}", "--recursive=false", "--overwrite=false", - "--exclude-pattern=*/dcamera.hevc", - "--exclude-pattern=*.mkv", - ] + ] + [f"--exclude-pattern={p}" for p in exclude_patterns] subprocess.check_call(cmd) def sync_to_ci_public(route): diff --git a/selfdrive/thermald/fan_controller.py b/selfdrive/thermald/fan_controller.py index b1c7013297..2094faeaa7 100644 --- a/selfdrive/thermald/fan_controller.py +++ b/selfdrive/thermald/fan_controller.py @@ -3,7 +3,7 @@ from abc import ABC, abstractmethod from common.realtime import DT_TRML from common.numpy_fast import interp -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog from selfdrive.controls.lib.pid import PIDController class BaseFanController(ABC): diff --git a/selfdrive/thermald/power_monitoring.py b/selfdrive/thermald/power_monitoring.py index 25b1bad04d..9f009d3265 100644 --- a/selfdrive/thermald/power_monitoring.py +++ b/selfdrive/thermald/power_monitoring.py @@ -1,14 +1,11 @@ -import random import threading -import time -from statistics import mean from typing import Optional from cereal import log from common.params import Params, put_nonblocking from common.realtime import sec_since_boot -from selfdrive.hardware import HARDWARE -from selfdrive.swaglog import cloudlog +from system.hardware import HARDWARE +from system.swaglog import cloudlog from selfdrive.statsd import statlog CAR_VOLTAGE_LOW_PASS_K = 0.091 # LPF gain for 5s tau (dt/tau / (dt/tau + 1)) @@ -82,52 +79,8 @@ class PowerMonitoring: self.car_battery_capacity_uWh += (CAR_CHARGING_RATE_W * 1e6 * integration_time_h) self.last_measurement_time = now else: - # No ignition, we integrate the offroad power used by the device - is_uno = peripheralState.pandaType == log.PandaState.PandaType.uno # Get current power draw somehow - current_power = HARDWARE.get_current_power_draw() # pylint: disable=assignment-from-none - if current_power is not None: - pass - elif (self.next_pulsed_measurement_time is not None) and (self.next_pulsed_measurement_time <= now): - # TODO: Figure out why this is off by a factor of 3/4??? - FUDGE_FACTOR = 1.33 - - # Turn off charging for about 10 sec in a thread that does not get killed on SIGINT, and perform measurement here to avoid blocking thermal - def perform_pulse_measurement(now): - try: - HARDWARE.set_battery_charging(False) - time.sleep(5) - - # Measure for a few sec to get a good average - voltages = [] - currents = [] - for _ in range(6): - voltages.append(HARDWARE.get_battery_voltage()) - currents.append(HARDWARE.get_battery_current()) - time.sleep(1) - current_power = ((mean(voltages) / 1000000) * (mean(currents) / 1000000)) - - self._perform_integration(now, current_power * FUDGE_FACTOR) - - # Enable charging again - HARDWARE.set_battery_charging(True) - except Exception: - cloudlog.exception("Pulsed power measurement failed") - - # Start pulsed measurement and return - threading.Thread(target=perform_pulse_measurement, args=(now,)).start() - self.next_pulsed_measurement_time = None - return - - elif self.next_pulsed_measurement_time is None and not is_uno: - # On a charging EON with black panda, or drawing more than 400mA out of a white/grey one - # Only way to get the power draw is to turn off charging for a few sec and check what the discharging rate is - # We shouldn't do this very often, so make sure it has been some long-ish random time interval - self.next_pulsed_measurement_time = now + random.randint(120, 180) - return - else: - # Do nothing - return + current_power = HARDWARE.get_current_power_draw() # Do the integration self._perform_integration(now, current_power) @@ -178,11 +131,9 @@ class PowerMonitoring: now = sec_since_boot() panda_charging = (peripheralState.usbPowerMode != log.PeripheralState.UsbPowerMode.client) - BATT_PERC_OFF = 10 should_shutdown = False # Wait until we have shut down charging before powering down should_shutdown |= (not panda_charging and self.should_disable_charging(ignition, in_car, offroad_timestamp)) - should_shutdown |= ((HARDWARE.get_battery_capacity() < BATT_PERC_OFF) and (not HARDWARE.get_battery_charging()) and ((now - offroad_timestamp) > 60)) should_shutdown &= started_seen or (now > MIN_ON_TIME_S) return should_shutdown diff --git a/selfdrive/thermald/tests/test_power_monitoring.py b/selfdrive/thermald/tests/test_power_monitoring.py index 9eeb5f0c6d..c0524add69 100755 --- a/selfdrive/thermald/tests/test_power_monitoring.py +++ b/selfdrive/thermald/tests/test_power_monitoring.py @@ -21,10 +21,7 @@ with patch("common.realtime.sec_since_boot", new=mock_sec_since_boot): CAR_CHARGING_RATE_W, VBATT_PAUSE_CHARGING TEST_DURATION_S = 50 -ALL_PANDA_TYPES = [(hw_type,) for hw_type in [log.PandaState.PandaType.whitePanda, - log.PandaState.PandaType.greyPanda, - log.PandaState.PandaType.blackPanda, - log.PandaState.PandaType.uno]] +ALL_PANDA_TYPES = [(log.PandaState.PandaType.dos,)] def pm_patch(name, value, constant=False): if constant: @@ -121,12 +118,8 @@ class TestPowerMonitoring(unittest.TestCase): # Test to check policy of stopping charging after MAX_TIME_OFFROAD_S @parameterized.expand(ALL_PANDA_TYPES) def test_max_time_offroad(self, hw_type): - BATT_VOLTAGE = 4 - BATT_CURRENT = 0 # To stop shutting down for other reasons MOCKED_MAX_OFFROAD_TIME = 3600 - with pm_patch("HARDWARE.get_battery_voltage", BATT_VOLTAGE * 1e6), pm_patch("HARDWARE.get_battery_current", BATT_CURRENT * 1e6), \ - pm_patch("HARDWARE.get_battery_status", "Discharging"), pm_patch("MAX_TIME_OFFROAD_S", MOCKED_MAX_OFFROAD_TIME, constant=True), \ - pm_patch("HARDWARE.get_current_power_draw", None): + with pm_patch("MAX_TIME_OFFROAD_S", MOCKED_MAX_OFFROAD_TIME, constant=True), pm_patch("HARDWARE.get_current_power_draw", None): pm = PowerMonitoring() pm.car_battery_capacity_uWh = CAR_BATTERY_CAPACITY_uWh start_time = ssb diff --git a/selfdrive/thermald/thermald.py b/selfdrive/thermald/thermald.py index 24aafcbfe0..6cf5c428a8 100755 --- a/selfdrive/thermald/thermald.py +++ b/selfdrive/thermald/thermald.py @@ -17,13 +17,13 @@ from common.filter_simple import FirstOrderFilter from common.params import Params from common.realtime import DT_TRML, sec_since_boot from selfdrive.controls.lib.alertmanager import set_offroad_alert -from selfdrive.hardware import HARDWARE, TICI +from system.hardware import HARDWARE, TICI, AGNOS from selfdrive.loggerd.config import get_available_percent from selfdrive.statsd import statlog -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog from selfdrive.thermald.power_monitoring import PowerMonitoring from selfdrive.thermald.fan_controller import TiciFanController -from selfdrive.version import terms_version, training_version +from system.version import terms_version, training_version ThermalStatus = log.DeviceState.ThermalStatus NetworkType = log.DeviceState.NetworkType @@ -31,7 +31,7 @@ NetworkStrength = log.DeviceState.NetworkStrength CURRENT_TAU = 15. # 15s time constant TEMP_TAU = 5. # 5s time constant DISCONNECT_TIMEOUT = 5. # wait 5 seconds before going offroad after disconnect so you get an alert -PANDA_STATES_TIMEOUT = int(1000 * 2.5 * DT_TRML) # 2.5x the expected pandaState frequency +PANDA_STATES_TIMEOUT = int(1000 * 1.5 * DT_TRML) # 1.5x the expected pandaState frequency ThermalBand = namedtuple("ThermalBand", ['min_temp', 'max_temp']) HardwareState = namedtuple("HardwareState", ['network_type', 'network_metered', 'network_strength', 'network_info', 'nvme_temps', 'modem_temps']) @@ -113,7 +113,7 @@ def hw_state_thread(end_event, hw_queue): modem_temps = prev_hw_state.modem_temps # Log modem version once - if TICI and ((modem_version is None) or (modem_nv is None)): + if AGNOS and ((modem_version is None) or (modem_nv is None)): modem_version = HARDWARE.get_modem_version() # pylint: disable=assignment-from-none modem_nv = HARDWARE.get_modem_nv() # pylint: disable=assignment-from-none @@ -134,7 +134,7 @@ def hw_state_thread(end_event, hw_queue): except queue.Full: pass - if TICI and (hw_state.network_info is not None) and (hw_state.network_info.get('state', None) == "REGISTERED"): + if AGNOS and (hw_state.network_info is not None) and (hw_state.network_info.get('state', None) == "REGISTERED"): registered_count += 1 else: registered_count = 0 @@ -220,6 +220,11 @@ def thermald_thread(end_event, hw_queue): if TICI: fan_controller = TiciFanController() + elif (sec_since_boot() - sm.rcv_time['pandaStates']) > DISCONNECT_TIMEOUT: + if onroad_conditions["ignition"]: + onroad_conditions["ignition"] = False + cloudlog.error("panda timed out onroad") + try: last_hw_state = hw_queue.get_nowait() except queue.Empty: @@ -240,8 +245,6 @@ def thermald_thread(end_event, hw_queue): msg.deviceState.modemTempC = last_hw_state.modem_temps msg.deviceState.screenBrightnessPercent = HARDWARE.get_screen_brightness() - msg.deviceState.batteryPercent = HARDWARE.get_battery_capacity() - msg.deviceState.batteryCurrent = HARDWARE.get_battery_current() msg.deviceState.usbOnline = HARDWARE.get_usb_present() current_filter.update(msg.deviceState.batteryCurrent / 1e6) diff --git a/selfdrive/tombstoned.py b/selfdrive/tombstoned.py index dcf3ee0f67..0045e0766c 100755 --- a/selfdrive/tombstoned.py +++ b/selfdrive/tombstoned.py @@ -10,15 +10,12 @@ import glob from typing import NoReturn from common.file_helpers import mkdirs_exists_ok -from selfdrive.hardware import TICI from selfdrive.loggerd.config import ROOT import selfdrive.sentry as sentry -from selfdrive.swaglog import cloudlog -from selfdrive.version import get_commit +from system.swaglog import cloudlog +from system.version import get_commit -MAX_SIZE = 100000 * 10 # mal size is 40-100k, allow up to 1M -if TICI: - MAX_SIZE = MAX_SIZE * 100 # Allow larger size for tici since files contain coredump +MAX_SIZE = 1_000_000 * 100 # allow up to 100M MAX_TOMBSTONE_FN_LEN = 62 # 85 - 23 ("/crash/") TOMBSTONE_DIR = "/data/tombstones/" diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index 1ea13d5564..28fcc5f56f 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -1,10 +1,13 @@ import os -Import('qt_env', 'arch', 'common', 'messaging', 'gpucommon', 'visionipc', +Import('qt_env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'transformations') -base_libs = [gpucommon, common, messaging, cereal, visionipc, transformations, 'zmq', +base_libs = [common, messaging, cereal, visionipc, transformations, 'zmq', 'capnp', 'kj', 'm', 'OpenCL', 'ssl', 'crypto', 'pthread'] + qt_env["LIBS"] +if arch == 'larch64': + base_libs.append('EGL') + maps = arch in ['larch64', 'x86_64'] if maps and arch == 'x86_64': @@ -118,11 +121,3 @@ if arch in ['x86_64', 'Darwin'] or GetOption('extras'): if GetOption('test'): qt_env.Program('replay/tests/test_replay', ['replay/tests/test_runner.cc', 'replay/tests/test_replay.cc'], LIBS=[replay_libs]) - -# navd -if maps: - navd_src = ["navd/main.cc", "navd/route_engine.cc", "navd/map_renderer.cc"] - qt_env.Program("navd/_navd", navd_src, LIBS=qt_libs + ['common', 'json11']) - - if GetOption('extras'): - qt_env.SharedLibrary("navd/map_renderer", ["navd/map_renderer.cc"], LIBS=qt_libs + ['common', 'messaging']) diff --git a/selfdrive/ui/main.cc b/selfdrive/ui/main.cc index cffa459622..1eecd78b19 100644 --- a/selfdrive/ui/main.cc +++ b/selfdrive/ui/main.cc @@ -2,7 +2,7 @@ #include -#include "selfdrive/hardware/hw.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/qt/qt_window.h" #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/window.h" diff --git a/selfdrive/ui/navd/.gitignore b/selfdrive/ui/navd/.gitignore deleted file mode 100644 index 0fa7b173e4..0000000000 --- a/selfdrive/ui/navd/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_navd diff --git a/selfdrive/ui/navd/main.cc b/selfdrive/ui/navd/main.cc deleted file mode 100644 index 7ae0393a47..0000000000 --- a/selfdrive/ui/navd/main.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include -#include -#include - -#include "selfdrive/ui/qt/util.h" -#include "selfdrive/ui/qt/maps/map_helpers.h" -#include "selfdrive/ui/navd/route_engine.h" -#include "selfdrive/ui/navd/map_renderer.h" -#include "selfdrive/hardware/hw.h" -#include "selfdrive/common/params.h" - -void sigHandler(int s) { - qInfo() << "Shutting down"; - std::signal(s, SIG_DFL); - - qApp->quit(); -} - - -int main(int argc, char *argv[]) { - qInstallMessageHandler(swagLogMessageHandler); - - QApplication app(argc, argv); - std::signal(SIGINT, sigHandler); - std::signal(SIGTERM, sigHandler); - - QCommandLineParser parser; - parser.setApplicationDescription("Navigation server. Runs stand-alone, or using pre-computer route"); - parser.addHelpOption(); - parser.process(app); - const QStringList args = parser.positionalArguments(); - - - RouteEngine* route_engine = new RouteEngine(); - - if (Params().getBool("NavdRender")) { - MapRenderer * m = new MapRenderer(get_mapbox_settings()); - QObject::connect(route_engine, &RouteEngine::positionUpdated, m, &MapRenderer::updatePosition); - QObject::connect(route_engine, &RouteEngine::routeUpdated, m, &MapRenderer::updateRoute); - } - - return app.exec(); -} diff --git a/selfdrive/ui/navd/map_renderer.cc b/selfdrive/ui/navd/map_renderer.cc deleted file mode 100644 index 1d78d68dfe..0000000000 --- a/selfdrive/ui/navd/map_renderer.cc +++ /dev/null @@ -1,200 +0,0 @@ -#include "selfdrive/ui/navd/map_renderer.h" - -#include -#include -#include - -#include "selfdrive/ui/qt/maps/map_helpers.h" -#include "selfdrive/common/timing.h" - -const float ZOOM = 13.5; // Don't go below 13 or features will start to disappear -const int WIDTH = 256; -const int HEIGHT = WIDTH; - -const int NUM_VIPC_BUFFERS = 4; - -MapRenderer::MapRenderer(const QMapboxGLSettings &settings, bool enable_vipc) : m_settings(settings) { - QSurfaceFormat fmt; - fmt.setRenderableType(QSurfaceFormat::OpenGLES); - - ctx = std::make_unique(); - ctx->setFormat(fmt); - ctx->create(); - assert(ctx->isValid()); - - surface = std::make_unique(); - surface->setFormat(ctx->format()); - surface->create(); - - ctx->makeCurrent(surface.get()); - assert(QOpenGLContext::currentContext() == ctx.get()); - - gl_functions.reset(ctx->functions()); - gl_functions->initializeOpenGLFunctions(); - - QOpenGLFramebufferObjectFormat fbo_format; - fbo.reset(new QOpenGLFramebufferObject(WIDTH, HEIGHT, fbo_format)); - - m_map.reset(new QMapboxGL(nullptr, m_settings, fbo->size(), 1)); - m_map->setCoordinateZoom(QMapbox::Coordinate(0, 0), ZOOM); - m_map->setStyleUrl("mapbox://styles/commaai/ckvmksrpd4n0a14pfdo5heqzr"); - m_map->createRenderer(); - - m_map->resize(fbo->size()); - m_map->setFramebufferObject(fbo->handle(), fbo->size()); - gl_functions->glViewport(0, 0, WIDTH, HEIGHT); - - if (enable_vipc) { - qWarning() << "Enabling navd map rendering"; - vipc_server.reset(new VisionIpcServer("navd")); - vipc_server->create_buffers(VisionStreamType::VISION_STREAM_RGB_MAP, NUM_VIPC_BUFFERS, true, WIDTH, HEIGHT); - vipc_server->start_listener(); - - pm.reset(new PubMaster({"navThumbnail"})); - } -} - -void MapRenderer::updatePosition(QMapbox::Coordinate position, float bearing) { - if (m_map.isNull()) { - return; - } - - m_map->setCoordinate(position); - m_map->setBearing(bearing); - update(); -} - -bool MapRenderer::loaded() { - return m_map->isFullyLoaded(); -} - -void MapRenderer::update() { - gl_functions->glClear(GL_COLOR_BUFFER_BIT); - m_map->render(); - gl_functions->glFlush(); - - sendVipc(); -} - -void MapRenderer::sendVipc() { - if (!vipc_server || !loaded()) { - return; - } - - QImage cap = fbo->toImage().convertToFormat(QImage::Format_RGB888, Qt::AutoColor); - uint64_t ts = nanos_since_boot(); - VisionBuf* buf = vipc_server->get_buffer(VisionStreamType::VISION_STREAM_RGB_MAP); - VisionIpcBufExtra extra = { - .frame_id = frame_id, - .timestamp_sof = ts, - .timestamp_eof = ts, - }; - - assert(cap.sizeInBytes() == buf->len); - memcpy(buf->addr, cap.bits(), buf->len); - vipc_server->send(buf, &extra); - - if (frame_id % 100 == 0) { - // Write jpeg into buffer - QByteArray buffer_bytes; - QBuffer buffer(&buffer_bytes); - buffer.open(QIODevice::WriteOnly); - cap.save(&buffer, "JPG", 50); - - kj::Array buffer_kj = kj::heapArray((const capnp::byte*)buffer_bytes.constData(), buffer_bytes.size()); - - // Send thumbnail - MessageBuilder msg; - auto thumbnaild = msg.initEvent().initNavThumbnail(); - thumbnaild.setFrameId(frame_id); - thumbnaild.setTimestampEof(ts); - thumbnaild.setThumbnail(buffer_kj); - pm->send("navThumbnail", msg); - } - - frame_id++; -} - -uint8_t* MapRenderer::getImage() { - QImage cap = fbo->toImage().convertToFormat(QImage::Format_RGB888, Qt::AutoColor); - uint8_t* buf = new uint8_t[cap.sizeInBytes()]; - memcpy(buf, cap.bits(), cap.sizeInBytes()); - - return buf; -} - -void MapRenderer::updateRoute(QList coordinates) { - if (m_map.isNull()) return; - initLayers(); - - auto route_points = coordinate_list_to_collection(coordinates); - QMapbox::Feature feature(QMapbox::Feature::LineStringType, route_points, {}, {}); - QVariantMap navSource; - navSource["type"] = "geojson"; - navSource["data"] = QVariant::fromValue(feature); - m_map->updateSource("navSource", navSource); - m_map->setLayoutProperty("navLayer", "visibility", "visible"); -} - -void MapRenderer::initLayers() { - if (!m_map->layerExists("navLayer")) { - QVariantMap nav; - nav["id"] = "navLayer"; - nav["type"] = "line"; - nav["source"] = "navSource"; - m_map->addLayer(nav, "road-intersection"); - m_map->setPaintProperty("navLayer", "line-color", QColor("blue")); - m_map->setPaintProperty("navLayer", "line-width", 3); - m_map->setLayoutProperty("navLayer", "line-cap", "round"); - } -} - -MapRenderer::~MapRenderer() { -} - -extern "C" { - MapRenderer* map_renderer_init() { - char *argv[] = { - (char*)"navd", - nullptr - }; - int argc = 0; - QApplication *app = new QApplication(argc, argv); - assert(app); - - QMapboxGLSettings settings; - settings.setApiBaseUrl(MAPS_HOST); - settings.setAccessToken(get_mapbox_token()); - - return new MapRenderer(settings, false); - } - - void map_renderer_update_position(MapRenderer *inst, float lat, float lon, float bearing) { - inst->updatePosition({lat, lon}, bearing); - QApplication::processEvents(); - } - - void map_renderer_update_route(MapRenderer *inst, char* polyline) { - inst->updateRoute(polyline_to_coordinate_list(QString::fromUtf8(polyline))); - } - - void map_renderer_update(MapRenderer *inst) { - inst->update(); - } - - void map_renderer_process(MapRenderer *inst) { - QApplication::processEvents(); - } - - bool map_renderer_loaded(MapRenderer *inst) { - return inst->loaded(); - } - - uint8_t * map_renderer_get_image(MapRenderer *inst) { - return inst->getImage(); - } - - void map_renderer_free_image(MapRenderer *inst, uint8_t * buf) { - delete[] buf; - } -} diff --git a/selfdrive/ui/navd/map_renderer.h b/selfdrive/ui/navd/map_renderer.h deleted file mode 100644 index 1746e76695..0000000000 --- a/selfdrive/ui/navd/map_renderer.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cereal/visionipc/visionipc_server.h" -#include "cereal/messaging/messaging.h" - - -class MapRenderer : public QObject { - Q_OBJECT - -public: - MapRenderer(const QMapboxGLSettings &, bool enable_vipc=true); - uint8_t* getImage(); - void update(); - bool loaded(); - ~MapRenderer(); - - -private: - std::unique_ptr ctx; - std::unique_ptr surface; - std::unique_ptr gl_functions; - std::unique_ptr fbo; - - std::unique_ptr vipc_server; - std::unique_ptr pm; - void sendVipc(); - - QMapboxGLSettings m_settings; - QScopedPointer m_map; - - void initLayers(); - - uint32_t frame_id = 0; - -public slots: - void updatePosition(QMapbox::Coordinate position, float bearing); - void updateRoute(QList coordinates); -}; diff --git a/selfdrive/ui/navd/map_renderer.py b/selfdrive/ui/navd/map_renderer.py deleted file mode 100755 index 28d006841b..0000000000 --- a/selfdrive/ui/navd/map_renderer.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python3 -# You might need to uninstall the PyQt5 pip package to avoid conflicts - -import os -import time -from cffi import FFI - -from common.ffi_wrapper import suffix -from common.basedir import BASEDIR - -HEIGHT = WIDTH = 256 - - -def get_ffi(): - lib = os.path.join(BASEDIR, "selfdrive", "ui", "navd", "libmap_renderer" + suffix()) - - ffi = FFI() - ffi.cdef(""" -void* map_renderer_init(); -void map_renderer_update_position(void *inst, float lat, float lon, float bearing); -void map_renderer_update_route(void *inst, char *polyline); -void map_renderer_update(void *inst); -void map_renderer_process(void *inst); -bool map_renderer_loaded(void *inst); -uint8_t* map_renderer_get_image(void *inst); -void map_renderer_free_image(void *inst, uint8_t *buf); -""") - return ffi, ffi.dlopen(lib) - - -def wait_ready(lib, renderer): - while not lib.map_renderer_loaded(renderer): - lib.map_renderer_update(renderer) - - # The main qt app is not execed, so we need to periodically process events for e.g. network requests - lib.map_renderer_process(renderer) - - time.sleep(0.01) - - -def get_image(lib, renderer): - buf = lib.map_renderer_get_image(renderer) - r = list(buf[0:3 * WIDTH * HEIGHT]) - lib.map_renderer_free_image(renderer, buf) - - # Convert to numpy - r = np.asarray(r) - return r.reshape((WIDTH, HEIGHT, 3)) - - -if __name__ == "__main__": - import matplotlib.pyplot as plt - import numpy as np - - ffi, lib = get_ffi() - renderer = lib.map_renderer_init() - wait_ready(lib, renderer) - - geometry = r"{yxk}@|obn~Eg@@eCFqc@J{RFw@?kA@gA?q|@Riu@NuJBgi@ZqVNcRBaPBkG@iSD{I@_H@cH?gG@mG@gG?aD@{LDgDDkVVyQLiGDgX@q_@@qI@qKhS{R~[}NtYaDbGoIvLwNfP_b@|f@oFnF_JxHel@bf@{JlIuxAlpAkNnLmZrWqFhFoh@jd@kX|TkJxH_RnPy^|[uKtHoZ~Um`DlkCorC``CuShQogCtwB_ThQcr@fk@sVrWgRhVmSb\\oj@jxA{Qvg@u]tbAyHzSos@xjBeKbWszAbgEc~@~jCuTrl@cYfo@mRn\\_m@v}@ij@jp@om@lk@y|A`pAiXbVmWzUod@xj@wNlTw}@|uAwSn\\kRfYqOdS_IdJuK`KmKvJoOhLuLbHaMzGwO~GoOzFiSrEsOhD}PhCqw@vJmnAxSczA`Vyb@bHk[fFgl@pJeoDdl@}}@zIyr@hG}X`BmUdBcM^aRR}Oe@iZc@mR_@{FScHxAn_@vz@zCzH~GjPxAhDlB~DhEdJlIbMhFfG|F~GlHrGjNjItLnGvQ~EhLnBfOn@p`@AzAAvn@CfC?fc@`@lUrArStCfSxEtSzGxM|ElFlBrOzJlEbDnC~BfDtCnHjHlLvMdTnZzHpObOf^pKla@~G|a@dErg@rCbj@zArYlj@ttJ~AfZh@r]LzYg@`TkDbj@gIdv@oE|i@kKzhA{CdNsEfOiGlPsEvMiDpLgBpHyB`MkB|MmArPg@|N?|P^rUvFz~AWpOCdAkB|PuB`KeFfHkCfGy@tAqC~AsBPkDs@uAiAcJwMe@s@eKkPMoXQux@EuuCoH?eI?Kas@}Dy@wAUkMOgDL" - lib.map_renderer_update_route(renderer, geometry.encode()) - - POSITIONS = [ - (32.71569271952601, -117.16384270868463, 0), (32.71569271952601, -117.16384270868463, 45), # San Diego - (52.378641991483136, 4.902623379456488, 0), (52.378641991483136, 4.902623379456488, 45), # Amsterdam - ] - plt.figure() - - for i, pos in enumerate(POSITIONS): - t = time.time() - lib.map_renderer_update_position(renderer, *pos) - wait_ready(lib, renderer) - - print(f"{pos} took {time.time() - t:.2f} s") - - plt.subplot(2, 2, i + 1) - plt.imshow(get_image(lib, renderer)) - - plt.show() diff --git a/selfdrive/ui/navd/navd b/selfdrive/ui/navd/navd deleted file mode 100755 index ff3103bd97..0000000000 --- a/selfdrive/ui/navd/navd +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -cd "$(dirname "$0")" -export QT_PLUGIN_PATH="../../../third_party/qt-plugins/$(uname -m)" -exec ./_navd diff --git a/selfdrive/ui/navd/route_engine.cc b/selfdrive/ui/navd/route_engine.cc deleted file mode 100644 index afa6c02e86..0000000000 --- a/selfdrive/ui/navd/route_engine.cc +++ /dev/null @@ -1,359 +0,0 @@ -#include "selfdrive/ui/navd/route_engine.h" - -#include - -#include "selfdrive/ui/qt/maps/map.h" -#include "selfdrive/ui/qt/maps/map_helpers.h" -#include "selfdrive/ui/qt/api.h" - -#include "selfdrive/common/params.h" - -const qreal REROUTE_DISTANCE = 25; -const float MANEUVER_TRANSITION_THRESHOLD = 10; - -static float get_time_typical(const QGeoRouteSegment &segment) { - auto maneuver = segment.maneuver(); - auto attrs = maneuver.extendedAttributes(); - return attrs.contains("mapbox.duration_typical") ? attrs["mapbox.duration_typical"].toDouble() : segment.travelTime(); -} - -static cereal::NavInstruction::Direction string_to_direction(QString d) { - if (d.contains("left")) { - return cereal::NavInstruction::Direction::LEFT; - } else if (d.contains("right")) { - return cereal::NavInstruction::Direction::RIGHT; - } else if (d.contains("straight")) { - return cereal::NavInstruction::Direction::STRAIGHT; - } - - return cereal::NavInstruction::Direction::NONE; -} - -static void parse_banner(cereal::NavInstruction::Builder &instruction, const QMap &banner, bool full) { - QString primary_str, secondary_str; - - auto p = banner["primary"].toMap(); - primary_str += p["text"].toString(); - - instruction.setShowFull(full); - - if (p.contains("type")) { - instruction.setManeuverType(p["type"].toString().toStdString()); - } - - if (p.contains("modifier")) { - instruction.setManeuverModifier(p["modifier"].toString().toStdString()); - } - - if (banner.contains("secondary")) { - auto s = banner["secondary"].toMap(); - secondary_str += s["text"].toString(); - } - - instruction.setManeuverPrimaryText(primary_str.toStdString()); - instruction.setManeuverSecondaryText(secondary_str.toStdString()); - - if (banner.contains("sub")) { - auto s = banner["sub"].toMap(); - auto components = s["components"].toList(); - - size_t num_lanes = 0; - for (auto &c : components) { - auto cc = c.toMap(); - if (cc["type"].toString() == "lane") { - num_lanes += 1; - } - } - - auto lanes = instruction.initLanes(num_lanes); - - size_t i = 0; - for (auto &c : components) { - auto cc = c.toMap(); - if (cc["type"].toString() == "lane") { - auto lane = lanes[i]; - lane.setActive(cc["active"].toBool()); - - if (cc.contains("active_direction")) { - lane.setActiveDirection(string_to_direction(cc["active_direction"].toString())); - } - - auto directions = lane.initDirections(cc["directions"].toList().size()); - - size_t j = 0; - for (auto &dir : cc["directions"].toList()) { - directions.set(j, string_to_direction(dir.toString())); - j++; - } - - - i++; - } - } - } -} - -RouteEngine::RouteEngine() { - sm = new SubMaster({"liveLocationKalman", "managerState"}); - pm = new PubMaster({"navInstruction", "navRoute"}); - - // Timers - route_timer = new QTimer(this); - QObject::connect(route_timer, SIGNAL(timeout()), this, SLOT(routeUpdate())); - route_timer->start(1000); - - msg_timer = new QTimer(this); - QObject::connect(msg_timer, SIGNAL(timeout()), this, SLOT(msgUpdate())); - msg_timer->start(50); - - // Build routing engine - QVariantMap parameters; - parameters["mapbox.access_token"] = get_mapbox_token(); - parameters["mapbox.directions_api_url"] = MAPS_HOST + "/directions/v5/mapbox/"; - - geoservice_provider = new QGeoServiceProvider("mapbox", parameters); - routing_manager = geoservice_provider->routingManager(); - if (routing_manager == nullptr) { - qWarning() << geoservice_provider->errorString(); - assert(routing_manager); - } - QObject::connect(routing_manager, &QGeoRoutingManager::finished, this, &RouteEngine::routeCalculated); - - // Get last gps position from params - auto last_gps_position = coordinate_from_param("LastGPSPosition"); - if (last_gps_position) { - last_position = *last_gps_position; - } -} - -void RouteEngine::msgUpdate() { - sm->update(1000); - if (!sm->updated("liveLocationKalman")) { - active = false; - return; - } - - - if (sm->updated("managerState")) { - for (auto const &p : (*sm)["managerState"].getManagerState().getProcesses()) { - if (p.getName() == "ui" && p.getRunning()) { - if (ui_pid && *ui_pid != p.getPid()){ - qWarning() << "UI restarting, sending route"; - QTimer::singleShot(5000, this, &RouteEngine::sendRoute); - } - ui_pid = p.getPid(); - } - } - } - - auto location = (*sm)["liveLocationKalman"].getLiveLocationKalman(); - auto pos = location.getPositionGeodetic(); - auto orientation = location.getCalibratedOrientationNED(); - - gps_ok = location.getGpsOK(); - - localizer_valid = (location.getStatus() == cereal::LiveLocationKalman::Status::VALID) && pos.getValid(); - - if (localizer_valid) { - last_bearing = RAD2DEG(orientation.getValue()[2]); - last_position = QMapbox::Coordinate(pos.getValue()[0], pos.getValue()[1]); - emit positionUpdated(*last_position, *last_bearing); - } - - active = true; -} - -void RouteEngine::routeUpdate() { - if (!active) { - return; - } - - recomputeRoute(); - - MessageBuilder msg; - cereal::Event::Builder evt = msg.initEvent(segment.isValid()); - cereal::NavInstruction::Builder instruction = evt.initNavInstruction(); - - // Show route instructions - if (segment.isValid()) { - auto cur_maneuver = segment.maneuver(); - auto attrs = cur_maneuver.extendedAttributes(); - if (cur_maneuver.isValid() && attrs.contains("mapbox.banner_instructions")) { - float along_geometry = distance_along_geometry(segment.path(), to_QGeoCoordinate(*last_position)); - float distance_to_maneuver_along_geometry = segment.distance() - along_geometry; - - auto banners = attrs["mapbox.banner_instructions"].toList(); - if (banners.size()) { - auto banner = banners[0].toMap(); - - for (auto &b : banners) { - auto bb = b.toMap(); - if (distance_to_maneuver_along_geometry < bb["distance_along_geometry"].toDouble()) { - banner = bb; - } - } - - instruction.setManeuverDistance(distance_to_maneuver_along_geometry); - parse_banner(instruction, banner, distance_to_maneuver_along_geometry < banner["distance_along_geometry"].toDouble()); - - // ETA - float progress = distance_along_geometry(segment.path(), to_QGeoCoordinate(*last_position)) / segment.distance(); - float total_distance = segment.distance() * (1.0 - progress); - float total_time = segment.travelTime() * (1.0 - progress); - float total_time_typical = get_time_typical(segment) * (1.0 - progress); - - auto s = segment.nextRouteSegment(); - while (s.isValid()) { - total_distance += s.distance(); - total_time += s.travelTime(); - total_time_typical += get_time_typical(s); - - s = s.nextRouteSegment(); - } - instruction.setTimeRemaining(total_time); - instruction.setTimeRemainingTypical(total_time_typical); - instruction.setDistanceRemaining(total_distance); - } - - // Transition to next route segment - if (distance_to_maneuver_along_geometry < -MANEUVER_TRANSITION_THRESHOLD) { - auto next_segment = segment.nextRouteSegment(); - if (next_segment.isValid()) { - segment = next_segment; - - recompute_backoff = 0; - recompute_countdown = 0; - } else { - qWarning() << "Destination reached"; - Params().remove("NavDestination"); - - // Clear route if driving away from destination - float d = segment.maneuver().position().distanceTo(to_QGeoCoordinate(*last_position)); - if (d > REROUTE_DISTANCE) { - clearRoute(); - } - } - } - } - } - - pm->send("navInstruction", msg); -} - -void RouteEngine::clearRoute() { - route = QGeoRoute(); - segment = QGeoRouteSegment(); - nav_destination = QMapbox::Coordinate(); -} - -bool RouteEngine::shouldRecompute() { - if (!segment.isValid()) { - return true; - } - - // Don't recompute in last segment, assume destination is reached - if (!segment.nextRouteSegment().isValid()) { - return false; - } - - // Compute closest distance to all line segments in the current path - float min_d = REROUTE_DISTANCE + 1; - auto path = segment.path(); - auto cur = to_QGeoCoordinate(*last_position); - for (size_t i = 0; i < path.size() - 1; i++) { - auto a = path[i]; - auto b = path[i+1]; - if (a.distanceTo(b) < 1.0) { - continue; - } - min_d = std::min(min_d, minimum_distance(a, b, cur)); - } - return min_d > REROUTE_DISTANCE; - - // TODO: Check for going wrong way in segment -} - -void RouteEngine::recomputeRoute() { - if (!last_position) { - return; - } - - auto new_destination = coordinate_from_param("NavDestination"); - if (!new_destination) { - clearRoute(); - return; - } - - bool should_recompute = shouldRecompute(); - if (*new_destination != nav_destination) { - qWarning() << "Got new destination from NavDestination param" << *new_destination; - should_recompute = true; - } - - if (!gps_ok && segment.isValid()) return; // Don't recompute when gps drifts in tunnels - - if (recompute_countdown == 0 && should_recompute) { - recompute_countdown = std::pow(2, recompute_backoff); - recompute_backoff = std::min(6, recompute_backoff + 1); - calculateRoute(*new_destination); - } else { - recompute_countdown = std::max(0, recompute_countdown - 1); - } -} - -void RouteEngine::calculateRoute(QMapbox::Coordinate destination) { - qWarning() << "Calculating route" << *last_position << "->" << destination; - - nav_destination = destination; - QGeoRouteRequest request(to_QGeoCoordinate(*last_position), to_QGeoCoordinate(destination)); - request.setFeatureWeight(QGeoRouteRequest::TrafficFeature, QGeoRouteRequest::AvoidFeatureWeight); - - if (last_bearing) { - QVariantMap params; - int bearing = ((int)(*last_bearing) + 360) % 360; - params["bearing"] = bearing; - request.setWaypointsMetadata({params}); - } - - routing_manager->calculateRoute(request); -} - -void RouteEngine::routeCalculated(QGeoRouteReply *reply) { - if (reply->error() == QGeoRouteReply::NoError) { - if (reply->routes().size() != 0) { - qWarning() << "Got route response"; - - route = reply->routes().at(0); - segment = route.firstRouteSegment(); - - auto path = route.path(); - emit routeUpdated(path); - } else { - qWarning() << "Got empty route response"; - } - } else { - qWarning() << "Got error in route reply" << reply->errorString(); - } - - sendRoute(); - - reply->deleteLater(); -} - -void RouteEngine::sendRoute() { - MessageBuilder msg; - cereal::Event::Builder evt = msg.initEvent(); - cereal::NavRoute::Builder nav_route = evt.initNavRoute(); - - auto path = route.path(); - auto coordinates = nav_route.initCoordinates(path.size()); - - size_t i = 0; - for (auto const &c : route.path()) { - coordinates[i].setLatitude(c.latitude()); - coordinates[i].setLongitude(c.longitude()); - i++; - } - - pm->send("navRoute", msg); -} diff --git a/selfdrive/ui/navd/route_engine.h b/selfdrive/ui/navd/route_engine.h deleted file mode 100644 index 33cbc79107..0000000000 --- a/selfdrive/ui/navd/route_engine.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cereal/messaging/messaging.h" - -class RouteEngine : public QObject { - Q_OBJECT - -public: - RouteEngine(); - - SubMaster *sm; - PubMaster *pm; - - QTimer* msg_timer; - QTimer* route_timer; - - std::optional ui_pid; - - // Route - bool gps_ok = false; - QGeoServiceProvider *geoservice_provider; - QGeoRoutingManager *routing_manager; - QGeoRoute route; - QGeoRouteSegment segment; - QMapbox::Coordinate nav_destination; - - // Position - std::optional last_position; - std::optional last_bearing; - bool localizer_valid = false; - - // Route recompute - bool active = false; - int recompute_backoff = 0; - int recompute_countdown = 0; - void calculateRoute(QMapbox::Coordinate destination); - void clearRoute(); - bool shouldRecompute(); - -private slots: - void routeUpdate(); - void msgUpdate(); - void routeCalculated(QGeoRouteReply *reply); - void recomputeRoute(); - void sendRoute(); - -signals: - void positionUpdated(QMapbox::Coordinate position, float bearing); - void routeUpdated(QList coordinates); -}; diff --git a/selfdrive/ui/qt/api.cc b/selfdrive/ui/qt/api.cc index 79e9506598..84e1a4032e 100644 --- a/selfdrive/ui/qt/api.cc +++ b/selfdrive/ui/qt/api.cc @@ -12,9 +12,9 @@ #include #include -#include "selfdrive/common/params.h" -#include "selfdrive/common/util.h" -#include "selfdrive/hardware/hw.h" +#include "common/params.h" +#include "common/util.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/qt/util.h" namespace CommaApi { diff --git a/selfdrive/ui/qt/api.h b/selfdrive/ui/qt/api.h index 5963d1cf44..ad64d7e722 100644 --- a/selfdrive/ui/qt/api.h +++ b/selfdrive/ui/qt/api.h @@ -5,7 +5,7 @@ #include #include -#include "selfdrive/common/util.h" +#include "common/util.h" namespace CommaApi { diff --git a/selfdrive/ui/qt/body.cc b/selfdrive/ui/qt/body.cc index 08d3611b46..f2628d304f 100644 --- a/selfdrive/ui/qt/body.cc +++ b/selfdrive/ui/qt/body.cc @@ -1,22 +1,131 @@ #include "selfdrive/ui/qt/body.h" #include +#include -BodyWindow::BodyWindow(QWidget *parent) : QLabel(parent) { +#include +#include + +#include "common/params.h" +#include "common/timing.h" + +RecordButton::RecordButton(QWidget *parent) : QPushButton(parent) { + setCheckable(true); + setChecked(false); + setFixedSize(148, 148); + + QObject::connect(this, &QPushButton::toggled, [=]() { + setEnabled(false); + }); +} + +void RecordButton::paintEvent(QPaintEvent *event) { + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + + QPoint center(width() / 2, height() / 2); + + QColor bg(isChecked() ? "#FFFFFF" : "#737373"); + QColor accent(isChecked() ? "#FF0000" : "#FFFFFF"); + if (!isEnabled()) { + bg = QColor("#404040"); + accent = QColor("#FFFFFF"); + } + + if (isDown()) { + accent.setAlphaF(0.7); + } + + p.setPen(Qt::NoPen); + p.setBrush(bg); + p.drawEllipse(center, 74, 74); + + p.setPen(QPen(accent, 6)); + p.setBrush(Qt::NoBrush); + p.drawEllipse(center, 42, 42); + + p.setPen(Qt::NoPen); + p.setBrush(accent); + p.drawEllipse(center, 22, 22); +} + + +BodyWindow::BodyWindow(QWidget *parent) : fuel_filter(1.0, 5., 1. / UI_FREQ), QWidget(parent) { + QStackedLayout *layout = new QStackedLayout(this); + layout->setStackingMode(QStackedLayout::StackAll); + + QWidget *w = new QWidget; + QVBoxLayout *vlayout = new QVBoxLayout(w); + vlayout->setMargin(45); + layout->addWidget(w); + + // face + face = new QLabel(); + face->setAlignment(Qt::AlignCenter); + layout->addWidget(face); awake = new QMovie("../assets/body/awake.gif"); awake->setCacheMode(QMovie::CacheAll); sleep = new QMovie("../assets/body/sleep.gif"); sleep->setCacheMode(QMovie::CacheAll); - QPalette p(Qt::black); - setPalette(p); - setAutoFillBackground(true); + // record button + btn = new RecordButton(this); + vlayout->addWidget(btn, 0, Qt::AlignBottom | Qt::AlignRight); + QObject::connect(btn, &QPushButton::clicked, [=](bool checked) { + btn->setEnabled(false); + Params().putBool("DisableLogging", !checked); + last_button = nanos_since_boot(); + }); + w->raise(); + + QObject::connect(uiState(), &UIState::uiUpdate, this, &BodyWindow::updateState); +} + +void BodyWindow::paintEvent(QPaintEvent *event) { + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); - setAlignment(Qt::AlignCenter); + p.fillRect(rect(), QColor(0, 0, 0)); - setAttribute(Qt::WA_TransparentForMouseEvents, true); + // battery outline + detail + p.translate(width() - 136, 16); + const QColor gray = QColor("#737373"); + p.setBrush(Qt::NoBrush); + p.setPen(QPen(gray, 4, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); + p.drawRoundedRect(2, 2, 78, 36, 8, 8); - QObject::connect(uiState(), &UIState::uiUpdate, this, &BodyWindow::updateState); + p.setPen(Qt::NoPen); + p.setBrush(gray); + p.drawRoundedRect(84, 12, 6, 16, 4, 4); + p.drawRect(84, 12, 3, 16); + + // battery level + double fuel = std::clamp(fuel_filter.x(), 0.2f, 1.0f); + const int m = 5; // manual margin since we can't do an inner border + p.setPen(Qt::NoPen); + p.setBrush(fuel > 0.25 ? QColor("#32D74B") : QColor("#FF453A")); + p.drawRoundedRect(2 + m, 2 + m, (78 - 2*m)*fuel, 36 - 2*m, 4, 4); + + // charging status + if (charging) { + p.setPen(Qt::NoPen); + p.setBrush(Qt::white); + const QPolygonF charger({ + QPointF(12.31, 0), + QPointF(12.31, 16.92), + QPointF(18.46, 16.92), + QPointF(6.15, 40), + QPointF(6.15, 23.08), + QPointF(0, 23.08), + }); + p.drawPolygon(charger.translated(98, 0)); + } +} + +void BodyWindow::offroadTransition(bool offroad) { + btn->setChecked(true); + btn->setEnabled(true); + fuel_filter.reset(1.0); } void BodyWindow::updateState(const UIState &s) { @@ -25,12 +134,28 @@ void BodyWindow::updateState(const UIState &s) { } const SubMaster &sm = *(s.sm); + auto cs = sm["carState"].getCarState(); + + charging = cs.getCharging(); + fuel_filter.update(cs.getFuelGauge()); // TODO: use carState.standstill when that's fixed - const bool standstill = std::abs(sm["carState"].getCarState().getVEgo()) < 0.01; + const bool standstill = std::abs(cs.getVEgo()) < 0.01; QMovie *m = standstill ? sleep : awake; - if (m != movie()) { - setMovie(m); - movie()->start(); + if (m != face->movie()) { + face->setMovie(m); + face->movie()->start(); + } + + // update record button state + if (sm.updated("managerState") && (sm.rcv_time("managerState") - last_button)*1e-9 > 0.5) { + for (auto proc : sm["managerState"].getManagerState().getProcesses()) { + if (proc.getName() == "loggerd") { + btn->setEnabled(true); + btn->setChecked(proc.getRunning()); + } + } } + + update(); } diff --git a/selfdrive/ui/qt/body.h b/selfdrive/ui/qt/body.h index 7f352715df..567a54d49b 100644 --- a/selfdrive/ui/qt/body.h +++ b/selfdrive/ui/qt/body.h @@ -2,18 +2,37 @@ #include #include +#include +#include "common/util.h" #include "selfdrive/ui/ui.h" -class BodyWindow : public QLabel { +class RecordButton : public QPushButton { + Q_OBJECT + +public: + RecordButton(QWidget* parent = 0); + +private: + void paintEvent(QPaintEvent*) override; +}; + +class BodyWindow : public QWidget { Q_OBJECT public: BodyWindow(QWidget* parent = 0); private: + bool charging = false; + uint64_t last_button = 0; + FirstOrderFilter fuel_filter; + QLabel *face; QMovie *awake, *sleep; + RecordButton *btn; + void paintEvent(QPaintEvent*) override; private slots: void updateState(const UIState &s); + void offroadTransition(bool onroad); }; diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc index 0b64900770..e522d6160d 100644 --- a/selfdrive/ui/qt/home.cc +++ b/selfdrive/ui/qt/home.cc @@ -5,7 +5,7 @@ #include #include -#include "selfdrive/common/params.h" +#include "common/params.h" #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/widgets/drive_stats.h" #include "selfdrive/ui/qt/widgets/prime.h" @@ -32,7 +32,6 @@ HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) { body = new BodyWindow(this); slayout->addWidget(body); - body->setEnabled(false); driver_view = new DriverViewWindow(this); connect(driver_view, &DriverViewWindow::done, [=] { @@ -59,6 +58,7 @@ void HomeWindow::updateState(const UIState &s) { } void HomeWindow::offroadTransition(bool offroad) { + body->setEnabled(false); sidebar->setVisible(offroad); if (offroad) { slayout->setCurrentWidget(home); diff --git a/selfdrive/ui/qt/maps/map.cc b/selfdrive/ui/qt/maps/map.cc index 3b8668d0b7..4c6a0a4e65 100644 --- a/selfdrive/ui/qt/maps/map.cc +++ b/selfdrive/ui/qt/maps/map.cc @@ -3,14 +3,14 @@ #include #include -#include #include +#include -#include "selfdrive/common/swaglog.h" -#include "selfdrive/ui/ui.h" -#include "selfdrive/ui/qt/util.h" +#include "common/swaglog.h" #include "selfdrive/ui/qt/maps/map_helpers.h" #include "selfdrive/ui/qt/request_repeater.h" +#include "selfdrive/ui/qt/util.h" +#include "selfdrive/ui/ui.h" const int PAN_TIMEOUT = 100; @@ -24,16 +24,8 @@ const float MAP_SCALE = 2; const QString ICON_SUFFIX = ".png"; -MapWindow::MapWindow(const QMapboxGLSettings &settings) : - m_settings(settings), velocity_filter(0, 10, 0.05) { - sm = new SubMaster({"liveLocationKalman", "navInstruction", "navRoute"}); - - // Connect now, so any navRoutes sent while the map is initializing are not dropped - sm->update(0); - - timer = new QTimer(this); - QObject::connect(timer, SIGNAL(timeout()), this, SLOT(timerUpdate())); - timer->start(50); +MapWindow::MapWindow(const QMapboxGLSettings &settings) : m_settings(settings), velocity_filter(0, 10, 0.05) { + QObject::connect(uiState(), &UIState::uiUpdate, this, &MapWindow::updateState); // Instructions map_instructions = new MapInstructions(this); @@ -105,33 +97,30 @@ void MapWindow::initLayers() { } } -void MapWindow::timerUpdate() { +void MapWindow::updateState(const UIState &s) { if (!uiState()->scene.started) { return; } - + const SubMaster &sm = *(s.sm); update(); - sm->update(0); - if (sm->updated("liveLocationKalman")) { - auto location = (*sm)["liveLocationKalman"].getLiveLocationKalman(); + if (sm.updated("liveLocationKalman")) { + auto location = sm["liveLocationKalman"].getLiveLocationKalman(); auto pos = location.getPositionGeodetic(); auto orientation = location.getCalibratedOrientationNED(); + auto velocity = location.getVelocityCalibrated(); - localizer_valid = (location.getStatus() == cereal::LiveLocationKalman::Status::VALID) && pos.getValid(); + localizer_valid = (location.getStatus() == cereal::LiveLocationKalman::Status::VALID) && + pos.getValid() && orientation.getValid() && velocity.getValid(); if (localizer_valid) { - float velocity = location.getVelocityCalibrated().getValue()[0]; - float bearing = RAD2DEG(orientation.getValue()[2]); - auto coordinate = QMapbox::Coordinate(pos.getValue()[0], pos.getValue()[1]); - - last_position = coordinate; - last_bearing = bearing; - velocity_filter.update(velocity); + last_position = QMapbox::Coordinate(pos.getValue()[0], pos.getValue()[1]); + last_bearing = RAD2DEG(orientation.getValue()[2]); + velocity_filter.update(velocity.getValue()[0]); } } - if (sm->updated("navRoute") && (*sm)["navRoute"].getNavRoute().getCoordinates().size()) { + if (sm.updated("navRoute") && sm["navRoute"].getNavRoute().getCoordinates().size()) { qWarning() << "Got new navRoute from navd. Opening map:" << allow_open; // Only open the map on setting destination the first time @@ -180,9 +169,9 @@ void MapWindow::timerUpdate() { zoom_counter--; } - if (sm->updated("navInstruction")) { - if (sm->valid("navInstruction")) { - auto i = (*sm)["navInstruction"].getNavInstruction(); + if (sm.updated("navInstruction")) { + if (sm.valid("navInstruction")) { + auto i = sm["navInstruction"].getNavInstruction(); emit ETAChanged(i.getTimeRemaining(), i.getTimeRemainingTypical(), i.getDistanceRemaining()); if (localizer_valid) { @@ -196,9 +185,9 @@ void MapWindow::timerUpdate() { } } - if (sm->rcv_frame("navRoute") != route_rcv_frame) { + if (sm.rcv_frame("navRoute") != route_rcv_frame) { qWarning() << "Updating navLayer with new route"; - auto route = (*sm)["navRoute"].getNavRoute(); + auto route = sm["navRoute"].getNavRoute(); auto route_points = capnp_coordinate_list_to_collection(route.getCoordinates()); QMapbox::Feature feature(QMapbox::Feature::LineStringType, route_points, {}, {}); QVariantMap navSource; @@ -207,7 +196,7 @@ void MapWindow::timerUpdate() { m_map->updateSource("navSource", navSource); m_map->setLayoutProperty("navLayer", "visibility", "visible"); - route_rcv_frame = sm->rcv_frame("navRoute"); + route_rcv_frame = sm.rcv_frame("navRoute"); } } diff --git a/selfdrive/ui/qt/maps/map.h b/selfdrive/ui/qt/maps/map.h index c62089cb25..7c39b24c3c 100644 --- a/selfdrive/ui/qt/maps/map.h +++ b/selfdrive/ui/qt/maps/map.h @@ -5,22 +5,22 @@ #include #include #include -#include #include +#include #include #include #include +#include #include #include -#include -#include +#include #include -#include -#include +#include -#include "selfdrive/common/params.h" -#include "selfdrive/common/util.h" #include "cereal/messaging/messaging.h" +#include "common/params.h" +#include "common/util.h" +#include "selfdrive/ui/ui.h" class MapInstructions : public QWidget { Q_OBJECT @@ -91,8 +91,6 @@ private: void pinchTriggered(QPinchGesture *gesture); bool m_sourceAdded = false; - SubMaster *sm; - QTimer* timer; bool loaded_once = false; bool allow_open = true; @@ -115,7 +113,7 @@ private: uint64_t route_rcv_frame = 0; private slots: - void timerUpdate(); + void updateState(const UIState &s); public slots: void offroadTransition(bool offroad); diff --git a/selfdrive/ui/qt/maps/map_helpers.cc b/selfdrive/ui/qt/maps/map_helpers.cc index f0545924c0..2b2c27418e 100644 --- a/selfdrive/ui/qt/maps/map_helpers.cc +++ b/selfdrive/ui/qt/maps/map_helpers.cc @@ -3,8 +3,8 @@ #include #include -#include "selfdrive/common/params.h" -#include "selfdrive/hardware/hw.h" +#include "common/params.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/qt/api.h" QString get_mapbox_token() { @@ -101,101 +101,6 @@ QMapbox::CoordinatesCollections coordinate_list_to_collection(QList polyline_to_coordinate_list(const QString &polylineString) { - QList path; - if (polylineString.isEmpty()) - return path; - - QByteArray data = polylineString.toLatin1(); - - bool parsingLatitude = true; - - int shift = 0; - int value = 0; - - QGeoCoordinate coord(0, 0); - - for (int i = 0; i < data.length(); ++i) { - unsigned char c = data.at(i) - 63; - - value |= (c & 0x1f) << shift; - shift += 5; - - // another chunk - if (c & 0x20) - continue; - - int diff = (value & 1) ? ~(value >> 1) : (value >> 1); - - if (parsingLatitude) { - coord.setLatitude(coord.latitude() + (double)diff/1e6); - } else { - coord.setLongitude(coord.longitude() + (double)diff/1e6); - path.append(coord); - } - - parsingLatitude = !parsingLatitude; - - value = 0; - shift = 0; - } - - return path; -} - -static QGeoCoordinate sub(QGeoCoordinate v, QGeoCoordinate w) { - return QGeoCoordinate(v.latitude() - w.latitude(), v.longitude() - w.longitude()); -} - -static QGeoCoordinate add(QGeoCoordinate v, QGeoCoordinate w) { - return QGeoCoordinate(v.latitude() + w.latitude(), v.longitude() + w.longitude()); -} - -static QGeoCoordinate mul(QGeoCoordinate v, float c) { - return QGeoCoordinate(c * v.latitude(), c * v.longitude()); -} - -static float dot(QGeoCoordinate v, QGeoCoordinate w) { - return v.latitude() * w.latitude() + v.longitude() * w.longitude(); -} - -float minimum_distance(QGeoCoordinate a, QGeoCoordinate b, QGeoCoordinate p) { - // If a and b are the same coordinate the computation below doesn't work - if (a.distanceTo(b) < 0.01) { - return a.distanceTo(p); - } - - const QGeoCoordinate ap = sub(p, a); - const QGeoCoordinate ab = sub(b, a); - const float t = std::clamp(dot(ap, ab) / dot(ab, ab), 0.0f, 1.0f); - const QGeoCoordinate projection = add(a, mul(ab, t)); - return projection.distanceTo(p); -} - -float distance_along_geometry(QList geometry, QGeoCoordinate pos) { - if (geometry.size() <= 2) { - return geometry[0].distanceTo(pos); - } - - // 1. Find segment that is closest to current position - // 2. Total distance is sum of distance to start of closest segment - // + all previous segments - double total_distance = 0; - double total_distance_closest = 0; - double closest_distance = std::numeric_limits::max(); - - for (int i = 0; i < geometry.size() - 1; i++) { - double d = minimum_distance(geometry[i], geometry[i+1], pos); - if (d < closest_distance) { - closest_distance = d; - total_distance_closest = total_distance + geometry[i].distanceTo(pos); - } - total_distance += geometry[i].distanceTo(geometry[i+1]); - } - - return total_distance_closest; -} - std::optional coordinate_from_param(std::string param) { QString json_str = QString::fromStdString(Params().get(param)); if (json_str.isEmpty()) return {}; diff --git a/selfdrive/ui/qt/maps/map_helpers.h b/selfdrive/ui/qt/maps/map_helpers.h index 1c8cacbebc..344246bb05 100644 --- a/selfdrive/ui/qt/maps/map_helpers.h +++ b/selfdrive/ui/qt/maps/map_helpers.h @@ -5,7 +5,7 @@ #include #include -#include "selfdrive/common/util.h" +#include "common/util.h" #include "common/transformations/coordinates.hpp" #include "common/transformations/orientation.hpp" #include "cereal/messaging/messaging.h" @@ -24,8 +24,5 @@ QMapbox::CoordinatesCollections model_to_collection( QMapbox::CoordinatesCollections coordinate_to_collection(QMapbox::Coordinate c); QMapbox::CoordinatesCollections capnp_coordinate_list_to_collection(const capnp::List::Reader &coordinate_list); QMapbox::CoordinatesCollections coordinate_list_to_collection(QList coordinate_list); -QList polyline_to_coordinate_list(const QString &polylineString); -float minimum_distance(QGeoCoordinate a, QGeoCoordinate b, QGeoCoordinate p); std::optional coordinate_from_param(std::string param); -float distance_along_geometry(QList geometry, QGeoCoordinate pos); diff --git a/selfdrive/ui/qt/maps/map_settings.cc b/selfdrive/ui/qt/maps/map_settings.cc index 1e3a99e31a..674c7fa7cb 100644 --- a/selfdrive/ui/qt/maps/map_settings.cc +++ b/selfdrive/ui/qt/maps/map_settings.cc @@ -2,7 +2,7 @@ #include -#include "selfdrive/common/util.h" +#include "common/util.h" #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/request_repeater.h" #include "selfdrive/ui/qt/widgets/controls.h" diff --git a/selfdrive/ui/qt/maps/map_settings.h b/selfdrive/ui/qt/maps/map_settings.h index 03720edee7..962d127679 100644 --- a/selfdrive/ui/qt/maps/map_settings.h +++ b/selfdrive/ui/qt/maps/map_settings.h @@ -8,7 +8,7 @@ #include #include -#include "selfdrive/common/params.h" +#include "common/params.h" #include "selfdrive/ui/qt/widgets/controls.h" class MapPanel : public QWidget { diff --git a/selfdrive/ui/qt/offroad/driverview.cc b/selfdrive/ui/qt/offroad/driverview.cc index 3302687bf4..06578b455a 100644 --- a/selfdrive/ui/qt/offroad/driverview.cc +++ b/selfdrive/ui/qt/offroad/driverview.cc @@ -63,12 +63,10 @@ void DriverViewScene::paintEvent(QPaintEvent* event) { // blackout const QColor bg(0, 0, 0, 140); - const QRect& blackout_rect = Hardware::TICI() ? rect() : rect2; + const QRect& blackout_rect = rect(); p.fillRect(blackout_rect.adjusted(0, 0, valid_rect.left() - blackout_rect.right(), 0), bg); p.fillRect(blackout_rect.adjusted(valid_rect.right() - blackout_rect.left(), 0, 0, 0), bg); - if (Hardware::TICI()) { - p.fillRect(blackout_rect.adjusted(valid_rect.left()-blackout_rect.left()+1, 0, valid_rect.right()-blackout_rect.right()-1, -valid_rect.height()*7/10), bg); // top dz - } + p.fillRect(blackout_rect.adjusted(valid_rect.left()-blackout_rect.left()+1, 0, valid_rect.right()-blackout_rect.right()-1, -valid_rect.height()*7/10), bg); // top dz // face bounding box cereal::DriverState::Reader driver_state = sm["driverState"].getDriverState(); diff --git a/selfdrive/ui/qt/offroad/driverview.h b/selfdrive/ui/qt/offroad/driverview.h index 4d4a4358ef..5d090ad772 100644 --- a/selfdrive/ui/qt/offroad/driverview.h +++ b/selfdrive/ui/qt/offroad/driverview.h @@ -4,7 +4,7 @@ #include -#include "selfdrive/common/util.h" +#include "common/util.h" #include "selfdrive/ui/qt/widgets/cameraview.h" class DriverViewScene : public QWidget { diff --git a/selfdrive/ui/qt/offroad/networking.cc b/selfdrive/ui/qt/offroad/networking.cc index 9c2088b1d7..418ccd3179 100644 --- a/selfdrive/ui/qt/offroad/networking.cc +++ b/selfdrive/ui/qt/offroad/networking.cc @@ -28,9 +28,9 @@ Networking::Networking(QWidget* parent, bool show_advanced) : QFrame(parent) { vlayout->setContentsMargins(20, 20, 20, 20); if (show_advanced) { QPushButton* advancedSettings = new QPushButton("Advanced"); - advancedSettings->setObjectName("advancedBtn"); + advancedSettings->setObjectName("advanced_btn"); advancedSettings->setStyleSheet("margin-right: 30px;"); - advancedSettings->setFixedSize(350, 100); + advancedSettings->setFixedSize(400, 100); connect(advancedSettings, &QPushButton::clicked, [=]() { main_layout->setCurrentWidget(an); }); vlayout->addSpacing(10); vlayout->addWidget(advancedSettings, 0, Qt::AlignRight); @@ -55,16 +55,18 @@ Networking::Networking(QWidget* parent, bool show_advanced) : QFrame(parent) { setAutoFillBackground(true); setPalette(pal); - // TODO: revisit pressed colors setStyleSheet(R"( - #wifiWidget > QPushButton, #back_btn, #advancedBtn { + #wifiWidget > QPushButton, #back_btn, #advanced_btn { font-size: 50px; margin: 0px; padding: 15px; border-width: 0; border-radius: 30px; color: #dddddd; - background-color: #444444; + background-color: #393939; + } + #back_btn:pressed, #advanced_btn:pressed { + background-color: #4a4a4a; } )"); main_layout->setCurrentWidget(wifiScreen); @@ -118,7 +120,7 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid // Back button QPushButton* back = new QPushButton("Back"); back->setObjectName("back_btn"); - back->setFixedSize(500, 100); + back->setFixedSize(400, 100); connect(back, &QPushButton::clicked, [=]() { emit backPress(); }); main_layout->addWidget(back, 0, Qt::AlignLeft); diff --git a/selfdrive/ui/qt/offroad/onboarding.cc b/selfdrive/ui/qt/offroad/onboarding.cc index 8e7601ca8a..d32cc26e43 100644 --- a/selfdrive/ui/qt/offroad/onboarding.cc +++ b/selfdrive/ui/qt/offroad/onboarding.cc @@ -6,8 +6,8 @@ #include #include -#include "selfdrive/common/util.h" -#include "selfdrive/common/params.h" +#include "common/util.h" +#include "common/params.h" #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/widgets/input.h" diff --git a/selfdrive/ui/qt/offroad/onboarding.h b/selfdrive/ui/qt/offroad/onboarding.h index 904aec4ade..48f4094899 100644 --- a/selfdrive/ui/qt/offroad/onboarding.h +++ b/selfdrive/ui/qt/offroad/onboarding.h @@ -7,7 +7,7 @@ #include #include -#include "selfdrive/common/params.h" +#include "common/params.h" #include "selfdrive/ui/qt/qt_window.h" class TrainingGuide : public QFrame { diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index ec686ba1f0..175e6cf5a3 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -12,9 +12,9 @@ #include "selfdrive/ui/qt/maps/map_settings.h" #endif -#include "selfdrive/common/params.h" -#include "selfdrive/common/util.h" -#include "selfdrive/hardware/hw.h" +#include "common/params.h" +#include "common/util.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/qt/widgets/controls.h" #include "selfdrive/ui/qt/widgets/input.h" #include "selfdrive/ui/qt/widgets/scrollview.h" @@ -57,12 +57,6 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { "Upload data from the driver facing camera and help improve the driver monitoring algorithm.", "../assets/offroad/icon_monitoring.png", }, - { - "EndToEndToggle", - "\U0001f96c Disable use of lanelines (Alpha) \U0001f96c", - "In this mode openpilot will ignore lanelines and just drive how it thinks a human would.", - "../assets/offroad/icon_road.png", - }, { "DisengageOnAccelerator", "Disengage On Accelerator Pedal", @@ -95,9 +89,6 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { auto toggle = new ParamControl(param, title, desc, icon, this); bool locked = params.getBool((param + "Lock").toStdString()); toggle->setEnabled(!locked); - if (!locked) { - connect(uiState(), &UIState::offroadTransition, toggle, &ParamControl::setEnabled); - } addItem(toggle); } } @@ -162,7 +153,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { power_layout->addWidget(poweroff_btn); QObject::connect(poweroff_btn, &QPushButton::clicked, this, &DevicePanel::poweroff); - if (Hardware::TICI()) { + if (!Hardware::PC()) { connect(uiState(), &UIState::offroadTransition, poweroff_btn, &QPushButton::setVisible); } diff --git a/selfdrive/ui/qt/offroad/wifiManager.cc b/selfdrive/ui/qt/offroad/wifiManager.cc index 1628f35d99..124138eea4 100644 --- a/selfdrive/ui/qt/offroad/wifiManager.cc +++ b/selfdrive/ui/qt/offroad/wifiManager.cc @@ -3,8 +3,8 @@ #include "selfdrive/ui/ui.h" #include "selfdrive/ui/qt/widgets/prime.h" -#include "selfdrive/common/params.h" -#include "selfdrive/common/swaglog.h" +#include "common/params.h" +#include "common/swaglog.h" #include "selfdrive/ui/qt/util.h" bool compare_by_strength(const Network &a, const Network &b) { diff --git a/selfdrive/ui/qt/onroad.cc b/selfdrive/ui/qt/onroad.cc index cee347daa9..38541ef2d5 100644 --- a/selfdrive/ui/qt/onroad.cc +++ b/selfdrive/ui/qt/onroad.cc @@ -4,7 +4,7 @@ #include -#include "selfdrive/common/timing.h" +#include "common/timing.h" #include "selfdrive/ui/qt/util.h" #ifdef ENABLE_MAPS #include "selfdrive/ui/qt/maps/map.h" @@ -91,7 +91,7 @@ void OnroadWindow::offroadTransition(bool offroad) { alerts->updateAlert({}, bg); // update stream type - bool wide_cam = Hardware::TICI() && Params().getBool("EnableWideCamera"); + bool wide_cam = Params().getBool("WideCameraOnly"); nvg->setStreamType(wide_cam ? VISION_STREAM_WIDE_ROAD : VISION_STREAM_ROAD); } @@ -174,17 +174,24 @@ void NvgWindow::updateState(const UIState &s) { const SubMaster &sm = *(s.sm); const auto cs = sm["controlsState"].getControlsState(); - float maxspeed = cs.getVCruise(); - bool cruise_set = maxspeed > 0 && (int)maxspeed != SET_SPEED_NA; + float set_speed = cs.getVCruise(); + bool cruise_set = set_speed > 0 && (int)set_speed != SET_SPEED_NA; if (cruise_set && !s.scene.is_metric) { - maxspeed *= KM_TO_MILE; + set_speed *= KM_TO_MILE; } - QString maxspeed_str = cruise_set ? QString::number(std::nearbyint(maxspeed)) : "N/A"; float cur_speed = std::max(0.0, sm["carState"].getCarState().getVEgo() * (s.scene.is_metric ? MS_TO_KPH : MS_TO_MPH)); + auto speed_limit_sign = sm["navInstruction"].getNavInstruction().getSpeedLimitSign(); + float speed_limit = sm["navInstruction"].getValid() ? sm["navInstruction"].getNavInstruction().getSpeedLimit() : 0.0; + speed_limit *= (s.scene.is_metric ? MS_TO_KPH : MS_TO_MPH); + + setProperty("speedLimit", speed_limit); + setProperty("has_us_speed_limit", speed_limit > 1 && speed_limit_sign == cereal::NavInstruction::SpeedLimitSign::MUTCD); + setProperty("has_eu_speed_limit", speed_limit > 1 && speed_limit_sign == cereal::NavInstruction::SpeedLimitSign::VIENNA); + setProperty("is_cruise_set", cruise_set); - setProperty("speed", QString::number(std::nearbyint(cur_speed))); - setProperty("maxSpeed", maxspeed_str); + setProperty("speed", cur_speed); + setProperty("setSpeed", set_speed); setProperty("speedUnit", s.scene.is_metric ? "km/h" : "mph"); setProperty("hideDM", cs.getAlertSize() != cereal::ControlsState::AlertSize::NONE); setProperty("status", s.status); @@ -205,26 +212,139 @@ void NvgWindow::drawHud(QPainter &p) { bg.setColorAt(1, QColor::fromRgbF(0, 0, 0, 0)); p.fillRect(0, 0, width(), header_h, bg); - // max speed - QRect rc(bdr_s * 2, bdr_s * 1.5, 184, 202); - p.setPen(QPen(QColor(0xff, 0xff, 0xff, 100), 10)); - p.setBrush(QColor(0, 0, 0, 100)); - p.drawRoundedRect(rc, 20, 20); - p.setPen(Qt::NoPen); + QString speedLimitStr = QString::number(std::nearbyint(speedLimit)); + QString speedStr = QString::number(std::nearbyint(speed)); + QString setSpeedStr = is_cruise_set ? QString::number(std::nearbyint(setSpeed)) : "–"; + + // Draw outer box + border to contain set speed and speed limit + int default_rect_width = 172; + int rect_width = default_rect_width; + if (has_us_speed_limit && speedLimitStr.size() >= 3) rect_width = 223; + else if (has_eu_speed_limit) rect_width = 200; - configFont(p, "Open Sans", 48, "Regular"); - drawText(p, rc.center().x(), 118, "MAX", is_cruise_set ? 200 : 100); + int rect_height = 204; + if (has_us_speed_limit) rect_height = 402; + else if (has_eu_speed_limit) rect_height = 392; + + int top_radius = 32; + int bottom_radius = has_eu_speed_limit ? 100 : 32; + + QRect set_speed_rect(60 + default_rect_width / 2 - rect_width / 2, 45, rect_width, rect_height); + p.setPen(QPen(whiteColor(75), 6)); + p.setBrush(blackColor(166)); + drawRoundedRect(p, set_speed_rect, top_radius, top_radius, bottom_radius, bottom_radius); + + // Draw set speed if (is_cruise_set) { - configFont(p, "Open Sans", 88, "Bold"); - drawText(p, rc.center().x(), 212, maxSpeed, 255); + if (speedLimit > 0 && status != STATUS_DISENGAGED && status != STATUS_OVERRIDE) { + p.setPen(interpColor( + setSpeed, + {speedLimit + 5, speedLimit + 15, speedLimit + 25}, + {whiteColor(), QColor(0xff, 0x95, 0x00, 0xff), QColor(0xff, 0x00, 0x00, 0xff)} + )); + } else { + p.setPen(whiteColor()); + } } else { - configFont(p, "Open Sans", 80, "SemiBold"); - drawText(p, rc.center().x(), 212, maxSpeed, 100); + p.setPen(QColor(0x72, 0x72, 0x72, 0xff)); + } + configFont(p, "Open Sans", 90, "Bold"); + QRect speed_rect = getTextRect(p, Qt::AlignCenter, setSpeedStr); + speed_rect.moveCenter({set_speed_rect.center().x(), 0}); + speed_rect.moveTop(set_speed_rect.top() + 8); + p.drawText(speed_rect, Qt::AlignCenter, setSpeedStr); + + // Draw MAX + if (is_cruise_set) { + if (status == STATUS_DISENGAGED) { + p.setPen(whiteColor()); + } else if (status == STATUS_OVERRIDE) { + p.setPen(QColor(0x91, 0x9b, 0x95, 0xff)); + } else if (speedLimit > 0) { + p.setPen(interpColor( + setSpeed, + {speedLimit + 5, speedLimit + 15, speedLimit + 25}, + {QColor(0x80, 0xd8, 0xa6, 0xff), QColor(0xff, 0xe4, 0xbf, 0xff), QColor(0xff, 0xbf, 0xbf, 0xff)} + )); + } else { + p.setPen(QColor(0x80, 0xd8, 0xa6, 0xff)); + } + } else { + p.setPen(QColor(0xa6, 0xa6, 0xa6, 0xff)); + } + configFont(p, "Open Sans", 40, "SemiBold"); + QRect max_rect = getTextRect(p, Qt::AlignCenter, "MAX"); + max_rect.moveCenter({set_speed_rect.center().x(), 0}); + max_rect.moveTop(set_speed_rect.top() + 123); + p.drawText(max_rect, Qt::AlignCenter, "MAX"); + + // US/Canada (MUTCD style) sign + if (has_us_speed_limit) { + const int border_width = 6; + const int sign_width = (speedLimitStr.size() >= 3) ? 199 : 148; + const int sign_height = 186; + + // White outer square + QRect sign_rect_outer(set_speed_rect.left() + 12, set_speed_rect.bottom() - 11 - sign_height, sign_width, sign_height); + p.setPen(Qt::NoPen); + p.setBrush(whiteColor()); + p.drawRoundedRect(sign_rect_outer, 24, 24); + + // Smaller white square with black border + QRect sign_rect(sign_rect_outer.left() + 1.5 * border_width, sign_rect_outer.top() + 1.5 * border_width, sign_width - 3 * border_width, sign_height - 3 * border_width); + p.setPen(QPen(blackColor(), border_width)); + p.setBrush(whiteColor()); + p.drawRoundedRect(sign_rect, 16, 16); + + // "SPEED" + configFont(p, "Open Sans", 28, "SemiBold"); + QRect text_speed_rect = getTextRect(p, Qt::AlignCenter, "SPEED"); + text_speed_rect.moveCenter({sign_rect.center().x(), 0}); + text_speed_rect.moveTop(sign_rect_outer.top() + 20); + p.drawText(text_speed_rect, Qt::AlignCenter, "SPEED"); + + // "LIMIT" + QRect text_limit_rect = getTextRect(p, Qt::AlignCenter, "LIMIT"); + text_limit_rect.moveCenter({sign_rect.center().x(), 0}); + text_limit_rect.moveTop(sign_rect_outer.top() + 48); + p.drawText(text_limit_rect, Qt::AlignCenter, "LIMIT"); + + // Speed limit value + configFont(p, "Open Sans", 70, "Bold"); + QRect speed_limit_rect = getTextRect(p, Qt::AlignCenter, speedLimitStr); + speed_limit_rect.moveCenter({sign_rect.center().x(), 0}); + speed_limit_rect.moveTop(sign_rect.top() + 70); + p.drawText(speed_limit_rect, Qt::AlignCenter, speedLimitStr); + } + + // EU (Vienna style) sign + if (has_eu_speed_limit) { + int outer_radius = 176 / 2; + int inner_radius_1 = outer_radius - 6; // White outer border + int inner_radius_2 = inner_radius_1 - 20; // Red circle + + // Draw white circle with red border + QPoint center(set_speed_rect.center().x() + 1, set_speed_rect.top() + 204 + outer_radius); + p.setPen(Qt::NoPen); + p.setBrush(whiteColor()); + p.drawEllipse(center, outer_radius, outer_radius); + p.setBrush(QColor(255, 0, 0, 255)); + p.drawEllipse(center, inner_radius_1, inner_radius_1); + p.setBrush(whiteColor()); + p.drawEllipse(center, inner_radius_2, inner_radius_2); + + // Speed limit value + int font_size = (speedLimitStr.size() >= 3) ? 62 : 70; + configFont(p, "Open Sans", font_size, "Bold"); + QRect speed_limit_rect = getTextRect(p, Qt::AlignCenter, speedLimitStr); + speed_limit_rect.moveCenter(center); + p.setPen(blackColor()); + p.drawText(speed_limit_rect, Qt::AlignCenter, speedLimitStr); } // current speed configFont(p, "Open Sans", 176, "Bold"); - drawText(p, rect().center().x(), 210, speed); + drawText(p, rect().center().x(), 210, speedStr); configFont(p, "Open Sans", 66, "Regular"); drawText(p, rect().center().x(), 290, speedUnit, 200); @@ -237,15 +357,13 @@ void NvgWindow::drawHud(QPainter &p) { // dm icon if (!hideDM) { drawIcon(p, radius / 2 + (bdr_s * 2), rect().bottom() - footer_h / 2, - dm_img, QColor(0, 0, 0, 70), dmActive ? 1.0 : 0.2); + dm_img, blackColor(70), dmActive ? 1.0 : 0.2); } p.restore(); } void NvgWindow::drawText(QPainter &p, int x, int y, const QString &text, int alpha) { - QFontMetrics fm(p.font()); - QRect init_rect = fm.boundingRect(text); - QRect real_rect = fm.boundingRect(init_rect, 0, text); + QRect real_rect = getTextRect(p, 0, text); real_rect.moveCenter({x, y - real_rect.height() / 2}); p.setPen(QColor(0xff, 0xff, 0xff, alpha)); @@ -294,6 +412,8 @@ void NvgWindow::updateFrameMat(int w, int h) { } void NvgWindow::drawLaneLines(QPainter &painter, const UIState *s) { + painter.save(); + const UIScene &scene = s->scene; // lanelines for (int i = 0; i < std::size(scene.lane_line_vertices); ++i) { @@ -309,29 +429,28 @@ void NvgWindow::drawLaneLines(QPainter &painter, const UIState *s) { // paint path QLinearGradient bg(0, height(), 0, height() / 4); - if (scene.end_to_end) { - const auto &orientation = (*s->sm)["modelV2"].getModelV2().getOrientation(); - float orientation_future = 0; - if (orientation.getZ().size() > 16) { - orientation_future = std::abs(orientation.getZ()[16]); // 2.5 seconds - } - // straight: 112, in turns: 70 - float curve_hue = fmax(70, 112 - (orientation_future * 420)); - // FIXME: painter.drawPolygon can be slow if hue is not rounded - curve_hue = int(curve_hue * 100 + 0.5) / 100; - - bg.setColorAt(0.0, QColor::fromHslF(148 / 360., 0.94, 0.51, 0.4)); - bg.setColorAt(0.75 / 1.5, QColor::fromHslF(curve_hue / 360., 1.0, 0.68, 0.35)); - bg.setColorAt(1.0, QColor::fromHslF(curve_hue / 360., 1.0, 0.68, 0.0)); - } else { - bg.setColorAt(0, whiteColor()); - bg.setColorAt(1, whiteColor(0)); + const auto &orientation = (*s->sm)["modelV2"].getModelV2().getOrientation(); + float orientation_future = 0; + if (orientation.getZ().size() > 16) { + orientation_future = std::abs(orientation.getZ()[16]); // 2.5 seconds } + // straight: 112, in turns: 70 + float curve_hue = fmax(70, 112 - (orientation_future * 420)); + // FIXME: painter.drawPolygon can be slow if hue is not rounded + curve_hue = int(curve_hue * 100 + 0.5) / 100; + + bg.setColorAt(0.0, QColor::fromHslF(148 / 360., 0.94, 0.51, 0.4)); + bg.setColorAt(0.75 / 1.5, QColor::fromHslF(curve_hue / 360., 1.0, 0.68, 0.35)); + bg.setColorAt(1.0, QColor::fromHslF(curve_hue / 360., 1.0, 0.68, 0.0)); painter.setBrush(bg); painter.drawPolygon(scene.track_vertices.v, scene.track_vertices.cnt); + + painter.restore(); } void NvgWindow::drawLead(QPainter &painter, const cereal::ModelDataV2::LeadDataV3::Reader &lead_data, const QPointF &vd) { + painter.save(); + const float speedBuff = 10.; const float leadBuff = 40.; const float d_rel = lead_data.getX()[0]; @@ -361,24 +480,26 @@ void NvgWindow::drawLead(QPainter &painter, const cereal::ModelDataV2::LeadDataV QPointF chevron[] = {{x + (sz * 1.25), y + sz}, {x, y}, {x - (sz * 1.25), y + sz}}; painter.setBrush(redColor(fillAlpha)); painter.drawPolygon(chevron, std::size(chevron)); + + painter.restore(); } void NvgWindow::paintGL() { + UIState *s = uiState(); + const cereal::ModelDataV2::Reader &model = (*s->sm)["modelV2"].getModelV2(); + CameraViewWidget::setFrameId(model.getFrameId()); CameraViewWidget::paintGL(); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setPen(Qt::NoPen); - drawHud(painter); - - UIState *s = uiState(); if (s->worldObjectsVisible()) { drawLaneLines(painter, s); if (s->scene.longitudinal_control) { - auto leads = (*s->sm)["modelV2"].getModelV2().getLeadsV3(); + const auto leads = model.getLeadsV3(); if (leads[0].getProb() > .5) { drawLead(painter, leads[0], s->scene.lead_vertices[0]); } @@ -388,6 +509,8 @@ void NvgWindow::paintGL() { } } + drawHud(painter); + double cur_draw_t = millis_since_boot(); double dt = cur_draw_t - prev_draw_t; double fps = fps_filter.update(1. / dt * 1000); diff --git a/selfdrive/ui/qt/onroad.h b/selfdrive/ui/qt/onroad.h index f4c62d1c7d..e58d7a7972 100644 --- a/selfdrive/ui/qt/onroad.h +++ b/selfdrive/ui/qt/onroad.h @@ -3,7 +3,7 @@ #include #include -#include "selfdrive/common/util.h" +#include "common/util.h" #include "selfdrive/ui/qt/widgets/cameraview.h" #include "selfdrive/ui/ui.h" @@ -27,10 +27,14 @@ private: // container window for the NVG UI class NvgWindow : public CameraViewWidget { Q_OBJECT - Q_PROPERTY(QString speed MEMBER speed); + Q_PROPERTY(float speed MEMBER speed); Q_PROPERTY(QString speedUnit MEMBER speedUnit); - Q_PROPERTY(QString maxSpeed MEMBER maxSpeed); + Q_PROPERTY(float setSpeed MEMBER setSpeed); + Q_PROPERTY(float speedLimit MEMBER speedLimit); Q_PROPERTY(bool is_cruise_set MEMBER is_cruise_set); + Q_PROPERTY(bool has_eu_speed_limit MEMBER has_eu_speed_limit); + Q_PROPERTY(bool has_us_speed_limit MEMBER has_us_speed_limit); + Q_PROPERTY(bool engageable MEMBER engageable); Q_PROPERTY(bool dmActive MEMBER dmActive); Q_PROPERTY(bool hideDM MEMBER hideDM); @@ -48,13 +52,16 @@ private: QPixmap dm_img; const int radius = 192; const int img_size = (radius / 2) * 1.5; - QString speed; + float speed; QString speedUnit; - QString maxSpeed; + float setSpeed; + float speedLimit; bool is_cruise_set = false; bool engageable = false; bool dmActive = false; bool hideDM = false; + bool has_us_speed_limit = false; + bool has_eu_speed_limit = false; int status = STATUS_DISENGAGED; protected: @@ -67,6 +74,7 @@ protected: void drawHud(QPainter &p); inline QColor redColor(int alpha = 255) { return QColor(201, 34, 49, alpha); } inline QColor whiteColor(int alpha = 255) { return QColor(255, 255, 255, alpha); } + inline QColor blackColor(int alpha = 255) { return QColor(0, 0, 0, alpha); } double prev_draw_t = 0; FirstOrderFilter fps_filter; diff --git a/selfdrive/ui/qt/qt_window.h b/selfdrive/ui/qt/qt_window.h index 2c9a24e55b..02d127e7ff 100644 --- a/selfdrive/ui/qt/qt_window.h +++ b/selfdrive/ui/qt/qt_window.h @@ -12,7 +12,7 @@ #include #endif -#include "selfdrive/hardware/hw.h" +#include "system/hardware/hw.h" const QString ASSET_PATH = ":/"; diff --git a/selfdrive/ui/qt/request_repeater.h b/selfdrive/ui/qt/request_repeater.h index fa80100d22..c0e2758273 100644 --- a/selfdrive/ui/qt/request_repeater.h +++ b/selfdrive/ui/qt/request_repeater.h @@ -1,6 +1,6 @@ #pragma once -#include "selfdrive/common/util.h" +#include "common/util.h" #include "selfdrive/ui/qt/api.h" #include "selfdrive/ui/ui.h" diff --git a/selfdrive/ui/qt/setup/setup.cc b/selfdrive/ui/qt/setup/setup.cc index 17304665c7..10a2d05f34 100644 --- a/selfdrive/ui/qt/setup/setup.cc +++ b/selfdrive/ui/qt/setup/setup.cc @@ -10,8 +10,8 @@ #include -#include "selfdrive/common/util.h" -#include "selfdrive/hardware/hw.h" +#include "common/util.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/qt/api.h" #include "selfdrive/ui/qt/qt_window.h" #include "selfdrive/ui/qt/offroad/networking.h" diff --git a/selfdrive/ui/qt/setup/updater.cc b/selfdrive/ui/qt/setup/updater.cc index b906b5739d..6e8189f4ba 100644 --- a/selfdrive/ui/qt/setup/updater.cc +++ b/selfdrive/ui/qt/setup/updater.cc @@ -2,7 +2,7 @@ #include #include -#include "selfdrive/hardware/hw.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/qt_window.h" #include "selfdrive/ui/qt/setup/updater.h" diff --git a/selfdrive/ui/qt/sidebar.cc b/selfdrive/ui/qt/sidebar.cc index cdce7b8281..312d8d8a59 100644 --- a/selfdrive/ui/qt/sidebar.cc +++ b/selfdrive/ui/qt/sidebar.cc @@ -57,7 +57,7 @@ void Sidebar::updateState(const UIState &s) { ItemStatus connectStatus; auto last_ping = deviceState.getLastAthenaPingTime(); if (last_ping == 0) { - connectStatus = params.getBool("PrimeRedirected") ? ItemStatus{"NO\nPRIME", danger_color} : ItemStatus{"CONNECT\nOFFLINE", warning_color}; + connectStatus = ItemStatus{"CONNECT\nOFFLINE", warning_color}; } else { connectStatus = nanos_since_boot() - last_ping < 80e9 ? ItemStatus{"CONNECT\nONLINE", good_color} : ItemStatus{"CONNECT\nERROR", danger_color}; } diff --git a/selfdrive/ui/qt/sidebar.h b/selfdrive/ui/qt/sidebar.h index 5d1b921750..ab3e990e61 100644 --- a/selfdrive/ui/qt/sidebar.h +++ b/selfdrive/ui/qt/sidebar.h @@ -3,7 +3,7 @@ #include #include -#include "selfdrive/common/params.h" +#include "common/params.h" #include "selfdrive/ui/ui.h" typedef QPair ItemStatus; diff --git a/selfdrive/ui/qt/spinner.cc b/selfdrive/ui/qt/spinner.cc index e0b263227b..8f13576fb2 100644 --- a/selfdrive/ui/qt/spinner.cc +++ b/selfdrive/ui/qt/spinner.cc @@ -10,7 +10,7 @@ #include #include -#include "selfdrive/hardware/hw.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/qt/qt_window.h" #include "selfdrive/ui/qt/util.h" diff --git a/selfdrive/ui/qt/text.cc b/selfdrive/ui/qt/text.cc index 04fda35483..ac8e7bcd18 100644 --- a/selfdrive/ui/qt/text.cc +++ b/selfdrive/ui/qt/text.cc @@ -5,7 +5,7 @@ #include #include -#include "selfdrive/hardware/hw.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/qt_window.h" #include "selfdrive/ui/qt/widgets/scrollview.h" diff --git a/selfdrive/ui/qt/util.cc b/selfdrive/ui/qt/util.cc index e38052ea59..366aa76f49 100644 --- a/selfdrive/ui/qt/util.cc +++ b/selfdrive/ui/qt/util.cc @@ -3,10 +3,11 @@ #include #include #include +#include -#include "selfdrive/common/params.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/hardware/hw.h" +#include "common/params.h" +#include "common/swaglog.h" +#include "system/hardware/hw.h" QString getVersion() { static QString version = QString::fromStdString(Params().get("Version")); @@ -135,3 +136,64 @@ QPixmap loadPixmap(const QString &fileName, const QSize &size, Qt::AspectRatioMo return QPixmap(fileName).scaled(size, aspectRatioMode, Qt::SmoothTransformation); } } + +QRect getTextRect(QPainter &p, int flags, QString text) { + QFontMetrics fm(p.font()); + QRect init_rect = fm.boundingRect(text); + return fm.boundingRect(init_rect, flags, text); +} + +void drawRoundedRect(QPainter &painter, const QRectF &rect, qreal xRadiusTop, qreal yRadiusTop, qreal xRadiusBottom, qreal yRadiusBottom){ + qreal w_2 = rect.width() / 2; + qreal h_2 = rect.height() / 2; + + xRadiusTop = 100 * qMin(xRadiusTop, w_2) / w_2; + yRadiusTop = 100 * qMin(yRadiusTop, h_2) / h_2; + + xRadiusBottom = 100 * qMin(xRadiusBottom, w_2) / w_2; + yRadiusBottom = 100 * qMin(yRadiusBottom, h_2) / h_2; + + qreal x = rect.x(); + qreal y = rect.y(); + qreal w = rect.width(); + qreal h = rect.height(); + + qreal rxx2Top = w*xRadiusTop/100; + qreal ryy2Top = h*yRadiusTop/100; + + qreal rxx2Bottom = w*xRadiusBottom/100; + qreal ryy2Bottom = h*yRadiusBottom/100; + + QPainterPath path; + path.arcMoveTo(x, y, rxx2Top, ryy2Top, 180); + path.arcTo(x, y, rxx2Top, ryy2Top, 180, -90); + path.arcTo(x+w-rxx2Top, y, rxx2Top, ryy2Top, 90, -90); + path.arcTo(x+w-rxx2Bottom, y+h-ryy2Bottom, rxx2Bottom, ryy2Bottom, 0, -90); + path.arcTo(x, y+h-ryy2Bottom, rxx2Bottom, ryy2Bottom, 270, -90); + path.closeSubpath(); + + painter.drawPath(path); +} + +QColor interpColor(float xv, std::vector xp, std::vector fp) { + assert(xp.size() == fp.size()); + + int N = xp.size(); + int hi = 0; + + while (hi < N and xv > xp[hi]) hi++; + int low = hi - 1; + + if (hi == N && xv > xp[low]) { + return fp[fp.size() - 1]; + } else if (hi == 0){ + return fp[0]; + } else { + return QColor( + (xv - xp[low]) * (fp[hi].red() - fp[low].red()) / (xp[hi] - xp[low]) + fp[low].red(), + (xv - xp[low]) * (fp[hi].green() - fp[low].green()) / (xp[hi] - xp[low]) + fp[low].green(), + (xv - xp[low]) * (fp[hi].blue() - fp[low].blue()) / (xp[hi] - xp[low]) + fp[low].blue(), + (xv - xp[low]) * (fp[hi].alpha() - fp[low].alpha()) / (xp[hi] - xp[low]) + fp[low].alpha() + ); + } +} diff --git a/selfdrive/ui/qt/util.h b/selfdrive/ui/qt/util.h index 813777710a..9491c6798e 100644 --- a/selfdrive/ui/qt/util.h +++ b/selfdrive/ui/qt/util.h @@ -22,3 +22,7 @@ void swagLogMessageHandler(QtMsgType type, const QMessageLogContext &context, co void initApp(int argc, char *argv[]); QWidget* topWidget (QWidget* widget); QPixmap loadPixmap(const QString &fileName, const QSize &size = {}, Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio); + +QRect getTextRect(QPainter &p, int flags, QString text); +void drawRoundedRect(QPainter &painter, const QRectF &rect, qreal xRadiusTop, qreal yRadiusTop, qreal xRadiusBottom, qreal yRadiusBottom); +QColor interpColor(float xv, std::vector xp, std::vector fp); diff --git a/selfdrive/ui/qt/widgets/cameraview.cc b/selfdrive/ui/qt/widgets/cameraview.cc index d817d55568..000ac48475 100644 --- a/selfdrive/ui/qt/widgets/cameraview.cc +++ b/selfdrive/ui/qt/widgets/cameraview.cc @@ -13,7 +13,7 @@ namespace { const char frame_vertex_shader[] = #ifdef __APPLE__ - "#version 150 core\n" + "#version 330 core\n" #else "#version 300 es\n" #endif @@ -26,27 +26,38 @@ const char frame_vertex_shader[] = " vTexCoord = aTexCoord;\n" "}\n"; +#ifdef QCOM2 +const char frame_fragment_shader[] = + "#version 300 es\n" + "#extension GL_OES_EGL_image_external_essl3 : enable\n" + "precision mediump float;\n" + "uniform samplerExternalOES uTexture;\n" + "in vec2 vTexCoord;\n" + "out vec4 colorOut;\n" + "void main() {\n" + " colorOut = texture(uTexture, vTexCoord);\n" + "}\n"; +#else const char frame_fragment_shader[] = #ifdef __APPLE__ - "#version 150 core\n" + "#version 330 core\n" #else "#version 300 es\n" "precision mediump float;\n" #endif "uniform sampler2D uTextureY;\n" - "uniform sampler2D uTextureU;\n" - "uniform sampler2D uTextureV;\n" + "uniform sampler2D uTextureUV;\n" "in vec2 vTexCoord;\n" "out vec4 colorOut;\n" "void main() {\n" " float y = texture(uTextureY, vTexCoord).r;\n" - " float u = texture(uTextureU, vTexCoord).r - 0.5;\n" - " float v = texture(uTextureV, vTexCoord).r - 0.5;\n" - " float r = y + 1.402 * v;\n" - " float g = y - 0.344 * u - 0.714 * v;\n" - " float b = y + 1.772 * u;\n" + " vec2 uv = texture(uTextureUV, vTexCoord).rg - 0.5;\n" + " float r = y + 1.402 * uv.y;\n" + " float g = y - 0.344 * uv.x - 0.714 * uv.y;\n" + " float b = y + 1.772 * uv.x;\n" " colorOut = vec4(r, g, b, 1.0);\n" "}\n"; +#endif const mat4 device_transform = {{ 1.0, 0.0, 0.0, 0.0, @@ -57,25 +68,15 @@ const mat4 device_transform = {{ mat4 get_driver_view_transform(int screen_width, int screen_height, int stream_width, int stream_height) { const float driver_view_ratio = 1.333; - mat4 transform; - if (stream_width == TICI_CAM_WIDTH) { - const float yscale = stream_height * driver_view_ratio / tici_dm_crop::width; - const float xscale = yscale*screen_height/screen_width*stream_width/stream_height; - transform = (mat4){{ - xscale, 0.0, 0.0, xscale*tici_dm_crop::x_offset/stream_width*2, - 0.0, yscale, 0.0, yscale*tici_dm_crop::y_offset/stream_height*2, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, - }}; - } else { - // frame from 4/3 to 16/9 display - transform = (mat4){{ - driver_view_ratio * screen_height / screen_width, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, - }}; - } + const float yscale = stream_height * driver_view_ratio / tici_dm_crop::width; + const float xscale = yscale*screen_height/screen_width*stream_width/stream_height; + mat4 transform = (mat4){{ + xscale, 0.0, 0.0, xscale*tici_dm_crop::x_offset/stream_width*2, + 0.0, yscale, 0.0, yscale*tici_dm_crop::y_offset/stream_height*2, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + }}; + return transform; } @@ -111,7 +112,7 @@ CameraViewWidget::~CameraViewWidget() { glDeleteVertexArrays(1, &frame_vao); glDeleteBuffers(1, &frame_vbo); glDeleteBuffers(1, &frame_ibo); - glDeleteBuffers(3, textures); + glDeleteBuffers(2, textures); } doneCurrent(); } @@ -155,15 +156,19 @@ void CameraViewWidget::initializeGL() { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); - glGenTextures(3, textures); glUseProgram(program->programId()); + +#ifdef QCOM2 + glUniform1i(program->uniformLocation("uTexture"), 0); +#else + glGenTextures(2, textures); glUniform1i(program->uniformLocation("uTextureY"), 0); - glUniform1i(program->uniformLocation("uTextureU"), 1); - glUniform1i(program->uniformLocation("uTextureV"), 2); + glUniform1i(program->uniformLocation("uTextureUV"), 1); +#endif } void CameraViewWidget::showEvent(QShowEvent *event) { - latest_frame = nullptr; + frames.clear(); if (!vipc_thread) { vipc_thread = new QThread(); connect(vipc_thread, &QThread::started, [=]() { vipcThread(); }); @@ -214,73 +219,119 @@ void CameraViewWidget::paintGL() { glClearColor(bg.redF(), bg.greenF(), bg.blueF(), bg.alphaF()); glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - std::lock_guard lk(lock); - - if (latest_frame == nullptr) return; + if (frames.empty()) return; - glViewport(0, 0, width(), height()); - // sync with the PBO - if (wait_fence) { - wait_fence->wait(); + int frame_idx; + for (frame_idx = 0; frame_idx < frames.size() - 1; frame_idx++) { + if (frames[frame_idx].first == draw_frame_id) break; } + glViewport(0, 0, width(), height()); glBindVertexArray(frame_vao); - glUseProgram(program->programId()); - uint8_t *address[3] = {latest_frame->y, latest_frame->u, latest_frame->v}; - for (int i = 0; i < 3; ++i) { - glActiveTexture(GL_TEXTURE0 + i); - glBindTexture(GL_TEXTURE_2D, textures[i]); - int width = i == 0 ? stream_width : stream_width / 2; - int height = i == 0 ? stream_height : stream_height / 2; - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, address[i]); - assert(glGetError() == GL_NO_ERROR); - } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glUniformMatrix4fv(program->uniformLocation("uTransform"), 1, GL_TRUE, frame_mat.v); + VisionBuf *frame = frames[frame_idx].second; + +#ifdef QCOM2 + glActiveTexture(GL_TEXTURE0); + glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_images[frame->idx]); + assert(glGetError() == GL_NO_ERROR); +#else + glPixelStorei(GL_UNPACK_ROW_LENGTH, stream_stride); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textures[0]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, stream_width, stream_height, GL_RED, GL_UNSIGNED_BYTE, frame->y); assert(glGetError() == GL_NO_ERROR); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, stream_stride/2); + glActiveTexture(GL_TEXTURE0 + 1); + glBindTexture(GL_TEXTURE_2D, textures[1]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, stream_width/2, stream_height/2, GL_RG, GL_UNSIGNED_BYTE, frame->uv); + assert(glGetError() == GL_NO_ERROR); +#endif + + glUniformMatrix4fv(program->uniformLocation("uTransform"), 1, GL_TRUE, frame_mat.v); glEnableVertexAttribArray(0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (const void *)0); glDisableVertexAttribArray(0); glBindVertexArray(0); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } void CameraViewWidget::vipcConnected(VisionIpcClient *vipc_client) { makeCurrent(); - latest_frame = nullptr; + frames.clear(); stream_width = vipc_client->buffers[0].width; stream_height = vipc_client->buffers[0].height; + stream_stride = vipc_client->buffers[0].stride; + +#ifdef QCOM2 + egl_display = eglGetCurrentDisplay(); - for (int i = 0; i < 3; ++i) { - glBindTexture(GL_TEXTURE_2D, textures[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - int width = i == 0 ? stream_width : stream_width / 2; - int height = i == 0 ? stream_height : stream_height / 2; - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr); - assert(glGetError() == GL_NO_ERROR); + for (auto &pair : egl_images) { + eglDestroyImageKHR(egl_display, pair.second); } + egl_images.clear(); + + for (int i = 0; i < vipc_client->num_buffers; i++) { // import buffers into OpenGL + int fd = dup(vipc_client->buffers[i].fd); // eglDestroyImageKHR will close, so duplicate + EGLint img_attrs[] = { + EGL_WIDTH, (int)vipc_client->buffers[i].width, + EGL_HEIGHT, (int)vipc_client->buffers[i].height, + EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_NV12, + EGL_DMA_BUF_PLANE0_FD_EXT, fd, + EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, + EGL_DMA_BUF_PLANE0_PITCH_EXT, (int)vipc_client->buffers[i].stride, + EGL_DMA_BUF_PLANE1_FD_EXT, fd, + EGL_DMA_BUF_PLANE1_OFFSET_EXT, (int)vipc_client->buffers[i].uv_offset, + EGL_DMA_BUF_PLANE1_PITCH_EXT, (int)vipc_client->buffers[i].stride, + EGL_NONE + }; + egl_images[i] = eglCreateImageKHR(egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, 0, img_attrs); + assert(eglGetError() == EGL_SUCCESS); + } +#else + glBindTexture(GL_TEXTURE_2D, textures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, stream_width, stream_height, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr); + assert(glGetError() == GL_NO_ERROR); + + glBindTexture(GL_TEXTURE_2D, textures[1]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, stream_width/2, stream_height/2, 0, GL_RG, GL_UNSIGNED_BYTE, nullptr); + assert(glGetError() == GL_NO_ERROR); +#endif updateFrameMat(width(), height()); } -void CameraViewWidget::vipcFrameReceived(VisionBuf *buf) { - latest_frame = buf; +void CameraViewWidget::vipcFrameReceived(VisionBuf *buf, uint32_t frame_id) { + frames.push_back(std::make_pair(frame_id, buf)); + while (frames.size() > FRAME_BUFFER_SIZE) { + frames.pop_front(); + } update(); } void CameraViewWidget::vipcThread() { VisionStreamType cur_stream_type = stream_type; std::unique_ptr vipc_client; + VisionIpcBufExtra meta_main = {0}; while (!QThread::currentThread()->isInterruptionRequested()) { if (!vipc_client || cur_stream_type != stream_type) { cur_stream_type = stream_type; - vipc_client.reset(new VisionIpcClient(stream_name, cur_stream_type, true)); + vipc_client.reset(new VisionIpcClient(stream_name, cur_stream_type, false)); } if (!vipc_client->connected) { @@ -291,8 +342,15 @@ void CameraViewWidget::vipcThread() { emit vipcThreadConnected(vipc_client.get()); } - if (VisionBuf *buf = vipc_client->recv(nullptr, 1000)) { - emit vipcThreadFrameReceived(buf); + if (VisionBuf *buf = vipc_client->recv(&meta_main, 1000)) { + emit vipcThreadFrameReceived(buf, meta_main.frame_id); } } + +#ifdef QCOM2 + for (auto &pair : egl_images) { + eglDestroyImageKHR(egl_display, pair.second); + } + egl_images.clear(); +#endif } diff --git a/selfdrive/ui/qt/widgets/cameraview.h b/selfdrive/ui/qt/widgets/cameraview.h index 1f19ea157b..ddc3fc253b 100644 --- a/selfdrive/ui/qt/widgets/cameraview.h +++ b/selfdrive/ui/qt/widgets/cameraview.h @@ -6,10 +6,23 @@ #include #include #include + +#ifdef QCOM2 +#define EGL_EGLEXT_PROTOTYPES +#define EGL_NO_X11 +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#include +#include +#include +#endif + #include "cereal/visionipc/visionipc_client.h" #include "selfdrive/camerad/cameras/camera_common.h" #include "selfdrive/ui/ui.h" +const int FRAME_BUFFER_SIZE = 5; +static_assert(FRAME_BUFFER_SIZE <= YUV_BUFFER_COUNT); + class CameraViewWidget : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT @@ -19,11 +32,12 @@ public: ~CameraViewWidget(); void setStreamType(VisionStreamType type) { stream_type = type; } void setBackgroundColor(const QColor &color) { bg = color; } + void setFrameId(int frame_id) { draw_frame_id = frame_id; } signals: void clicked(); void vipcThreadConnected(VisionIpcClient *); - void vipcThreadFrameReceived(VisionBuf *); + void vipcThreadFrameReceived(VisionBuf *, quint32); protected: void paintGL() override; @@ -35,31 +49,29 @@ protected: virtual void updateFrameMat(int w, int h); void vipcThread(); - struct WaitFence { - WaitFence() { sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); } - ~WaitFence() { glDeleteSync(sync); } - void wait() { glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); } - GLsync sync = 0; - }; - bool zoomed_view; - std::mutex lock; - VisionBuf *latest_frame = nullptr; GLuint frame_vao, frame_vbo, frame_ibo; + GLuint textures[2]; mat4 frame_mat; - std::unique_ptr wait_fence; std::unique_ptr program; QColor bg = QColor("#000000"); +#ifdef QCOM2 + EGLDisplay egl_display; + std::map egl_images; +#endif + std::string stream_name; int stream_width = 0; int stream_height = 0; + int stream_stride = 0; std::atomic stream_type; QThread *vipc_thread = nullptr; - GLuint textures[3]; + std::deque> frames; + uint32_t draw_frame_id = 0; protected slots: void vipcConnected(VisionIpcClient *vipc_client); - void vipcFrameReceived(VisionBuf *vipc_client); + void vipcFrameReceived(VisionBuf *vipc_client, uint32_t frame_id); }; diff --git a/selfdrive/ui/qt/widgets/controls.h b/selfdrive/ui/qt/widgets/controls.h index 024cefbb70..b6684e28b2 100644 --- a/selfdrive/ui/qt/widgets/controls.h +++ b/selfdrive/ui/qt/widgets/controls.h @@ -6,7 +6,7 @@ #include #include -#include "selfdrive/common/params.h" +#include "common/params.h" #include "selfdrive/ui/qt/widgets/toggle.h" QFrame *horizontal_line(QWidget *parent = nullptr); diff --git a/selfdrive/ui/qt/widgets/drive_stats.cc b/selfdrive/ui/qt/widgets/drive_stats.cc index f4c8f502a3..61d47db1c3 100644 --- a/selfdrive/ui/qt/widgets/drive_stats.cc +++ b/selfdrive/ui/qt/widgets/drive_stats.cc @@ -5,7 +5,7 @@ #include #include -#include "selfdrive/common/params.h" +#include "common/params.h" #include "selfdrive/ui/qt/request_repeater.h" #include "selfdrive/ui/qt/util.h" diff --git a/selfdrive/ui/qt/widgets/input.cc b/selfdrive/ui/qt/widgets/input.cc index 1122faf4c7..8a5d492804 100644 --- a/selfdrive/ui/qt/widgets/input.cc +++ b/selfdrive/ui/qt/widgets/input.cc @@ -2,7 +2,7 @@ #include -#include "selfdrive/hardware/hw.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/qt_window.h" #include "selfdrive/ui/qt/widgets/scrollview.h" diff --git a/selfdrive/ui/qt/widgets/offroad_alerts.cc b/selfdrive/ui/qt/widgets/offroad_alerts.cc index 2d7ae39c36..433193df5d 100644 --- a/selfdrive/ui/qt/widgets/offroad_alerts.cc +++ b/selfdrive/ui/qt/widgets/offroad_alerts.cc @@ -4,8 +4,8 @@ #include #include -#include "selfdrive/common/util.h" -#include "selfdrive/hardware/hw.h" +#include "common/util.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/qt/widgets/scrollview.h" AbstractAlert::AbstractAlert(bool hasRebootBtn, QWidget *parent) : QFrame(parent) { diff --git a/selfdrive/ui/qt/widgets/offroad_alerts.h b/selfdrive/ui/qt/widgets/offroad_alerts.h index 4110bdaa4e..69c12b0602 100644 --- a/selfdrive/ui/qt/widgets/offroad_alerts.h +++ b/selfdrive/ui/qt/widgets/offroad_alerts.h @@ -6,7 +6,7 @@ #include #include -#include "selfdrive/common/params.h" +#include "common/params.h" class AbstractAlert : public QFrame { Q_OBJECT diff --git a/selfdrive/ui/qt/widgets/prime.cc b/selfdrive/ui/qt/widgets/prime.cc index 27d472535b..8a208bf3cf 100644 --- a/selfdrive/ui/qt/widgets/prime.cc +++ b/selfdrive/ui/qt/widgets/prime.cc @@ -198,7 +198,7 @@ PrimeAdWidget::PrimeAdWidget(QWidget* parent) : QFrame(parent) { main_layout->addWidget(features, 0, Qt::AlignBottom); main_layout->addSpacing(30); - QVector bullets = {"Remote access", "14 days of storage", "Developer perks"}; + QVector bullets = {"Remote access", "1 year of storage", "Developer perks"}; for (auto &b: bullets) { const QString check = "✓ "; QLabel *l = new QLabel(check + b); diff --git a/selfdrive/ui/qt/widgets/prime.h b/selfdrive/ui/qt/widgets/prime.h index 566238fc33..ce4baecfa2 100644 --- a/selfdrive/ui/qt/widgets/prime.h +++ b/selfdrive/ui/qt/widgets/prime.h @@ -9,8 +9,10 @@ enum PrimeType { NONE = 0, - MAGENTA, - LITE, + MAGENTA = 1, + LITE = 2, + BLUE = 3, + MAGENTA_NEW = 4, }; // pairing QR code diff --git a/selfdrive/ui/qt/widgets/ssh_keys.cc b/selfdrive/ui/qt/widgets/ssh_keys.cc index 7630e65731..46ccf6aee3 100644 --- a/selfdrive/ui/qt/widgets/ssh_keys.cc +++ b/selfdrive/ui/qt/widgets/ssh_keys.cc @@ -1,6 +1,6 @@ #include "selfdrive/ui/qt/widgets/ssh_keys.h" -#include "selfdrive/common/params.h" +#include "common/params.h" #include "selfdrive/ui/qt/api.h" #include "selfdrive/ui/qt/widgets/input.h" diff --git a/selfdrive/ui/qt/widgets/ssh_keys.h b/selfdrive/ui/qt/widgets/ssh_keys.h index 0614e8c1d8..596d1d83b9 100644 --- a/selfdrive/ui/qt/widgets/ssh_keys.h +++ b/selfdrive/ui/qt/widgets/ssh_keys.h @@ -2,7 +2,7 @@ #include -#include "selfdrive/hardware/hw.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/qt/widgets/controls.h" // SSH enable toggle diff --git a/selfdrive/ui/qt/window.cc b/selfdrive/ui/qt/window.cc index fb21f6f7af..d9613df0d0 100644 --- a/selfdrive/ui/qt/window.cc +++ b/selfdrive/ui/qt/window.cc @@ -2,7 +2,7 @@ #include -#include "selfdrive/hardware/hw.h" +#include "system/hardware/hw.h" MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { main_layout = new QStackedLayout(this); diff --git a/selfdrive/ui/replay/camera.cc b/selfdrive/ui/replay/camera.cc index 9bcc00583e..2e8b68a415 100644 --- a/selfdrive/ui/replay/camera.cc +++ b/selfdrive/ui/replay/camera.cc @@ -3,7 +3,7 @@ #include -CameraServer::CameraServer(std::pair camera_size[MAX_CAMERAS], bool send_yuv) : send_yuv(send_yuv) { +CameraServer::CameraServer(std::pair camera_size[MAX_CAMERAS]) { for (int i = 0; i < MAX_CAMERAS; ++i) { std::tie(cameras_[i].width, cameras_[i].height) = camera_size[i]; } @@ -25,10 +25,7 @@ void CameraServer::startVipcServer() { for (auto &cam : cameras_) { if (cam.width > 0 && cam.height > 0) { rInfo("camera[%d] frame size %dx%d", cam.type, cam.width, cam.height); - vipc_server_->create_buffers(cam.rgb_type, UI_BUF_COUNT, true, cam.width, cam.height); - if (send_yuv) { - vipc_server_->create_buffers(cam.yuv_type, YUV_BUFFER_COUNT, false, cam.width, cam.height); - } + vipc_server_->create_buffers(cam.stream_type, YUV_BUFFER_COUNT, false, cam.width, cam.height); if (!cam.thread.joinable()) { cam.thread = std::thread(&CameraServer::cameraThread, this, std::ref(cam)); } @@ -39,10 +36,9 @@ void CameraServer::startVipcServer() { void CameraServer::cameraThread(Camera &cam) { auto read_frame = [&](FrameReader *fr, int frame_id) { - VisionBuf *rgb_buf = vipc_server_->get_buffer(cam.rgb_type); - VisionBuf *yuv_buf = send_yuv ? vipc_server_->get_buffer(cam.yuv_type) : nullptr; - bool ret = fr->get(frame_id, (uint8_t *)rgb_buf->addr, yuv_buf ? (uint8_t *)yuv_buf->addr : nullptr); - return ret ? std::pair{rgb_buf, yuv_buf} : std::pair{nullptr, nullptr}; + VisionBuf *yuv_buf = vipc_server_->get_buffer(cam.stream_type); + bool ret = fr->get(frame_id, yuv_buf ? (uint8_t *)yuv_buf->addr : nullptr); + return ret ? yuv_buf : nullptr; }; while (true) { @@ -51,15 +47,14 @@ void CameraServer::cameraThread(Camera &cam) { const int id = eidx.getSegmentId(); bool prefetched = (id == cam.cached_id && eidx.getSegmentNum() == cam.cached_seg); - auto [rgb, yuv] = prefetched ? cam.cached_buf : read_frame(fr, id); - if (rgb || yuv) { + auto yuv = prefetched ? cam.cached_buf : read_frame(fr, id); + if (yuv) { VisionIpcBufExtra extra = { .frame_id = eidx.getFrameId(), .timestamp_sof = eidx.getTimestampSof(), .timestamp_eof = eidx.getTimestampEof(), }; - if (rgb) vipc_server_->send(rgb, &extra, false); - if (yuv) vipc_server_->send(yuv, &extra, false); + vipc_server_->send(yuv, &extra, false); } else { rError("camera[%d] failed to get frame:", cam.type, eidx.getSegmentId()); } @@ -77,10 +72,16 @@ void CameraServer::pushFrame(CameraType type, FrameReader *fr, const cereal::Enc if (cam.width != fr->width || cam.height != fr->height) { cam.width = fr->width; cam.height = fr->height; - waitFinish(); + waitForSent(); startVipcServer(); } ++publishing_; cam.queue.push({fr, eidx}); } + +void CameraServer::waitForSent() { + while (publishing_ > 0) { + std::this_thread::yield(); + } +} diff --git a/selfdrive/ui/replay/camera.h b/selfdrive/ui/replay/camera.h index 9d72094d4c..7f078511cf 100644 --- a/selfdrive/ui/replay/camera.h +++ b/selfdrive/ui/replay/camera.h @@ -2,41 +2,37 @@ #include #include "cereal/visionipc/visionipc_server.h" -#include "selfdrive/common/queue.h" +#include "common/queue.h" #include "selfdrive/ui/replay/framereader.h" #include "selfdrive/ui/replay/logreader.h" class CameraServer { public: - CameraServer(std::pair camera_size[MAX_CAMERAS] = nullptr, bool send_yuv = false); + CameraServer(std::pair camera_size[MAX_CAMERAS] = nullptr); ~CameraServer(); void pushFrame(CameraType type, FrameReader* fr, const cereal::EncodeIndex::Reader& eidx); - inline void waitFinish() { - while (publishing_ > 0) usleep(0); - } + void waitForSent(); protected: struct Camera { CameraType type; - VisionStreamType rgb_type; - VisionStreamType yuv_type; + VisionStreamType stream_type; int width; int height; std::thread thread; SafeQueue> queue; int cached_id = -1; int cached_seg = -1; - std::pair cached_buf; + VisionBuf * cached_buf; }; void startVipcServer(); void cameraThread(Camera &cam); Camera cameras_[MAX_CAMERAS] = { - {.type = RoadCam, .rgb_type = VISION_STREAM_RGB_ROAD, .yuv_type = VISION_STREAM_ROAD}, - {.type = DriverCam, .rgb_type = VISION_STREAM_RGB_DRIVER, .yuv_type = VISION_STREAM_DRIVER}, - {.type = WideRoadCam, .rgb_type = VISION_STREAM_RGB_WIDE_ROAD, .yuv_type = VISION_STREAM_WIDE_ROAD}, + {.type = RoadCam, .stream_type = VISION_STREAM_ROAD}, + {.type = DriverCam, .stream_type = VISION_STREAM_DRIVER}, + {.type = WideRoadCam, .stream_type = VISION_STREAM_WIDE_ROAD}, }; std::atomic publishing_ = 0; std::unique_ptr vipc_server_; - bool send_yuv; }; diff --git a/selfdrive/ui/replay/consoleui.cc b/selfdrive/ui/replay/consoleui.cc index fbbc4c15f8..05eb09c9ed 100644 --- a/selfdrive/ui/replay/consoleui.cc +++ b/selfdrive/ui/replay/consoleui.cc @@ -3,7 +3,7 @@ #include #include -#include "selfdrive/common/version.h" +#include "common/version.h" namespace { diff --git a/selfdrive/ui/replay/filereader.cc b/selfdrive/ui/replay/filereader.cc index b57a62d501..5f862bec35 100644 --- a/selfdrive/ui/replay/filereader.cc +++ b/selfdrive/ui/replay/filereader.cc @@ -2,7 +2,7 @@ #include -#include "selfdrive/common/util.h" +#include "common/util.h" #include "selfdrive/ui/replay/util.h" std::string cacheFilePath(const std::string &url) { diff --git a/selfdrive/ui/replay/framereader.cc b/selfdrive/ui/replay/framereader.cc index 3186b4ff3a..8453407ce7 100644 --- a/selfdrive/ui/replay/framereader.cc +++ b/selfdrive/ui/replay/framereader.cc @@ -170,15 +170,15 @@ bool FrameReader::initHardwareDecoder(AVHWDeviceType hw_device_type) { return true; } -bool FrameReader::get(int idx, uint8_t *rgb, uint8_t *yuv) { - assert(rgb || yuv); +bool FrameReader::get(int idx, uint8_t *yuv) { + assert(yuv != nullptr); if (!valid_ || idx < 0 || idx >= packets.size()) { return false; } - return decode(idx, rgb, yuv); + return decode(idx, yuv); } -bool FrameReader::decode(int idx, uint8_t *rgb, uint8_t *yuv) { +bool FrameReader::decode(int idx, uint8_t *yuv) { int from_idx = idx; if (idx != prev_idx + 1 && key_frames_count_ > 1) { // seeking to the nearest key frame @@ -194,7 +194,7 @@ bool FrameReader::decode(int idx, uint8_t *rgb, uint8_t *yuv) { for (int i = from_idx; i <= idx; ++i) { AVFrame *f = decodeFrame(packets[i]); if (f && i == idx) { - return copyBuffers(f, rgb, yuv); + return copyBuffers(f, yuv); } } return false; @@ -226,29 +226,24 @@ AVFrame *FrameReader::decodeFrame(AVPacket *pkt) { } } -bool FrameReader::copyBuffers(AVFrame *f, uint8_t *rgb, uint8_t *yuv) { +bool FrameReader::copyBuffers(AVFrame *f, uint8_t *yuv) { if (hw_pix_fmt == HW_PIX_FMT) { uint8_t *y = yuv ? yuv : nv12toyuv_buffer.data(); - uint8_t *u = y + width * height; - uint8_t *v = u + (width / 2) * (height / 2); - libyuv::NV12ToI420(f->data[0], f->linesize[0], f->data[1], f->linesize[1], - y, width, u, width / 2, v, width / 2, width, height); - libyuv::I420ToRGB24(y, width, u, width / 2, v, width / 2, - rgb, aligned_width * 3, width, height); + uint8_t *uv = y + width * height; + for (int i = 0; i < height/2; i++) { + memcpy(y + (i*2 + 0)*width, f->data[0] + (i*2 + 0)*f->linesize[0], width); + memcpy(y + (i*2 + 1)*width, f->data[0] + (i*2 + 1)*f->linesize[0], width); + memcpy(uv + i*width, f->data[1] + i*f->linesize[1], width); + } } else { - if (yuv) { - uint8_t *u = yuv + width * height; - uint8_t *v = u + (width / 2) * (height / 2); - libyuv::I420Copy(f->data[0], f->linesize[0], + uint8_t *y = yuv ? yuv : nv12toyuv_buffer.data(); + uint8_t *uv = y + width * height; + libyuv::I420ToNV12(f->data[0], f->linesize[0], f->data[1], f->linesize[1], f->data[2], f->linesize[2], - yuv, width, u, width / 2, v, width / 2, + y, width, + uv, width / 2, width, height); - } - libyuv::I420ToRGB24(f->data[0], f->linesize[0], - f->data[1], f->linesize[1], - f->data[2], f->linesize[2], - rgb, aligned_width * 3, width, height); } return true; } diff --git a/selfdrive/ui/replay/framereader.h b/selfdrive/ui/replay/framereader.h index b58aca5f74..443636e27d 100644 --- a/selfdrive/ui/replay/framereader.h +++ b/selfdrive/ui/replay/framereader.h @@ -19,10 +19,10 @@ class FrameReader { public: FrameReader(); ~FrameReader(); - bool load(const std::string &url, bool no_hw_decoder = false, std::atomic *abort = nullptr, bool local_cache = false, int chunk_size = -1, int retries = 0); + bool load(const std::string &url, bool no_hw_decoder = false, std::atomic *abort = nullptr, bool local_cache = false, + int chunk_size = -1, int retries = 0); bool load(const std::byte *data, size_t size, bool no_hw_decoder = false, std::atomic *abort = nullptr); - bool get(int idx, uint8_t *rgb, uint8_t *yuv); - int getRGBSize() const { return aligned_width * aligned_height * 3; } + bool get(int idx, uint8_t *yuv); int getYUVSize() const { return width * height * 3 / 2; } size_t getFrameCount() const { return packets.size(); } bool valid() const { return valid_; } @@ -32,9 +32,9 @@ public: private: bool initHardwareDecoder(AVHWDeviceType hw_device_type); - bool decode(int idx, uint8_t *rgb, uint8_t *yuv); + bool decode(int idx, uint8_t *yuv); AVFrame * decodeFrame(AVPacket *pkt); - bool copyBuffers(AVFrame *f, uint8_t *rgb, uint8_t *yuv); + bool copyBuffers(AVFrame *f, uint8_t *yuv); std::vector packets; std::unique_ptrav_frame_, hw_frame; diff --git a/selfdrive/ui/replay/replay.cc b/selfdrive/ui/replay/replay.cc index 1fdce6fd66..5eb7469c92 100644 --- a/selfdrive/ui/replay/replay.cc +++ b/selfdrive/ui/replay/replay.cc @@ -5,9 +5,9 @@ #include #include "cereal/services.h" -#include "selfdrive/common/params.h" -#include "selfdrive/common/timing.h" -#include "selfdrive/hardware/hw.h" +#include "common/params.h" +#include "common/timing.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/replay/util.h" Replay::Replay(QString route, QStringList allow, QStringList block, SubMaster *sm_, uint32_t flags, QString data_dir, QObject *parent) @@ -275,7 +275,10 @@ void Replay::startStream(const Segment *cur_segment) { it = std::find_if(events.begin(), events.end(), [](auto e) { return e->which == cereal::Event::Which::CAR_PARAMS; }); if (it != events.end()) { car_fingerprint_ = (*it)->event.getCarParams().getCarFingerprint(); - auto bytes = (*it)->bytes(); + capnp::MallocMessageBuilder builder; + builder.setRoot((*it)->event.getCarParams()); + auto words = capnp::messageToFlatArray(builder); + auto bytes = words.asBytes(); Params().put("CarParams", (const char *)bytes.begin(), bytes.size()); } else { rWarning("failed to read CarParams from current segment"); @@ -289,7 +292,7 @@ void Replay::startStream(const Segment *cur_segment) { camera_size[type] = {fr->width, fr->height}; } } - camera_server_ = std::make_unique(camera_size, true); + camera_server_ = std::make_unique(camera_size); } // start stream thread @@ -383,7 +386,7 @@ void Replay::stream() { publishMessage(evt); } else if (camera_server_) { if (hasFlag(REPLAY_FLAG_FULL_SPEED)) { - camera_server_->waitFinish(); + camera_server_->waitForSent(); } publishFrame(evt); } @@ -391,7 +394,7 @@ void Replay::stream() { } // wait for frame to be sent before unlock.(frameReader may be deleted after unlock) if (camera_server_) { - camera_server_->waitFinish(); + camera_server_->waitForSent(); } if (eit == events_->end() && !hasFlag(REPLAY_FLAG_NO_LOOP)) { diff --git a/selfdrive/ui/replay/route.cc b/selfdrive/ui/replay/route.cc index 50ccc6156b..3d595141cd 100644 --- a/selfdrive/ui/replay/route.cc +++ b/selfdrive/ui/replay/route.cc @@ -9,7 +9,7 @@ #include -#include "selfdrive/hardware/hw.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/qt/api.h" #include "selfdrive/ui/replay/replay.h" #include "selfdrive/ui/replay/util.h" @@ -77,7 +77,11 @@ bool Route::loadFromLocal() { } void Route::addFileToSegment(int n, const QString &file) { - const QString name = QUrl(file).fileName(); + QString name = QUrl(file).fileName(); + + const int pos = name.lastIndexOf("--"); + name = pos != -1 ? name.mid(pos + 2) : name; + if (name == "rlog.bz2") { segments_[n].rlog = file; } else if (name == "qlog.bz2") { diff --git a/selfdrive/ui/replay/tests/test_replay.cc b/selfdrive/ui/replay/tests/test_replay.cc index 3cafa9b534..bf984f5f3d 100644 --- a/selfdrive/ui/replay/tests/test_replay.cc +++ b/selfdrive/ui/replay/tests/test_replay.cc @@ -5,7 +5,7 @@ #include #include "catch2/catch.hpp" -#include "selfdrive/common/util.h" +#include "common/util.h" #include "selfdrive/ui/replay/replay.h" #include "selfdrive/ui/replay/util.h" @@ -102,11 +102,10 @@ void read_segment(int n, const SegmentFile &segment_file, uint32_t flags) { if (cam == RoadCam || cam == WideRoadCam) { REQUIRE(fr->getFrameCount() == 1200); } - std::unique_ptr rgb_buf = std::make_unique(fr->getRGBSize()); std::unique_ptr yuv_buf = std::make_unique(fr->getYUVSize()); // sequence get 100 frames for (int i = 0; i < 100; ++i) { - REQUIRE(fr->get(i, rgb_buf.get(), yuv_buf.get())); + REQUIRE(fr->get(i, yuv_buf.get())); } } diff --git a/selfdrive/ui/replay/util.cc b/selfdrive/ui/replay/util.cc index 5f06a6c834..099219ccde 100644 --- a/selfdrive/ui/replay/util.cc +++ b/selfdrive/ui/replay/util.cc @@ -12,8 +12,8 @@ #include #include -#include "selfdrive/common/timing.h" -#include "selfdrive/common/util.h" +#include "common/timing.h" +#include "common/util.h" ReplayMessageHandler message_handler = nullptr; DownloadProgressHandler download_progress_handler = nullptr; @@ -305,7 +305,7 @@ void precise_nano_sleep(long sleep_ns) { // spin wait if (sleep_ns > 0) { while ((nanos_since_boot() - start_sleep) <= sleep_ns) { - usleep(0); + std::this_thread::yield(); } } } diff --git a/selfdrive/ui/soundd/sound.cc b/selfdrive/ui/soundd/sound.cc index f303aa92bf..6830450d8f 100644 --- a/selfdrive/ui/soundd/sound.cc +++ b/selfdrive/ui/soundd/sound.cc @@ -7,7 +7,7 @@ #include #include "cereal/messaging/messaging.h" -#include "selfdrive/common/util.h" +#include "common/util.h" // TODO: detect when we can't play sounds // TODO: detect when we can't display the UI diff --git a/selfdrive/ui/soundd/sound.h b/selfdrive/ui/soundd/sound.h index 82b360fd38..7e009d28ad 100644 --- a/selfdrive/ui/soundd/sound.h +++ b/selfdrive/ui/soundd/sound.h @@ -2,7 +2,7 @@ #include #include -#include "selfdrive/hardware/hw.h" +#include "system/hardware/hw.h" #include "selfdrive/ui/ui.h" const std::tuple sound_list[] = { diff --git a/selfdrive/ui/tests/body.py b/selfdrive/ui/tests/body.py new file mode 100755 index 0000000000..c34e717eaf --- /dev/null +++ b/selfdrive/ui/tests/body.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +import time +import cereal.messaging as messaging + +if __name__ == "__main__": + while True: + pm = messaging.PubMaster(['carParams', 'carState']) + batt = 1. + while True: + msg = messaging.new_message('carParams') + msg.carParams.carName = "COMMA BODY" + msg.carParams.notCar = True + pm.send('carParams', msg) + + for b in range(100, 0, -1): + msg = messaging.new_message('carState') + msg.carState.charging = True + msg.carState.fuelGauge = b / 100. + pm.send('carState', msg) + time.sleep(0.1) + + time.sleep(1) diff --git a/selfdrive/ui/tests/test_soundd.py b/selfdrive/ui/tests/test_soundd.py index cba0f6dbd1..8cc9215b74 100755 --- a/selfdrive/ui/tests/test_soundd.py +++ b/selfdrive/ui/tests/test_soundd.py @@ -8,7 +8,7 @@ import cereal.messaging as messaging from selfdrive.test.helpers import phone_only, with_processes # TODO: rewrite for unittest from common.realtime import DT_CTRL -from selfdrive.hardware import HARDWARE +from system.hardware import HARDWARE AudibleAlert = car.CarControl.HUDControl.AudibleAlert diff --git a/selfdrive/ui/ui b/selfdrive/ui/ui index 68c8c2cad5..c9f81c0539 100755 --- a/selfdrive/ui/ui +++ b/selfdrive/ui/ui @@ -1,5 +1,5 @@ #!/bin/sh cd "$(dirname "$0")" export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH" -export QT_PLUGIN_PATH="../../third_party/qt-plugins/$(uname -m)" +export QT_DBL_CLICK_DIST=150 exec ./_ui diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 0debb5ba04..4d1e1ab746 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -6,11 +6,11 @@ #include #include "common/transformations/orientation.hpp" -#include "selfdrive/common/params.h" -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" -#include "selfdrive/common/watchdog.h" -#include "selfdrive/hardware/hw.h" +#include "common/params.h" +#include "common/swaglog.h" +#include "common/util.h" +#include "common/watchdog.h" +#include "system/hardware/hw.h" #define BACKLIGHT_DT 0.05 #define BACKLIGHT_TS 10.00 @@ -114,7 +114,7 @@ static void update_model(UIState *s, const cereal::ModelDataV2::Reader &model) { max_distance = std::clamp((float)(lead_d - fmin(lead_d * 0.35, 10.)), 0.0f, max_distance); } max_idx = get_path_length_idx(model_position, max_distance); - update_line_data(s, model_position, scene.end_to_end ? 0.9 : 0.5, 1.22, &scene.track_vertices, max_idx, false); + update_line_data(s, model_position, 0.9, 1.22, &scene.track_vertices, max_idx, false); } static void update_sockets(UIState *s) { @@ -182,7 +182,7 @@ static void update_state(UIState *s) { } } } - if (Hardware::TICI() && sm.updated("wideRoadCameraState")) { + if (sm.updated("wideRoadCameraState")) { auto camera_state = sm["wideRoadCameraState"].getWideRoadCameraState(); float max_lines = 1618; @@ -221,8 +221,7 @@ void UIState::updateStatus() { if (scene.started) { status = STATUS_DISENGAGED; scene.started_frame = sm->frame; - scene.end_to_end = Params().getBool("EndToEndToggle"); - wide_camera = Hardware::TICI() ? Params().getBool("EnableWideCamera") : false; + wide_camera = Params().getBool("WideCameraOnly"); } started_prev = scene.started; emit offroadTransition(!scene.started); @@ -233,11 +232,11 @@ UIState::UIState(QObject *parent) : QObject(parent) { sm = std::make_unique>({ "modelV2", "controlsState", "liveCalibration", "radarState", "deviceState", "roadCameraState", "pandaStates", "carParams", "driverMonitoringState", "sensorEvents", "carState", "liveLocationKalman", - "wideRoadCameraState", + "wideRoadCameraState", "managerState", "navInstruction", "navRoute", }); Params params; - wide_camera = Hardware::TICI() ? params.getBool("EnableWideCamera") : false; + wide_camera = params.getBool("WideCameraOnly"); prime_type = std::atoi(params.get("PrimeType").c_str()); // update timer diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index e3415b8830..cbf3921e4e 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -11,9 +11,9 @@ #include #include "cereal/messaging/messaging.h" -#include "selfdrive/common/modeldata.h" -#include "selfdrive/common/params.h" -#include "selfdrive/common/timing.h" +#include "common/modeldata.h" +#include "common/params.h" +#include "common/timing.h" const int bdr_s = 30; const int header_h = 420; @@ -54,7 +54,7 @@ struct Alert { return {"openpilot Unavailable", "Waiting for controls to start", "controlsWaiting", cereal::ControlsState::AlertSize::MID, AudibleAlert::NONE}; - } else if (controls_missing > CONTROLS_TIMEOUT) { + } else if (controls_missing > CONTROLS_TIMEOUT && !Hardware::PC()) { // car is started, but controls is lagging or died if (cs.getEnabled() && (controls_missing - CONTROLS_TIMEOUT) < 10) { return {"TAKE CONTROL IMMEDIATELY", "Controls Unresponsive", @@ -107,7 +107,7 @@ typedef struct UIScene { QPointF lead_vertices[2]; float light_sensor, accel_sensor, gyro_sensor; - bool started, ignition, is_metric, longitudinal_control, end_to_end; + bool started, ignition, is_metric, longitudinal_control; uint64_t started_frame; } UIScene; diff --git a/selfdrive/ui/watch3.cc b/selfdrive/ui/watch3.cc index c1d47d040d..00d23ea976 100644 --- a/selfdrive/ui/watch3.cc +++ b/selfdrive/ui/watch3.cc @@ -19,8 +19,6 @@ int main(int argc, char *argv[]) { { QHBoxLayout *hlayout = new QHBoxLayout(); layout->addLayout(hlayout); - // TODO: make mapd output YUV - // hlayout->addWidget(new CameraViewWidget("navd", VISION_STREAM_MAP, false)); hlayout->addWidget(new CameraViewWidget("camerad", VISION_STREAM_ROAD, false)); } diff --git a/selfdrive/updated.py b/selfdrive/updated.py index c7df24c52a..bdec383f52 100755 --- a/selfdrive/updated.py +++ b/selfdrive/updated.py @@ -33,14 +33,14 @@ import time import threading from pathlib import Path from typing import List, Tuple, Optional +from markdown_it import MarkdownIt from common.basedir import BASEDIR -from common.markdown import parse_markdown from common.params import Params -from selfdrive.hardware import TICI, HARDWARE -from selfdrive.swaglog import cloudlog +from system.hardware import AGNOS, HARDWARE +from system.swaglog import cloudlog from selfdrive.controls.lib.alertmanager import set_offroad_alert -from selfdrive.version import is_tested_branch +from system.version import is_tested_branch LOCK_FILE = os.getenv("UPDATER_LOCK_FILE", "/tmp/safe_staging_overlay.lock") STAGING_ROOT = os.getenv("UPDATER_STAGING_ROOT", "/data/safe_staging") @@ -126,7 +126,7 @@ def set_params(new_version: bool, failed_count: int, exception: Optional[str]) - with open(os.path.join(FINALIZED, "RELEASES.md"), "rb") as f: r = f.read().split(b'\n\n', 1)[0] # Slice latest release notes try: - params.put("ReleaseNotes", parse_markdown(r.decode("utf-8"))) + params.put("ReleaseNotes", MarkdownIt().render(r.decode("utf-8"))) except Exception: params.put("ReleaseNotes", r + b"\n") except Exception: @@ -265,7 +265,7 @@ def finalize_update(wait_helper: WaitTimeHelper) -> None: def handle_agnos_update(wait_helper: WaitTimeHelper) -> None: - from selfdrive.hardware.tici.agnos import flash_agnos_update, get_target_slot_number + from system.hardware.tici.agnos import flash_agnos_update, get_target_slot_number cur_version = HARDWARE.get_os_version() updated_version = run(["bash", "-c", r"unset AGNOS_VERSION && source launch_env.sh && \ @@ -281,7 +281,7 @@ def handle_agnos_update(wait_helper: WaitTimeHelper) -> None: cloudlog.info(f"Beginning background installation for AGNOS {updated_version}") set_offroad_alert("Offroad_NeosUpdate", True) - manifest_path = os.path.join(OVERLAY_MERGED, "selfdrive/hardware/tici/agnos.json") + manifest_path = os.path.join(OVERLAY_MERGED, "system/hardware/tici/agnos.json") target_slot_number = get_target_slot_number() flash_agnos_update(manifest_path, target_slot_number, cloudlog) set_offroad_alert("Offroad_NeosUpdate", False) @@ -311,7 +311,7 @@ def fetch_update(wait_helper: WaitTimeHelper) -> bool: cur_hash = run(["git", "rev-parse", "HEAD"], OVERLAY_MERGED).rstrip() upstream_hash = run(["git", "rev-parse", "@{u}"], OVERLAY_MERGED).rstrip() - new_version = cur_hash != upstream_hash + new_version: bool = cur_hash != upstream_hash git_fetch_result = check_git_fetch_result(git_fetch_output) cloudlog.info(f"comparing {cur_hash} to {upstream_hash}") @@ -328,7 +328,7 @@ def fetch_update(wait_helper: WaitTimeHelper) -> bool: ] cloudlog.info("git reset success: %s", '\n'.join(r)) - if TICI: + if AGNOS: handle_agnos_update(wait_helper) # Create the finalized, ready-to-swap update diff --git a/tools/sim/test/__init__.py b/system/__init__.py similarity index 100% rename from tools/sim/test/__init__.py rename to system/__init__.py diff --git a/selfdrive/clocksd/.gitignore b/system/clocksd/.gitignore similarity index 100% rename from selfdrive/clocksd/.gitignore rename to system/clocksd/.gitignore diff --git a/selfdrive/clocksd/SConscript b/system/clocksd/SConscript similarity index 100% rename from selfdrive/clocksd/SConscript rename to system/clocksd/SConscript diff --git a/selfdrive/clocksd/clocksd.cc b/system/clocksd/clocksd.cc similarity index 95% rename from selfdrive/clocksd/clocksd.cc rename to system/clocksd/clocksd.cc index a6a92fc058..a5912cf51a 100644 --- a/selfdrive/clocksd/clocksd.cc +++ b/system/clocksd/clocksd.cc @@ -16,8 +16,8 @@ #include #include "cereal/messaging/messaging.h" -#include "selfdrive/common/timing.h" -#include "selfdrive/common/util.h" +#include "common/timing.h" +#include "common/util.h" ExitHandler do_exit; diff --git a/selfdrive/hardware/.gitignore b/system/hardware/.gitignore similarity index 100% rename from selfdrive/hardware/.gitignore rename to system/hardware/.gitignore diff --git a/selfdrive/hardware/__init__.py b/system/hardware/__init__.py similarity index 51% rename from selfdrive/hardware/__init__.py rename to system/hardware/__init__.py index 03dfce86d7..77bb0e5e2a 100644 --- a/selfdrive/hardware/__init__.py +++ b/system/hardware/__init__.py @@ -1,11 +1,12 @@ import os from typing import cast -from selfdrive.hardware.base import HardwareBase -from selfdrive.hardware.tici.hardware import Tici -from selfdrive.hardware.pc.hardware import Pc +from system.hardware.base import HardwareBase +from system.hardware.tici.hardware import Tici +from system.hardware.pc.hardware import Pc TICI = os.path.isfile('/TICI') +AGNOS = os.path.isfile('/AGNOS') PC = not TICI diff --git a/selfdrive/hardware/base.h b/system/hardware/base.h similarity index 63% rename from selfdrive/hardware/base.h rename to system/hardware/base.h index 2826d09700..b70948d482 100644 --- a/selfdrive/hardware/base.h +++ b/system/hardware/base.h @@ -2,6 +2,7 @@ #include #include +#include "cereal/messaging/messaging.h" // no-op base hw class class HardwareNone { @@ -10,6 +11,10 @@ public: static constexpr float MIN_VOLUME = 0.2; static std::string get_os_version() { return ""; } + static std::string get_name() { return ""; }; + static cereal::InitData::DeviceType get_device_type() { return cereal::InitData::DeviceType::UNKNOWN; }; + static int get_voltage() { return 0; }; + static int get_current() { return 0; }; static void reboot() {} static void poweroff() {} @@ -21,4 +26,5 @@ public: static bool PC() { return false; } static bool TICI() { return false; } + static bool AGNOS() { return false; } }; diff --git a/selfdrive/hardware/base.py b/system/hardware/base.py similarity index 87% rename from selfdrive/hardware/base.py rename to system/hardware/base.py index 7e580b1027..8684386f62 100644 --- a/selfdrive/hardware/base.py +++ b/system/hardware/base.py @@ -78,30 +78,6 @@ class HardwareBase(ABC): def set_bandwidth_limit(upload_speed_kbps: int, download_speed_kbps: int) -> None: pass - @abstractmethod - def get_battery_capacity(self): - pass - - @abstractmethod - def get_battery_status(self): - pass - - @abstractmethod - def get_battery_current(self): - pass - - @abstractmethod - def get_battery_voltage(self): - pass - - @abstractmethod - def get_battery_charging(self): - pass - - @abstractmethod - def set_battery_charging(self, on): - pass - @abstractmethod def get_usb_present(self): pass diff --git a/selfdrive/hardware/hw.h b/system/hardware/hw.h similarity index 71% rename from selfdrive/hardware/hw.h rename to system/hardware/hw.h index b221b63db2..f50e94abe1 100644 --- a/selfdrive/hardware/hw.h +++ b/system/hardware/hw.h @@ -1,17 +1,20 @@ #pragma once -#include "selfdrive/hardware/base.h" -#include "selfdrive/common/util.h" +#include "system/hardware/base.h" +#include "common/util.h" #if QCOM2 -#include "selfdrive/hardware/tici/hardware.h" +#include "system/hardware/tici/hardware.h" #define Hardware HardwareTici #else class HardwarePC : public HardwareNone { public: static std::string get_os_version() { return "openpilot for PC"; } + static std::string get_name() { return "pc"; }; + static cereal::InitData::DeviceType get_device_type() { return cereal::InitData::DeviceType::PC; }; static bool PC() { return true; } static bool TICI() { return util::getenv("TICI", 0) == 1; } + static bool AGNOS() { return util::getenv("TICI", 0) == 1; } }; #define Hardware HardwarePC #endif diff --git a/system/hardware/pc/__init__.py b/system/hardware/pc/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/selfdrive/hardware/pc/hardware.py b/system/hardware/pc/hardware.py similarity index 82% rename from selfdrive/hardware/pc/hardware.py rename to system/hardware/pc/hardware.py index 0d85f28bed..b2c4a4343b 100644 --- a/selfdrive/hardware/pc/hardware.py +++ b/system/hardware/pc/hardware.py @@ -1,7 +1,7 @@ import random from cereal import log -from selfdrive.hardware.base import HardwareBase, ThermalConfig +from system.hardware.base import HardwareBase, ThermalConfig NetworkType = log.DeviceState.NetworkType NetworkStrength = log.DeviceState.NetworkStrength @@ -50,24 +50,6 @@ class Pc(HardwareBase): def get_network_strength(self, network_type): return NetworkStrength.unknown - def get_battery_capacity(self): - return 100 - - def get_battery_status(self): - return "" - - def get_battery_current(self): - return 0 - - def get_battery_voltage(self): - return 0 - - def get_battery_charging(self): - return True - - def set_battery_charging(self, on): - pass - def get_usb_present(self): return False diff --git a/system/hardware/tici/__init__.py b/system/hardware/tici/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/selfdrive/hardware/tici/agnos.json b/system/hardware/tici/agnos.json similarity index 70% rename from selfdrive/hardware/tici/agnos.json rename to system/hardware/tici/agnos.json index 6674ddaa5b..004a0f9dfb 100644 --- a/selfdrive/hardware/tici/agnos.json +++ b/system/hardware/tici/agnos.json @@ -1,10 +1,10 @@ [ { "name": "boot", - "url": "https://commadist.azureedge.net/agnosupdate/boot-0a86272196cb54607f8ba082f412fed4607baaf6ce3eb8dc8e950b4a1d763954.img.xz", - "hash": "0a86272196cb54607f8ba082f412fed4607baaf6ce3eb8dc8e950b4a1d763954", - "hash_raw": "0a86272196cb54607f8ba082f412fed4607baaf6ce3eb8dc8e950b4a1d763954", - "size": 14776320, + "url": "https://commadist.azureedge.net/agnosupdate/boot-bb71f49294150c4233b89e2a10768a5a3de003203ecd02e3f845821b35cd409f.img.xz", + "hash": "bb71f49294150c4233b89e2a10768a5a3de003203ecd02e3f845821b35cd409f", + "hash_raw": "bb71f49294150c4233b89e2a10768a5a3de003203ecd02e3f845821b35cd409f", + "size": 14780416, "sparse": false, "full_check": true, "has_ab": true @@ -41,9 +41,9 @@ }, { "name": "system", - "url": "https://commadist.azureedge.net/agnosupdate/system-9b0b534ed0c35c25850dbb73d3f052611f2e2c9db32410edc25d75fbcfc6c15e.img.xz", - "hash": "b1f622f00037bbdb28c0a6016c0e42fa7f87e99591ff2417c757a67ff559b526", - "hash_raw": "9b0b534ed0c35c25850dbb73d3f052611f2e2c9db32410edc25d75fbcfc6c15e", + "url": "https://commadist.azureedge.net/agnosupdate/system-11fdbc9e8a9cd27f98346d7e1039bc5b3032d0e892ff95fa1258673ff1809bca.img.xz", + "hash": "45b4719a9e580617cf840036b24fb0dcd32491edd9654d8d74c28d91ff362d36", + "hash_raw": "11fdbc9e8a9cd27f98346d7e1039bc5b3032d0e892ff95fa1258673ff1809bca", "size": 10737418240, "sparse": true, "full_check": false, diff --git a/selfdrive/hardware/tici/agnos.py b/system/hardware/tici/agnos.py similarity index 93% rename from selfdrive/hardware/tici/agnos.py rename to system/hardware/tici/agnos.py index e36ef9cfbb..e664654c65 100755 --- a/selfdrive/hardware/tici/agnos.py +++ b/system/hardware/tici/agnos.py @@ -7,7 +7,7 @@ import struct import subprocess import time import os -from typing import Generator +from typing import Dict, Generator, Union SPARSE_CHUNK_FMT = struct.Struct('H2xI4x') @@ -99,26 +99,30 @@ def get_partition_path(target_slot_number: int, partition: dict) -> str: return path -def verify_partition(target_slot_number: int, partition: dict) -> bool: +def verify_partition(target_slot_number: int, partition: Dict[str, Union[str, int]]) -> bool: full_check = partition['full_check'] path = get_partition_path(target_slot_number, partition) - partition_size = partition['size'] + if not isinstance(partition['size'], int): + return False + partition_size: int = partition['size'] + if not isinstance(partition['hash_raw'], str): + return False + partition_hash: str = partition['hash_raw'] with open(path, 'rb+') as out: if full_check: raw_hash = hashlib.sha256() - pos = 0 - chunk_size = 1024 * 1024 + pos, chunk_size = 0, 1024 * 1024 while pos < partition_size: n = min(chunk_size, partition_size - pos) raw_hash.update(out.read(n)) pos += n - return raw_hash.hexdigest().lower() == partition['hash_raw'].lower() + return raw_hash.hexdigest().lower() == partition_hash.lower() else: out.seek(partition_size) - return out.read(64) == partition['hash_raw'].lower().encode() + return out.read(64) == partition_hash.lower().encode() def clear_partition_hash(target_slot_number: int, partition: dict) -> None: diff --git a/selfdrive/hardware/tici/amplifier.py b/system/hardware/tici/amplifier.py similarity index 100% rename from selfdrive/hardware/tici/amplifier.py rename to system/hardware/tici/amplifier.py diff --git a/selfdrive/hardware/tici/hardware.h b/system/hardware/tici/hardware.h similarity index 69% rename from selfdrive/hardware/tici/hardware.h rename to system/hardware/tici/hardware.h index c37dbb0a36..dcccb9f3d1 100644 --- a/selfdrive/hardware/tici/hardware.h +++ b/system/hardware/tici/hardware.h @@ -3,18 +3,24 @@ #include #include -#include "selfdrive/common/params.h" -#include "selfdrive/common/util.h" -#include "selfdrive/hardware/base.h" +#include "common/params.h" +#include "common/util.h" +#include "system/hardware/base.h" class HardwareTici : public HardwareNone { public: static constexpr float MAX_VOLUME = 0.9; static constexpr float MIN_VOLUME = 0.2; static bool TICI() { return true; } + static bool AGNOS() { return true; } static std::string get_os_version() { return "AGNOS " + util::read_file("/VERSION"); }; + static std::string get_name() { return "tici"; }; + static cereal::InitData::DeviceType get_device_type() { return cereal::InitData::DeviceType::TICI; }; + static int get_voltage() { return std::atoi(util::read_file("/sys/class/hwmon/hwmon1/in1_input").c_str()); }; + static int get_current() { return std::atoi(util::read_file("/sys/class/hwmon/hwmon1/curr1_input").c_str()); }; + static void reboot() { std::system("sudo reboot"); }; static void poweroff() { std::system("sudo poweroff"); }; diff --git a/selfdrive/hardware/tici/hardware.py b/system/hardware/tici/hardware.py similarity index 94% rename from selfdrive/hardware/tici/hardware.py rename to system/hardware/tici/hardware.py index c626c5f825..a69d3eb743 100644 --- a/selfdrive/hardware/tici/hardware.py +++ b/system/hardware/tici/hardware.py @@ -9,10 +9,10 @@ from pathlib import Path from cereal import log from common.gpio import gpio_set, gpio_init -from selfdrive.hardware.base import HardwareBase, ThermalConfig -from selfdrive.hardware.tici import iwlist -from selfdrive.hardware.tici.pins import GPIO -from selfdrive.hardware.tici.amplifier import Amplifier +from system.hardware.base import HardwareBase, ThermalConfig +from system.hardware.tici import iwlist +from system.hardware.tici.pins import GPIO +from system.hardware.tici.amplifier import Amplifier NM = 'org.freedesktop.NetworkManager' NM_CON_ACT = NM + '.Connection.Active' @@ -355,25 +355,6 @@ class Tici(HardwareBase): pass return ret - # We don't have a battery, so let's use some sane constants - def get_battery_capacity(self): - return 100 - - def get_battery_status(self): - return "" - - def get_battery_current(self): - return 0 - - def get_battery_voltage(self): - return 0 - - def get_battery_charging(self): - return True - - def set_battery_charging(self, on): - pass - def get_usb_present(self): # Not sure if relevant on tici, but the file exists return self.read_param_file("/sys/class/power_supply/usb/present", lambda x: bool(int(x)), False) @@ -428,6 +409,7 @@ class Tici(HardwareBase): # *** IRQ config *** affine_irq(5, 565) # kgsl-3d0 affine_irq(4, 740) # xhci-hcd:usb1 goes on the boardd core + affine_irq(4, 1069) # xhci-hcd:usb3 goes on the boardd core for irq in range(237, 246): affine_irq(5, irq) # camerad @@ -468,25 +450,30 @@ class Tici(HardwareBase): sudo_write("performance", "/sys/class/devfreq/soc:qcom,memlat-cpu0/governor") sudo_write("performance", "/sys/class/devfreq/soc:qcom,memlat-cpu4/governor") + # *** VIDC (encoder) config *** + sudo_write("N", "/sys/kernel/debug/msm_vidc/clock_scaling") + sudo_write("Y", "/sys/kernel/debug/msm_vidc/disable_thermal_mitigation") + def configure_modem(self): sim_id = self.get_sim_info().get('sim_id', '') + # configure modem as data-centric + cmds = [ + 'AT+QNVW=5280,0,"0102000000000000"', + 'AT+QNVFW="/nv/item_files/ims/IMS_enable",00', + 'AT+QNVFW="/nv/item_files/modem/mmode/ue_usage_setting",01', + ] + modem = self.get_modem() + for cmd in cmds: + try: + modem.Command(cmd, math.ceil(TIMEOUT), dbus_interface=MM_MODEM, timeout=TIMEOUT) + except Exception: + pass + # blue prime config if sim_id.startswith('8901410'): - cmds = [ - 'AT+QNVW=5280,0,"0102000000000000"', - 'AT+QNVFW="/nv/item_files/ims/IMS_enable",00', - 'AT+QNVFW="/nv/item_files/modem/mmode/ue_usage_setting",01', - ] - modem = self.get_modem() - for cmd in cmds: - try: - modem.Command(cmd, math.ceil(TIMEOUT), dbus_interface=MM_MODEM, timeout=TIMEOUT) - except Exception: - pass os.system('mmcli -m 0 --3gpp-set-initial-eps-bearer-settings="apn=Broadband"') - def get_networks(self): r = {} diff --git a/selfdrive/hardware/tici/iwlist.py b/system/hardware/tici/iwlist.py similarity index 100% rename from selfdrive/hardware/tici/iwlist.py rename to system/hardware/tici/iwlist.py diff --git a/selfdrive/hardware/tici/pins.py b/system/hardware/tici/pins.py similarity index 100% rename from selfdrive/hardware/tici/pins.py rename to system/hardware/tici/pins.py diff --git a/selfdrive/hardware/tici/power_draw_test.py b/system/hardware/tici/power_draw_test.py similarity index 97% rename from selfdrive/hardware/tici/power_draw_test.py rename to system/hardware/tici/power_draw_test.py index 1af51fc018..bde92ae4a5 100755 --- a/selfdrive/hardware/tici/power_draw_test.py +++ b/system/hardware/tici/power_draw_test.py @@ -2,8 +2,8 @@ import os import time import numpy as np -from selfdrive.hardware.tici.hardware import Tici -from selfdrive.hardware.tici.pins import GPIO +from system.hardware.tici.hardware import Tici +from system.hardware.tici.pins import GPIO from common.gpio import gpio_init, gpio_set def read_power(): diff --git a/selfdrive/hardware/tici/power_monitor.py b/system/hardware/tici/power_monitor.py similarity index 100% rename from selfdrive/hardware/tici/power_monitor.py rename to system/hardware/tici/power_monitor.py diff --git a/selfdrive/hardware/tici/precise_power_measure.py b/system/hardware/tici/precise_power_measure.py similarity index 77% rename from selfdrive/hardware/tici/precise_power_measure.py rename to system/hardware/tici/precise_power_measure.py index c66936aef8..5d68851367 100755 --- a/selfdrive/hardware/tici/precise_power_measure.py +++ b/system/hardware/tici/precise_power_measure.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 import numpy as np -from selfdrive.hardware.tici.power_monitor import sample_power +from system.hardware.tici.power_monitor import sample_power if __name__ == '__main__': print("measuring for 5 seconds") diff --git a/system/hardware/tici/restart_modem.sh b/system/hardware/tici/restart_modem.sh new file mode 100755 index 0000000000..26c04e4fba --- /dev/null +++ b/system/hardware/tici/restart_modem.sh @@ -0,0 +1,18 @@ +#!/usr/bin/bash + +#nmcli connection modify --temporary lte gsm.home-only yes +#nmcli connection modify --temporary lte gsm.auto-config yes +#nmcli connection modify --temporary lte connection.autoconnect-retries 20 +sudo nmcli connection reload + +sudo systemctl stop ModemManager +nmcli con down lte +nmcli con down magenta-prime + +# power cycle modem +/usr/comma/lte/lte.sh stop_blocking +/usr/comma/lte/lte.sh start + +sudo systemctl restart NetworkManager +#sudo systemctl restart ModemManager +sudo ModemManager --debug diff --git a/selfdrive/hardware/tici/test_agnos_updater.py b/system/hardware/tici/test_agnos_updater.py similarity index 100% rename from selfdrive/hardware/tici/test_agnos_updater.py rename to system/hardware/tici/test_agnos_updater.py diff --git a/selfdrive/hardware/tici/test_power_draw.py b/system/hardware/tici/test_power_draw.py similarity index 86% rename from selfdrive/hardware/tici/test_power_draw.py rename to system/hardware/tici/test_power_draw.py index 4261e10442..b6b5c735fa 100755 --- a/selfdrive/hardware/tici/test_power_draw.py +++ b/system/hardware/tici/test_power_draw.py @@ -4,8 +4,8 @@ import time import math from dataclasses import dataclass -from selfdrive.hardware import HARDWARE, TICI -from selfdrive.hardware.tici.power_monitor import get_power +from system.hardware import HARDWARE, TICI +from system.hardware.tici.power_monitor import get_power from selfdrive.manager.process_config import managed_processes from selfdrive.manager.manager import manager_cleanup @@ -16,13 +16,13 @@ class Proc: power: float rtol: float = 0.05 atol: float = 0.1 - warmup: float = 3. + warmup: float = 6. PROCS = [ - Proc('camerad', 2.5), - Proc('modeld', 0.95), + Proc('camerad', 2.15), + Proc('modeld', 1.0, atol=0.15), Proc('dmonitoringmodeld', 0.25), - Proc('loggerd', 0.45, warmup=10.), + Proc('encoderd', 0.23), ] diff --git a/selfdrive/hardware/tici/updater b/system/hardware/tici/updater similarity index 100% rename from selfdrive/hardware/tici/updater rename to system/hardware/tici/updater diff --git a/selfdrive/logcatd/.gitignore b/system/logcatd/.gitignore similarity index 100% rename from selfdrive/logcatd/.gitignore rename to system/logcatd/.gitignore diff --git a/selfdrive/logcatd/SConscript b/system/logcatd/SConscript similarity index 100% rename from selfdrive/logcatd/SConscript rename to system/logcatd/SConscript diff --git a/selfdrive/logcatd/logcatd_systemd.cc b/system/logcatd/logcatd_systemd.cc similarity index 96% rename from selfdrive/logcatd/logcatd_systemd.cc rename to system/logcatd/logcatd_systemd.cc index dabb11adcb..70467a9c15 100644 --- a/selfdrive/logcatd/logcatd_systemd.cc +++ b/system/logcatd/logcatd_systemd.cc @@ -8,8 +8,8 @@ #include "json11.hpp" #include "cereal/messaging/messaging.h" -#include "selfdrive/common/timing.h" -#include "selfdrive/common/util.h" +#include "common/timing.h" +#include "common/util.h" ExitHandler do_exit; int main(int argc, char *argv[]) { diff --git a/selfdrive/logmessaged.py b/system/logmessaged.py similarity index 95% rename from selfdrive/logmessaged.py rename to system/logmessaged.py index 1d1fab5162..280a23cf1d 100755 --- a/selfdrive/logmessaged.py +++ b/system/logmessaged.py @@ -4,7 +4,7 @@ from typing import NoReturn import cereal.messaging as messaging from common.logging_extra import SwagLogFileFormatter -from selfdrive.swaglog import get_file_handler +from system.swaglog import get_file_handler def main() -> NoReturn: diff --git a/selfdrive/proclogd/SConscript b/system/proclogd/SConscript similarity index 100% rename from selfdrive/proclogd/SConscript rename to system/proclogd/SConscript diff --git a/selfdrive/proclogd/main.cc b/system/proclogd/main.cc similarity index 81% rename from selfdrive/proclogd/main.cc rename to system/proclogd/main.cc index 4e31597c2b..c4faa916d9 100644 --- a/selfdrive/proclogd/main.cc +++ b/system/proclogd/main.cc @@ -1,8 +1,8 @@ #include -#include "selfdrive/common/util.h" -#include "selfdrive/proclogd/proclog.h" +#include "common/util.h" +#include "system/proclogd/proclog.h" ExitHandler do_exit; diff --git a/selfdrive/proclogd/proclog.cc b/system/proclogd/proclog.cc similarity index 98% rename from selfdrive/proclogd/proclog.cc rename to system/proclogd/proclog.cc index 26fc1d94d0..9064547d29 100644 --- a/selfdrive/proclogd/proclog.cc +++ b/system/proclogd/proclog.cc @@ -1,4 +1,4 @@ -#include "selfdrive/proclogd/proclog.h" +#include "system/proclogd/proclog.h" #include @@ -7,8 +7,8 @@ #include #include -#include "selfdrive/common/swaglog.h" -#include "selfdrive/common/util.h" +#include "common/swaglog.h" +#include "common/util.h" namespace Parser { diff --git a/selfdrive/proclogd/proclog.h b/system/proclogd/proclog.h similarity index 100% rename from selfdrive/proclogd/proclog.h rename to system/proclogd/proclog.h diff --git a/selfdrive/proclogd/tests/.gitignore b/system/proclogd/tests/.gitignore similarity index 100% rename from selfdrive/proclogd/tests/.gitignore rename to system/proclogd/tests/.gitignore diff --git a/selfdrive/proclogd/tests/test_proclog.cc b/system/proclogd/tests/test_proclog.cc similarity index 98% rename from selfdrive/proclogd/tests/test_proclog.cc rename to system/proclogd/tests/test_proclog.cc index 88a09dd03b..230e855acb 100644 --- a/selfdrive/proclogd/tests/test_proclog.cc +++ b/system/proclogd/tests/test_proclog.cc @@ -1,7 +1,7 @@ #define CATCH_CONFIG_MAIN #include "catch2/catch.hpp" -#include "selfdrive/common/util.h" -#include "selfdrive/proclogd/proclog.h" +#include "common/util.h" +#include "system/proclogd/proclog.h" const std::string allowed_states = "RSDTZtWXxKWPI"; diff --git a/selfdrive/swaglog.py b/system/swaglog.py similarity index 99% rename from selfdrive/swaglog.py rename to system/swaglog.py index a987bfe72c..68664330a5 100644 --- a/selfdrive/swaglog.py +++ b/system/swaglog.py @@ -7,7 +7,7 @@ from logging.handlers import BaseRotatingHandler import zmq from common.logging_extra import SwagLogger, SwagFormatter, SwagLogFileFormatter -from selfdrive.hardware import PC +from system.hardware import PC if PC: SWAGLOG_DIR = os.path.join(str(Path.home()), ".comma", "log") diff --git a/selfdrive/timezoned.py b/system/timezoned.py similarity index 96% rename from selfdrive/timezoned.py rename to system/timezoned.py index 6a7e9122c1..884a5c3812 100755 --- a/selfdrive/timezoned.py +++ b/system/timezoned.py @@ -9,8 +9,8 @@ import requests from timezonefinder import TimezoneFinder from common.params import Params -from selfdrive.hardware import TICI -from selfdrive.swaglog import cloudlog +from system.hardware import AGNOS +from system.swaglog import cloudlog def set_timezone(valid_timezones, timezone): @@ -20,7 +20,7 @@ def set_timezone(valid_timezones, timezone): cloudlog.debug(f"Setting timezone to {timezone}") try: - if TICI: + if AGNOS: tzpath = os.path.join("/usr/share/zoneinfo/", timezone) subprocess.check_call(f'sudo su -c "ln -snf {tzpath} /data/etc/tmptime && \ mv /data/etc/tmptime /data/etc/localtime"', shell=True) diff --git a/selfdrive/version.py b/system/version.py similarity index 94% rename from selfdrive/version.py rename to system/version.py index 5517fe728a..f0817b3a9f 100644 --- a/selfdrive/version.py +++ b/system/version.py @@ -5,7 +5,7 @@ from typing import List, Optional from functools import lru_cache from common.basedir import BASEDIR -from selfdrive.swaglog import cloudlog +from system.swaglog import cloudlog TESTED_BRANCHES = ['devel', 'release3-staging', 'dashcam3-staging', 'release3', 'dashcam3'] @@ -55,7 +55,7 @@ def get_origin(default: Optional[str] = None) -> Optional[str]: @cache def get_normalized_origin(default: Optional[str] = None) -> Optional[str]: - origin = get_origin() + origin: Optional[str] = get_origin() if origin is None: return default @@ -68,13 +68,13 @@ def get_normalized_origin(default: Optional[str] = None) -> Optional[str]: @cache def get_version() -> str: - with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "common", "version.h")) as _versionf: + with open(os.path.join(BASEDIR, "common", "version.h")) as _versionf: version = _versionf.read().split('"')[1] return version @cache def get_short_version() -> str: - return get_version().split('-')[0] + return get_version().split('-')[0] # type: ignore @cache def is_prebuilt() -> bool: @@ -85,7 +85,7 @@ def is_prebuilt() -> bool: def is_comma_remote() -> bool: # note to fork maintainers, this is used for release metrics. please do not # touch this to get rid of the orange startup alert. there's better ways to do that - origin = get_origin() + origin: Optional[str] = get_origin() if origin is None: return False diff --git a/third_party/acados/build.sh b/third_party/acados/build.sh index 0b14a4cec9..a4246fbda6 100755 --- a/third_party/acados/build.sh +++ b/third_party/acados/build.sh @@ -1,4 +1,5 @@ -#!/usr/bin/bash -e +#!/usr/bin/env bash +set -e DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" @@ -9,6 +10,13 @@ if [ -f /TICI ]; then BLAS_TARGET="ARMV8A_ARM_CORTEX_A57" fi +ACADOS_FLAGS="-DACADOS_WITH_QPOASES=ON -UBLASFEO_TARGET -DBLASFEO_TARGET=$BLAS_TARGET" + +if [[ "$OSTYPE" == "darwin"* ]]; then + ACADOS_FLAGS="$ACADOS_FLAGS -DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" + ARCHNAME="Darwin" +fi + if [ ! -d acados_repo/ ]; then git clone https://github.com/acados/acados.git $DIR/acados_repo # git clone https://github.com/commaai/acados.git $DIR/acados_repo @@ -21,7 +29,7 @@ git submodule update --recursive --init # build mkdir -p build cd build -cmake -DACADOS_WITH_QPOASES=ON -UBLASFEO_TARGET -DBLASFEO_TARGET=$BLAS_TARGET .. +cmake $ACADOS_FLAGS .. make -j20 install INSTALL_DIR="$DIR/$ARCHNAME" diff --git a/selfdrive/loggerd/include/msm_media_info.h b/third_party/linux/include/msm_media_info.h similarity index 100% rename from selfdrive/loggerd/include/msm_media_info.h rename to third_party/linux/include/msm_media_info.h diff --git a/third_party/linux/include/v4l2-controls.h b/third_party/linux/include/v4l2-controls.h new file mode 100644 index 0000000000..d14cd8fabe --- /dev/null +++ b/third_party/linux/include/v4l2-controls.h @@ -0,0 +1,1696 @@ +/* + * Video for Linux Two controls header file + * + * Copyright (C) 1999-2012 the contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Alternatively you can redistribute this file under the terms of the + * BSD license as stated below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The names of its contributors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The contents of this header was split off from videodev2.h. All control + * definitions should be added to this header, which is included by + * videodev2.h. + */ + +#ifndef __LINUX_V4L2_CONTROLS_H +#define __LINUX_V4L2_CONTROLS_H + +/* Control classes */ +#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ +#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ +#define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */ +#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator controls */ +#define V4L2_CTRL_CLASS_FLASH 0x009c0000 /* Camera flash controls */ +#define V4L2_CTRL_CLASS_JPEG 0x009d0000 /* JPEG-compression controls */ +#define V4L2_CTRL_CLASS_IMAGE_SOURCE 0x009e0000 /* Image source controls */ +#define V4L2_CTRL_CLASS_IMAGE_PROC 0x009f0000 /* Image processing controls */ +#define V4L2_CTRL_CLASS_DV 0x00a00000 /* Digital Video controls */ +#define V4L2_CTRL_CLASS_FM_RX 0x00a10000 /* FM Receiver controls */ +#define V4L2_CTRL_CLASS_RF_TUNER 0x00a20000 /* RF tuner controls */ +#define V4L2_CTRL_CLASS_DETECT 0x00a30000 /* Detection controls */ + +/* User-class control IDs */ + +#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900) +#define V4L2_CID_USER_BASE V4L2_CID_BASE +#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1) +#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) +#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) +#define V4L2_CID_SATURATION (V4L2_CID_BASE+2) +#define V4L2_CID_HUE (V4L2_CID_BASE+3) +#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) +#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) +#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) +#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) +#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) +#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */ +#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) +#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) +#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) +#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) +#define V4L2_CID_GAMMA (V4L2_CID_BASE+16) +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */ +#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) +#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) +#define V4L2_CID_GAIN (V4L2_CID_BASE+19) +#define V4L2_CID_HFLIP (V4L2_CID_BASE+20) +#define V4L2_CID_VFLIP (V4L2_CID_BASE+21) + +#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) +enum v4l2_power_line_frequency { + V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0, + V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1, + V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2, + V4L2_CID_POWER_LINE_FREQUENCY_AUTO = 3, +}; +#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) +#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) +#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) +#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) +#define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29) +#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) +#define V4L2_CID_COLORFX (V4L2_CID_BASE+31) +enum v4l2_colorfx { + V4L2_COLORFX_NONE = 0, + V4L2_COLORFX_BW = 1, + V4L2_COLORFX_SEPIA = 2, + V4L2_COLORFX_NEGATIVE = 3, + V4L2_COLORFX_EMBOSS = 4, + V4L2_COLORFX_SKETCH = 5, + V4L2_COLORFX_SKY_BLUE = 6, + V4L2_COLORFX_GRASS_GREEN = 7, + V4L2_COLORFX_SKIN_WHITEN = 8, + V4L2_COLORFX_VIVID = 9, + V4L2_COLORFX_AQUA = 10, + V4L2_COLORFX_ART_FREEZE = 11, + V4L2_COLORFX_SILHOUETTE = 12, + V4L2_COLORFX_SOLARIZATION = 13, + V4L2_COLORFX_ANTIQUE = 14, + V4L2_COLORFX_SET_CBCR = 15, +}; +#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) +#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) + +#define V4L2_CID_ROTATE (V4L2_CID_BASE+34) +#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) + +#define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36) + +#define V4L2_CID_ILLUMINATORS_1 (V4L2_CID_BASE+37) +#define V4L2_CID_ILLUMINATORS_2 (V4L2_CID_BASE+38) + +#define V4L2_CID_MIN_BUFFERS_FOR_CAPTURE (V4L2_CID_BASE+39) +#define V4L2_CID_MIN_BUFFERS_FOR_OUTPUT (V4L2_CID_BASE+40) + +#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41) +#define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE+42) + +/* last CID + 1 */ +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+43) + +/* USER-class private control IDs */ + +/* The base for the meye driver controls. See linux/meye.h for the list + * of controls. We reserve 16 controls for this driver. */ +#define V4L2_CID_USER_MEYE_BASE (V4L2_CID_USER_BASE + 0x1000) + +/* The base for the bttv driver controls. + * We reserve 32 controls for this driver. */ +#define V4L2_CID_USER_BTTV_BASE (V4L2_CID_USER_BASE + 0x1010) + + +/* The base for the s2255 driver controls. + * We reserve 16 controls for this driver. */ +#define V4L2_CID_USER_S2255_BASE (V4L2_CID_USER_BASE + 0x1030) + +/* + * The base for the si476x driver controls. See include/media/drv-intf/si476x.h + * for the list of controls. Total of 16 controls is reserved for this driver + */ +#define V4L2_CID_USER_SI476X_BASE (V4L2_CID_USER_BASE + 0x1040) + +/* The base for the TI VPE driver controls. Total of 16 controls is reserved for + * this driver */ +#define V4L2_CID_USER_TI_VPE_BASE (V4L2_CID_USER_BASE + 0x1050) + +/* The base for the saa7134 driver controls. + * We reserve 16 controls for this driver. */ +#define V4L2_CID_USER_SAA7134_BASE (V4L2_CID_USER_BASE + 0x1060) + +/* The base for the adv7180 driver controls. + * We reserve 16 controls for this driver. */ +#define V4L2_CID_USER_ADV7180_BASE (V4L2_CID_USER_BASE + 0x1070) + +/* The base for the tc358743 driver controls. + * We reserve 16 controls for this driver. */ +#define V4L2_CID_USER_TC358743_BASE (V4L2_CID_USER_BASE + 0x1080) + +/* MPEG-class control IDs */ +/* The MPEG controls are applicable to all codec controls + * and the 'MPEG' part of the define is historical */ + +#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) +#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1) + +/* MPEG streams, specific to multiplexed streams */ +#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0) +enum v4l2_mpeg_stream_type { + V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */ + V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */ + V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */ +}; +#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1) +#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2) +#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3) +#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4) +#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5) +#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6) +#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7) +enum v4l2_mpeg_stream_vbi_fmt { + V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */ + V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */ +}; + +/* MPEG audio controls specific to multiplexed streams */ +#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100) +enum v4l2_mpeg_audio_sampling_freq { + V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2, +}; +#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101) +enum v4l2_mpeg_audio_encoding { + V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1, + V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2, + V4L2_MPEG_AUDIO_ENCODING_AAC = 3, + V4L2_MPEG_AUDIO_ENCODING_AC3 = 4, +}; +#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) +enum v4l2_mpeg_audio_l1_bitrate { + V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1, + V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2, + V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3, + V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4, + V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5, + V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6, + V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7, + V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8, + V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9, + V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10, + V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11, + V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12, + V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103) +enum v4l2_mpeg_audio_l2_bitrate { + V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1, + V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2, + V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3, + V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4, + V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5, + V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6, + V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7, + V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8, + V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9, + V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10, + V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11, + V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12, + V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104) +enum v4l2_mpeg_audio_l3_bitrate { + V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1, + V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2, + V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3, + V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4, + V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5, + V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6, + V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7, + V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8, + V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9, + V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10, + V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11, + V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12, + V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105) +enum v4l2_mpeg_audio_mode { + V4L2_MPEG_AUDIO_MODE_STEREO = 0, + V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1, + V4L2_MPEG_AUDIO_MODE_DUAL = 2, + V4L2_MPEG_AUDIO_MODE_MONO = 3, +}; +#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106) +enum v4l2_mpeg_audio_mode_extension { + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3, +}; +#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107) +enum v4l2_mpeg_audio_emphasis { + V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0, + V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1, + V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2, +}; +#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108) +enum v4l2_mpeg_audio_crc { + V4L2_MPEG_AUDIO_CRC_NONE = 0, + V4L2_MPEG_AUDIO_CRC_CRC16 = 1, +}; +#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) +#define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110) +#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111) +enum v4l2_mpeg_audio_ac3_bitrate { + V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1, + V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2, + V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3, + V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4, + V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5, + V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6, + V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7, + V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8, + V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9, + V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10, + V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11, + V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12, + V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13, + V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14, + V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15, + V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16, + V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17, + V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18, +}; +#define V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK (V4L2_CID_MPEG_BASE+112) +enum v4l2_mpeg_audio_dec_playback { + V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO = 0, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO = 1, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT = 2, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT = 3, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO = 4, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO = 5, +}; +#define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE+113) + +/* MPEG video controls specific to multiplexed streams */ +#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) +enum v4l2_mpeg_video_encoding { + V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2, +}; +#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201) +enum v4l2_mpeg_video_aspect { + V4L2_MPEG_VIDEO_ASPECT_1x1 = 0, + V4L2_MPEG_VIDEO_ASPECT_4x3 = 1, + V4L2_MPEG_VIDEO_ASPECT_16x9 = 2, + V4L2_MPEG_VIDEO_ASPECT_221x100 = 3, +}; +#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202) +#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203) +#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204) +#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205) +#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206) +enum v4l2_mpeg_video_bitrate_mode { + V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0, + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1, +}; +#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) +#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) +#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209) +#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) +#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) +#define V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (V4L2_CID_MPEG_BASE+212) +#define V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (V4L2_CID_MPEG_BASE+213) +#define V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (V4L2_CID_MPEG_BASE+214) +#define V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (V4L2_CID_MPEG_BASE+215) +#define V4L2_CID_MPEG_VIDEO_HEADER_MODE (V4L2_CID_MPEG_BASE+216) +enum v4l2_mpeg_video_header_mode { + V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE = 0, + V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME = 1, + V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME = 2, +}; +#define V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (V4L2_CID_MPEG_BASE+217) +#define V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE (V4L2_CID_MPEG_BASE+218) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES (V4L2_CID_MPEG_BASE+219) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB (V4L2_CID_MPEG_BASE+220) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE (V4L2_CID_MPEG_BASE+221) +enum v4l2_mpeg_video_multi_slice_mode { + V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE = 0, + V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB = 1, + V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2, + V4L2_MPEG_VIDEO_MULTI_SLICE_GOB = 3, +}; +#define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE+222) +#define V4L2_CID_MPEG_VIDEO_DEC_PTS (V4L2_CID_MPEG_BASE+223) +#define V4L2_CID_MPEG_VIDEO_DEC_FRAME (V4L2_CID_MPEG_BASE+224) +#define V4L2_CID_MPEG_VIDEO_VBV_DELAY (V4L2_CID_MPEG_BASE+225) +#define V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER (V4L2_CID_MPEG_BASE+226) +#define V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE (V4L2_CID_MPEG_BASE+227) +#define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (V4L2_CID_MPEG_BASE+228) +#define V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME (V4L2_CID_MPEG_BASE+229) + +#define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300) +#define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301) +#define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302) +#define V4L2_CID_MPEG_VIDEO_H263_MIN_QP (V4L2_CID_MPEG_BASE+303) +#define V4L2_CID_MPEG_VIDEO_H263_MAX_QP (V4L2_CID_MPEG_BASE+304) +#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP (V4L2_CID_MPEG_BASE+350) +#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP (V4L2_CID_MPEG_BASE+351) +#define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP (V4L2_CID_MPEG_BASE+352) +#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP (V4L2_CID_MPEG_BASE+353) +#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP (V4L2_CID_MPEG_BASE+354) +#define V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM (V4L2_CID_MPEG_BASE+355) +#define V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (V4L2_CID_MPEG_BASE+356) +#define V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE (V4L2_CID_MPEG_BASE+357) +enum v4l2_mpeg_video_h264_entropy_mode { + V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC = 0, + V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_I_PERIOD (V4L2_CID_MPEG_BASE+358) +#define V4L2_CID_MPEG_VIDEO_H264_LEVEL (V4L2_CID_MPEG_BASE+359) +enum v4l2_mpeg_video_h264_level { + V4L2_MPEG_VIDEO_H264_LEVEL_1_0 = 0, + V4L2_MPEG_VIDEO_H264_LEVEL_1B = 1, + V4L2_MPEG_VIDEO_H264_LEVEL_1_1 = 2, + V4L2_MPEG_VIDEO_H264_LEVEL_1_2 = 3, + V4L2_MPEG_VIDEO_H264_LEVEL_1_3 = 4, + V4L2_MPEG_VIDEO_H264_LEVEL_2_0 = 5, + V4L2_MPEG_VIDEO_H264_LEVEL_2_1 = 6, + V4L2_MPEG_VIDEO_H264_LEVEL_2_2 = 7, + V4L2_MPEG_VIDEO_H264_LEVEL_3_0 = 8, + V4L2_MPEG_VIDEO_H264_LEVEL_3_1 = 9, + V4L2_MPEG_VIDEO_H264_LEVEL_3_2 = 10, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0 = 11, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1 = 12, + V4L2_MPEG_VIDEO_H264_LEVEL_4_2 = 13, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0 = 14, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1 = 15, + V4L2_MPEG_VIDEO_H264_LEVEL_5_2 = 16, +#define V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN \ + V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN + V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN = 17, +}; +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (V4L2_CID_MPEG_BASE+360) +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (V4L2_CID_MPEG_BASE+361) +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE (V4L2_CID_MPEG_BASE+362) +enum v4l2_mpeg_video_h264_loop_filter_mode { + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED = 0, + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED = 1, + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY = 2, +}; +#define V4L2_CID_MPEG_VIDEO_H264_PROFILE (V4L2_CID_MPEG_BASE+363) +enum v4l2_mpeg_video_h264_profile { + V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE = 0, + V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE = 1, + V4L2_MPEG_VIDEO_H264_PROFILE_MAIN = 2, + V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED = 3, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH = 4, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10 = 5, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422 = 6, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE = 7, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA = 8, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA = 9, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA = 10, + V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA = 11, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE = 12, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH = 13, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14, + V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH = 15, + V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16, + V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH = 17, +}; +#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE+364) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE+365) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE (V4L2_CID_MPEG_BASE+366) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC (V4L2_CID_MPEG_BASE+367) +enum v4l2_mpeg_video_h264_vui_sar_idc { + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED = 0, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 = 1, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 = 2, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 = 3, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 = 4, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 = 5, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 = 6, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 = 7, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 = 8, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 = 9, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 = 10, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 = 11, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 = 12, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 = 13, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 = 14, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 = 15, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 = 16, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED = 17, +}; +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING (V4L2_CID_MPEG_BASE+368) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0 (V4L2_CID_MPEG_BASE+369) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE (V4L2_CID_MPEG_BASE+370) +enum v4l2_mpeg_video_h264_sei_fp_arrangement_type { + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_CHECKERBOARD = 0, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_COLUMN = 1, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_ROW = 2, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE = 3, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TOP_BOTTOM = 4, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TEMPORAL = 5, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO (V4L2_CID_MPEG_BASE+371) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE (V4L2_CID_MPEG_BASE+372) +enum v4l2_mpeg_video_h264_fmo_map_type { + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES = 0, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES = 1, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER = 2, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT = 3, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN = 4, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN = 5, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT = 6, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP (V4L2_CID_MPEG_BASE+373) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION (V4L2_CID_MPEG_BASE+374) +enum v4l2_mpeg_video_h264_fmo_change_dir { + V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT = 0, + V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE (V4L2_CID_MPEG_BASE+375) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH (V4L2_CID_MPEG_BASE+376) +#define V4L2_CID_MPEG_VIDEO_H264_ASO (V4L2_CID_MPEG_BASE+377) +#define V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER (V4L2_CID_MPEG_BASE+378) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING (V4L2_CID_MPEG_BASE+379) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE (V4L2_CID_MPEG_BASE+380) +enum v4l2_mpeg_video_h264_hierarchical_coding_type { + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B = 0, + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER (V4L2_CID_MPEG_BASE+381) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_BASE+382) +#define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400) +#define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401) +#define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402) +#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP (V4L2_CID_MPEG_BASE+403) +#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP (V4L2_CID_MPEG_BASE+404) +#define V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL (V4L2_CID_MPEG_BASE+405) +enum v4l2_mpeg_video_mpeg4_level { + V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 = 0, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B = 1, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 = 2, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 = 3, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 = 4, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B = 5, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 = 6, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 = 7, +}; +#define V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE (V4L2_CID_MPEG_BASE+406) +enum v4l2_mpeg_video_mpeg4_profile { + V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE = 0, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE = 1, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE = 2, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE = 3, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY = 4, +}; +#define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL (V4L2_CID_MPEG_BASE+407) + +/* Control IDs for VP8 streams + * Although VP8 is not part of MPEG we add these controls to the MPEG class + * as that class is already handling other video compression standards + */ +#define V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS (V4L2_CID_MPEG_BASE+500) +enum v4l2_vp8_num_partitions { + V4L2_CID_MPEG_VIDEO_VPX_1_PARTITION = 0, + V4L2_CID_MPEG_VIDEO_VPX_2_PARTITIONS = 1, + V4L2_CID_MPEG_VIDEO_VPX_4_PARTITIONS = 2, + V4L2_CID_MPEG_VIDEO_VPX_8_PARTITIONS = 3, +}; +#define V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4 (V4L2_CID_MPEG_BASE+501) +#define V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES (V4L2_CID_MPEG_BASE+502) +enum v4l2_vp8_num_ref_frames { + V4L2_CID_MPEG_VIDEO_VPX_1_REF_FRAME = 0, + V4L2_CID_MPEG_VIDEO_VPX_2_REF_FRAME = 1, + V4L2_CID_MPEG_VIDEO_VPX_3_REF_FRAME = 2, +}; +#define V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL (V4L2_CID_MPEG_BASE+503) +#define V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS (V4L2_CID_MPEG_BASE+504) +#define V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD (V4L2_CID_MPEG_BASE+505) +#define V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL (V4L2_CID_MPEG_BASE+506) +enum v4l2_vp8_golden_frame_sel { + V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV = 0, + V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_REF_PERIOD = 1, +}; +#define V4L2_CID_MPEG_VIDEO_VPX_MIN_QP (V4L2_CID_MPEG_BASE+507) +#define V4L2_CID_MPEG_VIDEO_VPX_MAX_QP (V4L2_CID_MPEG_BASE+508) +#define V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP (V4L2_CID_MPEG_BASE+509) +#define V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP (V4L2_CID_MPEG_BASE+510) +#define V4L2_CID_MPEG_VIDEO_VPX_PROFILE (V4L2_CID_MPEG_BASE+511) + +/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ +#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) +#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) +enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { + V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0, + V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2) +enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type { + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3) +enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type { + V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4) +enum v4l2_mpeg_cx2341x_video_temporal_filter_mode { + V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0, + V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5) +#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6) +enum v4l2_mpeg_cx2341x_video_median_filter_type { + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8) +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9) +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) +#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11) + +/* MPEG-class control IDs specific to the Samsung MFC 5.1 driver as defined by V4L2 */ +#define V4L2_CID_MPEG_MFC51_BASE (V4L2_CTRL_CLASS_MPEG | 0x1100) + +#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY (V4L2_CID_MPEG_MFC51_BASE+0) +#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE (V4L2_CID_MPEG_MFC51_BASE+1) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE (V4L2_CID_MPEG_MFC51_BASE+2) +enum v4l2_mpeg_mfc51_video_frame_skip_mode { + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED = 0, + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT = 1, + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT = 2, +}; +#define V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE (V4L2_CID_MPEG_MFC51_BASE+3) +enum v4l2_mpeg_mfc51_video_force_frame_type { + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED = 0, + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME = 1, + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED = 2, +}; +#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING (V4L2_CID_MPEG_MFC51_BASE+4) +#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV (V4L2_CID_MPEG_MFC51_BASE+5) +#define V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (V4L2_CID_MPEG_MFC51_BASE+6) +#define V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF (V4L2_CID_MPEG_MFC51_BASE+7) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY (V4L2_CID_MPEG_MFC51_BASE+50) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK (V4L2_CID_MPEG_MFC51_BASE+51) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH (V4L2_CID_MPEG_MFC51_BASE+52) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC51_BASE+53) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (V4L2_CID_MPEG_MFC51_BASE+54) + +/* MPEG-class control IDs specific to the msm_vidc driver */ +#define V4L2_CID_MPEG_MSM_VIDC_BASE (V4L2_CTRL_CLASS_MPEG | 0x2000) + +#define V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+0) +enum v4l2_mpeg_vidc_video_pictype_dec_mode { + V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_OFF = 0, + V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_ON = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+1) + +#define V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT (V4L2_CID_MPEG_MSM_VIDC_BASE+2) +enum v4l2_mpeg_vidc_video_stream_format { + V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES = 0, + V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_ONE_NAL_PER_BUFFER = 1, + V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_ONE_BYTE_LENGTH = 2, + V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH = 3, + V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH = 4, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER (V4L2_CID_MPEG_MSM_VIDC_BASE+3) +enum v4l2_mpeg_vidc_video_output_order { + V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY = 0, + V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE (V4L2_CID_MPEG_MSM_VIDC_BASE+4) +#define V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD (V4L2_CID_MPEG_MSM_VIDC_BASE+5) +#define V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES (V4L2_CID_MPEG_MSM_VIDC_BASE+6) +#define V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES (V4L2_CID_MPEG_MSM_VIDC_BASE+7) +#define V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME (V4L2_CID_MPEG_MSM_VIDC_BASE+8) + +#define V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL (V4L2_CID_MPEG_MSM_VIDC_BASE+9) +enum v4l2_mpeg_vidc_video_rate_control { + V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF = 0, + V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR = 1, + V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR = 2, + V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR = 3, + V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR = 4, + V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_CFR = 5, + V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR = 6, + V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CQ = 7, +}; +#define V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_CFR \ + V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_CFR +#define V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR \ + V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR + +#define V4L2_CID_MPEG_VIDC_VIDEO_ROTATION (V4L2_CID_MPEG_MSM_VIDC_BASE+10) +enum v4l2_mpeg_vidc_video_rotation { + V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90 = 1, + V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180 = 2, + V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270 = 3, +}; +#define V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+11) +enum v4l2_mpeg_vidc_h264_cabac_model { + V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0 = 0, + V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1 = 1, + V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2 = 2, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+12) +enum v4l2_mpeg_vidc_video_intra_refresh_mode { + V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC = 1, + V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM = 2, + V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE = 3, + V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE = 4, +}; +#define V4L2_CID_MPEG_VIDC_VIDEO_IR_MBS (V4L2_CID_MPEG_MSM_VIDC_BASE+13) + +#define V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 14) +enum v4l2_mpeg_vidc_video_au_delimiter { + V4L2_MPEG_VIDC_VIDEO_AU_DELIMITER_DISABLED = 0, + V4L2_MPEG_VIDC_VIDEO_AU_DELIMITER_ENABLED = 1 +}; +#define V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 15) +enum v4l2_mpeg_vidc_video_sync_frame_decode { + V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_DISABLE = 0, + V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE = 1 +}; +#define V4L2_CID_MPEG_VIDC_VIDEO_SECURE (V4L2_CID_MPEG_MSM_VIDC_BASE+16) +#define V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 17) +enum v4l2_mpeg_vidc_extradata { + V4L2_MPEG_VIDC_EXTRADATA_NONE = 0, + V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION = 1, + V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO = 2, + V4L2_MPEG_VIDC_EXTRADATA_VC1_FRAMEDISP = 3, + V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP = 4, + V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP = 5, + V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING = 6, + V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE = 7, + V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW = 8, + V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI = 9, + V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO = 10, + V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB = 11, + V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER = 12, + V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP = 13, + V4L2_MPEG_VIDC_EXTRADATA_DIGITAL_ZOOM = 14, + V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO = 15, + V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP = 16, + V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA = 17, + V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP = 18, + V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO = 19, + V4L2_MPEG_VIDC_EXTRADATA_LTR = 20, + V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI = 21, + V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI = 22, + V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS = 23, + V4L2_MPEG_VIDC_EXTRADATA_ROI_QP = 24, +#define V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP \ + V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP + V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP = 25, +#define V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI \ + V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI + V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI = 26, +#define V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI \ + V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI + V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI = 27, +#define V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO \ + V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO + V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO = 28, +#define V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY \ + V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY + V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY = 29, +#define V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE \ + V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE + V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE = 30, +#define V4L2_MPEG_VIDC_EXTRADATA_UBWC_CR_STATS_INFO \ + V4L2_MPEG_VIDC_EXTRADATA_UBWC_CR_STATS_INFO + V4L2_MPEG_VIDC_EXTRADATA_UBWC_CR_STATS_INFO = 31, +#define V4L2_MPEG_VIDC_EXTRADATA_ENC_FRAME_QP \ + V4L2_MPEG_VIDC_EXTRADATA_ENC_FRAME_QP + V4L2_MPEG_VIDC_EXTRADATA_ENC_FRAME_QP = 32, +}; + +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 18) + +#define V4L2_CID_MPEG_VIDC_VIDEO_VUI_TIMING_INFO \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 19) +enum v4l2_mpeg_vidc_video_vui_timing_info { + V4L2_MPEG_VIDC_VIDEO_VUI_TIMING_INFO_DISABLED = 0, + V4L2_MPEG_VIDC_VIDEO_VUI_TIMING_INFO_ENABLED = 1 +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 20) +enum v4l2_mpeg_vidc_video_vp8_profile_level { + V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED, + V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0, + V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1, + V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_2, + V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_PRESERVE_TEXT_QUALITY \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 21) +enum v4l2_mpeg_vidc_video_preserve_text_quality { + V4L2_MPEG_VIDC_VIDEO_PRESERVE_TEXT_QUALITY_DISABLED = 0, + V4L2_MPEG_VIDC_VIDEO_PRESERVE_TEXT_QUALITY_ENABLED = 1 +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 22) +enum v4l2_mpeg_vidc_video_decoder_multi_stream { + V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY = 0, + V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL (V4L2_CID_MPEG_MSM_VIDC_BASE+23) +enum v4l2_mpeg_vidc_video_mpeg2_level { + V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_0 = 0, + V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_1 = 1, + V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_2 = 2, + V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_3 = 3, +}; +#define V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE (V4L2_CID_MPEG_MSM_VIDC_BASE+24) +enum v4l2_mpeg_vidc_video_mpeg2_profile { + V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SIMPLE = 0, + V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_MAIN = 1, + V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_422 = 2, + V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SNR_SCALABLE = 3, + V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SPATIAL_SCALABLE = 4, + V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_HIGH = 5, +}; + +enum v4l2_mpeg_vidc_video_mvc_layout { + V4L2_MPEG_VIDC_VIDEO_MVC_SEQUENTIAL = 0, + V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM = 1 +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 25) + +#define V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 26) + +enum v4l2_mpeg_vidc_video_ltrmode { + V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE = 0, + V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL = 1, + V4L2_MPEG_VIDC_VIDEO_LTR_MODE_PERIODIC = 2 +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 27) + +#define V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 28) + +#define V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 29) + +#define V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 30) + +#define V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+31) +enum v4l2_mpeg_vidc_video_alloc_mode_type { + V4L2_MPEG_VIDC_VIDEO_STATIC = 0, + V4L2_MPEG_VIDC_VIDEO_RING = 1, + V4L2_MPEG_VIDC_VIDEO_DYNAMIC = 2, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 32) + +#define V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 33) + +#define V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 34) + +#define V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 35) + +#define V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 36) + +#define V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 37) + +#define V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 38) + +#define V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 39) + +enum vl42_mpeg_vidc_video_vpx_error_resilience { + V4L2_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE_DISABLED = 0, + V4L2_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE_ENABLED = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 40) +enum v4l2_mpeg_video_hevc_profile { + V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN = 0, + V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10 = 1, + V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN_STILL_PIC = 2, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 41) +enum v4l2_mpeg_video_hevc_level { + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1 = 0, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1 = 1, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2 = 2, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2 = 3, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1 = 4, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1 = 5, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3 = 6, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3 = 7, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1 = 8, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1 = 9, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4 = 10, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4 = 11, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1 = 12, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1 = 13, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5 = 14, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5 = 15, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1 = 16, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1 = 17, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2 = 18, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2 = 19, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6 = 20, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6 = 21, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1 = 22, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1 = 23, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2 = 24, + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_2 = 25, +#define V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_UNKNOWN \ + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_UNKNOWN + V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_UNKNOWN = 26, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 42) + +#define V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 43) + +#define V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 44) + +enum v4l2_mpeg_vidc_video_dpb_color_format { + V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE = 0, + V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC = 1, + V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC = 2 +}; + +#define V4L2_CID_VIDC_QBUF_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 45) +enum v4l2_vidc_qbuf_mode { + V4L2_VIDC_QBUF_STANDARD = 0, + V4L2_VIDC_QBUF_BATCHED = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 46) + +#define V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 47) + +#define V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_WIDTH \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 48) + +#define V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_HEIGHT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 49) + +#define V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 50) + +enum v4l2_mpeg_vidc_video_vqzip_sei_enable { + V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_DISABLE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE = 1 +}; + +#define V4L2_CID_MPEG_VIDC_VENC_PARAM_LAYER_BITRATE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 51) + +#define V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 52) + +enum v4l2_mpeg_vidc_video_priority { + V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE = 0, + V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 53) + +#define V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 54) + +enum v4l2_mpeg_vidc_video_venc_bitrate_type_enable { + V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_DISABLE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE = 1 +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 55) + +enum v4l2_cid_mpeg_vidc_video_vpe_csc_type_enable { + V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_DISABLE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE = 1 +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 56) + +enum v4l2_mpeg_vidc_video_lowlatency_mode { + V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_DISABLE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_ENABLE = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_BLUR_WIDTH \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 57) + +#define V4L2_CID_MPEG_VIDC_VIDEO_BLUR_HEIGHT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 58) + +#define V4L2_CID_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8 \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 59) +enum v4l2_mpeg_vidc_video_h264_transform_8x8 { + V4L2_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8_DISABLE = 0, + V4L2_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8_ENABLE = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 60) + +#define V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 61) + +enum v4l2_cid_mpeg_vidc_video_full_range { + V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_DISABLE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_ENABLE = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 62) + +#define V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 63) + +#define V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 64) + +#define V4L2_CID_MPEG_VIDC_VIDEO_LAYER_ID \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 65) + +#define V4L2_CID_MPEG_VIDC_VIDEO_VP9_PROFILE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 66) +enum v4l2_mpeg_vidc_video_vp9_profile { + V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_UNUSED = 0, + V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P0 = 1, + V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P2_10 = 2, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 67) +enum v4l2_mpeg_vidc_video_vp9_level { + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_UNUSED = 0, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_1 = 1, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_11 = 2, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_2 = 3, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_21 = 4, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_3 = 5, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_31 = 6, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_4 = 7, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_41 = 8, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_5 = 9, + V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_51 = 10, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_MB_ERROR_MAP_REPORTING \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 68) +#define V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 69) + +#define V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_INPUT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 70) + +#define V4L2_CID_MPEG_VIDC_VIDEO_FRAME_ASSEMBLY \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 71) +enum v4l2_mpeg_vidc_video_assembly { + V4L2_MPEG_VIDC_FRAME_ASSEMBLY_DISABLE = 0, + V4L2_MPEG_VIDC_FRAME_ASSEMBLY_ENABLE = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE\ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 72) +enum v4l2_mpeg_vidc_video_h263_profile { + V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE = 0, + V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING = 1, + V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE = 2, + V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2 = 3, + V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3 = 4, + V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION = 5, + V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET = 6, + V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE = 7, + V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY = 8, +}; + +#define V4L2_CID_MPEG_VIDEO_MIN_QP_PACKED \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 97) +#define V4L2_CID_MPEG_VIDEO_MAX_QP_PACKED \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 98) +#define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 99) +#define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 100) +#define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 101) +#define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP_MIN \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 102) +#define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP_MIN \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 103) +#define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP_MIN \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 104) +#define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP_MAX \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 105) +#define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP_MAX \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 106) +#define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP_MAX \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 107) +#define V4L2_CID_MPEG_VIDC_VIDEO_QP_MASK \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 108) + +enum v4l2_mpeg_vidc_video_venc_iframesize_type { + V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT, + V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_MEDIUM, + V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_HUGE, + V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 109) +#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 110) + +#define V4L2_CID_MPEG_VIDC_VIDEO_TME_PROFILE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 111) + +enum v4l2_mpeg_vidc_video_tme_profile { + V4L2_MPEG_VIDC_VIDEO_TME_PROFILE_0 = 0, + V4L2_MPEG_VIDC_VIDEO_TME_PROFILE_1 = 1, + V4L2_MPEG_VIDC_VIDEO_TME_PROFILE_2 = 2, + V4L2_MPEG_VIDC_VIDEO_TME_PROFILE_3 = 3, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_TME_LEVEL \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 112) + +enum v4l2_mpeg_vidc_video_tme_level { + V4L2_MPEG_VIDC_VIDEO_TME_LEVEL_INTEGER = 0, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_TME_PAYLOAD_VERSION \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 113) + +#define V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_CUSTOM_MATRIX \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 114) + +#define V4L2_CID_MPEG_VIDC_VIDEO_FLIP (V4L2_CID_MPEG_MSM_VIDC_BASE + 115) +enum v4l2_mpeg_vidc_video_flip { + V4L2_CID_MPEG_VIDC_VIDEO_FLIP_NONE = 0, + V4L2_CID_MPEG_VIDC_VIDEO_FLIP_HORI = 1, + V4L2_CID_MPEG_VIDC_VIDEO_FLIP_VERT = 2, + V4L2_CID_MPEG_VIDC_VIDEO_FLIP_BOTH = 3, +}; + +/* HDR SEI INFO related control IDs and definitions*/ +#define V4L2_MPEG_VIDC_VENC_HDR_INFO_ENABLED 1 +#define V4L2_MPEG_VIDC_VENC_HDR_INFO_DISABLED 0 + +#define V4L2_CID_MPEG_VIDC_VENC_HDR_INFO \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 116) +#define V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_00 \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 117) +#define V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_01 \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 118) +#define V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_10 \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 119) +#define V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_11 \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 120) +#define V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_20 \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 121) +#define V4L2_CID_MPEG_VIDC_VENC_RGB_PRIMARY_21 \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 122) +#define V4L2_CID_MPEG_VIDC_VENC_WHITEPOINT_X \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 123) +#define V4L2_CID_MPEG_VIDC_VENC_WHITEPOINT_Y \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 124) +#define V4L2_CID_MPEG_VIDC_VENC_MAX_DISP_LUM \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 125) +#define V4L2_CID_MPEG_VIDC_VENC_MIN_DISP_LUM \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 126) +#define V4L2_CID_MPEG_VIDC_VENC_MAX_CLL \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 127) +#define V4L2_CID_MPEG_VIDC_VENC_MAX_FLL \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 128) + +#define V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 129) +enum v4l2_mpeg_vidc_perf_level { + V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL = 0, + V4L2_CID_MPEG_VIDC_PERF_LEVEL_PERFORMANCE = 1, + V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO = 2, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS (V4L2_CID_MPEG_MSM_VIDC_BASE + 130) +#define V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF (V4L2_CID_MPEG_MSM_VIDC_BASE + 131) +#define V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS (V4L2_CID_MPEG_MSM_VIDC_BASE + 132) + +#define V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 135) + +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 136) + +#define V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_BITSTREAM_RESTRICT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 137) +enum v4l2_mpeg_vidc_video_h264_vui_bitstream_restrict { + V4L2_MPEG_VIDC_VIDEO_H264_VUI_BITSTREAM_RESTRICT_DISABLED = 0, + V4L2_MPEG_VIDC_VIDEO_H264_VUI_BITSTREAM_RESTRICT_ENABLED = 1 +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 138) +enum v4l2_mpeg_vidc_video_deinterlace { + V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_DISABLED = 0, + V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED = 1 +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_MPEG4_TIME_RESOLUTION \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 139) + +#define V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 140) + +#define V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_TIMESTAMP_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 141) +enum v4l2_mpeg_vidc_video_rate_control_timestamp_mode { + V4L2_MPEG_VIDC_VIDEO_RATE_CONTROL_TIMESTAMP_MODE_HONOR = 0, + V4L2_MPEG_VIDC_VIDEO_RATE_CONTROL_TIMESTAMP_MODE_IGNORE = 1, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 142) +enum vl42_mpeg_vidc_video_enable_initial_qp { + V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP_IFRAME = 0x1, + V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP_PFRAME = 0x2, + V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP_BFRAME = 0x4, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 143) + +#define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 144) + +#define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 145) + +#define V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 146) + +#define V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 147) +enum v4l2_mpeg_vidc_video_perf_mode { + V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY = 1, + V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE = 2 +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_MBI_STATISTICS_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 148) + +#define V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 149) + +#define V4L2_CID_MPEG_VIDC_VIDEO_H264_PIC_ORDER_CNT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 150) + +#define V4L2_CID_MPEG_VIDC_VIDEO_SCS_THRESHOLD \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 151) + +#define V4L2_CID_MPEG_VIDC_VIDEO_MVC_BUFFER_LAYOUT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 152) + + +#define V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 153) + +#define V4L2_CID_MPEG_VIDC_VIDEO_NON_SECURE_OUTPUT2 \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 154) + +#define V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP (V4L2_CID_MPEG_MSM_VIDC_BASE + 155) +#define V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP (V4L2_CID_MPEG_MSM_VIDC_BASE + 156) + +#define V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL (V4L2_CID_MPEG_MSM_VIDC_BASE + 157) +enum v4l2_mpeg_vidc_video_h263_level { + V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0 = 0, + V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0 = 1, + V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0 = 2, + V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0 = 3, + V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5 = 4, + V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0 = 5, + V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0 = 6, + V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0 = 7, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_POST_LOOP_DEBLOCKER_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 158) + + +#define V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT (V4L2_CID_MPEG_MSM_VIDC_BASE+159) + +enum v4l2_mpeg_vidc_video_divx_format_type { + V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4 = 0, + V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5 = 1, + V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6 = 2, +}; + +#define V4L2_CID_MPEG_VIDC_VIDEO_FRAME_QUALITY \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+160) + +#define V4L2_CID_MPEG_VIDC_IMG_GRID_DIMENSION \ + (V4L2_CID_MPEG_MSM_VIDC_BASE+161) + +enum v4l2_mpeg_vidc_video_mbi_statistics_mode { + V4L2_CID_MPEG_VIDC_VIDEO_MBI_MODE_DEFAULT = 0, + V4L2_CID_MPEG_VIDC_VIDEO_MBI_MODE_1 = 1, + V4L2_CID_MPEG_VIDC_VIDEO_MBI_MODE_2 = 2, + V4L2_CID_MPEG_VIDC_VIDEO_MBI_MODE_3 = 3, +}; + +enum vl42_mpeg_vidc_video_h264_svc_nal { + V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_DISABLED = 0, + V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED = 1, +}; + +enum v4l2_mpeg_vidc_video_h264_vui_timing_info { + V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED = 0, + V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED = 1 +}; + +/* Camera class control IDs */ + +#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) +#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) + +#define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1) +enum v4l2_exposure_auto_type { + V4L2_EXPOSURE_AUTO = 0, + V4L2_EXPOSURE_MANUAL = 1, + V4L2_EXPOSURE_SHUTTER_PRIORITY = 2, + V4L2_EXPOSURE_APERTURE_PRIORITY = 3 +}; +#define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2) +#define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3) + +#define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4) +#define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5) +#define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6) +#define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7) + +#define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8) +#define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9) + +#define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10) +#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) +#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) + +#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13) +#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) +#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) + +#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) + +#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17) +#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18) + +#define V4L2_CID_AUTO_EXPOSURE_BIAS (V4L2_CID_CAMERA_CLASS_BASE+19) + +#define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE (V4L2_CID_CAMERA_CLASS_BASE+20) +enum v4l2_auto_n_preset_white_balance { + V4L2_WHITE_BALANCE_MANUAL = 0, + V4L2_WHITE_BALANCE_AUTO = 1, + V4L2_WHITE_BALANCE_INCANDESCENT = 2, + V4L2_WHITE_BALANCE_FLUORESCENT = 3, + V4L2_WHITE_BALANCE_FLUORESCENT_H = 4, + V4L2_WHITE_BALANCE_HORIZON = 5, + V4L2_WHITE_BALANCE_DAYLIGHT = 6, + V4L2_WHITE_BALANCE_FLASH = 7, + V4L2_WHITE_BALANCE_CLOUDY = 8, + V4L2_WHITE_BALANCE_SHADE = 9, +}; + +#define V4L2_CID_WIDE_DYNAMIC_RANGE (V4L2_CID_CAMERA_CLASS_BASE+21) +#define V4L2_CID_IMAGE_STABILIZATION (V4L2_CID_CAMERA_CLASS_BASE+22) + +#define V4L2_CID_ISO_SENSITIVITY (V4L2_CID_CAMERA_CLASS_BASE+23) +#define V4L2_CID_ISO_SENSITIVITY_AUTO (V4L2_CID_CAMERA_CLASS_BASE+24) +enum v4l2_iso_sensitivity_auto_type { + V4L2_ISO_SENSITIVITY_MANUAL = 0, + V4L2_ISO_SENSITIVITY_AUTO = 1, +}; + +#define V4L2_CID_EXPOSURE_METERING (V4L2_CID_CAMERA_CLASS_BASE+25) +enum v4l2_exposure_metering { + V4L2_EXPOSURE_METERING_AVERAGE = 0, + V4L2_EXPOSURE_METERING_CENTER_WEIGHTED = 1, + V4L2_EXPOSURE_METERING_SPOT = 2, + V4L2_EXPOSURE_METERING_MATRIX = 3, +}; + +#define V4L2_CID_SCENE_MODE (V4L2_CID_CAMERA_CLASS_BASE+26) +enum v4l2_scene_mode { + V4L2_SCENE_MODE_NONE = 0, + V4L2_SCENE_MODE_BACKLIGHT = 1, + V4L2_SCENE_MODE_BEACH_SNOW = 2, + V4L2_SCENE_MODE_CANDLE_LIGHT = 3, + V4L2_SCENE_MODE_DAWN_DUSK = 4, + V4L2_SCENE_MODE_FALL_COLORS = 5, + V4L2_SCENE_MODE_FIREWORKS = 6, + V4L2_SCENE_MODE_LANDSCAPE = 7, + V4L2_SCENE_MODE_NIGHT = 8, + V4L2_SCENE_MODE_PARTY_INDOOR = 9, + V4L2_SCENE_MODE_PORTRAIT = 10, + V4L2_SCENE_MODE_SPORTS = 11, + V4L2_SCENE_MODE_SUNSET = 12, + V4L2_SCENE_MODE_TEXT = 13, +}; + +#define V4L2_CID_3A_LOCK (V4L2_CID_CAMERA_CLASS_BASE+27) +#define V4L2_LOCK_EXPOSURE (1 << 0) +#define V4L2_LOCK_WHITE_BALANCE (1 << 1) +#define V4L2_LOCK_FOCUS (1 << 2) + +#define V4L2_CID_AUTO_FOCUS_START (V4L2_CID_CAMERA_CLASS_BASE+28) +#define V4L2_CID_AUTO_FOCUS_STOP (V4L2_CID_CAMERA_CLASS_BASE+29) +#define V4L2_CID_AUTO_FOCUS_STATUS (V4L2_CID_CAMERA_CLASS_BASE+30) +#define V4L2_AUTO_FOCUS_STATUS_IDLE (0 << 0) +#define V4L2_AUTO_FOCUS_STATUS_BUSY (1 << 0) +#define V4L2_AUTO_FOCUS_STATUS_REACHED (1 << 1) +#define V4L2_AUTO_FOCUS_STATUS_FAILED (1 << 2) + +#define V4L2_CID_AUTO_FOCUS_RANGE (V4L2_CID_CAMERA_CLASS_BASE+31) +enum v4l2_auto_focus_range { + V4L2_AUTO_FOCUS_RANGE_AUTO = 0, + V4L2_AUTO_FOCUS_RANGE_NORMAL = 1, + V4L2_AUTO_FOCUS_RANGE_MACRO = 2, + V4L2_AUTO_FOCUS_RANGE_INFINITY = 3, +}; + +#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE+32) +#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE+33) + +/* FM Modulator class control IDs */ + +#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) +#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1) + +#define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1) +#define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2) +#define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3) +#define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5) +#define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6) +#define V4L2_CID_RDS_TX_MONO_STEREO (V4L2_CID_FM_TX_CLASS_BASE + 7) +#define V4L2_CID_RDS_TX_ARTIFICIAL_HEAD (V4L2_CID_FM_TX_CLASS_BASE + 8) +#define V4L2_CID_RDS_TX_COMPRESSED (V4L2_CID_FM_TX_CLASS_BASE + 9) +#define V4L2_CID_RDS_TX_DYNAMIC_PTY (V4L2_CID_FM_TX_CLASS_BASE + 10) +#define V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT (V4L2_CID_FM_TX_CLASS_BASE + 11) +#define V4L2_CID_RDS_TX_TRAFFIC_PROGRAM (V4L2_CID_FM_TX_CLASS_BASE + 12) +#define V4L2_CID_RDS_TX_MUSIC_SPEECH (V4L2_CID_FM_TX_CLASS_BASE + 13) +#define V4L2_CID_RDS_TX_ALT_FREQS_ENABLE (V4L2_CID_FM_TX_CLASS_BASE + 14) +#define V4L2_CID_RDS_TX_ALT_FREQS (V4L2_CID_FM_TX_CLASS_BASE + 15) + +#define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64) +#define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65) +#define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66) + +#define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80) +#define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81) +#define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82) +#define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83) +#define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84) + +#define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96) +#define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97) +#define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98) + +#define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112) +enum v4l2_preemphasis { + V4L2_PREEMPHASIS_DISABLED = 0, + V4L2_PREEMPHASIS_50_uS = 1, + V4L2_PREEMPHASIS_75_uS = 2, +}; +#define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113) +#define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114) + + +/* Flash and privacy (indicator) light controls */ + +#define V4L2_CID_FLASH_CLASS_BASE (V4L2_CTRL_CLASS_FLASH | 0x900) +#define V4L2_CID_FLASH_CLASS (V4L2_CTRL_CLASS_FLASH | 1) + +#define V4L2_CID_FLASH_LED_MODE (V4L2_CID_FLASH_CLASS_BASE + 1) +enum v4l2_flash_led_mode { + V4L2_FLASH_LED_MODE_NONE, + V4L2_FLASH_LED_MODE_FLASH, + V4L2_FLASH_LED_MODE_TORCH, +}; + +#define V4L2_CID_FLASH_STROBE_SOURCE (V4L2_CID_FLASH_CLASS_BASE + 2) +enum v4l2_flash_strobe_source { + V4L2_FLASH_STROBE_SOURCE_SOFTWARE, + V4L2_FLASH_STROBE_SOURCE_EXTERNAL, +}; + +#define V4L2_CID_FLASH_STROBE (V4L2_CID_FLASH_CLASS_BASE + 3) +#define V4L2_CID_FLASH_STROBE_STOP (V4L2_CID_FLASH_CLASS_BASE + 4) +#define V4L2_CID_FLASH_STROBE_STATUS (V4L2_CID_FLASH_CLASS_BASE + 5) + +#define V4L2_CID_FLASH_TIMEOUT (V4L2_CID_FLASH_CLASS_BASE + 6) +#define V4L2_CID_FLASH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 7) +#define V4L2_CID_FLASH_TORCH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 8) +#define V4L2_CID_FLASH_INDICATOR_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 9) + +#define V4L2_CID_FLASH_FAULT (V4L2_CID_FLASH_CLASS_BASE + 10) +#define V4L2_FLASH_FAULT_OVER_VOLTAGE (1 << 0) +#define V4L2_FLASH_FAULT_TIMEOUT (1 << 1) +#define V4L2_FLASH_FAULT_OVER_TEMPERATURE (1 << 2) +#define V4L2_FLASH_FAULT_SHORT_CIRCUIT (1 << 3) +#define V4L2_FLASH_FAULT_OVER_CURRENT (1 << 4) +#define V4L2_FLASH_FAULT_INDICATOR (1 << 5) +#define V4L2_FLASH_FAULT_UNDER_VOLTAGE (1 << 6) +#define V4L2_FLASH_FAULT_INPUT_VOLTAGE (1 << 7) +#define V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE (1 << 8) + +#define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11) +#define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12) + + +/* JPEG-class control IDs */ + +#define V4L2_CID_JPEG_CLASS_BASE (V4L2_CTRL_CLASS_JPEG | 0x900) +#define V4L2_CID_JPEG_CLASS (V4L2_CTRL_CLASS_JPEG | 1) + +#define V4L2_CID_JPEG_CHROMA_SUBSAMPLING (V4L2_CID_JPEG_CLASS_BASE + 1) +enum v4l2_jpeg_chroma_subsampling { + V4L2_JPEG_CHROMA_SUBSAMPLING_444 = 0, + V4L2_JPEG_CHROMA_SUBSAMPLING_422 = 1, + V4L2_JPEG_CHROMA_SUBSAMPLING_420 = 2, + V4L2_JPEG_CHROMA_SUBSAMPLING_411 = 3, + V4L2_JPEG_CHROMA_SUBSAMPLING_410 = 4, + V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY = 5, +}; +#define V4L2_CID_JPEG_RESTART_INTERVAL (V4L2_CID_JPEG_CLASS_BASE + 2) +#define V4L2_CID_JPEG_COMPRESSION_QUALITY (V4L2_CID_JPEG_CLASS_BASE + 3) + +#define V4L2_CID_JPEG_ACTIVE_MARKER (V4L2_CID_JPEG_CLASS_BASE + 4) +#define V4L2_JPEG_ACTIVE_MARKER_APP0 (1 << 0) +#define V4L2_JPEG_ACTIVE_MARKER_APP1 (1 << 1) +#define V4L2_JPEG_ACTIVE_MARKER_COM (1 << 16) +#define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17) +#define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18) + + +/* Image source controls */ +#define V4L2_CID_IMAGE_SOURCE_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x900) +#define V4L2_CID_IMAGE_SOURCE_CLASS (V4L2_CTRL_CLASS_IMAGE_SOURCE | 1) + +#define V4L2_CID_VBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 1) +#define V4L2_CID_HBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2) +#define V4L2_CID_ANALOGUE_GAIN (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3) +#define V4L2_CID_TEST_PATTERN_RED (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 4) +#define V4L2_CID_TEST_PATTERN_GREENR (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 5) +#define V4L2_CID_TEST_PATTERN_BLUE (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 6) +#define V4L2_CID_TEST_PATTERN_GREENB (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 7) + + +/* Image processing controls */ + +#define V4L2_CID_IMAGE_PROC_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_PROC | 0x900) +#define V4L2_CID_IMAGE_PROC_CLASS (V4L2_CTRL_CLASS_IMAGE_PROC | 1) + +#define V4L2_CID_LINK_FREQ (V4L2_CID_IMAGE_PROC_CLASS_BASE + 1) +#define V4L2_CID_PIXEL_RATE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 2) +#define V4L2_CID_TEST_PATTERN (V4L2_CID_IMAGE_PROC_CLASS_BASE + 3) + + +/* DV-class control IDs defined by V4L2 */ +#define V4L2_CID_DV_CLASS_BASE (V4L2_CTRL_CLASS_DV | 0x900) +#define V4L2_CID_DV_CLASS (V4L2_CTRL_CLASS_DV | 1) + +#define V4L2_CID_DV_TX_HOTPLUG (V4L2_CID_DV_CLASS_BASE + 1) +#define V4L2_CID_DV_TX_RXSENSE (V4L2_CID_DV_CLASS_BASE + 2) +#define V4L2_CID_DV_TX_EDID_PRESENT (V4L2_CID_DV_CLASS_BASE + 3) +#define V4L2_CID_DV_TX_MODE (V4L2_CID_DV_CLASS_BASE + 4) +enum v4l2_dv_tx_mode { + V4L2_DV_TX_MODE_DVI_D = 0, + V4L2_DV_TX_MODE_HDMI = 1, +}; +#define V4L2_CID_DV_TX_RGB_RANGE (V4L2_CID_DV_CLASS_BASE + 5) +enum v4l2_dv_rgb_range { + V4L2_DV_RGB_RANGE_AUTO = 0, + V4L2_DV_RGB_RANGE_LIMITED = 1, + V4L2_DV_RGB_RANGE_FULL = 2, +}; + +#define V4L2_CID_DV_TX_IT_CONTENT_TYPE (V4L2_CID_DV_CLASS_BASE + 6) +enum v4l2_dv_it_content_type { + V4L2_DV_IT_CONTENT_TYPE_GRAPHICS = 0, + V4L2_DV_IT_CONTENT_TYPE_PHOTO = 1, + V4L2_DV_IT_CONTENT_TYPE_CINEMA = 2, + V4L2_DV_IT_CONTENT_TYPE_GAME = 3, + V4L2_DV_IT_CONTENT_TYPE_NO_ITC = 4, +}; + +#define V4L2_CID_DV_RX_POWER_PRESENT (V4L2_CID_DV_CLASS_BASE + 100) +#define V4L2_CID_DV_RX_RGB_RANGE (V4L2_CID_DV_CLASS_BASE + 101) +#define V4L2_CID_DV_RX_IT_CONTENT_TYPE (V4L2_CID_DV_CLASS_BASE + 102) + +#define V4L2_CID_FM_RX_CLASS_BASE (V4L2_CTRL_CLASS_FM_RX | 0x900) +#define V4L2_CID_FM_RX_CLASS (V4L2_CTRL_CLASS_FM_RX | 1) + +#define V4L2_CID_TUNE_DEEMPHASIS (V4L2_CID_FM_RX_CLASS_BASE + 1) +enum v4l2_deemphasis { + V4L2_DEEMPHASIS_DISABLED = V4L2_PREEMPHASIS_DISABLED, + V4L2_DEEMPHASIS_50_uS = V4L2_PREEMPHASIS_50_uS, + V4L2_DEEMPHASIS_75_uS = V4L2_PREEMPHASIS_75_uS, +}; + +#define V4L2_CID_RDS_RECEPTION (V4L2_CID_FM_RX_CLASS_BASE + 2) +#define V4L2_CID_RDS_RX_PTY (V4L2_CID_FM_RX_CLASS_BASE + 3) +#define V4L2_CID_RDS_RX_PS_NAME (V4L2_CID_FM_RX_CLASS_BASE + 4) +#define V4L2_CID_RDS_RX_RADIO_TEXT (V4L2_CID_FM_RX_CLASS_BASE + 5) +#define V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT (V4L2_CID_FM_RX_CLASS_BASE + 6) +#define V4L2_CID_RDS_RX_TRAFFIC_PROGRAM (V4L2_CID_FM_RX_CLASS_BASE + 7) +#define V4L2_CID_RDS_RX_MUSIC_SPEECH (V4L2_CID_FM_RX_CLASS_BASE + 8) + +#define V4L2_CID_RF_TUNER_CLASS_BASE (V4L2_CTRL_CLASS_RF_TUNER | 0x900) +#define V4L2_CID_RF_TUNER_CLASS (V4L2_CTRL_CLASS_RF_TUNER | 1) + +#define V4L2_CID_RF_TUNER_BANDWIDTH_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 11) +#define V4L2_CID_RF_TUNER_BANDWIDTH (V4L2_CID_RF_TUNER_CLASS_BASE + 12) +#define V4L2_CID_RF_TUNER_RF_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 32) +#define V4L2_CID_RF_TUNER_LNA_GAIN_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 41) +#define V4L2_CID_RF_TUNER_LNA_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 42) +#define V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 51) +#define V4L2_CID_RF_TUNER_MIXER_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 52) +#define V4L2_CID_RF_TUNER_IF_GAIN_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 61) +#define V4L2_CID_RF_TUNER_IF_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 62) +#define V4L2_CID_RF_TUNER_PLL_LOCK (V4L2_CID_RF_TUNER_CLASS_BASE + 91) + + +/* Detection-class control IDs defined by V4L2 */ +#define V4L2_CID_DETECT_CLASS_BASE (V4L2_CTRL_CLASS_DETECT | 0x900) +#define V4L2_CID_DETECT_CLASS (V4L2_CTRL_CLASS_DETECT | 1) + +#define V4L2_CID_DETECT_MD_MODE (V4L2_CID_DETECT_CLASS_BASE + 1) +enum v4l2_detect_md_mode { + V4L2_DETECT_MD_MODE_DISABLED = 0, + V4L2_DETECT_MD_MODE_GLOBAL = 1, + V4L2_DETECT_MD_MODE_THRESHOLD_GRID = 2, + V4L2_DETECT_MD_MODE_REGION_GRID = 3, +}; +#define V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD (V4L2_CID_DETECT_CLASS_BASE + 2) +#define V4L2_CID_DETECT_MD_THRESHOLD_GRID (V4L2_CID_DETECT_CLASS_BASE + 3) +#define V4L2_CID_DETECT_MD_REGION_GRID (V4L2_CID_DETECT_CLASS_BASE + 4) + +#endif diff --git a/third_party/openmax/include/OMX_Audio.h b/third_party/openmax/include/OMX_Audio.h deleted file mode 100644 index 0d455766c5..0000000000 --- a/third_party/openmax/include/OMX_Audio.h +++ /dev/null @@ -1,1312 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** @file OMX_Audio.h - OpenMax IL version 1.1.2 - * The structures needed by Audio components to exchange - * parameters and configuration data with the componenmilts. - */ - -#ifndef OMX_Audio_h -#define OMX_Audio_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/* Each OMX header must include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ - -#include - -/** @defgroup midi MIDI - * @ingroup audio - */ - -/** @defgroup effects Audio effects - * @ingroup audio - */ - -/** @defgroup audio OpenMAX IL Audio Domain - * Structures for OpenMAX IL Audio domain - * @{ - */ - -/** Enumeration used to define the possible audio codings. - * If "OMX_AUDIO_CodingUnused" is selected, the coding selection must - * be done in a vendor specific way. Since this is for an audio - * processing element this enum is relevant. However, for another - * type of component other enums would be in this area. - */ -typedef enum OMX_AUDIO_CODINGTYPE { - OMX_AUDIO_CodingUnused = 0, /**< Placeholder value when coding is N/A */ - OMX_AUDIO_CodingAutoDetect, /**< auto detection of audio format */ - OMX_AUDIO_CodingPCM, /**< Any variant of PCM coding */ - OMX_AUDIO_CodingADPCM, /**< Any variant of ADPCM encoded data */ - OMX_AUDIO_CodingAMR, /**< Any variant of AMR encoded data */ - OMX_AUDIO_CodingGSMFR, /**< Any variant of GSM fullrate (i.e. GSM610) */ - OMX_AUDIO_CodingGSMEFR, /**< Any variant of GSM Enhanced Fullrate encoded data*/ - OMX_AUDIO_CodingGSMHR, /**< Any variant of GSM Halfrate encoded data */ - OMX_AUDIO_CodingPDCFR, /**< Any variant of PDC Fullrate encoded data */ - OMX_AUDIO_CodingPDCEFR, /**< Any variant of PDC Enhanced Fullrate encoded data */ - OMX_AUDIO_CodingPDCHR, /**< Any variant of PDC Halfrate encoded data */ - OMX_AUDIO_CodingTDMAFR, /**< Any variant of TDMA Fullrate encoded data (TIA/EIA-136-420) */ - OMX_AUDIO_CodingTDMAEFR, /**< Any variant of TDMA Enhanced Fullrate encoded data (TIA/EIA-136-410) */ - OMX_AUDIO_CodingQCELP8, /**< Any variant of QCELP 8kbps encoded data */ - OMX_AUDIO_CodingQCELP13, /**< Any variant of QCELP 13kbps encoded data */ - OMX_AUDIO_CodingEVRC, /**< Any variant of EVRC encoded data */ - OMX_AUDIO_CodingSMV, /**< Any variant of SMV encoded data */ - OMX_AUDIO_CodingG711, /**< Any variant of G.711 encoded data */ - OMX_AUDIO_CodingG723, /**< Any variant of G.723 dot 1 encoded data */ - OMX_AUDIO_CodingG726, /**< Any variant of G.726 encoded data */ - OMX_AUDIO_CodingG729, /**< Any variant of G.729 encoded data */ - OMX_AUDIO_CodingAAC, /**< Any variant of AAC encoded data */ - OMX_AUDIO_CodingMP3, /**< Any variant of MP3 encoded data */ - OMX_AUDIO_CodingSBC, /**< Any variant of SBC encoded data */ - OMX_AUDIO_CodingVORBIS, /**< Any variant of VORBIS encoded data */ - OMX_AUDIO_CodingWMA, /**< Any variant of WMA encoded data */ - OMX_AUDIO_CodingRA, /**< Any variant of RA encoded data */ - OMX_AUDIO_CodingMIDI, /**< Any variant of MIDI encoded data */ - OMX_AUDIO_CodingAC3, /**< Any variant of AC3 encoded data */ - OMX_AUDIO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_CodingMax = 0x7FFFFFFF -} OMX_AUDIO_CODINGTYPE; - - -/** The PortDefinition structure is used to define all of the parameters - * necessary for the compliant component to setup an input or an output audio - * path. If additional information is needed to define the parameters of the - * port (such as frequency), additional structures must be sent such as the - * OMX_AUDIO_PARAM_PCMMODETYPE structure to supply the extra parameters for the port. - */ -typedef struct OMX_AUDIO_PORTDEFINITIONTYPE { - OMX_STRING cMIMEType; /**< MIME type of data for the port */ - OMX_NATIVE_DEVICETYPE pNativeRender; /** < platform specific reference - for an output device, - otherwise this field is 0 */ - OMX_BOOL bFlagErrorConcealment; /**< Turns on error concealment if it is - supported by the OMX component */ - OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this - port (e.g. PCM, AMR, MP3, etc) */ -} OMX_AUDIO_PORTDEFINITIONTYPE; - - -/** Port format parameter. This structure is used to enumerate - * the various data input/output format supported by the port. - */ -typedef struct OMX_AUDIO_PARAM_PORTFORMATTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Indicates which port to set */ - OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */ - OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this port (e.g. PCM, AMR, MP3, etc) */ -} OMX_AUDIO_PARAM_PORTFORMATTYPE; - - -/** PCM mode type */ -typedef enum OMX_AUDIO_PCMMODETYPE { - OMX_AUDIO_PCMModeLinear = 0, /**< Linear PCM encoded data */ - OMX_AUDIO_PCMModeALaw, /**< A law PCM encoded data (G.711) */ - OMX_AUDIO_PCMModeMULaw, /**< Mu law PCM encoded data (G.711) */ - OMX_AUDIO_PCMModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_PCMModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_PCMModeMax = 0x7FFFFFFF -} OMX_AUDIO_PCMMODETYPE; - - -typedef enum OMX_AUDIO_CHANNELTYPE { - OMX_AUDIO_ChannelNone = 0x0, /**< Unused or empty */ - OMX_AUDIO_ChannelLF = 0x1, /**< Left front */ - OMX_AUDIO_ChannelRF = 0x2, /**< Right front */ - OMX_AUDIO_ChannelCF = 0x3, /**< Center front */ - OMX_AUDIO_ChannelLS = 0x4, /**< Left surround */ - OMX_AUDIO_ChannelRS = 0x5, /**< Right surround */ - OMX_AUDIO_ChannelLFE = 0x6, /**< Low frequency effects */ - OMX_AUDIO_ChannelCS = 0x7, /**< Back surround */ - OMX_AUDIO_ChannelLR = 0x8, /**< Left rear. */ - OMX_AUDIO_ChannelRR = 0x9, /**< Right rear. */ - OMX_AUDIO_ChannelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_ChannelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_ChannelMax = 0x7FFFFFFF -} OMX_AUDIO_CHANNELTYPE; - -#define OMX_AUDIO_MAXCHANNELS 16 /**< maximum number distinct audio channels that a buffer may contain */ -#define OMX_MIN_PCMPAYLOAD_MSEC 5 /**< Minimum audio buffer payload size for uncompressed (PCM) audio */ - -/** PCM format description */ -typedef struct OMX_AUDIO_PARAM_PCMMODETYPE { - OMX_U32 nSize; /**< Size of this structure, in Bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels (e.g. 2 for stereo) */ - OMX_NUMERICALDATATYPE eNumData; /**< indicates PCM data as signed or unsigned */ - OMX_ENDIANTYPE eEndian; /**< indicates PCM data as little or big endian */ - OMX_BOOL bInterleaved; /**< True for normal interleaved data; false for - non-interleaved data (e.g. block data) */ - OMX_U32 nBitPerSample; /**< Bit per sample */ - OMX_U32 nSamplingRate; /**< Sampling rate of the source data. Use 0 for - variable or unknown sampling rate. */ - OMX_AUDIO_PCMMODETYPE ePCMMode; /**< PCM mode enumeration */ - OMX_AUDIO_CHANNELTYPE eChannelMapping[OMX_AUDIO_MAXCHANNELS]; /**< Slot i contains channel defined by eChannelMap[i] */ - -} OMX_AUDIO_PARAM_PCMMODETYPE; - - -/** Audio channel mode. This is used by both AAC and MP3, although the names are more appropriate - * for the MP3. For example, JointStereo for MP3 is CouplingChannels for AAC. - */ -typedef enum OMX_AUDIO_CHANNELMODETYPE { - OMX_AUDIO_ChannelModeStereo = 0, /**< 2 channels, the bitrate allocation between those - two channels changes accordingly to each channel information */ - OMX_AUDIO_ChannelModeJointStereo, /**< mode that takes advantage of what is common between - 2 channels for higher compression gain */ - OMX_AUDIO_ChannelModeDual, /**< 2 mono-channels, each channel is encoded with half - the bitrate of the overall bitrate */ - OMX_AUDIO_ChannelModeMono, /**< Mono channel mode */ - OMX_AUDIO_ChannelModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_ChannelModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_ChannelModeMax = 0x7FFFFFFF -} OMX_AUDIO_CHANNELMODETYPE; - - -typedef enum OMX_AUDIO_MP3STREAMFORMATTYPE { - OMX_AUDIO_MP3StreamFormatMP1Layer3 = 0, /**< MP3 Audio MPEG 1 Layer 3 Stream format */ - OMX_AUDIO_MP3StreamFormatMP2Layer3, /**< MP3 Audio MPEG 2 Layer 3 Stream format */ - OMX_AUDIO_MP3StreamFormatMP2_5Layer3, /**< MP3 Audio MPEG2.5 Layer 3 Stream format */ - OMX_AUDIO_MP3StreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_MP3StreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_MP3StreamFormatMax = 0x7FFFFFFF -} OMX_AUDIO_MP3STREAMFORMATTYPE; - -/** MP3 params */ -typedef struct OMX_AUDIO_PARAM_MP3TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels */ - OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable - rate or unknown bit rates */ - OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for - variable or unknown sampling rate. */ - OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should - limit the audio signal. Use 0 to let encoder decide */ - OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ - OMX_AUDIO_MP3STREAMFORMATTYPE eFormat; /**< MP3 stream format */ -} OMX_AUDIO_PARAM_MP3TYPE; - - -typedef enum OMX_AUDIO_AACSTREAMFORMATTYPE { - OMX_AUDIO_AACStreamFormatMP2ADTS = 0, /**< AAC Audio Data Transport Stream 2 format */ - OMX_AUDIO_AACStreamFormatMP4ADTS, /**< AAC Audio Data Transport Stream 4 format */ - OMX_AUDIO_AACStreamFormatMP4LOAS, /**< AAC Low Overhead Audio Stream format */ - OMX_AUDIO_AACStreamFormatMP4LATM, /**< AAC Low overhead Audio Transport Multiplex */ - OMX_AUDIO_AACStreamFormatADIF, /**< AAC Audio Data Interchange Format */ - OMX_AUDIO_AACStreamFormatMP4FF, /**< AAC inside MPEG-4/ISO File Format */ - OMX_AUDIO_AACStreamFormatRAW, /**< AAC Raw Format */ - OMX_AUDIO_AACStreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_AACStreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_AACStreamFormatMax = 0x7FFFFFFF -} OMX_AUDIO_AACSTREAMFORMATTYPE; - - -/** AAC mode type. Note that the term profile is used with the MPEG-2 - * standard and the term object type and profile is used with MPEG-4 */ -typedef enum OMX_AUDIO_AACPROFILETYPE{ - OMX_AUDIO_AACObjectNull = 0, /**< Null, not used */ - OMX_AUDIO_AACObjectMain = 1, /**< AAC Main object */ - OMX_AUDIO_AACObjectLC, /**< AAC Low Complexity object (AAC profile) */ - OMX_AUDIO_AACObjectSSR, /**< AAC Scalable Sample Rate object */ - OMX_AUDIO_AACObjectLTP, /**< AAC Long Term Prediction object */ - OMX_AUDIO_AACObjectHE, /**< AAC High Efficiency (object type SBR, HE-AAC profile) */ - OMX_AUDIO_AACObjectScalable, /**< AAC Scalable object */ - OMX_AUDIO_AACObjectERLC = 17, /**< ER AAC Low Complexity object (Error Resilient AAC-LC) */ - OMX_AUDIO_AACObjectLD = 23, /**< AAC Low Delay object (Error Resilient) */ - OMX_AUDIO_AACObjectHE_PS = 29, /**< AAC High Efficiency with Parametric Stereo coding (HE-AAC v2, object type PS) */ - OMX_AUDIO_AACObjectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_AACObjectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_AACObjectMax = 0x7FFFFFFF -} OMX_AUDIO_AACPROFILETYPE; - - -/** AAC tool usage (for nAACtools in OMX_AUDIO_PARAM_AACPROFILETYPE). - * Required for encoder configuration and optional as decoder info output. - * For MP3, OMX_AUDIO_CHANNELMODETYPE is sufficient. */ -#define OMX_AUDIO_AACToolNone 0x00000000 /**< no AAC tools allowed (encoder config) or active (decoder info output) */ -#define OMX_AUDIO_AACToolMS 0x00000001 /**< MS: Mid/side joint coding tool allowed or active */ -#define OMX_AUDIO_AACToolIS 0x00000002 /**< IS: Intensity stereo tool allowed or active */ -#define OMX_AUDIO_AACToolTNS 0x00000004 /**< TNS: Temporal Noise Shaping tool allowed or active */ -#define OMX_AUDIO_AACToolPNS 0x00000008 /**< PNS: MPEG-4 Perceptual Noise substitution tool allowed or active */ -#define OMX_AUDIO_AACToolLTP 0x00000010 /**< LTP: MPEG-4 Long Term Prediction tool allowed or active */ -#define OMX_AUDIO_AACToolAll 0x7FFFFFFF /**< all AAC tools allowed or active (*/ - -/** MPEG-4 AAC error resilience (ER) tool usage (for nAACERtools in OMX_AUDIO_PARAM_AACPROFILETYPE). - * Required for ER encoder configuration and optional as decoder info output */ -#define OMX_AUDIO_AACERNone 0x00000000 /**< no AAC ER tools allowed/used */ -#define OMX_AUDIO_AACERVCB11 0x00000001 /**< VCB11: Virtual Code Books for AAC section data */ -#define OMX_AUDIO_AACERRVLC 0x00000002 /**< RVLC: Reversible Variable Length Coding */ -#define OMX_AUDIO_AACERHCR 0x00000004 /**< HCR: Huffman Codeword Reordering */ -#define OMX_AUDIO_AACERAll 0x7FFFFFFF /**< all AAC ER tools allowed/used */ - - -/** AAC params */ -typedef struct OMX_AUDIO_PARAM_AACPROFILETYPE { - OMX_U32 nSize; /**< Size of this structure, in Bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels */ - OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for - variable or unknown sampling rate. */ - OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable - rate or unknown bit rates */ - OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should - limit the audio signal. Use 0 to let encoder decide */ - OMX_U32 nFrameLength; /**< Frame length (in audio samples per channel) of the codec. - Can be 1024 or 960 (AAC-LC), 2048 (HE-AAC), 480 or 512 (AAC-LD). - Use 0 to let encoder decide */ - OMX_U32 nAACtools; /**< AAC tool usage */ - OMX_U32 nAACERtools; /**< MPEG-4 AAC error resilience tool usage */ - OMX_AUDIO_AACPROFILETYPE eAACProfile; /**< AAC profile enumeration */ - OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat; /**< AAC stream format enumeration */ - OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ -} OMX_AUDIO_PARAM_AACPROFILETYPE; - - -/** VORBIS params */ -typedef struct OMX_AUDIO_PARAM_VORBISTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels */ - OMX_U32 nBitRate; /**< Bit rate of the encoded data data. Use 0 for variable - rate or unknown bit rates. Encoding is set to the - bitrate closest to specified value (in bps) */ - OMX_U32 nMinBitRate; /**< Sets minimum bitrate (in bps). */ - OMX_U32 nMaxBitRate; /**< Sets maximum bitrate (in bps). */ - - OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for - variable or unknown sampling rate. */ - OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should - limit the audio signal. Use 0 to let encoder decide */ - OMX_S32 nQuality; /**< Sets encoding quality to n, between -1 (low) and 10 (high). - In the default mode of operation, teh quality level is 3. - Normal quality range is 0 - 10. */ - OMX_BOOL bManaged; /**< Set bitrate management mode. This turns off the - normal VBR encoding, but allows hard or soft bitrate - constraints to be enforced by the encoder. This mode can - be slower, and may also be lower quality. It is - primarily useful for streaming. */ - OMX_BOOL bDownmix; /**< Downmix input from stereo to mono (has no effect on - non-stereo streams). Useful for lower-bitrate encoding. */ -} OMX_AUDIO_PARAM_VORBISTYPE; - - -/** WMA Version */ -typedef enum OMX_AUDIO_WMAFORMATTYPE { - OMX_AUDIO_WMAFormatUnused = 0, /**< format unused or unknown */ - OMX_AUDIO_WMAFormat7, /**< Windows Media Audio format 7 */ - OMX_AUDIO_WMAFormat8, /**< Windows Media Audio format 8 */ - OMX_AUDIO_WMAFormat9, /**< Windows Media Audio format 9 */ - OMX_AUDIO_WMAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_WMAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_WMAFormatMax = 0x7FFFFFFF -} OMX_AUDIO_WMAFORMATTYPE; - - -/** WMA Profile */ -typedef enum OMX_AUDIO_WMAPROFILETYPE { - OMX_AUDIO_WMAProfileUnused = 0, /**< profile unused or unknown */ - OMX_AUDIO_WMAProfileL1, /**< Windows Media audio version 9 profile L1 */ - OMX_AUDIO_WMAProfileL2, /**< Windows Media audio version 9 profile L2 */ - OMX_AUDIO_WMAProfileL3, /**< Windows Media audio version 9 profile L3 */ - OMX_AUDIO_WMAProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_WMAProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_WMAProfileMax = 0x7FFFFFFF -} OMX_AUDIO_WMAPROFILETYPE; - - -/** WMA params */ -typedef struct OMX_AUDIO_PARAM_WMATYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U16 nChannels; /**< Number of channels */ - OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable - rate or unknown bit rates */ - OMX_AUDIO_WMAFORMATTYPE eFormat; /**< Version of WMA stream / data */ - OMX_AUDIO_WMAPROFILETYPE eProfile; /**< Profile of WMA stream / data */ - OMX_U32 nSamplingRate; /**< Sampling rate of the source data */ - OMX_U16 nBlockAlign; /**< is the block alignment, or block size, in bytes of the audio codec */ - OMX_U16 nEncodeOptions; /**< WMA Type-specific data */ - OMX_U32 nSuperBlockAlign; /**< WMA Type-specific data */ -} OMX_AUDIO_PARAM_WMATYPE; - -/** - * RealAudio format - */ -typedef enum OMX_AUDIO_RAFORMATTYPE { - OMX_AUDIO_RAFormatUnused = 0, /**< Format unused or unknown */ - OMX_AUDIO_RA8, /**< RealAudio 8 codec */ - OMX_AUDIO_RA9, /**< RealAudio 9 codec */ - OMX_AUDIO_RA10_AAC, /**< MPEG-4 AAC codec for bitrates of more than 128kbps */ - OMX_AUDIO_RA10_CODEC, /**< RealAudio codec for bitrates less than 128 kbps */ - OMX_AUDIO_RA10_LOSSLESS, /**< RealAudio Lossless */ - OMX_AUDIO_RA10_MULTICHANNEL, /**< RealAudio Multichannel */ - OMX_AUDIO_RA10_VOICE, /**< RealAudio Voice for bitrates below 15 kbps */ - OMX_AUDIO_RAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_RAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_RAFormatMax = 0x7FFFFFFF -} OMX_AUDIO_RAFORMATTYPE; - -/** RA (Real Audio) params */ -typedef struct OMX_AUDIO_PARAM_RATYPE { - OMX_U32 nSize; /**< Size of this structure, in Bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels */ - OMX_U32 nSamplingRate; /**< is the sampling rate of the source data */ - OMX_U32 nBitsPerFrame; /**< is the value for bits per frame */ - OMX_U32 nSamplePerFrame; /**< is the value for samples per frame */ - OMX_U32 nCouplingQuantBits; /**< is the number of coupling quantization bits in the stream */ - OMX_U32 nCouplingStartRegion; /**< is the coupling start region in the stream */ - OMX_U32 nNumRegions; /**< is the number of regions value */ - OMX_AUDIO_RAFORMATTYPE eFormat; /**< is the RealAudio audio format */ -} OMX_AUDIO_PARAM_RATYPE; - - -/** SBC Allocation Method Type */ -typedef enum OMX_AUDIO_SBCALLOCMETHODTYPE { - OMX_AUDIO_SBCAllocMethodLoudness, /**< Loudness allocation method */ - OMX_AUDIO_SBCAllocMethodSNR, /**< SNR allocation method */ - OMX_AUDIO_SBCAllocMethodKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_SBCAllocMethodVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_SBCAllocMethodMax = 0x7FFFFFFF -} OMX_AUDIO_SBCALLOCMETHODTYPE; - - -/** SBC params */ -typedef struct OMX_AUDIO_PARAM_SBCTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels */ - OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable - rate or unknown bit rates */ - OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for - variable or unknown sampling rate. */ - OMX_U32 nBlocks; /**< Number of blocks */ - OMX_U32 nSubbands; /**< Number of subbands */ - OMX_U32 nBitPool; /**< Bitpool value */ - OMX_BOOL bEnableBitrate; /**< Use bitrate value instead of bitpool */ - OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ - OMX_AUDIO_SBCALLOCMETHODTYPE eSBCAllocType; /**< SBC Allocation method type */ -} OMX_AUDIO_PARAM_SBCTYPE; - - -/** ADPCM stream format parameters */ -typedef struct OMX_AUDIO_PARAM_ADPCMTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_U32 nBitsPerSample; /**< Number of bits in each sample */ - OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for - variable or unknown sampling rate. */ -} OMX_AUDIO_PARAM_ADPCMTYPE; - - -/** G723 rate */ -typedef enum OMX_AUDIO_G723RATE { - OMX_AUDIO_G723ModeUnused = 0, /**< AMRNB Mode unused / unknown */ - OMX_AUDIO_G723ModeLow, /**< 5300 bps */ - OMX_AUDIO_G723ModeHigh, /**< 6300 bps */ - OMX_AUDIO_G723ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_G723ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_G723ModeMax = 0x7FFFFFFF -} OMX_AUDIO_G723RATE; - - -/** G723 - Sample rate must be 8 KHz */ -typedef struct OMX_AUDIO_PARAM_G723TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_AUDIO_G723RATE eBitRate; /**< todo: Should this be moved to a config? */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ - OMX_BOOL bPostFilter; /**< Enable Post Filter */ -} OMX_AUDIO_PARAM_G723TYPE; - - -/** ITU G726 (ADPCM) rate */ -typedef enum OMX_AUDIO_G726MODE { - OMX_AUDIO_G726ModeUnused = 0, /**< G726 Mode unused / unknown */ - OMX_AUDIO_G726Mode16, /**< 16 kbps */ - OMX_AUDIO_G726Mode24, /**< 24 kbps */ - OMX_AUDIO_G726Mode32, /**< 32 kbps, most common rate, also G721 */ - OMX_AUDIO_G726Mode40, /**< 40 kbps */ - OMX_AUDIO_G726ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_G726ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_G726ModeMax = 0x7FFFFFFF -} OMX_AUDIO_G726MODE; - - -/** G.726 stream format parameters - must be at 8KHz */ -typedef struct OMX_AUDIO_PARAM_G726TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_AUDIO_G726MODE eG726Mode; -} OMX_AUDIO_PARAM_G726TYPE; - - -/** G729 coder type */ -typedef enum OMX_AUDIO_G729TYPE { - OMX_AUDIO_G729 = 0, /**< ITU G.729 encoded data */ - OMX_AUDIO_G729A, /**< ITU G.729 annex A encoded data */ - OMX_AUDIO_G729B, /**< ITU G.729 with annex B encoded data */ - OMX_AUDIO_G729AB, /**< ITU G.729 annexes A and B encoded data */ - OMX_AUDIO_G729KhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_G729VendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_G729Max = 0x7FFFFFFF -} OMX_AUDIO_G729TYPE; - - -/** G729 stream format parameters - fixed 6KHz sample rate */ -typedef struct OMX_AUDIO_PARAM_G729TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_AUDIO_G729TYPE eBitType; -} OMX_AUDIO_PARAM_G729TYPE; - - -/** AMR Frame format */ -typedef enum OMX_AUDIO_AMRFRAMEFORMATTYPE { - OMX_AUDIO_AMRFrameFormatConformance = 0, /**< Frame Format is AMR Conformance - (Standard) Format */ - OMX_AUDIO_AMRFrameFormatIF1, /**< Frame Format is AMR Interface - Format 1 */ - OMX_AUDIO_AMRFrameFormatIF2, /**< Frame Format is AMR Interface - Format 2*/ - OMX_AUDIO_AMRFrameFormatFSF, /**< Frame Format is AMR File Storage - Format */ - OMX_AUDIO_AMRFrameFormatRTPPayload, /**< Frame Format is AMR Real-Time - Transport Protocol Payload Format */ - OMX_AUDIO_AMRFrameFormatITU, /**< Frame Format is ITU Format (added at Motorola request) */ - OMX_AUDIO_AMRFrameFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_AMRFrameFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_AMRFrameFormatMax = 0x7FFFFFFF -} OMX_AUDIO_AMRFRAMEFORMATTYPE; - - -/** AMR band mode */ -typedef enum OMX_AUDIO_AMRBANDMODETYPE { - OMX_AUDIO_AMRBandModeUnused = 0, /**< AMRNB Mode unused / unknown */ - OMX_AUDIO_AMRBandModeNB0, /**< AMRNB Mode 0 = 4750 bps */ - OMX_AUDIO_AMRBandModeNB1, /**< AMRNB Mode 1 = 5150 bps */ - OMX_AUDIO_AMRBandModeNB2, /**< AMRNB Mode 2 = 5900 bps */ - OMX_AUDIO_AMRBandModeNB3, /**< AMRNB Mode 3 = 6700 bps */ - OMX_AUDIO_AMRBandModeNB4, /**< AMRNB Mode 4 = 7400 bps */ - OMX_AUDIO_AMRBandModeNB5, /**< AMRNB Mode 5 = 7950 bps */ - OMX_AUDIO_AMRBandModeNB6, /**< AMRNB Mode 6 = 10200 bps */ - OMX_AUDIO_AMRBandModeNB7, /**< AMRNB Mode 7 = 12200 bps */ - OMX_AUDIO_AMRBandModeWB0, /**< AMRWB Mode 0 = 6600 bps */ - OMX_AUDIO_AMRBandModeWB1, /**< AMRWB Mode 1 = 8850 bps */ - OMX_AUDIO_AMRBandModeWB2, /**< AMRWB Mode 2 = 12650 bps */ - OMX_AUDIO_AMRBandModeWB3, /**< AMRWB Mode 3 = 14250 bps */ - OMX_AUDIO_AMRBandModeWB4, /**< AMRWB Mode 4 = 15850 bps */ - OMX_AUDIO_AMRBandModeWB5, /**< AMRWB Mode 5 = 18250 bps */ - OMX_AUDIO_AMRBandModeWB6, /**< AMRWB Mode 6 = 19850 bps */ - OMX_AUDIO_AMRBandModeWB7, /**< AMRWB Mode 7 = 23050 bps */ - OMX_AUDIO_AMRBandModeWB8, /**< AMRWB Mode 8 = 23850 bps */ - OMX_AUDIO_AMRBandModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_AMRBandModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_AMRBandModeMax = 0x7FFFFFFF -} OMX_AUDIO_AMRBANDMODETYPE; - - -/** AMR Discontinuous Transmission mode */ -typedef enum OMX_AUDIO_AMRDTXMODETYPE { - OMX_AUDIO_AMRDTXModeOff = 0, /**< AMR Discontinuous Transmission Mode is disabled */ - OMX_AUDIO_AMRDTXModeOnVAD1, /**< AMR Discontinuous Transmission Mode using - Voice Activity Detector 1 (VAD1) is enabled */ - OMX_AUDIO_AMRDTXModeOnVAD2, /**< AMR Discontinuous Transmission Mode using - Voice Activity Detector 2 (VAD2) is enabled */ - OMX_AUDIO_AMRDTXModeOnAuto, /**< The codec will automatically select between - Off, VAD1 or VAD2 modes */ - - OMX_AUDIO_AMRDTXasEFR, /**< DTX as EFR instead of AMR standard (3GPP 26.101, frame type =8,9,10) */ - - OMX_AUDIO_AMRDTXModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_AMRDTXModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_AMRDTXModeMax = 0x7FFFFFFF -} OMX_AUDIO_AMRDTXMODETYPE; - - -/** AMR params */ -typedef struct OMX_AUDIO_PARAM_AMRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels */ - OMX_U32 nBitRate; /**< Bit rate read only field */ - OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode; /**< AMR Band Mode enumeration */ - OMX_AUDIO_AMRDTXMODETYPE eAMRDTXMode; /**< AMR DTX Mode enumeration */ - OMX_AUDIO_AMRFRAMEFORMATTYPE eAMRFrameFormat; /**< AMR frame format enumeration */ -} OMX_AUDIO_PARAM_AMRTYPE; - - -/** GSM_FR (ETSI 06.10, 3GPP 46.010) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_GSMFRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_GSMFRTYPE; - - -/** GSM-HR (ETSI 06.20, 3GPP 46.020) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_GSMHRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_GSMHRTYPE; - - -/** GSM-EFR (ETSI 06.60, 3GPP 46.060) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_GSMEFRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_GSMEFRTYPE; - - -/** TDMA FR (TIA/EIA-136-420, VSELP 7.95kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_TDMAFRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_TDMAFRTYPE; - - -/** TDMA EFR (TIA/EIA-136-410, ACELP 7.4kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_TDMAEFRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_TDMAEFRTYPE; - - -/** PDC FR ( RCR-27, VSELP 6.7kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_PDCFRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_PDCFRTYPE; - - -/** PDC EFR ( RCR-27, ACELP 6.7kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_PDCEFRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_PDCEFRTYPE; - -/** PDC HR ( RCR-27, PSI-CELP 3.45kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_PDCHRTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ - OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ -} OMX_AUDIO_PARAM_PDCHRTYPE; - - -/** CDMA Rate types */ -typedef enum OMX_AUDIO_CDMARATETYPE { - OMX_AUDIO_CDMARateBlank = 0, /**< CDMA encoded frame is blank */ - OMX_AUDIO_CDMARateFull, /**< CDMA encoded frame in full rate */ - OMX_AUDIO_CDMARateHalf, /**< CDMA encoded frame in half rate */ - OMX_AUDIO_CDMARateQuarter, /**< CDMA encoded frame in quarter rate */ - OMX_AUDIO_CDMARateEighth, /**< CDMA encoded frame in eighth rate (DTX)*/ - OMX_AUDIO_CDMARateErasure, /**< CDMA erasure frame */ - OMX_AUDIO_CDMARateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_CDMARateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_CDMARateMax = 0x7FFFFFFF -} OMX_AUDIO_CDMARATETYPE; - - -/** QCELP8 (TIA/EIA-96, up to 8kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_QCELP8TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable - rate or unknown bit rates */ - OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ - OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ - OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ -} OMX_AUDIO_PARAM_QCELP8TYPE; - - -/** QCELP13 ( CDMA, EIA/TIA-733, 13.3kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_QCELP13TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ - OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ - OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ -} OMX_AUDIO_PARAM_QCELP13TYPE; - - -/** EVRC ( CDMA, EIA/TIA-127, RCELP up to 8.55kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_EVRCTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_AUDIO_CDMARATETYPE eCDMARate; /**< actual Frame rate */ - OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */ - OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ - OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ - OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter */ - OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */ - OMX_BOOL bPostFilter; /**< Enable decoder's post Filter */ -} OMX_AUDIO_PARAM_EVRCTYPE; - - -/** SMV ( up to 8.55kbps coder) stream format parameters */ -typedef struct OMX_AUDIO_PARAM_SMVTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannels; /**< Number of channels in the data stream (not - necessarily the same as the number of channels - to be rendered. */ - OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ - OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */ - OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 ??*/ - OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 ??*/ - OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter ??*/ - OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */ - OMX_BOOL bPostFilter; /**< Enable decoder's post Filter ??*/ -} OMX_AUDIO_PARAM_SMVTYPE; - - -/** MIDI Format - * @ingroup midi - */ -typedef enum OMX_AUDIO_MIDIFORMATTYPE -{ - OMX_AUDIO_MIDIFormatUnknown = 0, /**< MIDI Format unknown or don't care */ - OMX_AUDIO_MIDIFormatSMF0, /**< Standard MIDI File Type 0 */ - OMX_AUDIO_MIDIFormatSMF1, /**< Standard MIDI File Type 1 */ - OMX_AUDIO_MIDIFormatSMF2, /**< Standard MIDI File Type 2 */ - OMX_AUDIO_MIDIFormatSPMIDI, /**< SP-MIDI */ - OMX_AUDIO_MIDIFormatXMF0, /**< eXtensible Music Format type 0 */ - OMX_AUDIO_MIDIFormatXMF1, /**< eXtensible Music Format type 1 */ - OMX_AUDIO_MIDIFormatMobileXMF, /**< Mobile XMF (eXtensible Music Format type 2) */ - OMX_AUDIO_MIDIFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_MIDIFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_MIDIFormatMax = 0x7FFFFFFF -} OMX_AUDIO_MIDIFORMATTYPE; - - -/** MIDI params - * @ingroup midi - */ -typedef struct OMX_AUDIO_PARAM_MIDITYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nFileSize; /**< size of the MIDI file in bytes, where the entire - MIDI file passed in, otherwise if 0x0, the MIDI data - is merged and streamed (instead of passed as an - entire MIDI file) */ - OMX_BU32 sMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic - voices. A value of zero indicates that the default - polyphony of the device is used */ - OMX_BOOL bLoadDefaultSound; /**< Whether to load default sound - bank at initialization */ - OMX_AUDIO_MIDIFORMATTYPE eMidiFormat; /**< Version of the MIDI file */ -} OMX_AUDIO_PARAM_MIDITYPE; - - -/** Type of the MIDI sound bank - * @ingroup midi - */ -typedef enum OMX_AUDIO_MIDISOUNDBANKTYPE { - OMX_AUDIO_MIDISoundBankUnused = 0, /**< unused/unknown soundbank type */ - OMX_AUDIO_MIDISoundBankDLS1, /**< DLS version 1 */ - OMX_AUDIO_MIDISoundBankDLS2, /**< DLS version 2 */ - OMX_AUDIO_MIDISoundBankMobileDLSBase, /**< Mobile DLS, using the base functionality */ - OMX_AUDIO_MIDISoundBankMobileDLSPlusOptions, /**< Mobile DLS, using the specification-defined optional feature set */ - OMX_AUDIO_MIDISoundBankKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_MIDISoundBankVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_MIDISoundBankMax = 0x7FFFFFFF -} OMX_AUDIO_MIDISOUNDBANKTYPE; - - -/** Bank Layout describes how bank MSB & LSB are used in the DLS instrument definitions sound bank - * @ingroup midi - */ -typedef enum OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE { - OMX_AUDIO_MIDISoundBankLayoutUnused = 0, /**< unused/unknown soundbank type */ - OMX_AUDIO_MIDISoundBankLayoutGM, /**< GS layout (based on bank MSB 0x00) */ - OMX_AUDIO_MIDISoundBankLayoutGM2, /**< General MIDI 2 layout (using MSB 0x78/0x79, LSB 0x00) */ - OMX_AUDIO_MIDISoundBankLayoutUser, /**< Does not conform to any bank numbering standards */ - OMX_AUDIO_MIDISoundBankLayoutKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_MIDISoundBankLayoutVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_MIDISoundBankLayoutMax = 0x7FFFFFFF -} OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE; - - -/** MIDI params to load/unload user soundbank - * @ingroup midi - */ -typedef struct OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nDLSIndex; /**< DLS file index to be loaded */ - OMX_U32 nDLSSize; /**< Size in bytes */ - OMX_PTR pDLSData; /**< Pointer to DLS file data */ - OMX_AUDIO_MIDISOUNDBANKTYPE eMidiSoundBank; /**< Midi sound bank type enumeration */ - OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE eMidiSoundBankLayout; /**< Midi sound bank layout enumeration */ -} OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE; - - -/** Structure for Live MIDI events and MIP messages. - * (MIP = Maximum Instantaneous Polyphony; part of the SP-MIDI standard.) - * @ingroup midi - */ -typedef struct OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port that this structure applies to */ - OMX_U32 nMidiEventSize; /**< Size of immediate MIDI events or MIP message in bytes */ - OMX_U8 nMidiEvents[1]; /**< MIDI event array to be rendered immediately, or an - array for the MIP message buffer, where the size is - indicated by nMidiEventSize */ -} OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE; - - -/** MIDI sound bank/ program pair in a given channel - * @ingroup midi - */ -typedef struct OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port that this structure applies to */ - OMX_U32 nChannel; /**< Valid channel values range from 1 to 16 */ - OMX_U16 nIDProgram; /**< Valid program ID range is 1 to 128 */ - OMX_U16 nIDSoundBank; /**< Sound bank ID */ - OMX_U32 nUserSoundBankIndex;/**< User soundbank index, easier to access soundbanks - by index if multiple banks are present */ -} OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE; - - -/** MIDI control - * @ingroup midi - */ -typedef struct OMX_AUDIO_CONFIG_MIDICONTROLTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BS32 sPitchTransposition; /**< Pitch transposition in semitones, stored as Q22.10 - format based on JAVA MMAPI (JSR-135) requirement */ - OMX_BU32 sPlayBackRate; /**< Relative playback rate, stored as Q14.17 fixed-point - number based on JSR-135 requirement */ - OMX_BU32 sTempo ; /**< Tempo in beats per minute (BPM), stored as Q22.10 - fixed-point number based on JSR-135 requirement */ - OMX_U32 nMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic - voices. A value of zero indicates that the default - polyphony of the device is used */ - OMX_U32 nNumRepeat; /**< Number of times to repeat playback */ - OMX_U32 nStopTime; /**< Time in milliseconds to indicate when playback - will stop automatically. Set to zero if not used */ - OMX_U16 nChannelMuteMask; /**< 16 bit mask for channel mute status */ - OMX_U16 nChannelSoloMask; /**< 16 bit mask for channel solo status */ - OMX_U32 nTrack0031MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 0-31 */ - OMX_U32 nTrack3263MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 32-63 */ - OMX_U32 nTrack0031SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 0-31 */ - OMX_U32 nTrack3263SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 32-63 */ - -} OMX_AUDIO_CONFIG_MIDICONTROLTYPE; - - -/** MIDI Playback States - * @ingroup midi - */ -typedef enum OMX_AUDIO_MIDIPLAYBACKSTATETYPE { - OMX_AUDIO_MIDIPlayBackStateUnknown = 0, /**< Unknown state or state does not map to - other defined states */ - OMX_AUDIO_MIDIPlayBackStateClosedEngaged, /**< No MIDI resource is currently open. - The MIDI engine is currently processing - MIDI events. */ - OMX_AUDIO_MIDIPlayBackStateParsing, /**< A MIDI resource is open and is being - primed. The MIDI engine is currently - processing MIDI events. */ - OMX_AUDIO_MIDIPlayBackStateOpenEngaged, /**< A MIDI resource is open and primed but - not playing. The MIDI engine is currently - processing MIDI events. The transition to - this state is only possible from the - OMX_AUDIO_MIDIPlayBackStatePlaying state, - when the 'playback head' reaches the end - of media data or the playback stops due - to stop time set.*/ - OMX_AUDIO_MIDIPlayBackStatePlaying, /**< A MIDI resource is open and currently - playing. The MIDI engine is currently - processing MIDI events.*/ - OMX_AUDIO_MIDIPlayBackStatePlayingPartially, /**< Best-effort playback due to SP-MIDI/DLS - resource constraints */ - OMX_AUDIO_MIDIPlayBackStatePlayingSilently, /**< Due to system resource constraints and - SP-MIDI content constraints, there is - no audible MIDI content during playback - currently. The situation may change if - resources are freed later.*/ - OMX_AUDIO_MIDIPlayBackStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_MIDIPlayBackStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_MIDIPlayBackStateMax = 0x7FFFFFFF -} OMX_AUDIO_MIDIPLAYBACKSTATETYPE; - - -/** MIDI status - * @ingroup midi - */ -typedef struct OMX_AUDIO_CONFIG_MIDISTATUSTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U16 nNumTracks; /**< Number of MIDI tracks in the file, read only field. - NOTE: May not return a meaningful value until the entire - file is parsed and buffered. */ - OMX_U32 nDuration; /**< The length of the currently open MIDI resource - in milliseconds. NOTE: May not return a meaningful value - until the entire file is parsed and buffered. */ - OMX_U32 nPosition; /**< Current Position of the MIDI resource being played - in milliseconds */ - OMX_BOOL bVibra; /**< Does Vibra track exist? NOTE: May not return a meaningful - value until the entire file is parsed and buffered. */ - OMX_U32 nNumMetaEvents; /**< Total number of MIDI Meta Events in the currently - open MIDI resource. NOTE: May not return a meaningful value - until the entire file is parsed and buffered. */ - OMX_U32 nNumActiveVoices; /**< Number of active voices in the currently playing - MIDI resource. NOTE: May not return a meaningful value until - the entire file is parsed and buffered. */ - OMX_AUDIO_MIDIPLAYBACKSTATETYPE eMIDIPlayBackState; /**< MIDI playback state enumeration, read only field */ -} OMX_AUDIO_CONFIG_MIDISTATUSTYPE; - - -/** MIDI Meta Event structure one per Meta Event. - * MIDI Meta Events are like audio metadata, except that they are interspersed - * with the MIDI content throughout the file and are not localized in the header. - * As such, it is necessary to retrieve information about these Meta Events from - * the engine, as it encounters these Meta Events within the MIDI content. - * For example, SMF files can have up to 14 types of MIDI Meta Events (copyright, - * author, default tempo, etc.) scattered throughout the file. - * @ingroup midi - */ -typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE{ - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nIndex; /**< Index of Meta Event */ - OMX_U8 nMetaEventType; /**< Meta Event Type, 7bits (i.e. 0 - 127) */ - OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */ - OMX_U32 nTrack; /**< track number for the meta event */ - OMX_U32 nPosition; /**< Position of the meta-event in milliseconds */ -} OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE; - - -/** MIDI Meta Event Data structure - one per Meta Event. - * @ingroup midi - */ -typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE{ - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nIndex; /**< Index of Meta Event */ - OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */ - OMX_U8 nData[1]; /**< array of one or more bytes of meta data - as indicated by the nMetaEventSize field */ -} OMX_AUDIO_CONFIG__MIDIMETAEVENTDATATYPE; - - -/** Audio Volume adjustment for a port */ -typedef struct OMX_AUDIO_CONFIG_VOLUMETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port index indicating which port to - set. Select the input port to set - just that port's volume. Select the - output port to adjust the master - volume. */ - OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) - or logarithmic scale (mB) */ - OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR - Volume logarithmic setting for this port. The values - for volume are in mB (millibels = 1/100 dB) relative - to a gain of 1 (e.g. the output is the same as the - input level). Values are in mB from nMax - (maximum volume) to nMin mB (typically negative). - Since the volume is "voltage" - and not a "power", it takes a setting of - -600 mB to decrease the volume by 1/2. If - a component cannot accurately set the - volume to the requested value, it must - set the volume to the closest value BELOW - the requested value. When getting the - volume setting, the current actual volume - must be returned. */ -} OMX_AUDIO_CONFIG_VOLUMETYPE; - - -/** Audio Volume adjustment for a channel */ -typedef struct OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port index indicating which port to - set. Select the input port to set - just that port's volume. Select the - output port to adjust the master - volume. */ - OMX_U32 nChannel; /**< channel to select from 0 to N-1, - using OMX_ALL to apply volume settings - to all channels */ - OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) or - logarithmic scale (mB) */ - OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR - Volume logarithmic setting for this port. - The values for volume are in mB - (millibels = 1/100 dB) relative to a gain - of 1 (e.g. the output is the same as the - input level). Values are in mB from nMax - (maximum volume) to nMin mB (typically negative). - Since the volume is "voltage" - and not a "power", it takes a setting of - -600 mB to decrease the volume by 1/2. If - a component cannot accurately set the - volume to the requested value, it must - set the volume to the closest value BELOW - the requested value. When getting the - volume setting, the current actual volume - must be returned. */ - OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel, - FALSE otherwise */ -} OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE; - - -/** Audio balance setting */ -typedef struct OMX_AUDIO_CONFIG_BALANCETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port index indicating which port to - set. Select the input port to set - just that port's balance. Select the - output port to adjust the master - balance. */ - OMX_S32 nBalance; /**< balance setting for this port - (-100 to 100, where -100 indicates - all left, and no right */ -} OMX_AUDIO_CONFIG_BALANCETYPE; - - -/** Audio Port mute */ -typedef struct OMX_AUDIO_CONFIG_MUTETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port index indicating which port to - set. Select the input port to set - just that port's mute. Select the - output port to adjust the master - mute. */ - OMX_BOOL bMute; /**< Mute setting for this port */ -} OMX_AUDIO_CONFIG_MUTETYPE; - - -/** Audio Channel mute */ -typedef struct OMX_AUDIO_CONFIG_CHANNELMUTETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nChannel; /**< channel to select from 0 to N-1, - using OMX_ALL to apply mute settings - to all channels */ - OMX_BOOL bMute; /**< Mute setting for this channel */ - OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel, - FALSE otherwise */ -} OMX_AUDIO_CONFIG_CHANNELMUTETYPE; - - - -/** Enable / Disable for loudness control, which boosts bass and to a - * smaller extent high end frequencies to compensate for hearing - * ability at the extreme ends of the audio spectrum - */ -typedef struct OMX_AUDIO_CONFIG_LOUDNESSTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bLoudness; /**< Enable/disable for loudness */ -} OMX_AUDIO_CONFIG_LOUDNESSTYPE; - - -/** Enable / Disable for bass, which controls low frequencies - */ -typedef struct OMX_AUDIO_CONFIG_BASSTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bEnable; /**< Enable/disable for bass control */ - OMX_S32 nBass; /**< bass setting for the port, as a - continuous value from -100 to 100 - (0 means no change in bass level)*/ -} OMX_AUDIO_CONFIG_BASSTYPE; - - -/** Enable / Disable for treble, which controls high frequencies tones - */ -typedef struct OMX_AUDIO_CONFIG_TREBLETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bEnable; /**< Enable/disable for treble control */ - OMX_S32 nTreble; /**< treble setting for the port, as a - continuous value from -100 to 100 - (0 means no change in treble level) */ -} OMX_AUDIO_CONFIG_TREBLETYPE; - - -/** An equalizer is typically used for two reasons: to compensate for an - * sub-optimal frequency response of a system to make it sound more natural - * or to create intentionally some unnatural coloring to the sound to create - * an effect. - * @ingroup effects - */ -typedef struct OMX_AUDIO_CONFIG_EQUALIZERTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bEnable; /**< Enable/disable for equalizer */ - OMX_BU32 sBandIndex; /**< Band number to be set. Upper Limit is - N-1, where N is the number of bands, lower limit is 0 */ - OMX_BU32 sCenterFreq; /**< Center frequecies in Hz. This is a - read only element and is used to determine - the lower, center and upper frequency of - this band. */ - OMX_BS32 sBandLevel; /**< band level in millibels */ -} OMX_AUDIO_CONFIG_EQUALIZERTYPE; - - -/** Stereo widening mode type - * @ingroup effects - */ -typedef enum OMX_AUDIO_STEREOWIDENINGTYPE { - OMX_AUDIO_StereoWideningHeadphones, /**< Stereo widening for loudspeakers */ - OMX_AUDIO_StereoWideningLoudspeakers, /**< Stereo widening for closely spaced loudspeakers */ - OMX_AUDIO_StereoWideningKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_StereoWideningVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_StereoWideningMax = 0x7FFFFFFF -} OMX_AUDIO_STEREOWIDENINGTYPE; - - -/** Control for stereo widening, which is a special 2-channel - * case of the audio virtualizer effect. For example, for 5.1-channel - * output, it translates to virtual surround sound. - * @ingroup effects - */ -typedef struct OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bEnable; /**< Enable/disable for stereo widening control */ - OMX_AUDIO_STEREOWIDENINGTYPE eWideningType; /**< Stereo widening algorithm type */ - OMX_U32 nStereoWidening; /**< stereo widening setting for the port, - as a continuous value from 0 to 100 */ -} OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE; - - -/** The chorus effect (or ``choralizer'') is any signal processor which makes - * one sound source (such as a voice) sound like many such sources singing - * (or playing) in unison. Since performance in unison is never exact, chorus - * effects simulate this by making independently modified copies of the input - * signal. Modifications may include (1) delay, (2) frequency shift, and - * (3) amplitude modulation. - * @ingroup effects - */ -typedef struct OMX_AUDIO_CONFIG_CHORUSTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bEnable; /**< Enable/disable for chorus */ - OMX_BU32 sDelay; /**< average delay in milliseconds */ - OMX_BU32 sModulationRate; /**< rate of modulation in millihertz */ - OMX_U32 nModulationDepth; /**< depth of modulation as a percentage of - delay (i.e. 0 to 100) */ - OMX_BU32 nFeedback; /**< Feedback from chorus output to input in percentage */ -} OMX_AUDIO_CONFIG_CHORUSTYPE; - - -/** Reverberation is part of the reflected sound that follows the early - * reflections. In a typical room, this consists of a dense succession of - * echoes whose energy decays exponentially. The reverberation effect structure - * as defined here includes both (early) reflections as well as (late) reverberations. - * @ingroup effects - */ -typedef struct OMX_AUDIO_CONFIG_REVERBERATIONTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bEnable; /**< Enable/disable for reverberation control */ - OMX_BS32 sRoomLevel; /**< Intensity level for the whole room effect - (i.e. both early reflections and late - reverberation) in millibels */ - OMX_BS32 sRoomHighFreqLevel; /**< Attenuation at high frequencies - relative to the intensity at low - frequencies in millibels */ - OMX_BS32 sReflectionsLevel; /**< Intensity level of early reflections - (relative to room value), in millibels */ - OMX_BU32 sReflectionsDelay; /**< Delay time of the first reflection relative - to the direct path, in milliseconds */ - OMX_BS32 sReverbLevel; /**< Intensity level of late reverberation - relative to room level, in millibels */ - OMX_BU32 sReverbDelay; /**< Time delay from the first early reflection - to the beginning of the late reverberation - section, in milliseconds */ - OMX_BU32 sDecayTime; /**< Late reverberation decay time at low - frequencies, in milliseconds */ - OMX_BU32 nDecayHighFreqRatio; /**< Ratio of high frequency decay time relative - to low frequency decay time in percent */ - OMX_U32 nDensity; /**< Modal density in the late reverberation decay, - in percent (i.e. 0 - 100) */ - OMX_U32 nDiffusion; /**< Echo density in the late reverberation decay, - in percent (i.e. 0 - 100) */ - OMX_BU32 sReferenceHighFreq; /**< Reference high frequency in Hertz. This is - the frequency used as the reference for all - the high-frequency settings above */ - -} OMX_AUDIO_CONFIG_REVERBERATIONTYPE; - - -/** Possible settings for the Echo Cancelation structure to use - * @ingroup effects - */ -typedef enum OMX_AUDIO_ECHOCANTYPE { - OMX_AUDIO_EchoCanOff = 0, /**< Echo Cancellation is disabled */ - OMX_AUDIO_EchoCanNormal, /**< Echo Cancellation normal operation - - echo from plastics and face */ - OMX_AUDIO_EchoCanHFree, /**< Echo Cancellation optimized for - Hands Free operation */ - OMX_AUDIO_EchoCanCarKit, /**< Echo Cancellation optimized for - Car Kit (longer echo) */ - OMX_AUDIO_EchoCanKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_AUDIO_EchoCanVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_AUDIO_EchoCanMax = 0x7FFFFFFF -} OMX_AUDIO_ECHOCANTYPE; - - -/** Enable / Disable for echo cancelation, which removes undesired echo's - * from the audio - * @ingroup effects - */ -typedef struct OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_AUDIO_ECHOCANTYPE eEchoCancelation; /**< Echo cancelation settings */ -} OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE; - - -/** Enable / Disable for noise reduction, which undesired noise from - * the audio - * @ingroup effects - */ -typedef struct OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BOOL bNoiseReduction; /**< Enable/disable for noise reduction */ -} OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE; - -/** @} */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ - diff --git a/third_party/openmax/include/OMX_Component.h b/third_party/openmax/include/OMX_Component.h deleted file mode 100644 index d5956405e2..0000000000 --- a/third_party/openmax/include/OMX_Component.h +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** OMX_Component.h - OpenMax IL version 1.1.2 - * The OMX_Component header file contains the definitions used to define - * the public interface of a component. This header file is intended to - * be used by both the application and the component. - */ - -#ifndef OMX_Component_h -#define OMX_Component_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - - -/* Each OMX header must include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ - -#include -#include -#include -#include - -/** @ingroup comp */ -typedef enum OMX_PORTDOMAINTYPE { - OMX_PortDomainAudio, - OMX_PortDomainVideo, - OMX_PortDomainImage, - OMX_PortDomainOther, - OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_PortDomainVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_PortDomainMax = 0x7ffffff -} OMX_PORTDOMAINTYPE; - -/** @ingroup comp */ -typedef struct OMX_PARAM_PORTDEFINITIONTYPE { - OMX_U32 nSize; /**< Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port number the structure applies to */ - OMX_DIRTYPE eDir; /**< Direction (input or output) of this port */ - OMX_U32 nBufferCountActual; /**< The actual number of buffers allocated on this port */ - OMX_U32 nBufferCountMin; /**< The minimum number of buffers this port requires */ - OMX_U32 nBufferSize; /**< Size, in bytes, for buffers to be used for this channel */ - OMX_BOOL bEnabled; /**< Ports default to enabled and are enabled/disabled by - OMX_CommandPortEnable/OMX_CommandPortDisable. - When disabled a port is unpopulated. A disabled port - is not populated with buffers on a transition to IDLE. */ - OMX_BOOL bPopulated; /**< Port is populated with all of its buffers as indicated by - nBufferCountActual. A disabled port is always unpopulated. - An enabled port is populated on a transition to OMX_StateIdle - and unpopulated on a transition to loaded. */ - OMX_PORTDOMAINTYPE eDomain; /**< Domain of the port. Determines the contents of metadata below. */ - union { - OMX_AUDIO_PORTDEFINITIONTYPE audio; - OMX_VIDEO_PORTDEFINITIONTYPE video; - OMX_IMAGE_PORTDEFINITIONTYPE image; - OMX_OTHER_PORTDEFINITIONTYPE other; - } format; - OMX_BOOL bBuffersContiguous; - OMX_U32 nBufferAlignment; -} OMX_PARAM_PORTDEFINITIONTYPE; - -/** @ingroup comp */ -typedef struct OMX_PARAM_U32TYPE { - OMX_U32 nSize; /**< Size of this structure, in Bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_U32 nU32; /**< U32 value */ -} OMX_PARAM_U32TYPE; - -/** @ingroup rpm */ -typedef enum OMX_SUSPENSIONPOLICYTYPE { - OMX_SuspensionDisabled, /**< No suspension; v1.0 behavior */ - OMX_SuspensionEnabled, /**< Suspension allowed */ - OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_SuspensionPolicyStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_SuspensionPolicyMax = 0x7fffffff -} OMX_SUSPENSIONPOLICYTYPE; - -/** @ingroup rpm */ -typedef struct OMX_PARAM_SUSPENSIONPOLICYTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_SUSPENSIONPOLICYTYPE ePolicy; -} OMX_PARAM_SUSPENSIONPOLICYTYPE; - -/** @ingroup rpm */ -typedef enum OMX_SUSPENSIONTYPE { - OMX_NotSuspended, /**< component is not suspended */ - OMX_Suspended, /**< component is suspended */ - OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_SuspensionVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_SuspendMax = 0x7FFFFFFF -} OMX_SUSPENSIONTYPE; - -/** @ingroup rpm */ -typedef struct OMX_PARAM_SUSPENSIONTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_SUSPENSIONTYPE eType; -} OMX_PARAM_SUSPENSIONTYPE ; - -typedef struct OMX_CONFIG_BOOLEANTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_BOOL bEnabled; -} OMX_CONFIG_BOOLEANTYPE; - -/* Parameter specifying the content uri to use. */ -/** @ingroup cp */ -typedef struct OMX_PARAM_CONTENTURITYPE -{ - OMX_U32 nSize; /**< size of the structure in bytes, including - actual URI name */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U8 contentURI[1]; /**< The URI name */ -} OMX_PARAM_CONTENTURITYPE; - -/* Parameter specifying the pipe to use. */ -/** @ingroup cp */ -typedef struct OMX_PARAM_CONTENTPIPETYPE -{ - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_HANDLETYPE hPipe; /**< The pipe handle*/ -} OMX_PARAM_CONTENTPIPETYPE; - -/** @ingroup rpm */ -typedef struct OMX_RESOURCECONCEALMENTTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment - methods (like degrading algorithm quality to - lower resource consumption or functional bypass) - on a component as a resolution to resource conflicts. */ -} OMX_RESOURCECONCEALMENTTYPE; - - -/** @ingroup metadata */ -typedef enum OMX_METADATACHARSETTYPE { - OMX_MetadataCharsetUnknown = 0, - OMX_MetadataCharsetASCII, - OMX_MetadataCharsetBinary, - OMX_MetadataCharsetCodePage1252, - OMX_MetadataCharsetUTF8, - OMX_MetadataCharsetJavaConformantUTF8, - OMX_MetadataCharsetUTF7, - OMX_MetadataCharsetImapUTF7, - OMX_MetadataCharsetUTF16LE, - OMX_MetadataCharsetUTF16BE, - OMX_MetadataCharsetGB12345, - OMX_MetadataCharsetHZGB2312, - OMX_MetadataCharsetGB2312, - OMX_MetadataCharsetGB18030, - OMX_MetadataCharsetGBK, - OMX_MetadataCharsetBig5, - OMX_MetadataCharsetISO88591, - OMX_MetadataCharsetISO88592, - OMX_MetadataCharsetISO88593, - OMX_MetadataCharsetISO88594, - OMX_MetadataCharsetISO88595, - OMX_MetadataCharsetISO88596, - OMX_MetadataCharsetISO88597, - OMX_MetadataCharsetISO88598, - OMX_MetadataCharsetISO88599, - OMX_MetadataCharsetISO885910, - OMX_MetadataCharsetISO885913, - OMX_MetadataCharsetISO885914, - OMX_MetadataCharsetISO885915, - OMX_MetadataCharsetShiftJIS, - OMX_MetadataCharsetISO2022JP, - OMX_MetadataCharsetISO2022JP1, - OMX_MetadataCharsetISOEUCJP, - OMX_MetadataCharsetSMS7Bit, - OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_MetadataCharsetVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_MetadataCharsetTypeMax= 0x7FFFFFFF -} OMX_METADATACHARSETTYPE; - -/** @ingroup metadata */ -typedef enum OMX_METADATASCOPETYPE -{ - OMX_MetadataScopeAllLevels, - OMX_MetadataScopeTopLevel, - OMX_MetadataScopePortLevel, - OMX_MetadataScopeNodeLevel, - OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_MetadataScopeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_MetadataScopeTypeMax = 0x7fffffff -} OMX_METADATASCOPETYPE; - -/** @ingroup metadata */ -typedef enum OMX_METADATASEARCHMODETYPE -{ - OMX_MetadataSearchValueSizeByIndex, - OMX_MetadataSearchItemByIndex, - OMX_MetadataSearchNextItemByKey, - OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_MetadataSearchVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_MetadataSearchTypeMax = 0x7fffffff -} OMX_METADATASEARCHMODETYPE; -/** @ingroup metadata */ -typedef struct OMX_CONFIG_METADATAITEMCOUNTTYPE -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_METADATASCOPETYPE eScopeMode; - OMX_U32 nScopeSpecifier; - OMX_U32 nMetadataItemCount; -} OMX_CONFIG_METADATAITEMCOUNTTYPE; - -/** @ingroup metadata */ -typedef struct OMX_CONFIG_METADATAITEMTYPE -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_METADATASCOPETYPE eScopeMode; - OMX_U32 nScopeSpecifier; - OMX_U32 nMetadataItemIndex; - OMX_METADATASEARCHMODETYPE eSearchMode; - OMX_METADATACHARSETTYPE eKeyCharset; - OMX_U8 nKeySizeUsed; - OMX_U8 nKey[128]; - OMX_METADATACHARSETTYPE eValueCharset; - OMX_STRING sLanguageCountry; - OMX_U32 nValueMaxSize; - OMX_U32 nValueSizeUsed; - OMX_U8 nValue[1]; -} OMX_CONFIG_METADATAITEMTYPE; - -/* @ingroup metadata */ -typedef struct OMX_CONFIG_CONTAINERNODECOUNTTYPE -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_BOOL bAllKeys; - OMX_U32 nParentNodeID; - OMX_U32 nNumNodes; -} OMX_CONFIG_CONTAINERNODECOUNTTYPE; - -/** @ingroup metadata */ -typedef struct OMX_CONFIG_CONTAINERNODEIDTYPE -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_BOOL bAllKeys; - OMX_U32 nParentNodeID; - OMX_U32 nNodeIndex; - OMX_U32 nNodeID; - OMX_STRING cNodeName; - OMX_BOOL bIsLeafType; -} OMX_CONFIG_CONTAINERNODEIDTYPE; - -/** @ingroup metadata */ -typedef struct OMX_PARAM_METADATAFILTERTYPE -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_BOOL bAllKeys; /* if true then this structure refers to all keys and - * the three key fields below are ignored */ - OMX_METADATACHARSETTYPE eKeyCharset; - OMX_U32 nKeySizeUsed; - OMX_U8 nKey [128]; - OMX_U32 nLanguageCountrySizeUsed; - OMX_U8 nLanguageCountry[128]; - OMX_BOOL bEnabled; /* if true then key is part of filter (e.g. - * retained for query later). If false then - * key is not part of filter */ -} OMX_PARAM_METADATAFILTERTYPE; - -/** The OMX_HANDLETYPE structure defines the component handle. The component - * handle is used to access all of the component's public methods and also - * contains pointers to the component's private data area. The component - * handle is initialized by the OMX core (with help from the component) - * during the process of loading the component. After the component is - * successfully loaded, the application can safely access any of the - * component's public functions (although some may return an error because - * the state is inappropriate for the access). - * - * @ingroup comp - */ -typedef struct OMX_COMPONENTTYPE -{ - /** The size of this structure, in bytes. It is the responsibility - of the allocator of this structure to fill in this value. Since - this structure is allocated by the GetHandle function, this - function will fill in this value. */ - OMX_U32 nSize; - - /** nVersion is the version of the OMX specification that the structure - is built against. It is the responsibility of the creator of this - structure to initialize this value and every user of this structure - should verify that it knows how to use the exact version of - this structure found herein. */ - OMX_VERSIONTYPE nVersion; - - /** pComponentPrivate is a pointer to the component private data area. - This member is allocated and initialized by the component when the - component is first loaded. The application should not access this - data area. */ - OMX_PTR pComponentPrivate; - - /** pApplicationPrivate is a pointer that is a parameter to the - OMX_GetHandle method, and contains an application private value - provided by the IL client. This application private data is - returned to the IL Client by OMX in all callbacks */ - OMX_PTR pApplicationPrivate; - - /** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL - specification for details on the GetComponentVersion method. - */ - OMX_ERRORTYPE (*GetComponentVersion)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_OUT OMX_STRING pComponentName, - OMX_OUT OMX_VERSIONTYPE* pComponentVersion, - OMX_OUT OMX_VERSIONTYPE* pSpecVersion, - OMX_OUT OMX_UUIDTYPE* pComponentUUID); - - /** refer to OMX_SendCommand in OMX_core.h or the OMX IL - specification for details on the SendCommand method. - */ - OMX_ERRORTYPE (*SendCommand)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_COMMANDTYPE Cmd, - OMX_IN OMX_U32 nParam1, - OMX_IN OMX_PTR pCmdData); - - /** refer to OMX_GetParameter in OMX_core.h or the OMX IL - specification for details on the GetParameter method. - */ - OMX_ERRORTYPE (*GetParameter)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nParamIndex, - OMX_INOUT OMX_PTR pComponentParameterStructure); - - - /** refer to OMX_SetParameter in OMX_core.h or the OMX IL - specification for details on the SetParameter method. - */ - OMX_ERRORTYPE (*SetParameter)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentParameterStructure); - - - /** refer to OMX_GetConfig in OMX_core.h or the OMX IL - specification for details on the GetConfig method. - */ - OMX_ERRORTYPE (*GetConfig)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_INOUT OMX_PTR pComponentConfigStructure); - - - /** refer to OMX_SetConfig in OMX_core.h or the OMX IL - specification for details on the SetConfig method. - */ - OMX_ERRORTYPE (*SetConfig)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_INDEXTYPE nIndex, - OMX_IN OMX_PTR pComponentConfigStructure); - - - /** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL - specification for details on the GetExtensionIndex method. - */ - OMX_ERRORTYPE (*GetExtensionIndex)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_STRING cParameterName, - OMX_OUT OMX_INDEXTYPE* pIndexType); - - - /** refer to OMX_GetState in OMX_core.h or the OMX IL - specification for details on the GetState method. - */ - OMX_ERRORTYPE (*GetState)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_OUT OMX_STATETYPE* pState); - - - /** The ComponentTunnelRequest method will interact with another OMX - component to determine if tunneling is possible and to setup the - tunneling. The return codes for this method can be used to - determine if tunneling is not possible, or if tunneling is not - supported. - - Base profile components (i.e. non-interop) do not support this - method and should return OMX_ErrorNotImplemented - - The interop profile component MUST support tunneling to another - interop profile component with a compatible port parameters. - A component may also support proprietary communication. - - If proprietary communication is supported the negotiation of - proprietary communication is done outside of OMX in a vendor - specific way. It is only required that the proper result be - returned and the details of how the setup is done is left - to the component implementation. - - When this method is invoked when nPort in an output port, the - component will: - 1. Populate the pTunnelSetup structure with the output port's - requirements and constraints for the tunnel. - - When this method is invoked when nPort in an input port, the - component will: - 1. Query the necessary parameters from the output port to - determine if the ports are compatible for tunneling - 2. If the ports are compatible, the component should store - the tunnel step provided by the output port - 3. Determine which port (either input or output) is the buffer - supplier, and call OMX_SetParameter on the output port to - indicate this selection. - - The component will return from this call within 5 msec. - - @param [in] hComp - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle method. - @param [in] nPort - nPort is used to select the port on the component to be used - for tunneling. - @param [in] hTunneledComp - Handle of the component to tunnel with. This is the component - handle returned by the call to the OMX_GetHandle method. When - this parameter is 0x0 the component should setup the port for - communication with the application / IL Client. - @param [in] nPortOutput - nPortOutput is used indicate the port the component should - tunnel with. - @param [in] pTunnelSetup - Pointer to the tunnel setup structure. When nPort is an output port - the component should populate the fields of this structure. When - When nPort is an input port the component should review the setup - provided by the component with the output port. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup tun - */ - - OMX_ERRORTYPE (*ComponentTunnelRequest)( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 nPort, - OMX_IN OMX_HANDLETYPE hTunneledComp, - OMX_IN OMX_U32 nTunneledPort, - OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup); - - /** refer to OMX_UseBuffer in OMX_core.h or the OMX IL - specification for details on the UseBuffer method. - @ingroup buf - */ - OMX_ERRORTYPE (*UseBuffer)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes, - OMX_IN OMX_U8* pBuffer); - - /** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL - specification for details on the AllocateBuffer method. - @ingroup buf - */ - OMX_ERRORTYPE (*AllocateBuffer)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN OMX_U32 nSizeBytes); - - /** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL - specification for details on the FreeBuffer method. - @ingroup buf - */ - OMX_ERRORTYPE (*FreeBuffer)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); - - /** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL - specification for details on the EmptyThisBuffer method. - @ingroup buf - */ - OMX_ERRORTYPE (*EmptyThisBuffer)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); - - /** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL - specification for details on the FillThisBuffer method. - @ingroup buf - */ - OMX_ERRORTYPE (*FillThisBuffer)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); - - /** The SetCallbacks method is used by the core to specify the callback - structure from the application to the component. This is a blocking - call. The component will return from this call within 5 msec. - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the GetHandle function. - @param [in] pCallbacks - pointer to an OMX_CALLBACKTYPE structure used to provide the - callback information to the component - @param [in] pAppData - pointer to an application defined value. It is anticipated that - the application will pass a pointer to a data structure or a "this - pointer" in this area to allow the callback (in the application) - to determine the context of the call - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - */ - OMX_ERRORTYPE (*SetCallbacks)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_CALLBACKTYPE* pCallbacks, - OMX_IN OMX_PTR pAppData); - - /** ComponentDeInit method is used to deinitialize the component - providing a means to free any resources allocated at component - initialization. NOTE: After this call the component handle is - not valid for further use. - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the GetHandle function. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - */ - OMX_ERRORTYPE (*ComponentDeInit)( - OMX_IN OMX_HANDLETYPE hComponent); - - /** @ingroup buf */ - OMX_ERRORTYPE (*UseEGLImage)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, - OMX_IN OMX_U32 nPortIndex, - OMX_IN OMX_PTR pAppPrivate, - OMX_IN void* eglImage); - - OMX_ERRORTYPE (*ComponentRoleEnum)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_OUT OMX_U8 *cRole, - OMX_IN OMX_U32 nIndex); - -} OMX_COMPONENTTYPE; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ diff --git a/third_party/openmax/include/OMX_ContentPipe.h b/third_party/openmax/include/OMX_ContentPipe.h deleted file mode 100644 index 5f6310c28a..0000000000 --- a/third_party/openmax/include/OMX_ContentPipe.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** OMX_ContentPipe.h - OpenMax IL version 1.1.2 - * The OMX_ContentPipe header file contains the definitions used to define - * the public interface for content piples. This header file is intended to - * be used by the component. - */ - -#ifndef OMX_CONTENTPIPE_H -#define OMX_CONTENTPIPE_H - -#ifndef KD_EACCES -/* OpenKODE error codes. CPResult values may be zero (indicating success - or one of the following values) */ -#define KD_EACCES (1) -#define KD_EADDRINUSE (2) -#define KD_EAGAIN (5) -#define KD_EBADF (7) -#define KD_EBUSY (8) -#define KD_ECONNREFUSED (9) -#define KD_ECONNRESET (10) -#define KD_EDEADLK (11) -#define KD_EDESTADDRREQ (12) -#define KD_ERANGE (35) -#define KD_EEXIST (13) -#define KD_EFBIG (14) -#define KD_EHOSTUNREACH (15) -#define KD_EINVAL (17) -#define KD_EIO (18) -#define KD_EISCONN (20) -#define KD_EISDIR (21) -#define KD_EMFILE (22) -#define KD_ENAMETOOLONG (23) -#define KD_ENOENT (24) -#define KD_ENOMEM (25) -#define KD_ENOSPC (26) -#define KD_ENOSYS (27) -#define KD_ENOTCONN (28) -#define KD_EPERM (33) -#define KD_ETIMEDOUT (36) -#define KD_EILSEQ (19) -#endif - -/** Map types from OMX standard types only here so interface is as generic as possible. */ -typedef OMX_U32 CPresult; -typedef char * CPstring; -typedef void * CPhandle; -typedef OMX_U32 CPuint; -typedef OMX_S32 CPint; -typedef char CPbyte; -typedef OMX_BOOL CPbool; - -/** enumeration of origin types used in the CP_PIPETYPE's Seek function - * @ingroup cp - */ -typedef enum CP_ORIGINTYPE { - CP_OriginBegin, - CP_OriginCur, - CP_OriginEnd, - CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - CP_OriginVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - CP_OriginMax = 0X7FFFFFFF -} CP_ORIGINTYPE; - -/** enumeration of contact access types used in the CP_PIPETYPE's Open function - * @ingroup cp - */ -typedef enum CP_ACCESSTYPE { - CP_AccessRead, - CP_AccessWrite, - CP_AccessReadWrite , - CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - CP_AccessVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - CP_AccessMax = 0X7FFFFFFF -} CP_ACCESSTYPE; - -/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function - * @ingroup cp - */ -typedef enum CP_CHECKBYTESRESULTTYPE -{ - CP_CheckBytesOk, /**< There are at least the request number - of bytes available */ - CP_CheckBytesNotReady, /**< The pipe is still retrieving bytes - and presently lacks sufficient bytes. - Client will be called when they are - sufficient bytes are available. */ - CP_CheckBytesInsufficientBytes , /**< The pipe has retrieved all bytes - but those available are less than those - requested */ - CP_CheckBytesAtEndOfStream, /**< The pipe has reached the end of stream - and no more bytes are available. */ - CP_CheckBytesOutOfBuffers, /**< All read/write buffers are currently in use. */ - CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - CP_CheckBytesVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - CP_CheckBytesMax = 0X7FFFFFFF -} CP_CHECKBYTESRESULTTYPE; - -/** enumeration of content pipe events sent to the client callback. - * @ingroup cp - */ -typedef enum CP_EVENTTYPE{ - CP_BytesAvailable, /** bytes requested in a CheckAvailableBytes call are now available*/ - CP_Overflow, /** enumeration of content pipe events sent to the client callback*/ - CP_PipeDisconnected , /** enumeration of content pipe events sent to the client callback*/ - CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - CP_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - CP_EventMax = 0X7FFFFFFF -} CP_EVENTTYPE; - -/** content pipe definition - * @ingroup cp - */ -typedef struct CP_PIPETYPE -{ - /** Open a content stream for reading or writing. */ - CPresult (*Open)( CPhandle* hContent, CPstring szURI, CP_ACCESSTYPE eAccess ); - - /** Close a content stream. */ - CPresult (*Close)( CPhandle hContent ); - - /** Create a content source and open it for writing. */ - CPresult (*Create)( CPhandle *hContent, CPstring szURI ); - - /** Check the that specified number of bytes are available for reading or writing (depending on access type).*/ - CPresult (*CheckAvailableBytes)( CPhandle hContent, CPuint nBytesRequested, CP_CHECKBYTESRESULTTYPE *eResult ); - - /** Seek to certain position in the content relative to the specified origin. */ - CPresult (*SetPosition)( CPhandle hContent, CPint nOffset, CP_ORIGINTYPE eOrigin); - - /** Retrieve the current position relative to the start of the content. */ - CPresult (*GetPosition)( CPhandle hContent, CPuint *pPosition); - - /** Retrieve data of the specified size from the content stream (advance content pointer by size of data). - Note: pipe client provides pointer. This function is appropriate for small high frequency reads. */ - CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize); - - /** Retrieve a buffer allocated by the pipe that contains the requested number of bytes. - Buffer contains the next block of bytes, as specified by nSize, of the content. nSize also - returns the size of the block actually read. Content pointer advances the by the returned size. - Note: pipe provides pointer. This function is appropriate for large reads. The client must call - ReleaseReadBuffer when done with buffer. - - In some cases the requested block may not reside in contiguous memory within the - pipe implementation. For instance if the pipe leverages a circular buffer then the requested - block may straddle the boundary of the circular buffer. By default a pipe implementation - performs a copy in this case to provide the block to the pipe client in one contiguous buffer. - If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory - boundary. Here the client may retrieve the data in segments over successive calls. */ - CPresult (*ReadBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint *nSize, CPbool bForbidCopy); - - /** Release a buffer obtained by ReadBuffer back to the pipe. */ - CPresult (*ReleaseReadBuffer)(CPhandle hContent, CPbyte *pBuffer); - - /** Write data of the specified size to the content (advance content pointer by size of data). - Note: pipe client provides pointer. This function is appropriate for small high frequency writes. */ - CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize); - - /** Retrieve a buffer allocated by the pipe used to write data to the content. - Client will fill buffer with output data. Note: pipe provides pointer. This function is appropriate - for large writes. The client must call WriteBuffer when done it has filled the buffer with data.*/ - CPresult (*GetWriteBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint nSize); - - /** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the - the contents of the buffer to content and advance content pointer by the size of the buffer */ - CPresult (*WriteBuffer)( CPhandle hContent, CPbyte *pBuffer, CPuint nFilledSize); - - /** Register a per-handle client callback with the content pipe. */ - CPresult (*RegisterCallback)( CPhandle hContent, CPresult (*ClientCallback)(CP_EVENTTYPE eEvent, CPuint iParam)); - -} CP_PIPETYPE; - -#endif - diff --git a/third_party/openmax/include/OMX_Core.h b/third_party/openmax/include/OMX_Core.h deleted file mode 100644 index 52d211f0dc..0000000000 --- a/third_party/openmax/include/OMX_Core.h +++ /dev/null @@ -1,1440 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** OMX_Core.h - OpenMax IL version 1.1.2 - * The OMX_Core header file contains the definitions used by both the - * application and the component to access common items. - */ - -#ifndef OMX_Core_h -#define OMX_Core_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/* Each OMX header shall include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ - -#include - - -/** The OMX_COMMANDTYPE enumeration is used to specify the action in the - * OMX_SendCommand macro. - * @ingroup core - */ -typedef enum OMX_COMMANDTYPE -{ - OMX_CommandStateSet, /**< Change the component state */ - OMX_CommandFlush, /**< Flush the data queue(s) of a component */ - OMX_CommandPortDisable, /**< Disable a port on a component. */ - OMX_CommandPortEnable, /**< Enable a port on a component. */ - OMX_CommandMarkBuffer, /**< Mark a component/buffer for observation */ - OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_CommandMax = 0X7FFFFFFF -} OMX_COMMANDTYPE; - - - -/** The OMX_STATETYPE enumeration is used to indicate or change the component - * state. This enumeration reflects the current state of the component when - * used with the OMX_GetState macro or becomes the parameter in a state change - * command when used with the OMX_SendCommand macro. - * - * The component will be in the Loaded state after the component is initially - * loaded into memory. In the Loaded state, the component is not allowed to - * allocate or hold resources other than to build it's internal parameter - * and configuration tables. The application will send one or more - * SetParameters/GetParameters and SetConfig/GetConfig commands to the - * component and the component will record each of these parameter and - * configuration changes for use later. When the application sends the - * Idle command, the component will acquire the resources needed for the - * specified configuration and will transition to the idle state if the - * allocation is successful. If the component cannot successfully - * transition to the idle state for any reason, the state of the component - * shall be fully rolled back to the Loaded state (e.g. all allocated - * resources shall be released). When the component receives the command - * to go to the Executing state, it shall begin processing buffers by - * sending all input buffers it holds to the application. While - * the component is in the Idle state, the application may also send the - * Pause command. If the component receives the pause command while in the - * Idle state, the component shall send all input buffers it holds to the - * application, but shall not begin processing buffers. This will allow the - * application to prefill buffers. - * - * @ingroup comp - */ - -typedef enum OMX_STATETYPE -{ - OMX_StateInvalid, /**< component has detected that it's internal data - structures are corrupted to the point that - it cannot determine it's state properly */ - OMX_StateLoaded, /**< component has been loaded but has not completed - initialization. The OMX_SetParameter macro - and the OMX_GetParameter macro are the only - valid macros allowed to be sent to the - component in this state. */ - OMX_StateIdle, /**< component initialization has been completed - successfully and the component is ready to - to start. */ - OMX_StateExecuting, /**< component has accepted the start command and - is processing data (if data is available) */ - OMX_StatePause, /**< component has received pause command */ - OMX_StateWaitForResources, /**< component is waiting for resources, either after - preemption or before it gets the resources requested. - See specification for complete details. */ - OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_StateMax = 0X7FFFFFFF -} OMX_STATETYPE; - -/** The OMX_ERRORTYPE enumeration defines the standard OMX Errors. These - * errors should cover most of the common failure cases. However, - * vendors are free to add additional error messages of their own as - * long as they follow these rules: - * 1. Vendor error messages shall be in the range of 0x90000000 to - * 0x9000FFFF. - * 2. Vendor error messages shall be defined in a header file provided - * with the component. No error messages are allowed that are - * not defined. - */ -typedef enum OMX_ERRORTYPE -{ - OMX_ErrorNone = 0, - - /** There were insufficient resources to perform the requested operation */ - OMX_ErrorInsufficientResources = (OMX_S32) 0x80001000, - - /** There was an error, but the cause of the error could not be determined */ - OMX_ErrorUndefined = (OMX_S32) 0x80001001, - - /** The component name string was not valid */ - OMX_ErrorInvalidComponentName = (OMX_S32) 0x80001002, - - /** No component with the specified name string was found */ - OMX_ErrorComponentNotFound = (OMX_S32) 0x80001003, - - /** The component specified did not have a "OMX_ComponentInit" or - "OMX_ComponentDeInit entry point */ - OMX_ErrorInvalidComponent = (OMX_S32) 0x80001004, - - /** One or more parameters were not valid */ - OMX_ErrorBadParameter = (OMX_S32) 0x80001005, - - /** The requested function is not implemented */ - OMX_ErrorNotImplemented = (OMX_S32) 0x80001006, - - /** The buffer was emptied before the next buffer was ready */ - OMX_ErrorUnderflow = (OMX_S32) 0x80001007, - - /** The buffer was not available when it was needed */ - OMX_ErrorOverflow = (OMX_S32) 0x80001008, - - /** The hardware failed to respond as expected */ - OMX_ErrorHardware = (OMX_S32) 0x80001009, - - /** The component is in the state OMX_StateInvalid */ - OMX_ErrorInvalidState = (OMX_S32) 0x8000100A, - - /** Stream is found to be corrupt */ - OMX_ErrorStreamCorrupt = (OMX_S32) 0x8000100B, - - /** Ports being connected are not compatible */ - OMX_ErrorPortsNotCompatible = (OMX_S32) 0x8000100C, - - /** Resources allocated to an idle component have been - lost resulting in the component returning to the loaded state */ - OMX_ErrorResourcesLost = (OMX_S32) 0x8000100D, - - /** No more indicies can be enumerated */ - OMX_ErrorNoMore = (OMX_S32) 0x8000100E, - - /** The component detected a version mismatch */ - OMX_ErrorVersionMismatch = (OMX_S32) 0x8000100F, - - /** The component is not ready to return data at this time */ - OMX_ErrorNotReady = (OMX_S32) 0x80001010, - - /** There was a timeout that occurred */ - OMX_ErrorTimeout = (OMX_S32) 0x80001011, - - /** This error occurs when trying to transition into the state you are already in */ - OMX_ErrorSameState = (OMX_S32) 0x80001012, - - /** Resources allocated to an executing or paused component have been - preempted, causing the component to return to the idle state */ - OMX_ErrorResourcesPreempted = (OMX_S32) 0x80001013, - - /** A non-supplier port sends this error to the IL client (via the EventHandler callback) - during the allocation of buffers (on a transition from the LOADED to the IDLE state or - on a port restart) when it deems that it has waited an unusually long time for the supplier - to send it an allocated buffer via a UseBuffer call. */ - OMX_ErrorPortUnresponsiveDuringAllocation = (OMX_S32) 0x80001014, - - /** A non-supplier port sends this error to the IL client (via the EventHandler callback) - during the deallocation of buffers (on a transition from the IDLE to LOADED state or - on a port stop) when it deems that it has waited an unusually long time for the supplier - to request the deallocation of a buffer header via a FreeBuffer call. */ - OMX_ErrorPortUnresponsiveDuringDeallocation = (OMX_S32) 0x80001015, - - /** A supplier port sends this error to the IL client (via the EventHandler callback) - during the stopping of a port (either on a transition from the IDLE to LOADED - state or a port stop) when it deems that it has waited an unusually long time for - the non-supplier to return a buffer via an EmptyThisBuffer or FillThisBuffer call. */ - OMX_ErrorPortUnresponsiveDuringStop = (OMX_S32) 0x80001016, - - /** Attempting a state transtion that is not allowed */ - OMX_ErrorIncorrectStateTransition = (OMX_S32) 0x80001017, - - /* Attempting a command that is not allowed during the present state. */ - OMX_ErrorIncorrectStateOperation = (OMX_S32) 0x80001018, - - /** The values encapsulated in the parameter or config structure are not supported. */ - OMX_ErrorUnsupportedSetting = (OMX_S32) 0x80001019, - - /** The parameter or config indicated by the given index is not supported. */ - OMX_ErrorUnsupportedIndex = (OMX_S32) 0x8000101A, - - /** The port index supplied is incorrect. */ - OMX_ErrorBadPortIndex = (OMX_S32) 0x8000101B, - - /** The port has lost one or more of its buffers and it thus unpopulated. */ - OMX_ErrorPortUnpopulated = (OMX_S32) 0x8000101C, - - /** Component suspended due to temporary loss of resources */ - OMX_ErrorComponentSuspended = (OMX_S32) 0x8000101D, - - /** Component suspended due to an inability to acquire dynamic resources */ - OMX_ErrorDynamicResourcesUnavailable = (OMX_S32) 0x8000101E, - - /** When the macroblock error reporting is enabled the component returns new error - for every frame that has errors */ - OMX_ErrorMbErrorsInFrame = (OMX_S32) 0x8000101F, - - /** A component reports this error when it cannot parse or determine the format of an input stream. */ - OMX_ErrorFormatNotDetected = (OMX_S32) 0x80001020, - - /** The content open operation failed. */ - OMX_ErrorContentPipeOpenFailed = (OMX_S32) 0x80001021, - - /** The content creation operation failed. */ - OMX_ErrorContentPipeCreationFailed = (OMX_S32) 0x80001022, - - /** Separate table information is being used */ - OMX_ErrorSeperateTablesUsed = (OMX_S32) 0x80001023, - - /** Tunneling is unsupported by the component*/ - OMX_ErrorTunnelingUnsupported = (OMX_S32) 0x80001024, - - OMX_ErrorKhronosExtensions = (OMX_S32)0x8F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_ErrorVendorStartUnused = (OMX_S32)0x90000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_ErrorMax = 0x7FFFFFFF -} OMX_ERRORTYPE; - -/** @ingroup core */ -typedef OMX_ERRORTYPE (* OMX_COMPONENTINITTYPE)(OMX_IN OMX_HANDLETYPE hComponent); - -/** @ingroup core */ -typedef struct OMX_COMPONENTREGISTERTYPE -{ - const char * pName; /* Component name, 128 byte limit (including '\0') applies */ - OMX_COMPONENTINITTYPE pInitialize; /* Component instance initialization function */ -} OMX_COMPONENTREGISTERTYPE; - -/** @ingroup core */ -extern OMX_COMPONENTREGISTERTYPE OMX_ComponentRegistered[]; - -/** @ingroup rpm */ -typedef struct OMX_PRIORITYMGMTTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nGroupPriority; /**< Priority of the component group */ - OMX_U32 nGroupID; /**< ID of the component group */ -} OMX_PRIORITYMGMTTYPE; - -/* Component name and Role names are limited to 128 characters including the terminating '\0'. */ -#define OMX_MAX_STRINGNAME_SIZE 128 - -/** @ingroup comp */ -typedef struct OMX_PARAM_COMPONENTROLETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U8 cRole[OMX_MAX_STRINGNAME_SIZE]; /**< name of standard component which defines component role */ -} OMX_PARAM_COMPONENTROLETYPE; - -/** End of Stream Buffer Flag: - * - * A component sets EOS when it has no more data to emit on a particular - * output port. Thus an output port shall set EOS on the last buffer it - * emits. A component's determination of when an output port should - * cease sending data is implemenation specific. - * @ingroup buf - */ - -#define OMX_BUFFERFLAG_EOS 0x00000001 - -/** Start Time Buffer Flag: - * - * The source of a stream (e.g. a demux component) sets the STARTTIME - * flag on the buffer that contains the starting timestamp for the - * stream. The starting timestamp corresponds to the first data that - * should be displayed at startup or after a seek. - * The first timestamp of the stream is not necessarily the start time. - * For instance, in the case of a seek to a particular video frame, - * the target frame may be an interframe. Thus the first buffer of - * the stream will be the intra-frame preceding the target frame and - * the starttime will occur with the target frame (with any other - * required frames required to reconstruct the target intervening). - * - * The STARTTIME flag is directly associated with the buffer's - * timestamp ' thus its association to buffer data and its - * propagation is identical to the timestamp's. - * - * When a Sync Component client receives a buffer with the - * STARTTIME flag it shall perform a SetConfig on its sync port - * using OMX_ConfigTimeClientStartTime and passing the buffer's - * timestamp. - * - * @ingroup buf - */ - -#define OMX_BUFFERFLAG_STARTTIME 0x00000002 - - - -/** Decode Only Buffer Flag: - * - * The source of a stream (e.g. a demux component) sets the DECODEONLY - * flag on any buffer that should shall be decoded but should not be - * displayed. This flag is used, for instance, when a source seeks to - * a target interframe that requires the decode of frames preceding the - * target to facilitate the target's reconstruction. In this case the - * source would emit the frames preceding the target downstream - * but mark them as decode only. - * - * The DECODEONLY is associated with buffer data and propagated in a - * manner identical to the buffer timestamp. - * - * A component that renders data should ignore all buffers with - * the DECODEONLY flag set. - * - * @ingroup buf - */ - -#define OMX_BUFFERFLAG_DECODEONLY 0x00000004 - - -/* Data Corrupt Flag: This flag is set when the IL client believes the data in the associated buffer is corrupt - * @ingroup buf - */ - -#define OMX_BUFFERFLAG_DATACORRUPT 0x00000008 - -/* End of Frame: The buffer contains exactly one end of frame and no data - * occurs after the end of frame. This flag is an optional hint. The absence - * of this flag does not imply the absence of an end of frame within the buffer. - * @ingroup buf -*/ -#define OMX_BUFFERFLAG_ENDOFFRAME 0x00000010 - -/* Sync Frame Flag: This flag is set when the buffer content contains a coded sync frame ' - * a frame that has no dependency on any other frame information - * @ingroup buf - */ -#define OMX_BUFFERFLAG_SYNCFRAME 0x00000020 - -/* Extra data present flag: there is extra data appended to the data stream - * residing in the buffer - * @ingroup buf - */ -#define OMX_BUFFERFLAG_EXTRADATA 0x00000040 - -/** Codec Config Buffer Flag: -* OMX_BUFFERFLAG_CODECCONFIG is an optional flag that is set by an -* output port when all bytes in the buffer form part or all of a set of -* codec specific configuration data. Examples include SPS/PPS nal units -* for OMX_VIDEO_CodingAVC or AudioSpecificConfig data for -* OMX_AUDIO_CodingAAC. Any component that for a given stream sets -* OMX_BUFFERFLAG_CODECCONFIG shall not mix codec configuration bytes -* with frame data in the same buffer, and shall send all buffers -* containing codec configuration bytes before any buffers containing -* frame data that those configurations bytes describe. -* If the stream format for a particular codec has a frame specific -* header at the start of each frame, for example OMX_AUDIO_CodingMP3 or -* OMX_AUDIO_CodingAAC in ADTS mode, then these shall be presented as -* normal without setting OMX_BUFFERFLAG_CODECCONFIG. - * @ingroup buf - */ -#define OMX_BUFFERFLAG_CODECCONFIG 0x00000080 - -/* -* OMX_BUFFERFLAG_READONLY: This flag is set when a component emitting the -* buffer on an output port or the IL client wishes to identify the buffer -* payload contents to be read-only. An IL client or an input port -* shall not alter the contents of the buffer. This flag shall only be -* cleared by the originator of the buffer when the buffer is returned. -* For tunneled ports, the usage of this flag shall be allowed only if the -* components negotiated a read-only tunnel -*/ -#define OMX_BUFFERFLAG_READONLY 0x00000200 - -/** @ingroup buf */ -typedef struct OMX_BUFFERHEADERTYPE -{ - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U8* pBuffer; /**< Pointer to actual block of memory - that is acting as the buffer */ - OMX_U32 nAllocLen; /**< size of the buffer allocated, in bytes */ - OMX_U32 nFilledLen; /**< number of bytes currently in the - buffer */ - OMX_U32 nOffset; /**< start offset of valid data in bytes from - the start of the buffer */ - OMX_PTR pAppPrivate; /**< pointer to any data the application - wants to associate with this buffer */ - OMX_PTR pPlatformPrivate; /**< pointer to any data the platform - wants to associate with this buffer */ - OMX_PTR pInputPortPrivate; /**< pointer to any data the input port - wants to associate with this buffer */ - OMX_PTR pOutputPortPrivate; /**< pointer to any data the output port - wants to associate with this buffer */ - OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will generate a - mark event upon processing this buffer. */ - OMX_PTR pMarkData; /**< Application specific data associated with - the mark sent on a mark event to disambiguate - this mark from others. */ - OMX_U32 nTickCount; /**< Optional entry that the component and - application can update with a tick count - when they access the component. This - value should be in microseconds. Since - this is a value relative to an arbitrary - starting point, this value cannot be used - to determine absolute time. This is an - optional entry and not all components - will update it.*/ - OMX_TICKS nTimeStamp; /**< Timestamp corresponding to the sample - starting at the first logical sample - boundary in the buffer. Timestamps of - successive samples within the buffer may - be inferred by adding the duration of the - of the preceding buffer to the timestamp - of the preceding buffer.*/ - OMX_U32 nFlags; /**< buffer specific flags */ - OMX_U32 nOutputPortIndex; /**< The index of the output port (if any) using - this buffer */ - OMX_U32 nInputPortIndex; /**< The index of the input port (if any) using - this buffer */ -} OMX_BUFFERHEADERTYPE; - -/** The OMX_EXTRADATATYPE enumeration is used to define the - * possible extra data payload types. - * NB: this enum is binary backwards compatible with the previous - * OMX_EXTRADATA_QUANT define. This should be replaced with - * OMX_ExtraDataQuantization. - */ -typedef enum OMX_EXTRADATATYPE -{ - OMX_ExtraDataNone = 0, /**< Indicates that no more extra data sections follow */ - OMX_ExtraDataQuantization, /**< The data payload contains quantization data */ - OMX_ExtraDataKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_ExtraDataVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_ExtraDataMax = 0x7FFFFFFF -} OMX_EXTRADATATYPE; - - -typedef struct OMX_OTHER_EXTRADATATYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_EXTRADATATYPE eType; /* Extra Data type */ - OMX_U32 nDataSize; /* Size of the supporting data to follow */ - OMX_U8 data[1]; /* Supporting data hint */ -} OMX_OTHER_EXTRADATATYPE; - -/** @ingroup comp */ -typedef struct OMX_PORT_PARAM_TYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPorts; /**< The number of ports for this component */ - OMX_U32 nStartPortNumber; /** first port number for this type of port */ -} OMX_PORT_PARAM_TYPE; - -/** @ingroup comp */ -typedef enum OMX_EVENTTYPE -{ - OMX_EventCmdComplete, /**< component has sucessfully completed a command */ - OMX_EventError, /**< component has detected an error condition */ - OMX_EventMark, /**< component has detected a buffer mark */ - OMX_EventPortSettingsChanged, /**< component is reported a port settings change */ - OMX_EventBufferFlag, /**< component has detected an EOS */ - OMX_EventResourcesAcquired, /**< component has been granted resources and is - automatically starting the state change from - OMX_StateWaitForResources to OMX_StateIdle. */ - OMX_EventComponentResumed, /**< Component resumed due to reacquisition of resources */ - OMX_EventDynamicResourcesAvailable, /**< Component has acquired previously unavailable dynamic resources */ - OMX_EventPortFormatDetected, /**< Component has detected a supported format. */ - OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_EventMax = 0x7FFFFFFF -} OMX_EVENTTYPE; - -typedef struct OMX_CALLBACKTYPE -{ - /** The EventHandler method is used to notify the application when an - event of interest occurs. Events are defined in the OMX_EVENTTYPE - enumeration. Please see that enumeration for details of what will - be returned for each type of event. Callbacks should not return - an error to the component, so if an error occurs, the application - shall handle it internally. This is a blocking call. - - The application should return from this call within 5 msec to avoid - blocking the component for an excessively long period of time. - - @param hComponent - handle of the component to access. This is the component - handle returned by the call to the GetHandle function. - @param pAppData - pointer to an application defined value that was provided in the - pAppData parameter to the OMX_GetHandle method for the component. - This application defined value is provided so that the application - can have a component specific context when receiving the callback. - @param eEvent - Event that the component wants to notify the application about. - @param nData1 - nData will be the OMX_ERRORTYPE for an error event and will be - an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event. - @param nData2 - nData2 will hold further information related to the event. Can be OMX_STATETYPE for - a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event. - Default value is 0 if not used. ) - @param pEventData - Pointer to additional event-specific data (see spec for meaning). - */ - - OMX_ERRORTYPE (*EventHandler)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_PTR pAppData, - OMX_IN OMX_EVENTTYPE eEvent, - OMX_IN OMX_U32 nData1, - OMX_IN OMX_U32 nData2, - OMX_IN OMX_PTR pEventData); - - /** The EmptyBufferDone method is used to return emptied buffers from an - input port back to the application for reuse. This is a blocking call - so the application should not attempt to refill the buffers during this - call, but should queue them and refill them in another thread. There - is no error return, so the application shall handle any errors generated - internally. - - The application should return from this call within 5 msec. - - @param hComponent - handle of the component to access. This is the component - handle returned by the call to the GetHandle function. - @param pAppData - pointer to an application defined value that was provided in the - pAppData parameter to the OMX_GetHandle method for the component. - This application defined value is provided so that the application - can have a component specific context when receiving the callback. - @param pBuffer - pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer - or AllocateBuffer indicating the buffer that was emptied. - @ingroup buf - */ - OMX_ERRORTYPE (*EmptyBufferDone)( - OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_PTR pAppData, - OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); - - /** The FillBufferDone method is used to return filled buffers from an - output port back to the application for emptying and then reuse. - This is a blocking call so the application should not attempt to - empty the buffers during this call, but should queue the buffers - and empty them in another thread. There is no error return, so - the application shall handle any errors generated internally. The - application shall also update the buffer header to indicate the - number of bytes placed into the buffer. - - The application should return from this call within 5 msec. - - @param hComponent - handle of the component to access. This is the component - handle returned by the call to the GetHandle function. - @param pAppData - pointer to an application defined value that was provided in the - pAppData parameter to the OMX_GetHandle method for the component. - This application defined value is provided so that the application - can have a component specific context when receiving the callback. - @param pBuffer - pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer - or AllocateBuffer indicating the buffer that was filled. - @ingroup buf - */ - OMX_ERRORTYPE (*FillBufferDone)( - OMX_OUT OMX_HANDLETYPE hComponent, - OMX_OUT OMX_PTR pAppData, - OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer); - -} OMX_CALLBACKTYPE; - -/** The OMX_BUFFERSUPPLIERTYPE enumeration is used to dictate port supplier - preference when tunneling between two ports. - @ingroup tun buf -*/ -typedef enum OMX_BUFFERSUPPLIERTYPE -{ - OMX_BufferSupplyUnspecified = 0x0, /**< port supplying the buffers is unspecified, - or don't care */ - OMX_BufferSupplyInput, /**< input port supplies the buffers */ - OMX_BufferSupplyOutput, /**< output port supplies the buffers */ - OMX_BufferSupplyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_BufferSupplyVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_BufferSupplyMax = 0x7FFFFFFF -} OMX_BUFFERSUPPLIERTYPE; - - -/** buffer supplier parameter - * @ingroup tun - */ -typedef struct OMX_PARAM_BUFFERSUPPLIERTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_BUFFERSUPPLIERTYPE eBufferSupplier; /**< buffer supplier */ -} OMX_PARAM_BUFFERSUPPLIERTYPE; - - -/**< indicates that buffers received by an input port of a tunnel - may not modify the data in the buffers - @ingroup tun - */ -#define OMX_PORTTUNNELFLAG_READONLY 0x00000001 - - -/** The OMX_TUNNELSETUPTYPE structure is used to pass data from an output - port to an input port as part the two ComponentTunnelRequest calls - resulting from a OMX_SetupTunnel call from the IL Client. - @ingroup tun - */ -typedef struct OMX_TUNNELSETUPTYPE -{ - OMX_U32 nTunnelFlags; /**< bit flags for tunneling */ - OMX_BUFFERSUPPLIERTYPE eSupplier; /**< supplier preference */ -} OMX_TUNNELSETUPTYPE; - -/* OMX Component headers is included to enable the core to use - macros for functions into the component for OMX release 1.0. - Developers should not access any structures or data from within - the component header directly */ -/* TO BE REMOVED - #include */ - -/** GetComponentVersion will return information about the component. - This is a blocking call. This macro will go directly from the - application to the component (via a core macro). The - component will return from this call within 5 msec. - @param [in] hComponent - handle of component to execute the command - @param [out] pComponentName - pointer to an empty string of length 128 bytes. The component - will write its name into this string. The name will be - terminated by a single zero byte. The name of a component will - be 127 bytes or less to leave room for the trailing zero byte. - An example of a valid component name is "OMX.ABC.ChannelMixer\0". - @param [out] pComponentVersion - pointer to an OMX Version structure that the component will fill - in. The component will fill in a value that indicates the - component version. NOTE: the component version is NOT the same - as the OMX Specification version (found in all structures). The - component version is defined by the vendor of the component and - its value is entirely up to the component vendor. - @param [out] pSpecVersion - pointer to an OMX Version structure that the component will fill - in. The SpecVersion is the version of the specification that the - component was built against. Please note that this value may or - may not match the structure's version. For example, if the - component was built against the 2.0 specification, but the - application (which creates the structure is built against the - 1.0 specification the versions would be different. - @param [out] pComponentUUID - pointer to the UUID of the component which will be filled in by - the component. The UUID is a unique identifier that is set at - RUN time for the component and is unique to each instantion of - the component. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_GetComponentVersion( \ - hComponent, \ - pComponentName, \ - pComponentVersion, \ - pSpecVersion, \ - pComponentUUID) \ - ((OMX_COMPONENTTYPE*)hComponent)->GetComponentVersion( \ - hComponent, \ - pComponentName, \ - pComponentVersion, \ - pSpecVersion, \ - pComponentUUID) /* Macro End */ - - -/** Send a command to the component. This call is a non-blocking call. - The component should check the parameters and then queue the command - to the component thread to be executed. The component thread shall - send the EventHandler() callback at the conclusion of the command. - This macro will go directly from the application to the component (via - a core macro). The component will return from this call within 5 msec. - - When the command is "OMX_CommandStateSet" the component will queue a - state transition to the new state idenfied in nParam. - - When the command is "OMX_CommandFlush", to flush a port's buffer queues, - the command will force the component to return all buffers NOT CURRENTLY - BEING PROCESSED to the application, in the order in which the buffers - were received. - - When the command is "OMX_CommandPortDisable" or - "OMX_CommandPortEnable", the component's port (given by the value of - nParam) will be stopped or restarted. - - When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the - pCmdData will point to a OMX_MARKTYPE structure containing the component - handle of the component to examine the buffer chain for the mark. nParam1 - contains the index of the port on which the buffer mark is applied. - - Specification text for more details. - - @param [in] hComponent - handle of component to execute the command - @param [in] Cmd - Command for the component to execute - @param [in] nParam - Parameter for the command to be executed. When Cmd has the value - OMX_CommandStateSet, value is a member of OMX_STATETYPE. When Cmd has - the value OMX_CommandFlush, value of nParam indicates which port(s) - to flush. -1 is used to flush all ports a single port index will - only flush that port. When Cmd has the value "OMX_CommandPortDisable" - or "OMX_CommandPortEnable", the component's port is given by - the value of nParam. When Cmd has the value "OMX_CommandMarkBuffer" - the components pot is given by the value of nParam. - @param [in] pCmdData - Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value - "OMX_CommandMarkBuffer". - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_SendCommand( \ - hComponent, \ - Cmd, \ - nParam, \ - pCmdData) \ - ((OMX_COMPONENTTYPE*)hComponent)->SendCommand( \ - hComponent, \ - Cmd, \ - nParam, \ - pCmdData) /* Macro End */ - - -/** The OMX_GetParameter macro will get one of the current parameter - settings from the component. This macro cannot only be invoked when - the component is in the OMX_StateInvalid state. The nParamIndex - parameter is used to indicate which structure is being requested from - the component. The application shall allocate the correct structure - and shall fill in the structure size and version information before - invoking this macro. When the parameter applies to a port, the - caller shall fill in the appropriate nPortIndex value indicating the - port on which the parameter applies. If the component has not had - any settings changed, then the component should return a set of - valid DEFAULT parameters for the component. This is a blocking - call. - - The component should return from this call within 20 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] nParamIndex - Index of the structure to be filled. This value is from the - OMX_INDEXTYPE enumeration. - @param [in,out] pComponentParameterStructure - Pointer to application allocated structure to be filled by the - component. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_GetParameter( \ - hComponent, \ - nParamIndex, \ - pComponentParameterStructure) \ - ((OMX_COMPONENTTYPE*)hComponent)->GetParameter( \ - hComponent, \ - nParamIndex, \ - pComponentParameterStructure) /* Macro End */ - - -/** The OMX_SetParameter macro will send an initialization parameter - structure to a component. Each structure shall be sent one at a time, - in a separate invocation of the macro. This macro can only be - invoked when the component is in the OMX_StateLoaded state, or the - port is disabled (when the parameter applies to a port). The - nParamIndex parameter is used to indicate which structure is being - passed to the component. The application shall allocate the - correct structure and shall fill in the structure size and version - information (as well as the actual data) before invoking this macro. - The application is free to dispose of this structure after the call - as the component is required to copy any data it shall retain. This - is a blocking call. - - The component should return from this call within 20 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] nIndex - Index of the structure to be sent. This value is from the - OMX_INDEXTYPE enumeration. - @param [in] pComponentParameterStructure - pointer to application allocated structure to be used for - initialization by the component. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_SetParameter( \ - hComponent, \ - nParamIndex, \ - pComponentParameterStructure) \ - ((OMX_COMPONENTTYPE*)hComponent)->SetParameter( \ - hComponent, \ - nParamIndex, \ - pComponentParameterStructure) /* Macro End */ - - -/** The OMX_GetConfig macro will get one of the configuration structures - from a component. This macro can be invoked anytime after the - component has been loaded. The nParamIndex call parameter is used to - indicate which structure is being requested from the component. The - application shall allocate the correct structure and shall fill in the - structure size and version information before invoking this macro. - If the component has not had this configuration parameter sent before, - then the component should return a set of valid DEFAULT values for the - component. This is a blocking call. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] nIndex - Index of the structure to be filled. This value is from the - OMX_INDEXTYPE enumeration. - @param [in,out] pComponentConfigStructure - pointer to application allocated structure to be filled by the - component. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp -*/ -#define OMX_GetConfig( \ - hComponent, \ - nConfigIndex, \ - pComponentConfigStructure) \ - ((OMX_COMPONENTTYPE*)hComponent)->GetConfig( \ - hComponent, \ - nConfigIndex, \ - pComponentConfigStructure) /* Macro End */ - - -/** The OMX_SetConfig macro will send one of the configuration - structures to a component. Each structure shall be sent one at a time, - each in a separate invocation of the macro. This macro can be invoked - anytime after the component has been loaded. The application shall - allocate the correct structure and shall fill in the structure size - and version information (as well as the actual data) before invoking - this macro. The application is free to dispose of this structure after - the call as the component is required to copy any data it shall retain. - This is a blocking call. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] nConfigIndex - Index of the structure to be sent. This value is from the - OMX_INDEXTYPE enumeration above. - @param [in] pComponentConfigStructure - pointer to application allocated structure to be used for - initialization by the component. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_SetConfig( \ - hComponent, \ - nConfigIndex, \ - pComponentConfigStructure) \ - ((OMX_COMPONENTTYPE*)hComponent)->SetConfig( \ - hComponent, \ - nConfigIndex, \ - pComponentConfigStructure) /* Macro End */ - - -/** The OMX_GetExtensionIndex macro will invoke a component to translate - a vendor specific configuration or parameter string into an OMX - structure index. There is no requirement for the vendor to support - this command for the indexes already found in the OMX_INDEXTYPE - enumeration (this is done to save space in small components). The - component shall support all vendor supplied extension indexes not found - in the master OMX_INDEXTYPE enumeration. This is a blocking call. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the GetHandle function. - @param [in] cParameterName - OMX_STRING that shall be less than 128 characters long including - the trailing null byte. This is the string that will get - translated by the component into a configuration index. - @param [out] pIndexType - a pointer to a OMX_INDEXTYPE to receive the index value. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_GetExtensionIndex( \ - hComponent, \ - cParameterName, \ - pIndexType) \ - ((OMX_COMPONENTTYPE*)hComponent)->GetExtensionIndex( \ - hComponent, \ - cParameterName, \ - pIndexType) /* Macro End */ - - -/** The OMX_GetState macro will invoke the component to get the current - state of the component and place the state value into the location - pointed to by pState. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [out] pState - pointer to the location to receive the state. The value returned - is one of the OMX_STATETYPE members - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp - */ -#define OMX_GetState( \ - hComponent, \ - pState) \ - ((OMX_COMPONENTTYPE*)hComponent)->GetState( \ - hComponent, \ - pState) /* Macro End */ - - -/** The OMX_UseBuffer macro will request that the component use - a buffer (and allocate its own buffer header) already allocated - by another component, or by the IL Client. This is a blocking - call. - - The component should return from this call within 20 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [out] ppBuffer - pointer to an OMX_BUFFERHEADERTYPE structure used to receive the - pointer to the buffer header - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp buf - */ - -#define OMX_UseBuffer( \ - hComponent, \ - ppBufferHdr, \ - nPortIndex, \ - pAppPrivate, \ - nSizeBytes, \ - pBuffer) \ - ((OMX_COMPONENTTYPE*)hComponent)->UseBuffer( \ - hComponent, \ - ppBufferHdr, \ - nPortIndex, \ - pAppPrivate, \ - nSizeBytes, \ - pBuffer) - - -/** The OMX_AllocateBuffer macro will request that the component allocate - a new buffer and buffer header. The component will allocate the - buffer and the buffer header and return a pointer to the buffer - header. This is a blocking call. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [out] ppBuffer - pointer to an OMX_BUFFERHEADERTYPE structure used to receive - the pointer to the buffer header - @param [in] nPortIndex - nPortIndex is used to select the port on the component the buffer will - be used with. The port can be found by using the nPortIndex - value as an index into the Port Definition array of the component. - @param [in] pAppPrivate - pAppPrivate is used to initialize the pAppPrivate member of the - buffer header structure. - @param [in] nSizeBytes - size of the buffer to allocate. Used when bAllocateNew is true. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp buf - */ -#define OMX_AllocateBuffer( \ - hComponent, \ - ppBuffer, \ - nPortIndex, \ - pAppPrivate, \ - nSizeBytes) \ - ((OMX_COMPONENTTYPE*)hComponent)->AllocateBuffer( \ - hComponent, \ - ppBuffer, \ - nPortIndex, \ - pAppPrivate, \ - nSizeBytes) /* Macro End */ - - -/** The OMX_FreeBuffer macro will release a buffer header from the component - which was allocated using either OMX_AllocateBuffer or OMX_UseBuffer. If - the component allocated the buffer (see the OMX_UseBuffer macro) then - the component shall free the buffer and buffer header. This is a - blocking call. - - The component should return from this call within 20 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] nPortIndex - nPortIndex is used to select the port on the component the buffer will - be used with. - @param [in] pBuffer - pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer - or AllocateBuffer. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp buf - */ -#define OMX_FreeBuffer( \ - hComponent, \ - nPortIndex, \ - pBuffer) \ - ((OMX_COMPONENTTYPE*)hComponent)->FreeBuffer( \ - hComponent, \ - nPortIndex, \ - pBuffer) /* Macro End */ - - -/** The OMX_EmptyThisBuffer macro will send a buffer full of data to an - input port of a component. The buffer will be emptied by the component - and returned to the application via the EmptyBufferDone call back. - This is a non-blocking call in that the component will record the buffer - and return immediately and then empty the buffer, later, at the proper - time. As expected, this macro may be invoked only while the component - is in the OMX_StateExecuting. If nPortIndex does not specify an input - port, the component shall return an error. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] pBuffer - pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer - or AllocateBuffer. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp buf - */ -#define OMX_EmptyThisBuffer( \ - hComponent, \ - pBuffer) \ - ((OMX_COMPONENTTYPE*)hComponent)->EmptyThisBuffer( \ - hComponent, \ - pBuffer) /* Macro End */ - - -/** The OMX_FillThisBuffer macro will send an empty buffer to an - output port of a component. The buffer will be filled by the component - and returned to the application via the FillBufferDone call back. - This is a non-blocking call in that the component will record the buffer - and return immediately and then fill the buffer, later, at the proper - time. As expected, this macro may be invoked only while the component - is in the OMX_ExecutingState. If nPortIndex does not specify an output - port, the component shall return an error. - - The component should return from this call within 5 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [in] pBuffer - pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer - or AllocateBuffer. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp buf - */ -#define OMX_FillThisBuffer( \ - hComponent, \ - pBuffer) \ - ((OMX_COMPONENTTYPE*)hComponent)->FillThisBuffer( \ - hComponent, \ - pBuffer) /* Macro End */ - - - -/** The OMX_UseEGLImage macro will request that the component use - a EGLImage provided by EGL (and allocate its own buffer header) - This is a blocking call. - - The component should return from this call within 20 msec. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the OMX_GetHandle function. - @param [out] ppBuffer - pointer to an OMX_BUFFERHEADERTYPE structure used to receive the - pointer to the buffer header. Note that the memory location used - for this buffer is NOT visible to the IL Client. - @param [in] nPortIndex - nPortIndex is used to select the port on the component the buffer will - be used with. The port can be found by using the nPortIndex - value as an index into the Port Definition array of the component. - @param [in] pAppPrivate - pAppPrivate is used to initialize the pAppPrivate member of the - buffer header structure. - @param [in] eglImage - eglImage contains the handle of the EGLImage to use as a buffer on the - specified port. The component is expected to validate properties of - the EGLImage against the configuration of the port to ensure the component - can use the EGLImage as a buffer. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup comp buf - */ -#define OMX_UseEGLImage( \ - hComponent, \ - ppBufferHdr, \ - nPortIndex, \ - pAppPrivate, \ - eglImage) \ - ((OMX_COMPONENTTYPE*)hComponent)->UseEGLImage( \ - hComponent, \ - ppBufferHdr, \ - nPortIndex, \ - pAppPrivate, \ - eglImage) - -/** The OMX_Init method is used to initialize the OMX core. It shall be the - first call made into OMX and it should only be executed one time without - an interviening OMX_Deinit call. - - The core should return from this call within 20 msec. - - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void); - - -/** The OMX_Deinit method is used to deinitialize the OMX core. It shall be - the last call made into OMX. In the event that the core determines that - thare are components loaded when this call is made, the core may return - with an error rather than try to unload the components. - - The core should return from this call within 20 msec. - - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void); - - -/** The OMX_ComponentNameEnum method will enumerate through all the names of - recognised valid components in the system. This function is provided - as a means to detect all the components in the system run-time. There is - no strict ordering to the enumeration order of component names, although - each name will only be enumerated once. If the OMX core supports run-time - installation of new components, it is only requried to detect newly - installed components when the first call to enumerate component names - is made (i.e. when nIndex is 0x0). - - The core should return from this call in 20 msec. - - @param [out] cComponentName - pointer to a null terminated string with the component name. The - names of the components are strings less than 127 bytes in length - plus the trailing null for a maximum size of 128 bytes. An example - of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are - assigned by the vendor, but shall start with "OMX." and then have - the Vendor designation next. - @param [in] nNameLength - number of characters in the cComponentName string. With all - component name strings restricted to less than 128 characters - (including the trailing null) it is recomended that the caller - provide a input string for the cComponentName of 128 characters. - @param [in] nIndex - number containing the enumeration index for the component. - Multiple calls to OMX_ComponentNameEnum with increasing values - of nIndex will enumerate through the component names in the - system until OMX_ErrorNoMore is returned. The value of nIndex - is 0 to (N-1), where N is the number of valid installed components - in the system. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. When the value of nIndex exceeds the number of - components in the system minus 1, OMX_ErrorNoMore will be - returned. Otherwise the appropriate OMX error will be returned. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum( - OMX_OUT OMX_STRING cComponentName, - OMX_IN OMX_U32 nNameLength, - OMX_IN OMX_U32 nIndex); - - -/** The OMX_GetHandle method will locate the component specified by the - component name given, load that component into memory and then invoke - the component's methods to create an instance of the component. - - The core should return from this call within 20 msec. - - @param [out] pHandle - pointer to an OMX_HANDLETYPE pointer to be filled in by this method. - @param [in] cComponentName - pointer to a null terminated string with the component name. The - names of the components are strings less than 127 bytes in length - plus the trailing null for a maximum size of 128 bytes. An example - of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are - assigned by the vendor, but shall start with "OMX." and then have - the Vendor designation next. - @param [in] pAppData - pointer to an application defined value that will be returned - during callbacks so that the application can identify the source - of the callback. - @param [in] pCallBacks - pointer to a OMX_CALLBACKTYPE structure that will be passed to the - component to initialize it with. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle( - OMX_OUT OMX_HANDLETYPE* pHandle, - OMX_IN OMX_STRING cComponentName, - OMX_IN OMX_PTR pAppData, - OMX_IN OMX_CALLBACKTYPE* pCallBacks); - - -/** The OMX_FreeHandle method will free a handle allocated by the OMX_GetHandle - method. If the component reference count goes to zero, the component will - be unloaded from memory. - - The core should return from this call within 20 msec when the component is - in the OMX_StateLoaded state. - - @param [in] hComponent - Handle of the component to be accessed. This is the component - handle returned by the call to the GetHandle function. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle( - OMX_IN OMX_HANDLETYPE hComponent); - - - -/** The OMX_SetupTunnel method will handle the necessary calls to the components - to setup the specified tunnel the two components. NOTE: This is - an actual method (not a #define macro). This method will make calls into - the component ComponentTunnelRequest method to do the actual tunnel - connection. - - The ComponentTunnelRequest method on both components will be called. - This method shall not be called unless the component is in the - OMX_StateLoaded state except when the ports used for the tunnel are - disabled. In this case, the component may be in the OMX_StateExecuting, - OMX_StatePause, or OMX_StateIdle states. - - The core should return from this call within 20 msec. - - @param [in] hOutput - Handle of the component to be accessed. Also this is the handle - of the component whose port, specified in the nPortOutput parameter - will be used the source for the tunnel. This is the component handle - returned by the call to the OMX_GetHandle function. There is a - requirement that hOutput be the source for the data when - tunelling (i.e. nPortOutput is an output port). If 0x0, the component - specified in hInput will have it's port specified in nPortInput - setup for communication with the application / IL client. - @param [in] nPortOutput - nPortOutput is used to select the source port on component to be - used in the tunnel. - @param [in] hInput - This is the component to setup the tunnel with. This is the handle - of the component whose port, specified in the nPortInput parameter - will be used the destination for the tunnel. This is the component handle - returned by the call to the OMX_GetHandle function. There is a - requirement that hInput be the destination for the data when - tunelling (i.e. nPortInut is an input port). If 0x0, the component - specified in hOutput will have it's port specified in nPortPOutput - setup for communication with the application / IL client. - @param [in] nPortInput - nPortInput is used to select the destination port on component to be - used in the tunnel. - @return OMX_ERRORTYPE - If the command successfully executes, the return code will be - OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. - When OMX_ErrorNotImplemented is returned, one or both components is - a non-interop component and does not support tunneling. - - On failure, the ports of both components are setup for communication - with the application / IL Client. - @ingroup core tun - */ -OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel( - OMX_IN OMX_HANDLETYPE hOutput, - OMX_IN OMX_U32 nPortOutput, - OMX_IN OMX_HANDLETYPE hInput, - OMX_IN OMX_U32 nPortInput); - -/** @ingroup cp */ -OMX_API OMX_ERRORTYPE OMX_GetContentPipe( - OMX_OUT OMX_HANDLETYPE *hPipe, - OMX_IN OMX_STRING szURI); - -/** The OMX_GetComponentsOfRole method will return the number of components that support the given - role and (if the compNames field is non-NULL) the names of those components. The call will fail if - an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the - client should: - * first call this function with the compNames field NULL to determine the number of component names - * second call this function with the compNames field pointing to an array of names allocated - according to the number returned by the first call. - - The core should return from this call within 5 msec. - - @param [in] role - This is generic standard component name consisting only of component class - name and the type within that class (e.g. 'audio_decoder.aac'). - @param [inout] pNumComps - This is used both as input and output. - - If compNames is NULL, the input is ignored and the output specifies how many components support - the given role. - - If compNames is not NULL, on input it bounds the size of the input structure and - on output, it specifies the number of components string names listed within the compNames parameter. - @param [inout] compNames - If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings which accepts - a list of the names of all physical components that implement the specified standard component name. - Each name is NULL terminated. numComps indicates the number of names. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole ( - OMX_IN OMX_STRING role, - OMX_INOUT OMX_U32 *pNumComps, - OMX_INOUT OMX_U8 **compNames); - -/** The OMX_GetRolesOfComponent method will return the number of roles supported by the given - component and (if the roles field is non-NULL) the names of those roles. The call will fail if - an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the - client should: - * first call this function with the roles field NULL to determine the number of role names - * second call this function with the roles field pointing to an array of names allocated - according to the number returned by the first call. - - The core should return from this call within 5 msec. - - @param [in] compName - This is the name of the component being queried about. - @param [inout] pNumRoles - This is used both as input and output. - - If roles is NULL, the input is ignored and the output specifies how many roles the component supports. - - If compNames is not NULL, on input it bounds the size of the input structure and - on output, it specifies the number of roles string names listed within the roles parameter. - @param [out] roles - If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings - which accepts a list of the names of all standard components roles implemented on the - specified component name. numComps indicates the number of names. - @ingroup core - */ -OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent ( - OMX_IN OMX_STRING compName, - OMX_INOUT OMX_U32 *pNumRoles, - OMX_OUT OMX_U8 **roles); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ - diff --git a/third_party/openmax/include/OMX_CoreExt.h b/third_party/openmax/include/OMX_CoreExt.h deleted file mode 100644 index 3ec14b05f3..0000000000 --- a/third_party/openmax/include/OMX_CoreExt.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2009 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** OMX_CoreExt.h - OpenMax IL version 1.1.2 - * The OMX_CoreExt header file contains extensions to the definitions used - * by both the application and the component to access common items. - */ - -#ifndef OMX_CoreExt_h -#define OMX_CoreExt_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Each OMX header shall include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ -#include - - -/** Event type extensions. */ -typedef enum OMX_EVENTEXTTYPE -{ - OMX_EventIndexSettingChanged = OMX_EventKhronosExtensions, /**< component signals the IL client of a change - in a param, config, or extension */ - OMX_EventExtMax = 0x7FFFFFFF -} OMX_EVENTEXTTYPE; - - -/** Enable or disable a callback event. */ -typedef struct OMX_CONFIG_CALLBACKREQUESTTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_INDEXTYPE nIndex; /**< the index the callback is requested for */ - OMX_BOOL bEnable; /**< enable (OMX_TRUE) or disable (OMX_FALSE) the callback */ -} OMX_CONFIG_CALLBACKREQUESTTYPE; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* OMX_CoreExt_h */ -/* File EOF */ diff --git a/third_party/openmax/include/OMX_IVCommon.h b/third_party/openmax/include/OMX_IVCommon.h deleted file mode 100644 index ec717565a0..0000000000 --- a/third_party/openmax/include/OMX_IVCommon.h +++ /dev/null @@ -1,933 +0,0 @@ -/** - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** - * @file OMX_IVCommon.h - OpenMax IL version 1.1.2 - * The structures needed by Video and Image components to exchange - * parameters and configuration data with the components. - */ -#ifndef OMX_IVCommon_h -#define OMX_IVCommon_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * Each OMX header must include all required header files to allow the header - * to compile without errors. The includes below are required for this header - * file to compile successfully - */ - -#include - -/** @defgroup iv OpenMAX IL Imaging and Video Domain - * Common structures for OpenMAX IL Imaging and Video domains - * @{ - */ - - -/** - * Enumeration defining possible uncompressed image/video formats. - * - * ENUMS: - * Unused : Placeholder value when format is N/A - * Monochrome : black and white - * 8bitRGB332 : Red 7:5, Green 4:2, Blue 1:0 - * 12bitRGB444 : Red 11:8, Green 7:4, Blue 3:0 - * 16bitARGB4444 : Alpha 15:12, Red 11:8, Green 7:4, Blue 3:0 - * 16bitARGB1555 : Alpha 15, Red 14:10, Green 9:5, Blue 4:0 - * 16bitRGB565 : Red 15:11, Green 10:5, Blue 4:0 - * 16bitBGR565 : Blue 15:11, Green 10:5, Red 4:0 - * 18bitRGB666 : Red 17:12, Green 11:6, Blue 5:0 - * 18bitARGB1665 : Alpha 17, Red 16:11, Green 10:5, Blue 4:0 - * 19bitARGB1666 : Alpha 18, Red 17:12, Green 11:6, Blue 5:0 - * 24bitRGB888 : Red 24:16, Green 15:8, Blue 7:0 - * 24bitBGR888 : Blue 24:16, Green 15:8, Red 7:0 - * 24bitARGB1887 : Alpha 23, Red 22:15, Green 14:7, Blue 6:0 - * 25bitARGB1888 : Alpha 24, Red 23:16, Green 15:8, Blue 7:0 - * 32bitBGRA8888 : Blue 31:24, Green 23:16, Red 15:8, Alpha 7:0 - * 32bitARGB8888 : Alpha 31:24, Red 23:16, Green 15:8, Blue 7:0 - * YUV411Planar : U,Y are subsampled by a factor of 4 horizontally - * YUV411PackedPlanar : packed per payload in planar slices - * YUV420Planar : Three arrays Y,U,V. - * YUV420PackedPlanar : packed per payload in planar slices - * YUV420SemiPlanar : Two arrays, one is all Y, the other is U and V - * YUV422Planar : Three arrays Y,U,V. - * YUV422PackedPlanar : packed per payload in planar slices - * YUV422SemiPlanar : Two arrays, one is all Y, the other is U and V - * YCbYCr : Organized as 16bit YUYV (i.e. YCbYCr) - * YCrYCb : Organized as 16bit YVYU (i.e. YCrYCb) - * CbYCrY : Organized as 16bit UYVY (i.e. CbYCrY) - * CrYCbY : Organized as 16bit VYUY (i.e. CrYCbY) - * YUV444Interleaved : Each pixel contains equal parts YUV - * RawBayer8bit : SMIA camera output format - * RawBayer10bit : SMIA camera output format - * RawBayer8bitcompressed : SMIA camera output format - */ -typedef enum OMX_COLOR_FORMATTYPE { - OMX_COLOR_FormatUnused, - OMX_COLOR_FormatMonochrome, - OMX_COLOR_Format8bitRGB332, - OMX_COLOR_Format12bitRGB444, - OMX_COLOR_Format16bitARGB4444, - OMX_COLOR_Format16bitARGB1555, - OMX_COLOR_Format16bitRGB565, - OMX_COLOR_Format16bitBGR565, - OMX_COLOR_Format18bitRGB666, - OMX_COLOR_Format18bitARGB1665, - OMX_COLOR_Format19bitARGB1666, - OMX_COLOR_Format24bitRGB888, - OMX_COLOR_Format24bitBGR888, - OMX_COLOR_Format24bitARGB1887, - OMX_COLOR_Format25bitARGB1888, - OMX_COLOR_Format32bitBGRA8888, - OMX_COLOR_Format32bitARGB8888, - OMX_COLOR_FormatYUV411Planar, - OMX_COLOR_FormatYUV411PackedPlanar, - OMX_COLOR_FormatYUV420Planar, - OMX_COLOR_FormatYUV420PackedPlanar, - OMX_COLOR_FormatYUV420SemiPlanar, - OMX_COLOR_FormatYUV422Planar, - OMX_COLOR_FormatYUV422PackedPlanar, - OMX_COLOR_FormatYUV422SemiPlanar, - OMX_COLOR_FormatYCbYCr, - OMX_COLOR_FormatYCrYCb, - OMX_COLOR_FormatCbYCrY, - OMX_COLOR_FormatCrYCbY, - OMX_COLOR_FormatYUV444Interleaved, - OMX_COLOR_FormatRawBayer8bit, - OMX_COLOR_FormatRawBayer10bit, - OMX_COLOR_FormatRawBayer8bitcompressed, - OMX_COLOR_FormatL2, - OMX_COLOR_FormatL4, - OMX_COLOR_FormatL8, - OMX_COLOR_FormatL16, - OMX_COLOR_FormatL24, - OMX_COLOR_FormatL32, - OMX_COLOR_FormatYUV420PackedSemiPlanar, - OMX_COLOR_FormatYUV422PackedSemiPlanar, - OMX_COLOR_Format18BitBGR666, - OMX_COLOR_Format24BitARGB6666, - OMX_COLOR_Format24BitABGR6666, - OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - /** - -/** @defgroup imaging OpenMAX IL Imaging Domain - * @ingroup iv - * Structures for OpenMAX IL Imaging domain - * @{ - */ - -/** - * Enumeration used to define the possible image compression coding. - */ -typedef enum OMX_IMAGE_CODINGTYPE { - OMX_IMAGE_CodingUnused, /**< Value when format is N/A */ - OMX_IMAGE_CodingAutoDetect, /**< Auto detection of image format */ - OMX_IMAGE_CodingJPEG, /**< JPEG/JFIF image format */ - OMX_IMAGE_CodingJPEG2K, /**< JPEG 2000 image format */ - OMX_IMAGE_CodingEXIF, /**< EXIF image format */ - OMX_IMAGE_CodingTIFF, /**< TIFF image format */ - OMX_IMAGE_CodingGIF, /**< Graphics image format */ - OMX_IMAGE_CodingPNG, /**< PNG image format */ - OMX_IMAGE_CodingLZW, /**< LZW image format */ - OMX_IMAGE_CodingBMP, /**< Windows Bitmap format */ - OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_IMAGE_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_IMAGE_CodingMax = 0x7FFFFFFF -} OMX_IMAGE_CODINGTYPE; - - -/** - * Data structure used to define an image path. The number of image paths - * for input and output will vary by type of the image component. - * - * Input (aka Source) : Zero Inputs, one Output, - * Splitter : One Input, 2 or more Outputs, - * Processing Element : One Input, one output, - * Mixer : 2 or more inputs, one output, - * Output (aka Sink) : One Input, zero outputs. - * - * The PortDefinition structure is used to define all of the parameters - * necessary for the compliant component to setup an input or an output - * image path. If additional vendor specific data is required, it should - * be transmitted to the component using the CustomCommand function. - * Compliant components will prepopulate this structure with optimal - * values during the OMX_GetParameter() command. - * - * STRUCT MEMBERS: - * cMIMEType : MIME type of data for the port - * pNativeRender : Platform specific reference for a display if a - * sync, otherwise this field is 0 - * nFrameWidth : Width of frame to be used on port if - * uncompressed format is used. Use 0 for - * unknown, don't care or variable - * nFrameHeight : Height of frame to be used on port if - * uncompressed format is used. Use 0 for - * unknown, don't care or variable - * nStride : Number of bytes per span of an image (i.e. - * indicates the number of bytes to get from - * span N to span N+1, where negative stride - * indicates the image is bottom up - * nSliceHeight : Height used when encoding in slices - * bFlagErrorConcealment : Turns on error concealment if it is supported by - * the OMX component - * eCompressionFormat : Compression format used in this instance of - * the component. When OMX_IMAGE_CodingUnused is - * specified, eColorFormat is valid - * eColorFormat : Decompressed format used by this component - * pNativeWindow : Platform specific reference for a window object if a - * display sink , otherwise this field is 0x0. - */ -typedef struct OMX_IMAGE_PORTDEFINITIONTYPE { - OMX_STRING cMIMEType; - OMX_NATIVE_DEVICETYPE pNativeRender; - OMX_U32 nFrameWidth; - OMX_U32 nFrameHeight; - OMX_S32 nStride; - OMX_U32 nSliceHeight; - OMX_BOOL bFlagErrorConcealment; - OMX_IMAGE_CODINGTYPE eCompressionFormat; - OMX_COLOR_FORMATTYPE eColorFormat; - OMX_NATIVE_WINDOWTYPE pNativeWindow; -} OMX_IMAGE_PORTDEFINITIONTYPE; - - -/** - * Port format parameter. This structure is used to enumerate the various - * data input/output format supported by the port. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Indicates which port to set - * nIndex : Indicates the enumeration index for the format from - * 0x0 to N-1 - * eCompressionFormat : Compression format used in this instance of the - * component. When OMX_IMAGE_CodingUnused is specified, - * eColorFormat is valid - * eColorFormat : Decompressed format used by this component - */ -typedef struct OMX_IMAGE_PARAM_PORTFORMATTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nIndex; - OMX_IMAGE_CODINGTYPE eCompressionFormat; - OMX_COLOR_FORMATTYPE eColorFormat; -} OMX_IMAGE_PARAM_PORTFORMATTYPE; - - -/** - * Flash control type - * - * ENUMS - * Torch : Flash forced constantly on - */ -typedef enum OMX_IMAGE_FLASHCONTROLTYPE { - OMX_IMAGE_FlashControlOn = 0, - OMX_IMAGE_FlashControlOff, - OMX_IMAGE_FlashControlAuto, - OMX_IMAGE_FlashControlRedEyeReduction, - OMX_IMAGE_FlashControlFillin, - OMX_IMAGE_FlashControlTorch, - OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_IMAGE_FlashControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_IMAGE_FlashControlMax = 0x7FFFFFFF -} OMX_IMAGE_FLASHCONTROLTYPE; - - -/** - * Flash control configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eFlashControl : Flash control type - */ -typedef struct OMX_IMAGE_PARAM_FLASHCONTROLTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_IMAGE_FLASHCONTROLTYPE eFlashControl; -} OMX_IMAGE_PARAM_FLASHCONTROLTYPE; - - -/** - * Focus control type - */ -typedef enum OMX_IMAGE_FOCUSCONTROLTYPE { - OMX_IMAGE_FocusControlOn = 0, - OMX_IMAGE_FocusControlOff, - OMX_IMAGE_FocusControlAuto, - OMX_IMAGE_FocusControlAutoLock, - OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_IMAGE_FocusControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_IMAGE_FocusControlMax = 0x7FFFFFFF -} OMX_IMAGE_FOCUSCONTROLTYPE; - - -/** - * Focus control configuration - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eFocusControl : Focus control - * nFocusSteps : Focus can take on values from 0 mm to infinity. - * Interest is only in number of steps over this range. - * nFocusStepIndex : Current focus step index - */ -typedef struct OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_IMAGE_FOCUSCONTROLTYPE eFocusControl; - OMX_U32 nFocusSteps; - OMX_U32 nFocusStepIndex; -} OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE; - - -/** - * Q Factor for JPEG compression, which controls the tradeoff between image - * quality and size. Q Factor provides a more simple means of controlling - * JPEG compression quality, without directly programming Quantization - * tables for chroma and luma - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nQFactor : JPEG Q factor value in the range of 1-100. A factor of 1 - * produces the smallest, worst quality images, and a factor - * of 100 produces the largest, best quality images. A - * typical default is 75 for small good quality images - */ -typedef struct OMX_IMAGE_PARAM_QFACTORTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nQFactor; -} OMX_IMAGE_PARAM_QFACTORTYPE; - -/** - * Quantization table type - */ - -typedef enum OMX_IMAGE_QUANTIZATIONTABLETYPE { - OMX_IMAGE_QuantizationTableLuma = 0, - OMX_IMAGE_QuantizationTableChroma, - OMX_IMAGE_QuantizationTableChromaCb, - OMX_IMAGE_QuantizationTableChromaCr, - OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_IMAGE_QuantizationTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_IMAGE_QuantizationTableMax = 0x7FFFFFFF -} OMX_IMAGE_QUANTIZATIONTABLETYPE; - -/** - * JPEG quantization tables are used to determine DCT compression for - * YUV data, as an alternative to specifying Q factor, providing exact - * control of compression - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eQuantizationTable : Quantization table type - * nQuantizationMatrix[64] : JPEG quantization table of coefficients stored - * in increasing columns then by rows of data (i.e. - * row 1, ... row 8). Quantization values are in - * the range 0-255 and stored in linear order - * (i.e. the component will zig-zag the - * quantization table data if required internally) - */ -typedef struct OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_IMAGE_QUANTIZATIONTABLETYPE eQuantizationTable; - OMX_U8 nQuantizationMatrix[64]; -} OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE; - - -/** - * Huffman table type, the same Huffman table is applied for chroma and - * luma component - */ -typedef enum OMX_IMAGE_HUFFMANTABLETYPE { - OMX_IMAGE_HuffmanTableAC = 0, - OMX_IMAGE_HuffmanTableDC, - OMX_IMAGE_HuffmanTableACLuma, - OMX_IMAGE_HuffmanTableACChroma, - OMX_IMAGE_HuffmanTableDCLuma, - OMX_IMAGE_HuffmanTableDCChroma, - OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_IMAGE_HuffmanTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_IMAGE_HuffmanTableMax = 0x7FFFFFFF -} OMX_IMAGE_HUFFMANTABLETYPE; - -/** - * JPEG Huffman table - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eHuffmanTable : Huffman table type - * nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each - * possible length - * nHuffmanTable[256] : 0-255, the size used for AC and DC - * HuffmanTable are 16 and 162 - */ -typedef struct OMX_IMAGE_PARAM_HUFFMANTTABLETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_IMAGE_HUFFMANTABLETYPE eHuffmanTable; - OMX_U8 nNumberOfHuffmanCodeOfLength[16]; - OMX_U8 nHuffmanTable[256]; -}OMX_IMAGE_PARAM_HUFFMANTTABLETYPE; - -/** @} */ -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ diff --git a/third_party/openmax/include/OMX_Index.h b/third_party/openmax/include/OMX_Index.h deleted file mode 100644 index a1f17487d3..0000000000 --- a/third_party/openmax/include/OMX_Index.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** @file OMX_Index.h - OpenMax IL version 1.1.2 - * The OMX_Index header file contains the definitions for both applications - * and components . - */ - - -#ifndef OMX_Index_h -#define OMX_Index_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/* Each OMX header must include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ -#include - - -/** The OMX_INDEXTYPE enumeration is used to select a structure when either - * getting or setting parameters and/or configuration data. Each entry in - * this enumeration maps to an OMX specified structure. When the - * OMX_GetParameter, OMX_SetParameter, OMX_GetConfig or OMX_SetConfig methods - * are used, the second parameter will always be an entry from this enumeration - * and the third entry will be the structure shown in the comments for the entry. - * For example, if the application is initializing a cropping function, the - * OMX_SetConfig command would have OMX_IndexConfigCommonInputCrop as the second parameter - * and would send a pointer to an initialized OMX_RECTTYPE structure as the - * third parameter. - * - * The enumeration entries named with the OMX_Config prefix are sent using - * the OMX_SetConfig command and the enumeration entries named with the - * OMX_PARAM_ prefix are sent using the OMX_SetParameter command. - */ -typedef enum OMX_INDEXTYPE { - - OMX_IndexComponentStartUnused = 0x01000000, - OMX_IndexParamPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ - OMX_IndexParamAudioInit, /**< reference: OMX_PORT_PARAM_TYPE */ - OMX_IndexParamImageInit, /**< reference: OMX_PORT_PARAM_TYPE */ - OMX_IndexParamVideoInit, /**< reference: OMX_PORT_PARAM_TYPE */ - OMX_IndexParamOtherInit, /**< reference: OMX_PORT_PARAM_TYPE */ - OMX_IndexParamNumAvailableStreams, /**< reference: OMX_PARAM_U32TYPE */ - OMX_IndexParamActiveStream, /**< reference: OMX_PARAM_U32TYPE */ - OMX_IndexParamSuspensionPolicy, /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */ - OMX_IndexParamComponentSuspended, /**< reference: OMX_PARAM_SUSPENSIONTYPE */ - OMX_IndexConfigCapturing, /**< reference: OMX_CONFIG_BOOLEANTYPE */ - OMX_IndexConfigCaptureMode, /**< reference: OMX_CONFIG_CAPTUREMODETYPE */ - OMX_IndexAutoPauseAfterCapture, /**< reference: OMX_CONFIG_BOOLEANTYPE */ - OMX_IndexParamContentURI, /**< reference: OMX_PARAM_CONTENTURITYPE */ - OMX_IndexParamCustomContentPipe, /**< reference: OMX_PARAM_CONTENTPIPETYPE */ - OMX_IndexParamDisableResourceConcealment, /**< reference: OMX_RESOURCECONCEALMENTTYPE */ - OMX_IndexConfigMetadataItemCount, /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */ - OMX_IndexConfigContainerNodeCount, /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */ - OMX_IndexConfigMetadataItem, /**< reference: OMX_CONFIG_METADATAITEMTYPE */ - OMX_IndexConfigCounterNodeID, /**< reference: OMX_CONFIG_CONTAINERNODEIDTYPE */ - OMX_IndexParamMetadataFilterType, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ - OMX_IndexParamMetadataKeyFilter, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ - OMX_IndexConfigPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ - OMX_IndexParamStandardComponentRole, /**< reference: OMX_PARAM_COMPONENTROLETYPE */ - - OMX_IndexPortStartUnused = 0x02000000, - OMX_IndexParamPortDefinition, /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */ - OMX_IndexParamCompBufferSupplier, /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */ - OMX_IndexReservedStartUnused = 0x03000000, - - /* Audio parameters and configurations */ - OMX_IndexAudioStartUnused = 0x04000000, - OMX_IndexParamAudioPortFormat, /**< reference: OMX_AUDIO_PARAM_PORTFORMATTYPE */ - OMX_IndexParamAudioPcm, /**< reference: OMX_AUDIO_PARAM_PCMMODETYPE */ - OMX_IndexParamAudioAac, /**< reference: OMX_AUDIO_PARAM_AACPROFILETYPE */ - OMX_IndexParamAudioRa, /**< reference: OMX_AUDIO_PARAM_RATYPE */ - OMX_IndexParamAudioMp3, /**< reference: OMX_AUDIO_PARAM_MP3TYPE */ - OMX_IndexParamAudioAdpcm, /**< reference: OMX_AUDIO_PARAM_ADPCMTYPE */ - OMX_IndexParamAudioG723, /**< reference: OMX_AUDIO_PARAM_G723TYPE */ - OMX_IndexParamAudioG729, /**< reference: OMX_AUDIO_PARAM_G729TYPE */ - OMX_IndexParamAudioAmr, /**< reference: OMX_AUDIO_PARAM_AMRTYPE */ - OMX_IndexParamAudioWma, /**< reference: OMX_AUDIO_PARAM_WMATYPE */ - OMX_IndexParamAudioSbc, /**< reference: OMX_AUDIO_PARAM_SBCTYPE */ - OMX_IndexParamAudioMidi, /**< reference: OMX_AUDIO_PARAM_MIDITYPE */ - OMX_IndexParamAudioGsm_FR, /**< reference: OMX_AUDIO_PARAM_GSMFRTYPE */ - OMX_IndexParamAudioMidiLoadUserSound, /**< reference: OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE */ - OMX_IndexParamAudioG726, /**< reference: OMX_AUDIO_PARAM_G726TYPE */ - OMX_IndexParamAudioGsm_EFR, /**< reference: OMX_AUDIO_PARAM_GSMEFRTYPE */ - OMX_IndexParamAudioGsm_HR, /**< reference: OMX_AUDIO_PARAM_GSMHRTYPE */ - OMX_IndexParamAudioPdc_FR, /**< reference: OMX_AUDIO_PARAM_PDCFRTYPE */ - OMX_IndexParamAudioPdc_EFR, /**< reference: OMX_AUDIO_PARAM_PDCEFRTYPE */ - OMX_IndexParamAudioPdc_HR, /**< reference: OMX_AUDIO_PARAM_PDCHRTYPE */ - OMX_IndexParamAudioTdma_FR, /**< reference: OMX_AUDIO_PARAM_TDMAFRTYPE */ - OMX_IndexParamAudioTdma_EFR, /**< reference: OMX_AUDIO_PARAM_TDMAEFRTYPE */ - OMX_IndexParamAudioQcelp8, /**< reference: OMX_AUDIO_PARAM_QCELP8TYPE */ - OMX_IndexParamAudioQcelp13, /**< reference: OMX_AUDIO_PARAM_QCELP13TYPE */ - OMX_IndexParamAudioEvrc, /**< reference: OMX_AUDIO_PARAM_EVRCTYPE */ - OMX_IndexParamAudioSmv, /**< reference: OMX_AUDIO_PARAM_SMVTYPE */ - OMX_IndexParamAudioVorbis, /**< reference: OMX_AUDIO_PARAM_VORBISTYPE */ - - OMX_IndexConfigAudioMidiImmediateEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE */ - OMX_IndexConfigAudioMidiControl, /**< reference: OMX_AUDIO_CONFIG_MIDICONTROLTYPE */ - OMX_IndexConfigAudioMidiSoundBankProgram, /**< reference: OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE */ - OMX_IndexConfigAudioMidiStatus, /**< reference: OMX_AUDIO_CONFIG_MIDISTATUSTYPE */ - OMX_IndexConfigAudioMidiMetaEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE */ - OMX_IndexConfigAudioMidiMetaEventData, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE */ - OMX_IndexConfigAudioVolume, /**< reference: OMX_AUDIO_CONFIG_VOLUMETYPE */ - OMX_IndexConfigAudioBalance, /**< reference: OMX_AUDIO_CONFIG_BALANCETYPE */ - OMX_IndexConfigAudioChannelMute, /**< reference: OMX_AUDIO_CONFIG_CHANNELMUTETYPE */ - OMX_IndexConfigAudioMute, /**< reference: OMX_AUDIO_CONFIG_MUTETYPE */ - OMX_IndexConfigAudioLoudness, /**< reference: OMX_AUDIO_CONFIG_LOUDNESSTYPE */ - OMX_IndexConfigAudioEchoCancelation, /**< reference: OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE */ - OMX_IndexConfigAudioNoiseReduction, /**< reference: OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE */ - OMX_IndexConfigAudioBass, /**< reference: OMX_AUDIO_CONFIG_BASSTYPE */ - OMX_IndexConfigAudioTreble, /**< reference: OMX_AUDIO_CONFIG_TREBLETYPE */ - OMX_IndexConfigAudioStereoWidening, /**< reference: OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE */ - OMX_IndexConfigAudioChorus, /**< reference: OMX_AUDIO_CONFIG_CHORUSTYPE */ - OMX_IndexConfigAudioEqualizer, /**< reference: OMX_AUDIO_CONFIG_EQUALIZERTYPE */ - OMX_IndexConfigAudioReverberation, /**< reference: OMX_AUDIO_CONFIG_REVERBERATIONTYPE */ - OMX_IndexConfigAudioChannelVolume, /**< reference: OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE */ - - /* Image specific parameters and configurations */ - OMX_IndexImageStartUnused = 0x05000000, - OMX_IndexParamImagePortFormat, /**< reference: OMX_IMAGE_PARAM_PORTFORMATTYPE */ - OMX_IndexParamFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ - OMX_IndexConfigFocusControl, /**< reference: OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE */ - OMX_IndexParamQFactor, /**< reference: OMX_IMAGE_PARAM_QFACTORTYPE */ - OMX_IndexParamQuantizationTable, /**< reference: OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE */ - OMX_IndexParamHuffmanTable, /**< reference: OMX_IMAGE_PARAM_HUFFMANTTABLETYPE */ - OMX_IndexConfigFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ - - /* Video specific parameters and configurations */ - OMX_IndexVideoStartUnused = 0x06000000, - OMX_IndexParamVideoPortFormat, /**< reference: OMX_VIDEO_PARAM_PORTFORMATTYPE */ - OMX_IndexParamVideoQuantization, /**< reference: OMX_VIDEO_PARAM_QUANTIZATIONTYPE */ - OMX_IndexParamVideoFastUpdate, /**< reference: OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE */ - OMX_IndexParamVideoBitrate, /**< reference: OMX_VIDEO_PARAM_BITRATETYPE */ - OMX_IndexParamVideoMotionVector, /**< reference: OMX_VIDEO_PARAM_MOTIONVECTORTYPE */ - OMX_IndexParamVideoIntraRefresh, /**< reference: OMX_VIDEO_PARAM_INTRAREFRESHTYPE */ - OMX_IndexParamVideoErrorCorrection, /**< reference: OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE */ - OMX_IndexParamVideoVBSMC, /**< reference: OMX_VIDEO_PARAM_VBSMCTYPE */ - OMX_IndexParamVideoMpeg2, /**< reference: OMX_VIDEO_PARAM_MPEG2TYPE */ - OMX_IndexParamVideoMpeg4, /**< reference: OMX_VIDEO_PARAM_MPEG4TYPE */ - OMX_IndexParamVideoWmv, /**< reference: OMX_VIDEO_PARAM_WMVTYPE */ - OMX_IndexParamVideoRv, /**< reference: OMX_VIDEO_PARAM_RVTYPE */ - OMX_IndexParamVideoAvc, /**< reference: OMX_VIDEO_PARAM_AVCTYPE */ - OMX_IndexParamVideoH263, /**< reference: OMX_VIDEO_PARAM_H263TYPE */ - OMX_IndexParamVideoProfileLevelQuerySupported, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ - OMX_IndexParamVideoProfileLevelCurrent, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ - OMX_IndexConfigVideoBitrate, /**< reference: OMX_VIDEO_CONFIG_BITRATETYPE */ - OMX_IndexConfigVideoFramerate, /**< reference: OMX_CONFIG_FRAMERATETYPE */ - OMX_IndexConfigVideoIntraVOPRefresh, /**< reference: OMX_CONFIG_INTRAREFRESHVOPTYPE */ - OMX_IndexConfigVideoIntraMBRefresh, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ - OMX_IndexConfigVideoMBErrorReporting, /**< reference: OMX_CONFIG_MBERRORREPORTINGTYPE */ - OMX_IndexParamVideoMacroblocksPerFrame, /**< reference: OMX_PARAM_MACROBLOCKSTYPE */ - OMX_IndexConfigVideoMacroBlockErrorMap, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ - OMX_IndexParamVideoSliceFMO, /**< reference: OMX_VIDEO_PARAM_AVCSLICEFMO */ - OMX_IndexConfigVideoAVCIntraPeriod, /**< reference: OMX_VIDEO_CONFIG_AVCINTRAPERIOD */ - OMX_IndexConfigVideoNalSize, /**< reference: OMX_VIDEO_CONFIG_NALSIZE */ - OMX_IndexConfigCommonDeinterlace, /**< reference: OMX_VIDEO_CONFIG_DEINTERLACE */ - - /* Image & Video common Configurations */ - OMX_IndexCommonStartUnused = 0x07000000, - OMX_IndexParamCommonDeblocking, /**< reference: OMX_PARAM_DEBLOCKINGTYPE */ - OMX_IndexParamCommonSensorMode, /**< reference: OMX_PARAM_SENSORMODETYPE */ - OMX_IndexParamCommonInterleave, /**< reference: OMX_PARAM_INTERLEAVETYPE */ - OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */ - OMX_IndexConfigCommonScale, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ - OMX_IndexConfigCommonImageFilter, /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */ - OMX_IndexConfigCommonColorEnhancement, /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */ - OMX_IndexConfigCommonColorKey, /**< reference: OMX_CONFIG_COLORKEYTYPE */ - OMX_IndexConfigCommonColorBlend, /**< reference: OMX_CONFIG_COLORBLENDTYPE */ - OMX_IndexConfigCommonFrameStabilisation,/**< reference: OMX_CONFIG_FRAMESTABTYPE */ - OMX_IndexConfigCommonRotate, /**< reference: OMX_CONFIG_ROTATIONTYPE */ - OMX_IndexConfigCommonMirror, /**< reference: OMX_CONFIG_MIRRORTYPE */ - OMX_IndexConfigCommonOutputPosition, /**< reference: OMX_CONFIG_POINTTYPE */ - OMX_IndexConfigCommonInputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ - OMX_IndexConfigCommonOutputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ - OMX_IndexConfigCommonDigitalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ - OMX_IndexConfigCommonOpticalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE*/ - OMX_IndexConfigCommonWhiteBalance, /**< reference: OMX_CONFIG_WHITEBALCONTROLTYPE */ - OMX_IndexConfigCommonExposure, /**< reference: OMX_CONFIG_EXPOSURECONTROLTYPE */ - OMX_IndexConfigCommonContrast, /**< reference: OMX_CONFIG_CONTRASTTYPE */ - OMX_IndexConfigCommonBrightness, /**< reference: OMX_CONFIG_BRIGHTNESSTYPE */ - OMX_IndexConfigCommonBacklight, /**< reference: OMX_CONFIG_BACKLIGHTTYPE */ - OMX_IndexConfigCommonGamma, /**< reference: OMX_CONFIG_GAMMATYPE */ - OMX_IndexConfigCommonSaturation, /**< reference: OMX_CONFIG_SATURATIONTYPE */ - OMX_IndexConfigCommonLightness, /**< reference: OMX_CONFIG_LIGHTNESSTYPE */ - OMX_IndexConfigCommonExclusionRect, /**< reference: OMX_CONFIG_RECTTYPE */ - OMX_IndexConfigCommonDithering, /**< reference: OMX_CONFIG_DITHERTYPE */ - OMX_IndexConfigCommonPlaneBlend, /**< reference: OMX_CONFIG_PLANEBLENDTYPE */ - OMX_IndexConfigCommonExposureValue, /**< reference: OMX_CONFIG_EXPOSUREVALUETYPE */ - OMX_IndexConfigCommonOutputSize, /**< reference: OMX_FRAMESIZETYPE */ - OMX_IndexParamCommonExtraQuantData, /**< reference: OMX_OTHER_EXTRADATATYPE */ - OMX_IndexConfigCommonFocusRegion, /**< reference: OMX_CONFIG_FOCUSREGIONTYPE */ - OMX_IndexConfigCommonFocusStatus, /**< reference: OMX_PARAM_FOCUSSTATUSTYPE */ - OMX_IndexConfigCommonTransitionEffect, /**< reference: OMX_CONFIG_TRANSITIONEFFECTTYPE */ - - /* Reserved Configuration range */ - OMX_IndexOtherStartUnused = 0x08000000, - OMX_IndexParamOtherPortFormat, /**< reference: OMX_OTHER_PARAM_PORTFORMATTYPE */ - OMX_IndexConfigOtherPower, /**< reference: OMX_OTHER_CONFIG_POWERTYPE */ - OMX_IndexConfigOtherStats, /**< reference: OMX_OTHER_CONFIG_STATSTYPE */ - - - /* Reserved Time range */ - OMX_IndexTimeStartUnused = 0x09000000, - OMX_IndexConfigTimeScale, /**< reference: OMX_TIME_CONFIG_SCALETYPE */ - OMX_IndexConfigTimeClockState, /**< reference: OMX_TIME_CONFIG_CLOCKSTATETYPE */ - OMX_IndexConfigTimeActiveRefClock, /**< reference: OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE */ - OMX_IndexConfigTimeCurrentMediaTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ - OMX_IndexConfigTimeCurrentWallTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ - OMX_IndexConfigTimeCurrentAudioReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ - OMX_IndexConfigTimeCurrentVideoReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ - OMX_IndexConfigTimeMediaTimeRequest, /**< reference: OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE (write only) */ - OMX_IndexConfigTimeClientStartTime, /** - - -/** Khronos standard extension indices. - -This enum lists the current Khronos extension indices to OpenMAX IL. -*/ -typedef enum OMX_INDEXEXTTYPE { - - /* Component parameters and configurations */ - OMX_IndexExtComponentStartUnused = OMX_IndexKhronosExtensions + 0x00100000, - OMX_IndexConfigCallbackRequest, /**< reference: OMX_CONFIG_CALLBACKREQUESTTYPE */ - OMX_IndexConfigCommitMode, /**< reference: OMX_CONFIG_COMMITMODETYPE */ - OMX_IndexConfigCommit, /**< reference: OMX_CONFIG_COMMITTYPE */ - - /* Port parameters and configurations */ - OMX_IndexExtPortStartUnused = OMX_IndexKhronosExtensions + 0x00200000, - - /* Audio parameters and configurations */ - OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000, - - /* Image parameters and configurations */ - OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000, - - /* Video parameters and configurations */ - OMX_IndexExtVideoStartUnused = OMX_IndexKhronosExtensions + 0x00600000, - OMX_IndexParamNalStreamFormatSupported, /**< reference: OMX_NALSTREAMFORMATTYPE */ - OMX_IndexParamNalStreamFormat, /**< reference: OMX_NALSTREAMFORMATTYPE */ - OMX_IndexParamNalStreamFormatSelect, /**< reference: OMX_NALSTREAMFORMATTYPE */ - OMX_IndexParamVideoVp8, /**< reference: OMX_VIDEO_PARAM_VP8TYPE */ - OMX_IndexConfigVideoVp8ReferenceFrame, /**< reference: OMX_VIDEO_VP8REFERENCEFRAMETYPE */ - OMX_IndexConfigVideoVp8ReferenceFrameType, /**< reference: OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE */ - OMX_IndexParamVideoReserved, /**< Reserved for future index */ - OMX_IndexParamVideoHevc, /**< reference: OMX_VIDEO_PARAM_HEVCTYPE */ - - /* Image & Video common configurations */ - OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000, - - /* Other configurations */ - OMX_IndexExtOtherStartUnused = OMX_IndexKhronosExtensions + 0x00800000, - OMX_IndexConfigAutoFramerateConversion, /**< reference: OMX_CONFIG_BOOLEANTYPE */ - OMX_IndexConfigPriority, /**< reference: OMX_PARAM_U32TYPE */ - OMX_IndexConfigOperatingRate, /**< reference: OMX_PARAM_U32TYPE in Q16 format for video and in Hz for audio */ - - /* Time configurations */ - OMX_IndexExtTimeStartUnused = OMX_IndexKhronosExtensions + 0x00900000, - - OMX_IndexExtMax = 0x7FFFFFFF -} OMX_INDEXEXTTYPE; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* OMX_IndexExt_h */ -/* File EOF */ diff --git a/third_party/openmax/include/OMX_Other.h b/third_party/openmax/include/OMX_Other.h deleted file mode 100644 index caf7f38448..0000000000 --- a/third_party/openmax/include/OMX_Other.h +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** @file OMX_Other.h - OpenMax IL version 1.1.2 - * The structures needed by Other components to exchange - * parameters and configuration data with the components. - */ - -#ifndef OMX_Other_h -#define OMX_Other_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/* Each OMX header must include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ - -#include - - -/** - * Enumeration of possible data types which match to multiple domains or no - * domain at all. For types which are vendor specific, a value above - * OMX_OTHER_VENDORTSTART should be used. - */ -typedef enum OMX_OTHER_FORMATTYPE { - OMX_OTHER_FormatTime = 0, /**< Transmission of various timestamps, elapsed time, - time deltas, etc */ - OMX_OTHER_FormatPower, /**< Perhaps used for enabling/disabling power - management, setting clocks? */ - OMX_OTHER_FormatStats, /**< Could be things such as frame rate, frames - dropped, etc */ - OMX_OTHER_FormatBinary, /**< Arbitrary binary data */ - OMX_OTHER_FormatVendorReserved = 1000, /**< Starting value for vendor specific - formats */ - - OMX_OTHER_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_OTHER_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_OTHER_FormatMax = 0x7FFFFFFF -} OMX_OTHER_FORMATTYPE; - -/** - * Enumeration of seek modes. - */ -typedef enum OMX_TIME_SEEKMODETYPE { - OMX_TIME_SeekModeFast = 0, /**< Prefer seeking to an approximation - * of the requested seek position over - * the actual seek position if it - * results in a faster seek. */ - OMX_TIME_SeekModeAccurate, /**< Prefer seeking to the actual seek - * position over an approximation - * of the requested seek position even - * if it results in a slower seek. */ - OMX_TIME_SeekModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_TIME_SeekModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_TIME_SeekModeMax = 0x7FFFFFFF -} OMX_TIME_SEEKMODETYPE; - -/* Structure representing the seekmode of the component */ -typedef struct OMX_TIME_CONFIG_SEEKMODETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_TIME_SEEKMODETYPE eType; /**< The seek mode */ -} OMX_TIME_CONFIG_SEEKMODETYPE; - -/** Structure representing a time stamp used with the following configs - * on the Clock Component (CC): - * - * OMX_IndexConfigTimeCurrentWallTime: query of the CC’s current wall - * time - * OMX_IndexConfigTimeCurrentMediaTime: query of the CC’s current media - * time - * OMX_IndexConfigTimeCurrentAudioReference and - * OMX_IndexConfigTimeCurrentVideoReference: audio/video reference - * clock sending SC its reference time - * OMX_IndexConfigTimeClientStartTime: a Clock Component client sends - * this structure to the Clock Component via a SetConfig on its - * client port when it receives a buffer with - * OMX_BUFFERFLAG_STARTTIME set. It must use the timestamp - * specified by that buffer for nStartTimestamp. - * - * It’s also used with the following config on components in general: - * - * OMX_IndexConfigTimePosition: IL client querying component position - * (GetConfig) or commanding a component to seek to the given location - * (SetConfig) - */ -typedef struct OMX_TIME_CONFIG_TIMESTAMPTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version - * information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_TICKS nTimestamp; /**< timestamp .*/ -} OMX_TIME_CONFIG_TIMESTAMPTYPE; - -/** Enumeration of possible reference clocks to the media time. */ -typedef enum OMX_TIME_UPDATETYPE { - OMX_TIME_UpdateRequestFulfillment, /**< Update is the fulfillment of a media time request. */ - OMX_TIME_UpdateScaleChanged, /**< Update was generated because the scale chagned. */ - OMX_TIME_UpdateClockStateChanged, /**< Update was generated because the clock state changed. */ - OMX_TIME_UpdateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_TIME_UpdateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_TIME_UpdateMax = 0x7FFFFFFF -} OMX_TIME_UPDATETYPE; - -/** Enumeration of possible reference clocks to the media time. */ -typedef enum OMX_TIME_REFCLOCKTYPE { - OMX_TIME_RefClockNone, /**< Use no references. */ - OMX_TIME_RefClockAudio, /**< Use references sent through OMX_IndexConfigTimeCurrentAudioReference */ - OMX_TIME_RefClockVideo, /**< Use references sent through OMX_IndexConfigTimeCurrentVideoReference */ - OMX_TIME_RefClockKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_TIME_RefClockVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_TIME_RefClockMax = 0x7FFFFFFF -} OMX_TIME_REFCLOCKTYPE; - -/** Enumeration of clock states. */ -typedef enum OMX_TIME_CLOCKSTATE { - OMX_TIME_ClockStateRunning, /**< Clock running. */ - OMX_TIME_ClockStateWaitingForStartTime, /**< Clock waiting until the - * prescribed clients emit their - * start time. */ - OMX_TIME_ClockStateStopped, /**< Clock stopped. */ - OMX_TIME_ClockStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_TIME_ClockStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_TIME_ClockStateMax = 0x7FFFFFFF -} OMX_TIME_CLOCKSTATE; - -/** Structure representing a media time request to the clock component. - * - * A client component sends this structure to the Clock Component via a SetConfig - * on its client port to specify a media timestamp the Clock Component - * should emit. The Clock Component should fulfill the request by sending a - * OMX_TIME_MEDIATIMETYPE when its media clock matches the requested - * timestamp. - * - * The client may require a media time request be fulfilled slightly - * earlier than the media time specified. In this case the client specifies - * an offset which is equal to the difference between wall time corresponding - * to the requested media time and the wall time when it will be - * fulfilled. - * - * A client component may uses these requests and the OMX_TIME_MEDIATIMETYPE to - * time events according to timestamps. If a client must perform an operation O at - * a time T (e.g. deliver a video frame at its corresponding timestamp), it makes a - * media time request at T (perhaps specifying an offset to ensure the request fulfillment - * is a little early). When the clock component passes the resulting OMX_TIME_MEDIATIMETYPE - * structure back to the client component, the client may perform operation O (perhaps having - * to wait a slight amount more time itself as specified by the return values). - */ - -typedef struct OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< port that this structure applies to */ - OMX_PTR pClientPrivate; /**< Client private data to disabiguate this media time - * from others (e.g. the number of the frame to deliver). - * Duplicated in the media time structure that fulfills - * this request. A value of zero is reserved for time scale - * updates. */ - OMX_TICKS nMediaTimestamp; /**< Media timestamp requested.*/ - OMX_TICKS nOffset; /**< Amount of wall clock time by which this - * request should be fulfilled early */ -} OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE; - -/**< Structure sent from the clock component client either when fulfilling - * a media time request or when the time scale has changed. - * - * In the former case the Clock Component fills this structure and times its emission - * to a client component (via the client port) according to the corresponding media - * time request sent by the client. The Clock Component should time the emission to occur - * when the requested timestamp matches the Clock Component's media time but also the - * prescribed offset early. - * - * Upon scale changes the clock component clears the nClientPrivate data, sends the current - * media time and sets the nScale to the new scale via the client port. It emits a - * OMX_TIME_MEDIATIMETYPE to all clients independent of any requests. This allows clients to - * alter processing to accomodate scaling. For instance a video component might skip inter-frames - * in the case of extreme fastforward. Likewise an audio component might add or remove samples - * from an audio frame to scale audio data. - * - * It is expected that some clock components may not be able to fulfill requests - * at exactly the prescribed time. This is acceptable so long as the request is - * fulfilled at least as early as described and not later. This structure provides - * fields the client may use to wait for the remaining time. - * - * The client may use either the nOffset or nWallTimeAtMedia fields to determine the - * wall time until the nMediaTimestamp actually occurs. In the latter case the - * client can get a more accurate value for offset by getting the current wall - * from the cloc component and subtracting it from nWallTimeAtMedia. - */ - -typedef struct OMX_TIME_MEDIATIMETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nClientPrivate; /**< Client private data to disabiguate this media time - * from others. Copied from the media time request. - * A value of zero is reserved for time scale updates. */ - OMX_TIME_UPDATETYPE eUpdateType; /**< Reason for the update */ - OMX_TICKS nMediaTimestamp; /**< Media time requested. If no media time was - * requested then this is the current media time. */ - OMX_TICKS nOffset; /**< Amount of wall clock time by which this - * request was actually fulfilled early */ - - OMX_TICKS nWallTimeAtMediaTime; /**< Wall time corresponding to nMediaTimeStamp. - * A client may compare this value to current - * media time obtained from the Clock Component to determine - * the wall time until the media timestamp is really - * current. */ - OMX_S32 xScale; /**< Current media time scale in Q16 format. */ - OMX_TIME_CLOCKSTATE eState; /* Seeking Change. Added 7/12.*/ - /**< State of the media time. */ -} OMX_TIME_MEDIATIMETYPE; - -/** Structure representing the current media time scale factor. Applicable only to clock - * component, other components see scale changes via OMX_TIME_MEDIATIMETYPE buffers sent via - * the clock component client ports. Upon recieving this config the clock component changes - * the rate by which the media time increases or decreases effectively implementing trick modes. - */ -typedef struct OMX_TIME_CONFIG_SCALETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_S32 xScale; /**< This is a value in Q16 format which is used for - * scaling the media time */ -} OMX_TIME_CONFIG_SCALETYPE; - -/** Bits used to identify a clock port. Used in OMX_TIME_CONFIG_CLOCKSTATETYPE’s nWaitMask field */ -#define OMX_CLOCKPORT0 0x00000001 -#define OMX_CLOCKPORT1 0x00000002 -#define OMX_CLOCKPORT2 0x00000004 -#define OMX_CLOCKPORT3 0x00000008 -#define OMX_CLOCKPORT4 0x00000010 -#define OMX_CLOCKPORT5 0x00000020 -#define OMX_CLOCKPORT6 0x00000040 -#define OMX_CLOCKPORT7 0x00000080 - -/** Structure representing the current mode of the media clock. - * IL Client uses this config to change or query the mode of the - * media clock of the clock component. Applicable only to clock - * component. - * - * On a SetConfig if eState is OMX_TIME_ClockStateRunning media time - * starts immediately at the prescribed start time. If - * OMX_TIME_ClockStateWaitingForStartTime the Clock Component ignores - * the given nStartTime and waits for all clients specified in the - * nWaitMask to send starttimes (via - * OMX_IndexConfigTimeClientStartTime). The Clock Component then starts - * the media clock using the earliest start time supplied. */ -typedef struct OMX_TIME_CONFIG_CLOCKSTATETYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version - * information */ - OMX_TIME_CLOCKSTATE eState; /**< State of the media time. */ - OMX_TICKS nStartTime; /**< Start time of the media time. */ - OMX_TICKS nOffset; /**< Time to offset the media time by - * (e.g. preroll). Media time will be - * reported to be nOffset ticks earlier. - */ - OMX_U32 nWaitMask; /**< Mask of OMX_CLOCKPORT values. */ -} OMX_TIME_CONFIG_CLOCKSTATETYPE; - -/** Structure representing the reference clock currently being used to - * compute media time. IL client uses this config to change or query the - * clock component's active reference clock */ -typedef struct OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_TIME_REFCLOCKTYPE eClock; /**< Reference clock used to compute media time */ -} OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE; - -/** Descriptor for setting specifics of power type. - * Note: this structure is listed for backwards compatibility. */ -typedef struct OMX_OTHER_CONFIG_POWERTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_BOOL bEnablePM; /**< Flag to enable Power Management */ -} OMX_OTHER_CONFIG_POWERTYPE; - - -/** Descriptor for setting specifics of stats type. - * Note: this structure is listed for backwards compatibility. */ -typedef struct OMX_OTHER_CONFIG_STATSTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - /* what goes here */ -} OMX_OTHER_CONFIG_STATSTYPE; - - -/** - * The PortDefinition structure is used to define all of the parameters - * necessary for the compliant component to setup an input or an output other - * path. - */ -typedef struct OMX_OTHER_PORTDEFINITIONTYPE { - OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */ -} OMX_OTHER_PORTDEFINITIONTYPE; - -/** Port format parameter. This structure is used to enumerate - * the various data input/output format supported by the port. - */ -typedef struct OMX_OTHER_PARAM_PORTFORMATTYPE { - OMX_U32 nSize; /**< size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Indicates which port to set */ - OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */ - OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */ -} OMX_OTHER_PARAM_PORTFORMATTYPE; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ diff --git a/third_party/openmax/include/OMX_QCOMExtns.h b/third_party/openmax/include/OMX_QCOMExtns.h deleted file mode 100644 index 20917932be..0000000000 --- a/third_party/openmax/include/OMX_QCOMExtns.h +++ /dev/null @@ -1,1888 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2009-2015, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef __OMX_QCOM_EXTENSIONS_H__ -#define __OMX_QCOM_EXTENSIONS_H__ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/*============================================================================ -*//** @file OMX_QCOMExtns.h - This header contains constants and type definitions that specify the - extensions added to the OpenMAX Vendor specific APIs. - -*//*========================================================================*/ - - -/////////////////////////////////////////////////////////////////////////////// -// Include Files -/////////////////////////////////////////////////////////////////////////////// -#include "OMX_Core.h" -#include "OMX_Video.h" - -#define OMX_VIDEO_MAX_HP_LAYERS 6 -/** - * This extension is used to register mapping of a virtual - * address to a physical address. This extension is a parameter - * which can be set using the OMX_SetParameter macro. The data - * pointer corresponding to this extension is - * OMX_QCOM_MemMapEntry. This parameter is a 'write only' - * parameter (Current value cannot be queried using - * OMX_GetParameter macro). - */ -#define OMX_QCOM_EXTN_REGISTER_MMAP "OMX.QCOM.index.param.register_mmap" - -/** - * This structure describes the data pointer corresponding to - * the OMX_QCOM_MMAP_REGISTER_EXTN extension. This parameter - * must be set only 'after' populating a port with a buffer - * using OMX_UseBuffer, wherein the data pointer of the buffer - * corresponds to the virtual address as specified in this - * structure. - */ -struct OMX_QCOM_PARAM_MEMMAPENTRYTYPE -{ - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ - OMX_U32 nPortIndex; /**< Port number the structure applies to */ - - /** - * The virtual address of memory block - */ - OMX_U64 nVirtualAddress; - - /** - * The physical address corresponding to the virtual address. The physical - * address is contiguous for the entire valid range of the virtual - * address. - */ - OMX_U64 nPhysicalAddress; -}; - -#define QOMX_VIDEO_IntraRefreshRandom (OMX_VIDEO_IntraRefreshVendorStartUnused + 0) - -/* This error event is used for H.264 long-term reference (LTR) encoding. - * When IL client specifies an LTR frame with its identifier via - * OMX_QCOM_INDEX_CONFIG_VIDEO_LTRUSE to the encoder, if the specified - * LTR frame can not be located by the encoder in its LTR list, the encoder - * issues this error event to IL client to notify the failure of LTRUse config. - */ -#define QOMX_ErrorLTRUseFailed (OMX_ErrorVendorStartUnused + 1) - -#define QOMX_VIDEO_BUFFERFLAG_BFRAME 0x00100000 - -#define QOMX_VIDEO_BUFFERFLAG_EOSEQ 0x00200000 - -#define QOMX_VIDEO_BUFFERFLAG_MBAFF 0x00400000 - -#define QOMX_VIDEO_BUFFERFLAG_CANCEL 0x00800000 - -#define OMX_QCOM_PORTDEFN_EXTN "OMX.QCOM.index.param.portdefn" -/* Allowed APIs on the above Index: OMX_GetParameter() and OMX_SetParameter() */ - -typedef enum OMX_QCOMMemoryRegion -{ - OMX_QCOM_MemRegionInvalid, - OMX_QCOM_MemRegionEBI1, - OMX_QCOM_MemRegionSMI, - OMX_QCOM_MemRegionMax = 0X7FFFFFFF -} OMX_QCOMMemoryRegion; - -typedef enum OMX_QCOMCacheAttr -{ - OMX_QCOM_CacheAttrNone, - OMX_QCOM_CacheAttrWriteBack, - OMX_QCOM_CacheAttrWriteThrough, - OMX_QCOM_CacheAttrMAX = 0X7FFFFFFF -} OMX_QCOMCacheAttr; - -typedef struct OMX_QCOMRectangle -{ - OMX_S32 x; - OMX_S32 y; - OMX_S32 dx; - OMX_S32 dy; -} OMX_QCOMRectangle; - -/** OMX_QCOMFramePackingFormat - * Input or output buffer format - */ -typedef enum OMX_QCOMFramePackingFormat -{ - /* 0 - unspecified - */ - OMX_QCOM_FramePacking_Unspecified, - - /* 1 - Partial frames may be present OMX IL 1.1.1 Figure 2-10: - * Case 1??Each Buffer Filled In Whole or In Part - */ - OMX_QCOM_FramePacking_Arbitrary, - - /* 2 - Multiple complete frames per buffer (integer number) - * OMX IL 1.1.1 Figure 2-11: Case 2—Each Buffer Filled with - * Only Complete Frames of Data - */ - OMX_QCOM_FramePacking_CompleteFrames, - - /* 3 - Only one complete frame per buffer, no partial frame - * OMX IL 1.1.1 Figure 2-12: Case 3—Each Buffer Filled with - * Only One Frame of Compressed Data. Usually at least one - * complete unit of data will be delivered in a buffer for - * uncompressed data formats. - */ - OMX_QCOM_FramePacking_OnlyOneCompleteFrame, - - /* 4 - Only one complete subframe per buffer, no partial subframe - * Example: In H264, one complete NAL per buffer, where one frame - * can contatin multiple NAL - */ - OMX_QCOM_FramePacking_OnlyOneCompleteSubFrame, - - OMX_QCOM_FramePacking_MAX = 0X7FFFFFFF -} OMX_QCOMFramePackingFormat; - -typedef struct OMX_QCOM_PARAM_PORTDEFINITIONTYPE { - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion;/** OMX specification version information */ - OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ - - /** Platform specific memory region EBI1, SMI, etc.,*/ - OMX_QCOMMemoryRegion nMemRegion; - - OMX_QCOMCacheAttr nCacheAttr; /** Cache attributes */ - - /** Input or output buffer format */ - OMX_U32 nFramePackingFormat; - -} OMX_QCOM_PARAM_PORTDEFINITIONTYPE; - -typedef struct OMX_QCOM_VIDEO_PARAM_QPRANGETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 minQP; - OMX_U32 maxQP; -} OMX_QCOM_VIDEO_PARAM_QPRANGETYPE; - -#define OMX_QCOM_PLATFORMPVT_EXTN "OMX.QCOM.index.param.platformprivate" -/** Allowed APIs on the above Index: OMX_SetParameter() */ - -typedef enum OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE -{ - /** Enum for PMEM information */ - OMX_QCOM_PLATFORM_PRIVATE_PMEM = 0x1 -} OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE; - -/** IL client will set the following structure. A failure - * code will be returned if component does not support the - * value provided for 'type'. - */ -struct OMX_QCOM_PLATFORMPRIVATE_EXTN -{ - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /** OMX spec version information */ - OMX_U32 nPortIndex; /** Port number on which usebuffer extn is applied */ - - /** Type of extensions should match an entry from - OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE - */ - OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE type; -}; - -typedef struct OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO -{ - /** pmem file descriptor */ - unsigned long pmem_fd; - /** Offset from pmem device base address */ - OMX_U32 offset; - OMX_U32 size; - OMX_U32 mapped_size; - OMX_PTR buffer; -}OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO; - -typedef struct OMX_QCOM_PLATFORM_PRIVATE_ENTRY -{ - /** Entry type */ - OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE type; - - /** Pointer to platform specific entry */ - OMX_PTR entry; -}OMX_QCOM_PLATFORM_PRIVATE_ENTRY; - -typedef struct OMX_QCOM_PLATFORM_PRIVATE_LIST -{ - /** Number of entries */ - OMX_U32 nEntries; - - /** Pointer to array of platform specific entries * - * Contiguous block of OMX_QCOM_PLATFORM_PRIVATE_ENTRY element - */ - OMX_QCOM_PLATFORM_PRIVATE_ENTRY* entryList; -}OMX_QCOM_PLATFORM_PRIVATE_LIST; - -#define OMX_QCOM_FRAME_PACKING_FORMAT "OMX.QCOM.index.param.framepackfmt" -/* Allowed API call: OMX_GetParameter() */ -/* IL client can use this index to rerieve the list of frame formats * - * supported by the component */ - -typedef struct OMX_QCOM_FRAME_PACKINGFORMAT_TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nIndex; - OMX_QCOMFramePackingFormat eframePackingFormat; -} OMX_QCOM_FRAME_PACKINGFORMAT_TYPE; - - -/** - * Following is the enum for color formats supported on Qualcomm - * MSMs YVU420SemiPlanar color format is not defined in OpenMAX - * 1.1.1 and prior versions of OpenMAX specification. - */ - -enum OMX_QCOM_COLOR_FORMATTYPE -{ - -/** YVU420SemiPlanar: YVU planar format, organized with a first - * plane containing Y pixels, and a second plane containing - * interleaved V and U pixels. V and U pixels are sub-sampled - * by a factor of two both horizontally and vertically. - */ - QOMX_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00, - QOMX_COLOR_FormatYVU420PackedSemiPlanar32m4ka, - QOMX_COLOR_FormatYUV420PackedSemiPlanar16m2ka, - QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka, - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m, - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView, - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed, - QOMX_COLOR_Format32bitRGBA8888, - QOMX_COLOR_Format32bitRGBA8888Compressed, - QOMX_COLOR_FormatAndroidOpaque = (OMX_COLOR_FORMATTYPE) OMX_COLOR_FormatVendorStartUnused + 0x789, -}; - -enum OMX_QCOM_VIDEO_CODINGTYPE -{ -/** Codecs support by qualcomm which are not listed in OMX 1.1.x - * spec - * */ - OMX_QCOM_VIDEO_CodingVC1 = 0x7FA30C00 , - OMX_QCOM_VIDEO_CodingWMV9 = 0x7FA30C01, - QOMX_VIDEO_CodingDivx = 0x7FA30C02, /**< Value when coding is Divx */ - QOMX_VIDEO_CodingSpark = 0x7FA30C03, /**< Value when coding is Sorenson Spark */ - QOMX_VIDEO_CodingVp = 0x7FA30C04, - QOMX_VIDEO_CodingVp8 = OMX_VIDEO_CodingVP8, /**< keeping old enum for backwards compatibility*/ - QOMX_VIDEO_CodingHevc = OMX_VIDEO_CodingHEVC, /**< keeping old enum for backwards compatibility*/ - QOMX_VIDEO_CodingMVC = 0x7FA30C07, - QOMX_VIDEO_CodingVp9 = OMX_VIDEO_CodingVP9, /**< keeping old enum for backwards compatibility*/ -}; - -enum OMX_QCOM_EXTN_INDEXTYPE -{ - /** Qcom proprietary extension index list */ - - /* "OMX.QCOM.index.param.register_mmap" */ - OMX_QcomIndexRegmmap = 0x7F000000, - - /* "OMX.QCOM.index.param.platformprivate" */ - OMX_QcomIndexPlatformPvt = 0x7F000001, - - /* "OMX.QCOM.index.param.portdefn" */ - OMX_QcomIndexPortDefn = 0x7F000002, - - /* "OMX.QCOM.index.param.framepackingformat" */ - OMX_QcomIndexPortFramePackFmt = 0x7F000003, - - /*"OMX.QCOM.index.param.Interlaced */ - OMX_QcomIndexParamInterlaced = 0x7F000004, - - /*"OMX.QCOM.index.config.interlaceformat */ - OMX_QcomIndexConfigInterlaced = 0x7F000005, - - /*"OMX.QCOM.index.param.syntaxhdr" */ - QOMX_IndexParamVideoSyntaxHdr = 0x7F000006, - - /*"OMX.QCOM.index.config.intraperiod" */ - QOMX_IndexConfigVideoIntraperiod = 0x7F000007, - - /*"OMX.QCOM.index.config.randomIntrarefresh" */ - QOMX_IndexConfigVideoIntraRefresh = 0x7F000008, - - /*"OMX.QCOM.index.config.video.TemporalSpatialTradeOff" */ - QOMX_IndexConfigVideoTemporalSpatialTradeOff = 0x7F000009, - - /*"OMX.QCOM.index.param.video.EncoderMode" */ - QOMX_IndexParamVideoEncoderMode = 0x7F00000A, - - /*"OMX.QCOM.index.param.Divxtype */ - OMX_QcomIndexParamVideoDivx = 0x7F00000B, - - /*"OMX.QCOM.index.param.Sparktype */ - OMX_QcomIndexParamVideoSpark = 0x7F00000C, - - /*"OMX.QCOM.index.param.Vptype */ - OMX_QcomIndexParamVideoVp = 0x7F00000D, - - OMX_QcomIndexQueryNumberOfVideoDecInstance = 0x7F00000E, - - OMX_QcomIndexParamVideoSyncFrameDecodingMode = 0x7F00000F, - - OMX_QcomIndexParamVideoDecoderPictureOrder = 0x7F000010, - - /* "OMX.QCOM.index.config.video.FramePackingInfo" */ - OMX_QcomIndexConfigVideoFramePackingArrangement = 0x7F000011, - - OMX_QcomIndexParamConcealMBMapExtraData = 0x7F000012, - - OMX_QcomIndexParamFrameInfoExtraData = 0x7F000013, - - OMX_QcomIndexParamInterlaceExtraData = 0x7F000014, - - OMX_QcomIndexParamH264TimeInfo = 0x7F000015, - - OMX_QcomIndexParamIndexExtraDataType = 0x7F000016, - - OMX_GoogleAndroidIndexEnableAndroidNativeBuffers = 0x7F000017, - - OMX_GoogleAndroidIndexUseAndroidNativeBuffer = 0x7F000018, - - OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage = 0x7F000019, - - /*"OMX.QCOM.index.config.video.QPRange" */ - OMX_QcomIndexConfigVideoQPRange = 0x7F00001A, - - /*"OMX.QCOM.index.param.EnableTimeStampReoder"*/ - OMX_QcomIndexParamEnableTimeStampReorder = 0x7F00001B, - - /*"OMX.google.android.index.storeMetaDataInBuffers"*/ - OMX_QcomIndexParamVideoMetaBufferMode = 0x7F00001C, - - /*"OMX.google.android.index.useAndroidNativeBuffer2"*/ - OMX_GoogleAndroidIndexUseAndroidNativeBuffer2 = 0x7F00001D, - - /*"OMX.QCOM.index.param.VideoMaxAllowedBitrateCheck"*/ - OMX_QcomIndexParamVideoMaxAllowedBitrateCheck = 0x7F00001E, - - OMX_QcomIndexEnableSliceDeliveryMode = 0x7F00001F, - - /* "OMX.QCOM.index.param.video.ExtnUserExtraData" */ - OMX_QcomIndexEnableExtnUserData = 0x7F000020, - - /*"OMX.QCOM.index.param.video.EnableSmoothStreaming"*/ - OMX_QcomIndexParamEnableSmoothStreaming = 0x7F000021, - - /*"OMX.QCOM.index.param.video.QPRange" */ - OMX_QcomIndexParamVideoQPRange = 0x7F000022, - - OMX_QcomIndexEnableH263PlusPType = 0x7F000023, - - /*"OMX.QCOM.index.param.video.LTRCountRangeSupported"*/ - QOMX_IndexParamVideoLTRCountRangeSupported = 0x7F000024, - - /*"OMX.QCOM.index.param.video.LTRMode"*/ - QOMX_IndexParamVideoLTRMode = 0x7F000025, - - /*"OMX.QCOM.index.param.video.LTRCount"*/ - QOMX_IndexParamVideoLTRCount = 0x7F000026, - - /*"OMX.QCOM.index.config.video.LTRPeriod"*/ - QOMX_IndexConfigVideoLTRPeriod = 0x7F000027, - - /*"OMX.QCOM.index.config.video.LTRUse"*/ - QOMX_IndexConfigVideoLTRUse = 0x7F000028, - - /*"OMX.QCOM.index.config.video.LTRMark"*/ - QOMX_IndexConfigVideoLTRMark = 0x7F000029, - - /* OMX.google.android.index.prependSPSPPSToIDRFrames */ - OMX_QcomIndexParamSequenceHeaderWithIDR = 0x7F00002A, - - OMX_QcomIndexParamH264AUDelimiter = 0x7F00002B, - - OMX_QcomIndexParamVideoDownScalar = 0x7F00002C, - - /* "OMX.QCOM.index.param.video.FramePackingExtradata" */ - OMX_QcomIndexParamVideoFramePackingExtradata = 0x7F00002D, - - /* "OMX.QCOM.index.config.activeregiondetection" */ - OMX_QcomIndexConfigActiveRegionDetection = 0x7F00002E, - - /* "OMX.QCOM.index.config.activeregiondetectionstatus" */ - OMX_QcomIndexConfigActiveRegionDetectionStatus = 0x7F00002F, - - /* "OMX.QCOM.index.config.scalingmode" */ - OMX_QcomIndexConfigScalingMode = 0x7F000030, - - /* "OMX.QCOM.index.config.noisereduction" */ - OMX_QcomIndexConfigNoiseReduction = 0x7F000031, - - /* "OMX.QCOM.index.config.imageenhancement" */ - OMX_QcomIndexConfigImageEnhancement = 0x7F000032, - - /* google smooth-streaming support */ - OMX_QcomIndexParamVideoAdaptivePlaybackMode = 0x7F000033, - - /* H.264 MVC codec index */ - QOMX_IndexParamVideoMvc = 0x7F000034, - - /* "OMX.QCOM.index.param.video.QPExtradata" */ - OMX_QcomIndexParamVideoQPExtraData = 0x7F000035, - - /* "OMX.QCOM.index.param.video.InputBitsInfoExtradata" */ - OMX_QcomIndexParamVideoInputBitsInfoExtraData = 0x7F000036, - - /* VP8 Hierarchical P support */ - OMX_QcomIndexHierarchicalStructure = 0x7F000037, - - OMX_QcomIndexParamPerfLevel = 0x7F000038, - - OMX_QcomIndexParamH264VUITimingInfo = 0x7F000039, - - OMX_QcomIndexParamPeakBitrate = 0x7F00003A, - - /* Enable InitialQP index */ - QOMX_IndexParamVideoInitialQp = 0x7F00003B, - - OMX_QcomIndexParamSetMVSearchrange = 0x7F00003C, - - OMX_QcomIndexConfigPerfLevel = 0x7F00003D, - - /*"OMX.QCOM.index.param.video.LTRCount"*/ - OMX_QcomIndexParamVideoLTRCount = QOMX_IndexParamVideoLTRCount, - - /*"OMX.QCOM.index.config.video.LTRUse"*/ - OMX_QcomIndexConfigVideoLTRUse = QOMX_IndexConfigVideoLTRUse, - - /*"OMX.QCOM.index.config.video.LTRMark"*/ - OMX_QcomIndexConfigVideoLTRMark = QOMX_IndexConfigVideoLTRMark, - - /*"OMX.QCOM.index.param.video.CustomBufferSize"*/ - OMX_QcomIndexParamVideoCustomBufferSize = 0x7F00003E, - - /* Max Hierarchical P layers */ - OMX_QcomIndexMaxHierarchicallayers = 0x7F000041, - - /* Set Encoder Performance Index */ - OMX_QcomIndexConfigVideoVencPerfMode = 0x7F000042, - - /* Set Hybrid Hier-p layers */ - OMX_QcomIndexParamVideoHybridHierpMode = 0x7F000043, - - OMX_QcomIndexFlexibleYUVDescription = 0x7F000044, - - /* Vpp Hqv Control Type */ - OMX_QcomIndexParamVppHqvControl = 0x7F000045, - - /* Enable VPP */ - OMX_QcomIndexParamEnableVpp = 0x7F000046, - - /* MBI statistics mode */ - OMX_QcomIndexParamMBIStatisticsMode = 0x7F000047, - - /* Set PictureTypeDecode */ - OMX_QcomIndexConfigPictureTypeDecode = 0x7F000048, - - OMX_QcomIndexConfigH264EntropyCodingCabac = 0x7F000049, - - /* "OMX.QCOM.index.param.video.InputBatch" */ - OMX_QcomIndexParamBatchSize = 0x7F00004A, - - OMX_QcomIndexConfigNumHierPLayers = 0x7F00004B, - - OMX_QcomIndexConfigRectType = 0x7F00004C, - - OMX_QcomIndexConfigBaseLayerId = 0x7F00004E, - - OMX_QcomIndexParamDriverVersion = 0x7F00004F, - - OMX_QcomIndexConfigQp = 0x7F000050, - - OMX_QcomIndexParamVencAspectRatio = 0x7F000051, - - OMX_QTIIndexParamVQZipSEIExtraData = 0x7F000052, - - /* Enable VQZIP SEI NAL type */ - OMX_QTIIndexParamVQZIPSEIType = 0x7F000053, - - OMX_QTIIndexParamPassInputBufferFd = 0x7F000054, - - /* Set Prefer-adaptive playback*/ - /* "OMX.QTI.index.param.video.PreferAdaptivePlayback" */ - OMX_QTIIndexParamVideoPreferAdaptivePlayback = 0x7F000055, - - /* Set time params */ - OMX_QTIIndexConfigSetTimeData = 0x7F000056, - /* Force Compressed format for DPB when resolution <=1080p - * and OPB is cpu_access */ - /* OMX.QTI.index.param.video.ForceCompressedForDPB */ - OMX_QTIIndexParamForceCompressedForDPB = 0x7F000057, - - /* Enable ROI info */ - OMX_QTIIndexParamVideoEnableRoiInfo = 0x7F000058, - - /* Configure ROI info */ - OMX_QTIIndexConfigVideoRoiInfo = 0x7F000059, - - /* Set Low Latency Mode */ - OMX_QTIIndexParamLowLatencyMode = 0x7F00005A, - - /* Force OPB to UnCompressed mode */ - OMX_QTIIndexParamForceUnCompressedForOPB = 0x7F00005B, - -}; - -/** -* This is custom extension to configure Low Latency Mode. -* -* STRUCT MEMBERS -* -* nSize : Size of Structure in bytes -* nVersion : OpenMAX IL specification version information -* bLowLatencyMode : Enable/Disable Low Latency mode -*/ - -typedef struct QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_BOOL bLowLatencyMode; -} QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE; - -/** -* This is custom extension to configure Encoder Aspect Ratio. -* -* STRUCT MEMBERS -* -* nSize : Size of Structure in bytes -* nVersion : OpenMAX IL specification version information -* nSARWidth : Horizontal aspect size -* nSARHeight : Vertical aspect size -*/ - -typedef struct QOMX_EXTNINDEX_VIDEO_VENC_SAR -{ - OMX_U32 nSize; - OMX_U32 nVersion; - OMX_U32 nSARWidth; - OMX_U32 nSARHeight; -} QOMX_EXTNINDEX_VIDEO_VENC_SAR; - -/** -* This is custom extension to configure Hier-p layers. -* This mode configures Hier-p layers dynamically. -* -* STRUCT MEMBERS -* -* nSize : Size of Structure in bytes -* nVersion : OpenMAX IL specification version information -* nNumHierLayers: Set the number of Hier-p layers for the session -* - This should be less than the MAX Hier-P -* layers set for the session. -*/ - -typedef struct QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nNumHierLayers; -} QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS; - - -/** -* This is custom extension to configure Hybrid Hier-p settings. -* This mode is different from enabling Hier-p mode. This -* property enables Hier-p encoding with LTR referencing in each -* sub-GOP. -* -* STRUCT MEMBERS -* -* nSize : Size of Structure in bytes -* nVersion : OpenMAX IL specification version information -* nKeyFrameInterval : Indicates the I frame interval -* nHpLayers : Set the number of Hier-p layers for the session -* - This should be <= 6. (1 Base layer + -* 5 Enhancement layers) -* nTemporalLayerBitrateRatio[OMX_VIDEO_MAX_HP_LAYERS] : Bitrate to -* be set for each enhancement layer -* nMinQuantizer : minimum session QP -* nMaxQuantizer : Maximun session QP -*/ - -typedef struct QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nKeyFrameInterval; - OMX_U32 nTemporalLayerBitrateRatio[OMX_VIDEO_MAX_HP_LAYERS]; - OMX_U32 nMinQuantizer; - OMX_U32 nMaxQuantizer; - OMX_U32 nHpLayers; -} QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE; - -/** - * Encoder Performance Mode. This structure is used to set - * performance mode or power save mode when encoding. The search - * range is modified to save power or improve quality. - * - * STRUCT MEMBERS: - * OMX_U32 nPerfMode : Performance mode: - * 1: MAX_QUALITY - * 2: POWER_SAVE - */ - -typedef struct QOMX_EXTNINDEX_VIDEO_PERFMODE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPerfMode; -} QOMX_EXTNINDEX_VIDEO_PERFMODE; - -/** - * Initial QP parameter. This structure is used to enable - * vendor specific extension to let client enable setting - * initial QP values to I P B Frames - * - * STRUCT MEMBERS: - * nSize : Size of Structure in bytes - * nVersion : OpenMAX IL specification version information - * nPortIndex : Index of the port to which this structure applies - * OMX_U32 nQpI : First Iframe QP - * OMX_U32 nQpP : First Pframe QP - * OMX_U32 nQpB : First Bframe QP - * OMX_U32 bEnableInitQp : Bit field indicating which frame type(s) shall - * use the specified initial QP. - * Bit 0: Enable initial QP for I/IDR - * and use value specified in nInitQpI - * Bit 1: Enable initial QP for P - * and use value specified in nInitQpP - * Bit 2: Enable initial QP for B - * and use value specified in nInitQpB - */ - -typedef struct QOMX_EXTNINDEX_VIDEO_INITIALQP { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nQpI; - OMX_U32 nQpP; - OMX_U32 nQpB; - OMX_U32 bEnableInitQp; -} QOMX_EXTNINDEX_VIDEO_INITIALQP; - -/** - * Extension index parameter. This structure is used to enable - * vendor specific extension on input/output port and - * to pass the required flags and data, if any. - * The format of flags and data being passed is known to - * the client and component apriori. - * - * STRUCT MEMBERS: - * nSize : Size of Structure plus pData size - * nVersion : OMX specification version information - * nPortIndex : Indicates which port to set - * bEnable : Extension index enable (1) or disable (0) - * nFlags : Extension index flags, if any - * nDataSize : Size of the extension index data to follow - * pData : Extension index data, if present. - */ -typedef struct QOMX_EXTNINDEX_PARAMTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnable; - OMX_U32 nFlags; - OMX_U32 nDataSize; - OMX_PTR pData; -} QOMX_EXTNINDEX_PARAMTYPE; - -/** - * Range index parameter. This structure is used to enable - * vendor specific extension on input/output port and - * to pass the required minimum and maximum values - * - * STRUCT MEMBERS: - * nSize : Size of Structure in bytes - * nVersion : OpenMAX IL specification version information - * nPortIndex : Index of the port to which this structure applies - * nMin : Minimum value - * nMax : Maximum value - * nSteSize : Step size - */ -typedef struct QOMX_EXTNINDEX_RANGETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_S32 nMin; - OMX_S32 nMax; - OMX_S32 nStepSize; -} QOMX_EXTNINDEX_RANGETYPE; - -/** - * Specifies LTR mode types. - */ -typedef enum QOMX_VIDEO_LTRMODETYPE -{ - QOMX_VIDEO_LTRMode_Disable = 0x0, /**< LTR encoding is disabled */ - QOMX_VIDEO_LTRMode_Manual = 0x1, /**< In this mode, IL client configures - ** the encoder the LTR count and manually - ** controls the marking and use of LTR - ** frames during video encoding. - */ - QOMX_VIDEO_LTRMode_Auto = 0x2, /**< In this mode, IL client configures - ** the encoder the LTR count and LTR - ** period. The encoder marks LTR frames - ** automatically based on the LTR period - ** during video encoding. IL client controls - ** the use of LTR frames. - */ - QOMX_VIDEO_LTRMode_MAX = 0x7FFFFFFF /** Maximum LTR Mode type */ -} QOMX_VIDEO_LTRMODETYPE; - -/** - * LTR mode index parameter. This structure is used - * to enable vendor specific extension on output port - * to pass the LTR mode information. - * - * STRUCT MEMBERS: - * nSize : Size of Structure in bytes - * nVersion : OpenMAX IL specification version information - * nPortIndex : Index of the port to which this structure applies - * eLTRMode : Specifies the LTR mode used in encoder - */ -typedef struct QOMX_VIDEO_PARAM_LTRMODE_TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - QOMX_VIDEO_LTRMODETYPE eLTRMode; -} QOMX_VIDEO_PARAM_LTRMODE_TYPE; - -/** - * LTR count index parameter. This structure is used - * to enable vendor specific extension on output port - * to pass the LTR count information. - * - * STRUCT MEMBERS: - * nSize : Size of Structure in bytes - * nVersion : OpenMAX IL specification version information - * nPortIndex : Index of the port to which this structure applies - * nCount : Specifies the number of LTR frames stored in the - * encoder component - */ -typedef struct QOMX_VIDEO_PARAM_LTRCOUNT_TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nCount; -} QOMX_VIDEO_PARAM_LTRCOUNT_TYPE; - - -/** - * This should be used with OMX_QcomIndexParamVideoLTRCount extension. - */ -typedef QOMX_VIDEO_PARAM_LTRCOUNT_TYPE OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE; - -/** - * LTR period index parameter. This structure is used - * to enable vendor specific extension on output port - * to pass the LTR period information. - * - * STRUCT MEMBERS: - * nSize : Size of Structure in bytes - * nVersion : OpenMAX IL specification version information - * nPortIndex : Index of the port to which this structure applies - * nFrames : Specifies the number of frames between two consecutive - * LTR frames. - */ -typedef struct QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nFrames; -} QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE; - -/** - * Marks the next encoded frame as an LTR frame. - * STRUCT MEMBERS: - * nSize : Size of Structure in bytes - * nVersion : OpenMAX IL specification version information - * nPortIndex : Index of the port to which this structure applies - * nID : Specifies the identifier of the LTR frame to be marked - * as reference frame for encoding subsequent frames. - */ -typedef struct QOMX_VIDEO_CONFIG_LTRMARK_TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nID; -} QOMX_VIDEO_CONFIG_LTRMARK_TYPE; - -/** - * This should be used with OMX_QcomIndexConfigVideoLTRMark extension. - */ -typedef QOMX_VIDEO_CONFIG_LTRMARK_TYPE OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE; - -/** - * Specifies an LTR frame to encode subsequent frames. - * STRUCT MEMBERS: - * nSize : Size of Structure in bytes - * nVersion : OpenMAX IL specification version information - * nPortIndex : Index of the port to which this structure applies - * nID : Specifies the identifier of the LTR frame to be used - as reference frame for encoding subsequent frames. - * nFrames : Specifies the number of subsequent frames to be - encoded using the LTR frame with its identifier - nID as reference frame. Short-term reference frames - will be used thereafter. The value of 0xFFFFFFFF - indicates that all subsequent frames will be - encodedusing this LTR frame as reference frame. - */ -typedef struct QOMX_VIDEO_CONFIG_LTRUSE_TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nID; - OMX_U32 nFrames; -} QOMX_VIDEO_CONFIG_LTRUSE_TYPE; - -/** - * This should be used with OMX_QcomIndexConfigVideoLTRUse extension. - */ -typedef QOMX_VIDEO_CONFIG_LTRUSE_TYPE OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE; - -/** - * Enumeration used to define the video encoder modes - * - * ENUMS: - * EncoderModeDefault : Default video recording mode. - * All encoder settings made through - * OMX_SetParameter/OMX_SetConfig are applied. No - * parameter is overridden. - * EncoderModeMMS : Video recording mode for MMS (Multimedia Messaging - * Service). This mode is similar to EncoderModeDefault - * except that here the Rate control mode is overridden - * internally and set as a variant of variable bitrate with - * variable frame rate. After this mode is set if the IL - * client tries to set OMX_VIDEO_CONTROLRATETYPE via - * OMX_IndexParamVideoBitrate that would be rejected. For - * this, client should set mode back to EncoderModeDefault - * first and then change OMX_VIDEO_CONTROLRATETYPE. - */ -typedef enum QOMX_VIDEO_ENCODERMODETYPE -{ - QOMX_VIDEO_EncoderModeDefault = 0x00, - QOMX_VIDEO_EncoderModeMMS = 0x01, - QOMX_VIDEO_EncoderModeMax = 0x7FFFFFFF -} QOMX_VIDEO_ENCODERMODETYPE; - -/** - * This structure is used to set the video encoder mode. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version info - * nPortIndex : Port that this structure applies to - * nMode : defines the video encoder mode - */ -typedef struct QOMX_VIDEO_PARAM_ENCODERMODETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - QOMX_VIDEO_ENCODERMODETYPE nMode; -} QOMX_VIDEO_PARAM_ENCODERMODETYPE; - -/** - * This structure describes the parameters corresponding to the - * QOMX_VIDEO_SYNTAXHDRTYPE extension. This parameter can be queried - * during the loaded state. - */ - -typedef struct QOMX_VIDEO_SYNTAXHDRTYPE -{ - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion;/** OMX specification version information */ - OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ - OMX_U32 nBytes; /** The number of bytes filled in to the buffer */ - OMX_U8 data[1]; /** Buffer to store the header information */ -} QOMX_VIDEO_SYNTAXHDRTYPE; - -/** - * This structure describes the parameters corresponding to the - * QOMX_VIDEO_TEMPORALSPATIALTYPE extension. This parameter can be set - * dynamically during any state except the state invalid. This is primarily - * used for setting MaxQP from the application. This is set on the out port. - */ - -typedef struct QOMX_VIDEO_TEMPORALSPATIALTYPE -{ - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion;/** OMX specification version information */ - OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ - OMX_U32 nTSFactor; /** Temoral spatial tradeoff factor value in 0-100 */ -} QOMX_VIDEO_TEMPORALSPATIALTYPE; - -/** - * This structure describes the parameters corresponding to the - * OMX_QCOM_VIDEO_CONFIG_INTRAPERIODTYPE extension. This parameter can be set - * dynamically during any state except the state invalid. This is set on the out port. - */ - -typedef struct QOMX_VIDEO_INTRAPERIODTYPE -{ - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion;/** OMX specification version information */ - OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ - OMX_U32 nIDRPeriod; /** This specifies coding a frame as IDR after every nPFrames - of intra frames. If this parameter is set to 0, only the - first frame of the encode session is an IDR frame. This - field is ignored for non-AVC codecs and is used only for - codecs that support IDR Period */ - OMX_U32 nPFrames; /** The number of "P" frames between two "I" frames */ - OMX_U32 nBFrames; /** The number of "B" frames between two "I" frames */ -} QOMX_VIDEO_INTRAPERIODTYPE; - -/** - * This structure describes the parameters corresponding to the - * OMX_QCOM_VIDEO_CONFIG_ULBUFFEROCCUPANCYTYPE extension. This parameter can be set - * dynamically during any state except the state invalid. This is used for the buffer negotiation - * with other clients. This is set on the out port. - */ -typedef struct OMX_QCOM_VIDEO_CONFIG_ULBUFFEROCCUPANCYTYPE -{ - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /** OMX specification version information */ - OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ - OMX_U32 nBufferOccupancy; /** The number of bytes to be set for the buffer occupancy */ -} OMX_QCOM_VIDEO_CONFIG_ULBUFFEROCCUPANCYTYPE; - -/** - * This structure describes the parameters corresponding to the - * OMX_QCOM_VIDEO_CONFIG_RANDOMINTRAREFRESHTYPE extension. This parameter can be set - * dynamically during any state except the state invalid. This is primarily used for the dynamic/random - * intrarefresh. This is set on the out port. - */ -typedef struct OMX_QCOM_VIDEO_CONFIG_RANDOMINTRAREFRESHTYPE -{ - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion;/** OMX specification version information */ - OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ - OMX_U32 nRirMBs; /** The number of MBs to be set for intrarefresh */ -} OMX_QCOM_VIDEO_CONFIG_RANDOMINTRAREFRESHTYPE; - - -/** - * This structure describes the parameters corresponding to the - * OMX_QCOM_VIDEO_CONFIG_QPRANGE extension. This parameter can be set - * dynamically during any state except the state invalid. This is primarily - * used for the min/max QP to be set from the application. This - * is set on the out port. - */ -typedef struct OMX_QCOM_VIDEO_CONFIG_QPRANGE -{ - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion;/** OMX specification version information */ - OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ - OMX_U32 nMinQP; /** The number for minimum quantization parameter */ - OMX_U32 nMaxQP; /** The number for maximum quantization parameter */ -} OMX_QCOM_VIDEO_CONFIG_QPRANGE; - -/** - * This structure describes the parameters for the - * OMX_QcomIndexParamH264AUDelimiter extension. It enables/disables - * the AU delimiters in the H264 stream, which is used by WFD. - */ -typedef struct OMX_QCOM_VIDEO_CONFIG_H264_AUD -{ - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion;/** OMX specification version information */ - OMX_BOOL bEnable; /** Enable/disable the setting */ -} OMX_QCOM_VIDEO_CONFIG_H264_AUD; - -typedef enum QOMX_VIDEO_PERF_LEVEL -{ - OMX_QCOM_PerfLevelNominal, - OMX_QCOM_PerfLevelTurbo -} QOMX_VIDEO_PERF_LEVEL; - -/** - * This structure describes the parameters corresponding - * to OMX_QcomIndexParamPerfLevel extension. It will set - * the performance mode specified as QOMX_VIDEO_PERF_LEVEL. - */ -typedef struct OMX_QCOM_VIDEO_PARAM_PERF_LEVEL { - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /** OMX specification version information */ - QOMX_VIDEO_PERF_LEVEL ePerfLevel; /** Performance level */ -} OMX_QCOM_VIDEO_PARAM_PERF_LEVEL; - -/** - * This structure describes the parameters corresponding - * to OMX_QcomIndexConfigPerfLevel extension. It will set - * the performance mode specified as QOMX_VIDEO_PERF_LEVEL. - */ -typedef struct OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL { - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /** OMX specification version information */ - QOMX_VIDEO_PERF_LEVEL ePerfLevel; /** Performance level */ -} OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL; - -typedef enum QOMX_VIDEO_PICTURE_TYPE_DECODE -{ - OMX_QCOM_PictypeDecode_IPB, - OMX_QCOM_PictypeDecode_I -} QOMX_VIDEO_PICTURE_TYPE_DECODE; - -/** - * This structure describes the parameters corresponding - * to OMX_QcomIndexConfigPictureTypeDecode extension. It - * will set the picture type decode specified by eDecodeType. - */ -typedef struct OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE { - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /** OMX specification version information */ - QOMX_VIDEO_PICTURE_TYPE_DECODE eDecodeType; /** Decode type */ -} OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE; - -/** - * This structure describes the parameters corresponding - * to OMX_QcomIndexParamH264VUITimingInfo extension. It - * will enable/disable the VUI timing info. - */ -typedef struct OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO { - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /** OMX specification version information */ - OMX_BOOL bEnable; /** Enable/disable the setting */ -} OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO; - -/** - * This structure describes the parameters corresponding - * to OMX_QcomIndexParamVQZIPSEIType extension. It - * will enable/disable the VQZIP SEI info. - */ -typedef struct OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE { - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /** OMX specification version information */ - OMX_BOOL bEnable; /** Enable/disable the setting */ -} OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE; - -/** - * This structure describes the parameters corresponding - * to OMX_QcomIndexParamPeakBitrate extension. It will - * set the peak bitrate specified by nPeakBitrate. - */ -typedef struct OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE { - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /** OMX specification version information */ - OMX_U32 nPeakBitrate; /** Peak bitrate value */ -} OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE; - -/** - * This structure describes the parameters corresponding - * to OMX_QTIIndexParamForceCompressedForDPB extension. Enabling - * this extension will force the split mode DPB(compressed)/OPB(Linear) - * for all resolutions.On some chipsets preferred mode would be combined - * Linear for both DPB/OPB to save memory. For example on 8996 preferred mode - * would be combined linear for resolutions <= 1080p . - * Enabling this might save power but with the cost - * of increased memory i.e almost double the number on output YUV buffers. - */ -typedef struct OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE { - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion; /** OMX specification version information */ - OMX_BOOL bEnable; /** Enable/disable the setting */ -} OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE; - -/** - * This structure describes the parameters corresponding - * to OMX_QTIIndexParamForceUnCompressedForOPB extension. Enabling this - * extension will force the OPB to be linear for the current video session. - * If this property is not set, then the OPB will be set to linear or compressed - * based on resolution selected and/or if cpu access is requested on the - * OPB buffer. - */ -typedef struct OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE { - OMX_U32 nSize; /** Sizeo f the structure in bytes */ - OMX_VERSIONTYPE nVersion; /** OMX specification version information */ - OMX_BOOL bEnable; /** Enable/disable the setting */ -} OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE; - -typedef struct OMX_VENDOR_EXTRADATATYPE { - OMX_U32 nPortIndex; - OMX_U32 nDataSize; - OMX_U8 *pData; // cdata (codec_data/extradata) -} OMX_VENDOR_EXTRADATATYPE; - -/** - * This structure describes the parameters corresponding to the - * OMX_VENDOR_VIDEOFRAMERATE extension. This parameter can be set - * dynamically during any state except the state invalid. This is - * used for frame rate to be set from the application. This - * is set on the in port. - */ -typedef struct OMX_VENDOR_VIDEOFRAMERATE { - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion;/** OMX specification version information */ - OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ - OMX_U32 nFps; /** Frame rate value */ - OMX_BOOL bEnabled; /** Flag to enable or disable client's frame rate value */ -} OMX_VENDOR_VIDEOFRAMERATE; - -typedef enum OMX_INDEXVENDORTYPE { - OMX_IndexVendorFileReadInputFilename = 0xFF000001, - OMX_IndexVendorParser3gpInputFilename = 0xFF000002, - OMX_IndexVendorVideoExtraData = 0xFF000003, - OMX_IndexVendorAudioExtraData = 0xFF000004, - OMX_IndexVendorVideoFrameRate = 0xFF000005, -} OMX_INDEXVENDORTYPE; - -typedef enum OMX_QCOM_VC1RESOLUTIONTYPE -{ - OMX_QCOM_VC1_PICTURE_RES_1x1, - OMX_QCOM_VC1_PICTURE_RES_2x1, - OMX_QCOM_VC1_PICTURE_RES_1x2, - OMX_QCOM_VC1_PICTURE_RES_2x2 -} OMX_QCOM_VC1RESOLUTIONTYPE; - -typedef enum OMX_QCOM_INTERLACETYPE -{ - OMX_QCOM_InterlaceFrameProgressive, - OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst, - OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst, - OMX_QCOM_InterlaceFrameTopFieldFirst, - OMX_QCOM_InterlaceFrameBottomFieldFirst, - OMX_QCOM_InterlaceFieldTop, - OMX_QCOM_InterlaceFieldBottom -}OMX_QCOM_INTERLACETYPE; - -typedef struct OMX_QCOM_PARAM_VIDEO_INTERLACETYPE -{ - OMX_U32 nSize; /** Size of the structure in bytes */ - OMX_VERSIONTYPE nVersion;/** OMX specification version information */ - OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ - OMX_BOOL bInterlace; /** Interlace content **/ -}OMX_QCOM_PARAM_VIDEO_INTERLACETYPE; - -typedef struct OMX_QCOM_CONFIG_INTERLACETYPE -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nIndex; - OMX_QCOM_INTERLACETYPE eInterlaceType; -}OMX_QCOM_CONFIG_INTERLACETYPE; - -#define MAX_PAN_SCAN_WINDOWS 4 - -typedef struct OMX_QCOM_PANSCAN -{ - OMX_U32 numWindows; - OMX_QCOMRectangle window[MAX_PAN_SCAN_WINDOWS]; -} OMX_QCOM_PANSCAN; - -typedef struct OMX_QCOM_ASPECT_RATIO -{ - OMX_U32 aspectRatioX; - OMX_U32 aspectRatioY; -} OMX_QCOM_ASPECT_RATIO; - -typedef struct OMX_QCOM_DISPLAY_ASPECT_RATIO -{ - OMX_U32 displayVerticalSize; - OMX_U32 displayHorizontalSize; -} OMX_QCOM_DISPLAY_ASPECT_RATIO; - -typedef struct OMX_QCOM_FRAME_PACK_ARRANGEMENT -{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 id; - OMX_U32 cancel_flag; - OMX_U32 type; - OMX_U32 quincunx_sampling_flag; - OMX_U32 content_interpretation_type; - OMX_U32 spatial_flipping_flag; - OMX_U32 frame0_flipped_flag; - OMX_U32 field_views_flag; - OMX_U32 current_frame_is_frame0_flag; - OMX_U32 frame0_self_contained_flag; - OMX_U32 frame1_self_contained_flag; - OMX_U32 frame0_grid_position_x; - OMX_U32 frame0_grid_position_y; - OMX_U32 frame1_grid_position_x; - OMX_U32 frame1_grid_position_y; - OMX_U32 reserved_byte; - OMX_U32 repetition_period; - OMX_U32 extension_flag; -} OMX_QCOM_FRAME_PACK_ARRANGEMENT; - -typedef struct OMX_QCOM_EXTRADATA_QP -{ - OMX_U32 nQP; -} OMX_QCOM_EXTRADATA_QP; - -typedef struct OMX_QCOM_EXTRADATA_BITS_INFO -{ - OMX_U32 header_bits; - OMX_U32 frame_bits; -} OMX_QCOM_EXTRADATA_BITS_INFO; - -typedef struct OMX_QCOM_EXTRADATA_USERDATA { - OMX_U32 type; - OMX_U32 data[1]; -} OMX_QCOM_EXTRADATA_USERDATA; - -typedef struct OMX_QCOM_EXTRADATA_FRAMEINFO -{ - // common frame meta data. interlace related info removed - OMX_VIDEO_PICTURETYPE ePicType; - OMX_QCOM_INTERLACETYPE interlaceType; - OMX_QCOM_PANSCAN panScan; - OMX_QCOM_ASPECT_RATIO aspectRatio; - OMX_QCOM_DISPLAY_ASPECT_RATIO displayAspectRatio; - OMX_U32 nConcealedMacroblocks; - OMX_U32 nFrameRate; - OMX_TICKS nTimeStamp; -} OMX_QCOM_EXTRADATA_FRAMEINFO; - -typedef struct OMX_QCOM_EXTRADATA_FRAMEDIMENSION -{ - /** Frame Dimensions added to each YUV buffer */ - OMX_U32 nDecWidth; /** Width rounded to multiple of 16 */ - OMX_U32 nDecHeight; /** Height rounded to multiple of 16 */ - OMX_U32 nActualWidth; /** Actual Frame Width */ - OMX_U32 nActualHeight; /** Actual Frame Height */ - -} OMX_QCOM_EXTRADATA_FRAMEDIMENSION; - -typedef struct OMX_QCOM_H264EXTRADATA -{ - OMX_U64 seiTimeStamp; -} OMX_QCOM_H264EXTRADATA; - -typedef struct OMX_QCOM_VC1EXTRADATA -{ - OMX_U32 nVC1RangeY; - OMX_U32 nVC1RangeUV; - OMX_QCOM_VC1RESOLUTIONTYPE eVC1PicResolution; -} OMX_QCOM_VC1EXTRADATA; - -typedef union OMX_QCOM_EXTRADATA_CODEC_DATA -{ - OMX_QCOM_H264EXTRADATA h264ExtraData; - OMX_QCOM_VC1EXTRADATA vc1ExtraData; -} OMX_QCOM_EXTRADATA_CODEC_DATA; - -typedef struct OMX_QCOM_EXTRADATA_MBINFO -{ - OMX_U32 nFormat; - OMX_U32 nDataSize; - OMX_U8 data[0]; -} OMX_QCOM_EXTRADATA_MBINFO; - -typedef struct OMX_QCOM_EXTRADATA_VQZIPSEI { - OMX_U32 nSize; - OMX_U8 data[0]; -} OMX_QCOM_EXTRADATA_VQZIPSEI; - -typedef struct OMX_QTI_VIDEO_PARAM_ENABLE_ROIINFO { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnableRoiInfo; -} OMX_QTI_VIDEO_PARAM_ENABLE_ROIINFO; - -typedef struct OMX_QTI_VIDEO_CONFIG_ROIINFO { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_S32 nUpperQpOffset; - OMX_S32 nLowerQpOffset; - OMX_BOOL bUseRoiInfo; - OMX_S32 nRoiMBInfoSize; - OMX_PTR pRoiMBInfo; -} OMX_QTI_VIDEO_CONFIG_ROIINFO; - -typedef enum OMX_QCOM_EXTRADATATYPE -{ - OMX_ExtraDataFrameInfo = 0x7F000001, - OMX_ExtraDataH264 = 0x7F000002, - OMX_ExtraDataVC1 = 0x7F000003, - OMX_ExtraDataFrameDimension = 0x7F000004, - OMX_ExtraDataVideoEncoderSliceInfo = 0x7F000005, - OMX_ExtraDataConcealMB = 0x7F000006, - OMX_ExtraDataInterlaceFormat = 0x7F000007, - OMX_ExtraDataPortDef = 0x7F000008, - OMX_ExtraDataMP2ExtnData = 0x7F000009, - OMX_ExtraDataMP2UserData = 0x7F00000a, - OMX_ExtraDataVideoLTRInfo = 0x7F00000b, - OMX_ExtraDataFramePackingArrangement = 0x7F00000c, - OMX_ExtraDataQP = 0x7F00000d, - OMX_ExtraDataInputBitsInfo = 0x7F00000e, - OMX_ExtraDataVideoEncoderMBInfo = 0x7F00000f, - OMX_ExtraDataVQZipSEI = 0x7F000010, -} OMX_QCOM_EXTRADATATYPE; - -typedef struct OMX_STREAMINTERLACEFORMATTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bInterlaceFormat; - OMX_U32 nInterlaceFormats; -} OMX_STREAMINTERLACEFORMAT; - -typedef enum OMX_INTERLACETYPE -{ - OMX_InterlaceFrameProgressive, - OMX_InterlaceInterleaveFrameTopFieldFirst, - OMX_InterlaceInterleaveFrameBottomFieldFirst, - OMX_InterlaceFrameTopFieldFirst, - OMX_InterlaceFrameBottomFieldFirst -} OMX_INTERLACES; - - -#define OMX_EXTRADATA_HEADER_SIZE 20 - -/** - * AVC profile types, each profile indicates support for various - * performance bounds and different annexes. - */ -typedef enum QOMX_VIDEO_AVCPROFILETYPE { - QOMX_VIDEO_AVCProfileBaseline = OMX_VIDEO_AVCProfileBaseline, - QOMX_VIDEO_AVCProfileMain = OMX_VIDEO_AVCProfileMain, - QOMX_VIDEO_AVCProfileExtended = OMX_VIDEO_AVCProfileExtended, - QOMX_VIDEO_AVCProfileHigh = OMX_VIDEO_AVCProfileHigh, - QOMX_VIDEO_AVCProfileHigh10 = OMX_VIDEO_AVCProfileHigh10, - QOMX_VIDEO_AVCProfileHigh422 = OMX_VIDEO_AVCProfileHigh422, - QOMX_VIDEO_AVCProfileHigh444 = OMX_VIDEO_AVCProfileHigh444, - /* QCom specific profile indexes */ - QOMX_VIDEO_AVCProfileConstrained = OMX_VIDEO_AVCProfileVendorStartUnused, - QOMX_VIDEO_AVCProfileConstrainedBaseline, - QOMX_VIDEO_AVCProfileConstrainedHigh, -} QOMX_VIDEO_AVCPROFILETYPE; - - -/** - * H.264 MVC Profiles - */ -typedef enum QOMX_VIDEO_MVCPROFILETYPE { - QOMX_VIDEO_MVCProfileStereoHigh = 0x1, - QOMX_VIDEO_MVCProfileMultiViewHigh = 0x2, - QOMX_VIDEO_MVCProfileKhronosExtensions = 0x6F000000, - QOMX_VIDEO_MVCProfileVendorStartUnused = 0x7F000000, - QOMX_VIDEO_MVCProfileMax = 0x7FFFFFFF -} QOMX_VIDEO_MVCPROFILETYPE; - -/** - * H.264 MVC Levels - */ -typedef enum QOMX_VIDEO_MVCLEVELTYPE { - QOMX_VIDEO_MVCLevel1 = 0x01, /**< Level 1 */ - QOMX_VIDEO_MVCLevel1b = 0x02, /**< Level 1b */ - QOMX_VIDEO_MVCLevel11 = 0x04, /**< Level 1.1 */ - QOMX_VIDEO_MVCLevel12 = 0x08, /**< Level 1.2 */ - QOMX_VIDEO_MVCLevel13 = 0x10, /**< Level 1.3 */ - QOMX_VIDEO_MVCLevel2 = 0x20, /**< Level 2 */ - QOMX_VIDEO_MVCLevel21 = 0x40, /**< Level 2.1 */ - QOMX_VIDEO_MVCLevel22 = 0x80, /**< Level 2.2 */ - QOMX_VIDEO_MVCLevel3 = 0x100, /**< Level 3 */ - QOMX_VIDEO_MVCLevel31 = 0x200, /**< Level 3.1 */ - QOMX_VIDEO_MVCLevel32 = 0x400, /**< Level 3.2 */ - QOMX_VIDEO_MVCLevel4 = 0x800, /**< Level 4 */ - QOMX_VIDEO_MVCLevel41 = 0x1000, /**< Level 4.1 */ - QOMX_VIDEO_MVCLevel42 = 0x2000, /**< Level 4.2 */ - QOMX_VIDEO_MVCLevel5 = 0x4000, /**< Level 5 */ - QOMX_VIDEO_MVCLevel51 = 0x8000, /**< Level 5.1 */ - QOMX_VIDEO_MVCLevelKhronosExtensions = 0x6F000000, - QOMX_VIDEO_MVCLevelVendorStartUnused = 0x7F000000, - QOMX_VIDEO_MVCLevelMax = 0x7FFFFFFF -} QOMX_VIDEO_MVCLEVELTYPE; - -/** - * DivX Versions - */ -typedef enum QOMX_VIDEO_DIVXFORMATTYPE { - QOMX_VIDEO_DIVXFormatUnused = 0x01, /**< Format unused or unknown */ - QOMX_VIDEO_DIVXFormat311 = 0x02, /**< DivX 3.11 */ - QOMX_VIDEO_DIVXFormat4 = 0x04, /**< DivX 4 */ - QOMX_VIDEO_DIVXFormat5 = 0x08, /**< DivX 5 */ - QOMX_VIDEO_DIVXFormat6 = 0x10, /**< DivX 6 */ - QOMX_VIDEO_DIVXFormatKhronosExtensions = 0x6F000000, - QOMX_VIDEO_DIVXFormatVendorStartUnused = 0x7F000000, - QOMX_VIDEO_DIVXFormatMax = 0x7FFFFFFF -} QOMX_VIDEO_DIVXFORMATTYPE; - -/** - * DivX profile types, each profile indicates support for - * various performance bounds. - */ -typedef enum QOMX_VIDEO_DIVXPROFILETYPE { - QOMX_VIDEO_DivXProfileqMobile = 0x01, /**< qMobile Profile */ - QOMX_VIDEO_DivXProfileMobile = 0x02, /**< Mobile Profile */ - QOMX_VIDEO_DivXProfileMT = 0x04, /**< Mobile Theatre Profile */ - QOMX_VIDEO_DivXProfileHT = 0x08, /**< Home Theatre Profile */ - QOMX_VIDEO_DivXProfileHD = 0x10, /**< High Definition Profile */ - QOMX_VIDEO_DIVXProfileKhronosExtensions = 0x6F000000, - QOMX_VIDEO_DIVXProfileVendorStartUnused = 0x7F000000, - QOMX_VIDEO_DIVXProfileMax = 0x7FFFFFFF -} QOMX_VIDEO_DIVXPROFILETYPE; - -/** - * DivX Video Params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eFormat : Version of DivX stream / data - * eProfile : Profile of DivX stream / data - */ -typedef struct QOMX_VIDEO_PARAM_DIVXTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - QOMX_VIDEO_DIVXFORMATTYPE eFormat; - QOMX_VIDEO_DIVXPROFILETYPE eProfile; -} QOMX_VIDEO_PARAM_DIVXTYPE; - - - -/** - * VP Versions - */ -typedef enum QOMX_VIDEO_VPFORMATTYPE { - QOMX_VIDEO_VPFormatUnused = 0x01, /**< Format unused or unknown */ - QOMX_VIDEO_VPFormat6 = 0x02, /**< VP6 Video Format */ - QOMX_VIDEO_VPFormat7 = 0x04, /**< VP7 Video Format */ - QOMX_VIDEO_VPFormat8 = 0x08, /**< VP8 Video Format */ - QOMX_VIDEO_VPFormat9 = 0x10, /**< VP9 Video Format */ - QOMX_VIDEO_VPFormatKhronosExtensions = 0x6F000000, - QOMX_VIDEO_VPFormatVendorStartUnused = 0x7F000000, - QOMX_VIDEO_VPFormatMax = 0x7FFFFFFF -} QOMX_VIDEO_VPFORMATTYPE; - -/** - * VP profile types, each profile indicates support for various - * encoding tools. - */ -typedef enum QOMX_VIDEO_VPPROFILETYPE { - QOMX_VIDEO_VPProfileSimple = 0x01, /**< Simple Profile, applies to VP6 only */ - QOMX_VIDEO_VPProfileAdvanced = 0x02, /**< Advanced Profile, applies to VP6 only */ - QOMX_VIDEO_VPProfileVersion0 = 0x04, /**< Version 0, applies to VP7 and VP8 */ - QOMX_VIDEO_VPProfileVersion1 = 0x08, /**< Version 1, applies to VP7 and VP8 */ - QOMX_VIDEO_VPProfileVersion2 = 0x10, /**< Version 2, applies to VP8 only */ - QOMX_VIDEO_VPProfileVersion3 = 0x20, /**< Version 3, applies to VP8 only */ - QOMX_VIDEO_VPProfileKhronosExtensions = 0x6F000000, - QOMX_VIDEO_VPProfileVendorStartUnused = 0x7F000000, - QOMX_VIDEO_VPProfileMax = 0x7FFFFFFF -} QOMX_VIDEO_VPPROFILETYPE; - -/** - * VP Video Params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eFormat : Format of VP stream / data - * eProfile : Profile or Version of VP stream / data - */ -typedef struct QOMX_VIDEO_PARAM_VPTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - QOMX_VIDEO_VPFORMATTYPE eFormat; - QOMX_VIDEO_VPPROFILETYPE eProfile; -} QOMX_VIDEO_PARAM_VPTYPE; - -/** - * Spark Versions - */ -typedef enum QOMX_VIDEO_SPARKFORMATTYPE { - QOMX_VIDEO_SparkFormatUnused = 0x01, /**< Format unused or unknown */ - QOMX_VIDEO_SparkFormat0 = 0x02, /**< Video Format Version 0 */ - QOMX_VIDEO_SparkFormat1 = 0x04, /**< Video Format Version 1 */ - QOMX_VIDEO_SparkFormatKhronosExtensions = 0x6F000000, - QOMX_VIDEO_SparkFormatVendorStartUnused = 0x7F000000, - QOMX_VIDEO_SparkFormatMax = 0x7FFFFFFF -} QOMX_VIDEO_SPARKFORMATTYPE; - -/** - * Spark Video Params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eFormat : Version of Spark stream / data - */ -typedef struct QOMX_VIDEO_PARAM_SPARKTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - QOMX_VIDEO_SPARKFORMATTYPE eFormat; -} QOMX_VIDEO_PARAM_SPARKTYPE; - - -typedef struct QOMX_VIDEO_QUERY_DECODER_INSTANCES { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nNumOfInstances; -} QOMX_VIDEO_QUERY_DECODER_INSTANCES; - -typedef struct QOMX_ENABLETYPE { - OMX_BOOL bEnable; -} QOMX_ENABLETYPE; - -typedef enum QOMX_VIDEO_EVENTS { - OMX_EventIndexsettingChanged = OMX_EventVendorStartUnused -} QOMX_VIDEO_EVENTS; - -typedef enum QOMX_VIDEO_PICTURE_ORDER { - QOMX_VIDEO_DISPLAY_ORDER = 0x1, - QOMX_VIDEO_DECODE_ORDER = 0x2 -} QOMX_VIDEO_PICTURE_ORDER; - -typedef struct QOMX_VIDEO_DECODER_PICTURE_ORDER { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - QOMX_VIDEO_PICTURE_ORDER eOutputPictureOrder; -} QOMX_VIDEO_DECODER_PICTURE_ORDER; - -typedef struct QOMX_INDEXEXTRADATATYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnabled; - OMX_INDEXTYPE nIndex; -} QOMX_INDEXEXTRADATATYPE; - -typedef struct QOMX_INDEXTIMESTAMPREORDER { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnable; -} QOMX_INDEXTIMESTAMPREORDER; - -typedef struct QOMX_INDEXDOWNSCALAR { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnable; -} QOMX_INDEXDOWNSCALAR; - -typedef struct QOMX_VIDEO_CUSTOM_BUFFERSIZE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nBufferSize; -} QOMX_VIDEO_CUSTOM_BUFFERSIZE; - -#define OMX_QCOM_INDEX_PARAM_VIDEO_SYNCFRAMEDECODINGMODE "OMX.QCOM.index.param.video.SyncFrameDecodingMode" -#define OMX_QCOM_INDEX_PARAM_INDEXEXTRADATA "OMX.QCOM.index.param.IndexExtraData" -#define OMX_QCOM_INDEX_PARAM_VIDEO_SLICEDELIVERYMODE "OMX.QCOM.index.param.SliceDeliveryMode" -#define OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA "OMX.QCOM.index.param.video.FramePackingExtradata" -#define OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA "OMX.QCOM.index.param.video.QPExtradata" -#define OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA "OMX.QCOM.index.param.video.InputBitsInfoExtradata" -#define OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA "OMX.QCOM.index.param.video.ExtnUserExtraData" -#define OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO "OMX.QCOM.index.config.video.FramePackingInfo" -#define OMX_QCOM_INDEX_PARAM_VIDEO_MPEG2SEQDISP_EXTRADATA "OMX.QCOM.index.param.video.Mpeg2SeqDispExtraData" - -#define OMX_QCOM_INDEX_PARAM_VIDEO_HIERSTRUCTURE "OMX.QCOM.index.param.video.HierStructure" -#define OMX_QCOM_INDEX_PARAM_VIDEO_LTRCOUNT "OMX.QCOM.index.param.video.LTRCount" -#define OMX_QCOM_INDEX_PARAM_VIDEO_LTRPERIOD "OMX.QCOM.index.param.video.LTRPeriod" -#define OMX_QCOM_INDEX_CONFIG_VIDEO_LTRUSE "OMX.QCOM.index.config.video.LTRUse" -#define OMX_QCOM_INDEX_CONFIG_VIDEO_LTRMARK "OMX.QCOM.index.config.video.LTRMark" -#define OMX_QCOM_INDEX_CONFIG_VIDEO_HIER_P_LAYERS "OMX.QCOM.index.config.video.hierplayers" -#define OMX_QCOM_INDEX_CONFIG_RECTANGLE_TYPE "OMX.QCOM.index.config.video.rectangle" -#define OMX_QCOM_INDEX_PARAM_VIDEO_BASE_LAYER_ID "OMX.QCOM.index.param.video.baselayerid" -#define OMX_QCOM_INDEX_CONFIG_VIDEO_QP "OMX.QCOM.index.config.video.qp" -#define OMX_QCOM_INDEX_PARAM_VIDEO_SAR "OMX.QCOM.index.param.video.sar" -#define OMX_QTI_INDEX_PARAM_VIDEO_LOW_LATENCY "OMX.QTI.index.param.video.LowLatency" - -#define OMX_QCOM_INDEX_PARAM_VIDEO_PASSINPUTBUFFERFD "OMX.QCOM.index.param.video.PassInputBufferFd" -#define OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK "OMX.QTI.index.param.video.PreferAdaptivePlayback" -#define OMX_QTI_INDEX_CONFIG_VIDEO_SETTIMEDATA "OMX.QTI.index.config.video.settimedata" -#define OMX_QTI_INDEX_PARAM_VIDEO_FORCE_COMPRESSED_FOR_DPB "OMX.QTI.index.param.video.ForceCompressedForDPB" -#define OMX_QTI_INDEX_PARAM_VIDEO_ENABLE_ROIINFO "OMX.QTI.index.param.enableRoiInfo" -#define OMX_QTI_INDEX_CONFIG_VIDEO_ROIINFO "OMX.QTI.index.config.RoiInfo" - -typedef enum { - QOMX_VIDEO_FRAME_PACKING_CHECKERBOARD = 0, - QOMX_VIDEO_FRAME_PACKING_COLUMN_INTERLEAVE = 1, - QOMX_VIDEO_FRAME_PACKING_ROW_INTERLEAVE = 2, - QOMX_VIDEO_FRAME_PACKING_SIDE_BY_SIDE = 3, - QOMX_VIDEO_FRAME_PACKING_TOP_BOTTOM = 4, - QOMX_VIDEO_FRAME_PACKING_TEMPORAL = 5, -} QOMX_VIDEO_FRAME_PACKING_ARRANGEMENT; - -typedef enum { - QOMX_VIDEO_CONTENT_UNSPECIFIED = 0, - QOMX_VIDEO_CONTENT_LR_VIEW = 1, - QOMX_VIDEO_CONTENT_RL_VIEW = 2, -} QOMX_VIDEO_CONTENT_INTERPRETATION; - -/** - * Specifies the extended picture types. These values should be - * OR'd along with the types defined in OMX_VIDEO_PICTURETYPE to - * signal all pictures types which are allowed. - * - * ENUMS: - * H.264 Specific Picture Types: IDR - */ -typedef enum QOMX_VIDEO_PICTURETYPE { - QOMX_VIDEO_PictureTypeIDR = OMX_VIDEO_PictureTypeVendorStartUnused + 0x1000 -} QOMX_VIDEO_PICTURETYPE; - -#define OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION "OMX.QCOM.index.config.activeregiondetection" -#define OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION_STATUS "OMX.QCOM.index.config.activeregiondetectionstatus" -#define OMX_QCOM_INDEX_CONFIG_SCALING_MODE "OMX.QCOM.index.config.scalingmode" -#define OMX_QCOM_INDEX_CONFIG_NOISEREDUCTION "OMX.QCOM.index.config.noisereduction" -#define OMX_QCOM_INDEX_CONFIG_IMAGEENHANCEMENT "OMX.QCOM.index.config.imageenhancement" -#define OMX_QCOM_INDEX_PARAM_HELDBUFFERCOUNT "OMX.QCOM.index.param.HeldBufferCount" /**< reference: QOMX_HELDBUFFERCOUNTTYPE */ - - -typedef struct QOMX_RECTTYPE { - OMX_S32 nLeft; - OMX_S32 nTop; - OMX_U32 nWidth; - OMX_U32 nHeight; -} QOMX_RECTTYPE; - -typedef struct QOMX_ACTIVEREGIONDETECTIONTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnable; - QOMX_RECTTYPE sROI; - OMX_U32 nNumExclusionRegions; - QOMX_RECTTYPE sExclusionRegions[1]; -} QOMX_ACTIVEREGIONDETECTIONTYPE; - -typedef struct QOMX_ACTIVEREGIONDETECTION_STATUSTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bDetected; - QOMX_RECTTYPE sDetectedRegion; -} QOMX_ACTIVEREGIONDETECTION_STATUSTYPE; - -typedef enum QOMX_SCALE_MODETYPE { - QOMX_SCALE_MODE_Normal, - QOMX_SCALE_MODE_Anamorphic, - QOMX_SCALE_MODE_Max = 0x7FFFFFFF -} QOMX_SCALE_MODETYPE; - -typedef struct QOMX_SCALINGMODETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - QOMX_SCALE_MODETYPE eScaleMode; -} QOMX_SCALINGMODETYPE; - -typedef struct QOMX_NOISEREDUCTIONTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnable; - OMX_BOOL bAutoMode; - OMX_S32 nNoiseReduction; -} QOMX_NOISEREDUCTIONTYPE; - -typedef struct QOMX_IMAGEENHANCEMENTTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnable; - OMX_BOOL bAutoMode; - OMX_S32 nImageEnhancement; -} QOMX_IMAGEENHANCEMENTTYPE; - -/* - * these are part of OMX1.2 but JB MR2 branch doesn't have them defined - * OMX_IndexParamInterlaceFormat - * OMX_INTERLACEFORMATTYPE - */ -#ifndef OMX_IndexParamInterlaceFormat -#define OMX_IndexParamInterlaceFormat (0x7FF00000) -typedef struct OMX_INTERLACEFORMATTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nFormat; - OMX_TICKS nTimeStamp; -} OMX_INTERLACEFORMATTYPE; -#endif - -/** - * This structure is used to indicate the maximum number of buffers - * that a port will hold during data flow. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version info - * nPortIndex : Port that this structure applies to - * nHeldBufferCount : Read-only, maximum number of buffers that will be held - */ -typedef struct QOMX_HELDBUFFERCOUNTTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nHeldBufferCount; -} QOMX_HELDBUFFERCOUNTTYPE; - -typedef enum QOMX_VIDEO_HIERARCHICALCODINGTYPE { - QOMX_HIERARCHICALCODING_P = 0x01, - QOMX_HIERARCHICALCODING_B = 0x02, -} QOMX_VIDEO_HIERARCHICALCODINGTYPE; - -typedef struct QOMX_VIDEO_HIERARCHICALLAYERS { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nNumLayers; - QOMX_VIDEO_HIERARCHICALCODINGTYPE eHierarchicalCodingType; -} QOMX_VIDEO_HIERARCHICALLAYERS; - -typedef struct QOMX_VIDEO_H264ENTROPYCODINGTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_BOOL bCabac; - OMX_U32 nCabacInitIdc; -} QOMX_VIDEO_H264ENTROPYCODINGTYPE; - - -/* VIDEO POSTPROCESSING CTRLS AND ENUMS */ -#define QOMX_VPP_HQV_CUSTOMPAYLOAD_SZ 256 -#define VPP_HQV_CONTROL_GLOBAL_START (VPP_HQV_CONTROL_CUST + 1) - -typedef enum QOMX_VPP_HQV_MODE { - VPP_HQV_MODE_OFF, - VPP_HQV_MODE_AUTO, - VPP_HQV_MODE_MANUAL, - VPP_HQV_MODE_MAX -} QOMX_VPP_HQV_MODE; - -typedef enum QOMX_VPP_HQVCONTROLTYPE { - VPP_HQV_CONTROL_CADE = 0x1, - VPP_HQV_CONTROL_CNR = 0x04, - VPP_HQV_CONTROL_AIE = 0x05, - VPP_HQV_CONTROL_FRC = 0x06, - VPP_HQV_CONTROL_CUST = 0x07, - VPP_HQV_CONTROL_GLOBAL_DEMO = VPP_HQV_CONTROL_GLOBAL_START, - VPP_HQV_CONTROL_MAX, -} QOMX_VPP_HQVCONTROLTYPE; - -typedef enum QOMX_VPP_HQV_HUE_MODE { - VPP_HQV_HUE_MODE_OFF, - VPP_HQV_HUE_MODE_ON, - VPP_HQV_HUE_MODE_MAX, -} QOMX_VPP_HQV_HUE_MODE; - -typedef enum QOMX_VPP_HQV_FRC_MODE { - VPP_HQV_FRC_MODE_OFF, - VPP_HQV_FRC_MODE_LOW, - VPP_HQV_FRC_MODE_MED, - VPP_HQV_FRC_MODE_HIGH, - VPP_HQV_FRC_MODE_MAX, -} QOMX_VPP_HQV_FRC_MODE; - - -typedef struct QOMX_VPP_HQVCTRL_CADE { - QOMX_VPP_HQV_MODE mode; - OMX_U32 level; - OMX_S32 contrast; - OMX_S32 saturation; -} QOMX_VPP_HQVCTRL_CADE; - -typedef struct QOMX_VPP_HQVCTRL_CNR { - QOMX_VPP_HQV_MODE mode; - OMX_U32 level; -} QOMX_VPP_HQVCTRL_CNR; - -typedef struct QOMX_VPP_HQVCTRL_AIE { - QOMX_VPP_HQV_MODE mode; - QOMX_VPP_HQV_HUE_MODE hue_mode; - OMX_U32 cade_level; - OMX_U32 ltm_level; -} QOMX_VPP_HQVCTRL_AIE; - -typedef struct QOMX_VPP_HQVCTRL_CUSTOM { - OMX_U32 id; - OMX_U32 len; - OMX_U8 data[QOMX_VPP_HQV_CUSTOMPAYLOAD_SZ]; -} QOMX_VPP_HQVCTRL_CUSTOM; - -typedef struct QOMX_VPP_HQVCTRL_GLOBAL_DEMO { - OMX_U32 process_percent; -} QOMX_VPP_HQVCTRL_GLOBAL_DEMO; - -typedef struct QOMX_VPP_HQVCTRL_FRC { - QOMX_VPP_HQV_FRC_MODE mode; -} QOMX_VPP_HQVCTRL_FRC; - -typedef struct QOMX_VPP_HQVCONTROL { - QOMX_VPP_HQV_MODE mode; - QOMX_VPP_HQVCONTROLTYPE ctrl_type; - union { - QOMX_VPP_HQVCTRL_CADE cade; - QOMX_VPP_HQVCTRL_CNR cnr; - QOMX_VPP_HQVCTRL_AIE aie; - QOMX_VPP_HQVCTRL_CUSTOM custom; - QOMX_VPP_HQVCTRL_GLOBAL_DEMO global_demo; - QOMX_VPP_HQVCTRL_FRC frc; - }; -} QOMX_VPP_HQVCONTROL; - -/* STRUCTURE TO TURN VPP ON */ -typedef struct QOMX_VPP_ENABLE { - OMX_BOOL enable_vpp; -} QOMX_VPP_ENABLE; - -typedef enum OMX_QOMX_VIDEO_MBISTATISTICSTYPE { - QOMX_MBI_STATISTICS_MODE_DEFAULT = 0, - QOMX_MBI_STATISTICS_MODE_1 = 0x01, - QOMX_MBI_STATISTICS_MODE_2 = 0x02, -} OMX_QOMX_VIDEO_MBISTATISTICSTYPE; - -typedef struct OMX_QOMX_VIDEO_MBI_STATISTICS { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_QOMX_VIDEO_MBISTATISTICSTYPE eMBIStatisticsType; -} OMX_QOMX_VIDEO_MBI_STATISTICS; - -typedef struct QOMX_VIDEO_BATCHSIZETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nBatchSize; -} QOMX_VIDEO_BATCHSIZETYPE; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __OMX_QCOM_EXTENSIONS_H__ */ diff --git a/third_party/openmax/include/OMX_Skype_VideoExtensions.h b/third_party/openmax/include/OMX_Skype_VideoExtensions.h deleted file mode 100644 index 5cc832930f..0000000000 --- a/third_party/openmax/include/OMX_Skype_VideoExtensions.h +++ /dev/null @@ -1,155 +0,0 @@ -/*@@@+++@@@@****************************************************************** - - Microsoft Skype Engineering - Copyright (C) 2014 Microsoft Corporation. - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - -*@@@---@@@@******************************************************************/ - - -#ifndef __OMX_SKYPE_VIDEOEXTENSIONS_H__ -#define __OMX_SKYPE_VIDEOEXTENSIONS_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include - -#pragma pack(push, 1) - - -typedef enum OMX_SKYPE_VIDEO_SliceControlMode -{ - OMX_SKYPE_VIDEO_SliceControlModeNone = 0, - OMX_SKYPE_VIDEO_SliceControlModeMB = 1, - OMX_SKYPE_VIDEO_SliceControlModeByte = 2, - OMX_SKYPE_VIDEO_SliceControlModMBRow = 3, -} OMX_SKYPE_VIDEO_SliceControlMode; - - -typedef enum OMX_SKYPE_VIDEO_HierarType -{ - OMX_SKYPE_VIDEO_HierarType_P = 0x01, - OMX_SKYPE_VIDEO_HierarType_B = 0x02, -} OMX_SKYPE_VIDEO_HIERAR_HierarType; - -typedef enum OMX_VIDEO_EXTENSION_AVCPROFILETYPE -{ - OMX_VIDEO_EXT_AVCProfileConstrainedBaseline = 0x01, - OMX_VIDEO_EXT_AVCProfileConstrainedHigh = 0x02, -} OMX_VIDEO_EXTENSION_AVCPROFILETYPE; - -typedef struct OMX_SKYPE_VIDEO_ENCODERPARAMS { - OMX_BOOL bLowLatency; - OMX_BOOL bUseExtendedProfile; - OMX_BOOL bSequenceHeaderWithIDR; - OMX_VIDEO_EXTENSION_AVCPROFILETYPE eProfile; - OMX_U32 nLTRFrames; - OMX_SKYPE_VIDEO_HierarType eHierarType; - OMX_U32 nMaxTemporalLayerCount; - OMX_SKYPE_VIDEO_SliceControlMode eSliceControlMode; - OMX_U32 nSarIndex; - OMX_U32 nSarWidth; - OMX_U32 nSarHeight; -} OMX_SKYPE_VIDEO_ENCODERPARAMS; - -typedef struct OMX_SKYPE_VIDEO_PARAM_ENCODERSETTING { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_SKYPE_VIDEO_ENCODERPARAMS stEncParam; -} OMX_SKYPE_VIDEO_PARAM_ENCODESETTING; - -typedef struct OMX_SKYPE_VIDEO_ENCODERCAP { - OMX_BOOL bLowLatency; - OMX_U32 nMaxFrameWidth; - OMX_U32 nMaxFrameHeight; - OMX_U32 nMaxInstances; - OMX_U32 nMaxTemporaLayerCount; - OMX_U32 nMaxRefFrames; - OMX_U32 nMaxLTRFrames; - OMX_VIDEO_AVCLEVELTYPE nMaxLevel; - OMX_U32 nSliceControlModesBM; - OMX_U32 nMaxMacroblockProcessingRate; - OMX_U32 xMinScaleFactor; -} OMX_SKYPE_VIDEO_ENCODERCAP; - -typedef struct OMX_SKYPE_VIDEO_PARAM_ENCODERCAP { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_SKYPE_VIDEO_ENCODERCAP stEncCap; -} OMX_SKYPE_VIDEO_PARAM_ENCODERCAP; - -typedef struct OMX_SKYPE_VIDEO_DECODERCAP { - OMX_BOOL bLowLatency; - OMX_U32 nMaxFrameWidth; - OMX_U32 nMaxFrameHeight; - OMX_U32 nMaxInstances; - OMX_VIDEO_AVCLEVELTYPE nMaxLevel; - OMX_U32 nMaxMacroblockProcessingRate; -} OMX_SKYPE_VIDEO_DECODERCAP; - -typedef struct OMX_SKYPE_VIDEO_PARAM_DECODERCAP { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_SKYPE_VIDEO_DECODERCAP stDecoderCap; -} OMX_SKYPE_VIDEO_PARAM_DECODERCAP; - -typedef struct OMX_SKYPE_VIDEO_CONFIG_QP { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nQP; -} OMX_SKYPE_VIDEO_CONFIG_QP; - -typedef struct OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nPID; -} OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID; - -typedef struct OMX_SKYPE_VIDEO_PARAM_DRIVERVER { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U64 nDriverVersion; -} OMX_SKYPE_VIDEO_PARAM_DRIVERVER; - -typedef enum OMX_SKYPE_VIDEO_DownScaleFactor -{ - OMX_SKYPE_VIDEO_DownScaleFactor_1_1 = 0, - OMX_SKYPE_VIDEO_DownScaleFactor_Equal_AR = 1, - OMX_SKYPE_VIDEO_DownScaleFactor_Any = 2, -} OMX_SKYPE_VIDEO_DownScaleFactor; - -#pragma pack(pop) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/third_party/openmax/include/OMX_Types.h b/third_party/openmax/include/OMX_Types.h deleted file mode 100644 index 3b9fab4fc2..0000000000 --- a/third_party/openmax/include/OMX_Types.h +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** OMX_Types.h - OpenMax IL version 1.1.2 - * The OMX_Types header file contains the primitive type definitions used by - * the core, the application and the component. This file may need to be - * modified to be used on systems that do not have "char" set to 8 bits, - * "short" set to 16 bits and "long" set to 32 bits. - */ - -#ifndef OMX_Types_h -#define OMX_Types_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** The OMX_API and OMX_APIENTRY are platform specific definitions used - * to declare OMX function prototypes. They are modified to meet the - * requirements for a particular platform */ -#ifdef __SYMBIAN32__ -# ifdef __OMX_EXPORTS -# define OMX_API __declspec(dllexport) -# else -# ifdef _WIN32 -# define OMX_API __declspec(dllexport) -# else -# define OMX_API __declspec(dllimport) -# endif -# endif -#else -# ifdef _WIN32 -# ifdef __OMX_EXPORTS -# define OMX_API __declspec(dllexport) -# else -# define OMX_API __declspec(dllimport) -# endif -# else -# ifdef __OMX_EXPORTS -# define OMX_API -# else -# define OMX_API extern -# endif -# endif -#endif - -#ifndef OMX_APIENTRY -#define OMX_APIENTRY -#endif - -/** OMX_IN is used to identify inputs to an OMX function. This designation - will also be used in the case of a pointer that points to a parameter - that is used as an output. */ -#ifndef OMX_IN -#define OMX_IN -#endif - -/** OMX_OUT is used to identify outputs from an OMX function. This - designation will also be used in the case of a pointer that points - to a parameter that is used as an input. */ -#ifndef OMX_OUT -#define OMX_OUT -#endif - - -/** OMX_INOUT is used to identify parameters that may be either inputs or - outputs from an OMX function at the same time. This designation will - also be used in the case of a pointer that points to a parameter that - is used both as an input and an output. */ -#ifndef OMX_INOUT -#define OMX_INOUT -#endif - -/** OMX_ALL is used to as a wildcard to select all entities of the same type - * when specifying the index, or referring to a object by an index. (i.e. - * use OMX_ALL to indicate all N channels). When used as a port index - * for a config or parameter this OMX_ALL denotes that the config or - * parameter applies to the entire component not just one port. */ -#define OMX_ALL 0xFFFFFFFF - -/** In the following we define groups that help building doxygen documentation */ - -/** @defgroup core OpenMAX IL core - * Functions and structure related to the OMX IL core - */ - - /** @defgroup comp OpenMAX IL component - * Functions and structure related to the OMX IL component - */ - -/** @defgroup rpm Resource and Policy Management - * Structures for resource and policy management of components - */ - -/** @defgroup buf Buffer Management - * Buffer handling functions and structures - */ - -/** @defgroup tun Tunneling - * @ingroup core comp - * Structures and functions to manage tunnels among component ports - */ - -/** @defgroup cp Content Pipes - * @ingroup core - */ - - /** @defgroup metadata Metadata handling - * - */ - -/** OMX_U8 is an 8 bit unsigned quantity that is byte aligned */ -typedef unsigned char OMX_U8; - -/** OMX_S8 is an 8 bit signed quantity that is byte aligned */ -typedef signed char OMX_S8; - -/** OMX_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */ -typedef unsigned short OMX_U16; - -/** OMX_S16 is a 16 bit signed quantity that is 16 bit word aligned */ -typedef signed short OMX_S16; - -/** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */ -typedef unsigned int OMX_U32; - -/** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */ -typedef signed int OMX_S32; - - -/* Users with compilers that cannot accept the "long long" designation should - define the OMX_SKIP64BIT macro. It should be noted that this may cause - some components to fail to compile if the component was written to require - 64 bit integral types. However, these components would NOT compile anyway - since the compiler does not support the way the component was written. -*/ -#ifndef OMX_SKIP64BIT -#ifdef __SYMBIAN32__ -/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ -typedef unsigned long long OMX_U64; - -/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ -typedef signed long long OMX_S64; - -#elif defined(WIN32) - -/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ -typedef unsigned __int64 OMX_U64; - -/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ -typedef signed __int64 OMX_S64; - -#else /* WIN32 */ - -/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ -typedef unsigned long long OMX_U64; - -/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ -typedef signed long long OMX_S64; - -#endif /* WIN32 */ -#endif - - -/** The OMX_BOOL type is intended to be used to represent a true or a false - value when passing parameters to and from the OMX core and components. The - OMX_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary. - */ -typedef enum OMX_BOOL { - OMX_FALSE = 0, - OMX_TRUE = !OMX_FALSE, - OMX_BOOL_MAX = 0x7FFFFFFF -} OMX_BOOL; - -#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS - -typedef OMX_U32 OMX_PTR; -typedef OMX_PTR OMX_STRING; -typedef OMX_PTR OMX_BYTE; - -#else - -/** The OMX_PTR type is intended to be used to pass pointers between the OMX - applications and the OMX Core and components. This is a 32 bit pointer and - is aligned on a 32 bit boundary. - */ -typedef void* OMX_PTR; - -/** The OMX_STRING type is intended to be used to pass "C" type strings between - the application and the core and component. The OMX_STRING type is a 32 - bit pointer to a zero terminated string. The pointer is word aligned and - the string is byte aligned. - */ -typedef char* OMX_STRING; - -/** The OMX_BYTE type is intended to be used to pass arrays of bytes such as - buffers between the application and the component and core. The OMX_BYTE - type is a 32 bit pointer to a zero terminated string. The pointer is word - aligned and the string is byte aligned. - */ -typedef unsigned char* OMX_BYTE; - -/** OMX_UUIDTYPE is a very long unique identifier to uniquely identify - at runtime. This identifier should be generated by a component in a way - that guarantees that every instance of the identifier running on the system - is unique. */ - - -#endif - -typedef unsigned char OMX_UUIDTYPE[128]; - -/** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or - an output port. This enumeration is common across all component types. - */ -typedef enum OMX_DIRTYPE -{ - OMX_DirInput, /**< Port is an input port */ - OMX_DirOutput, /**< Port is an output port */ - OMX_DirMax = 0x7FFFFFFF -} OMX_DIRTYPE; - -/** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering - for numerical data (i.e. big endian, or little endian). - */ -typedef enum OMX_ENDIANTYPE -{ - OMX_EndianBig, /**< big endian */ - OMX_EndianLittle, /**< little endian */ - OMX_EndianMax = 0x7FFFFFFF -} OMX_ENDIANTYPE; - - -/** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data - is signed or unsigned - */ -typedef enum OMX_NUMERICALDATATYPE -{ - OMX_NumericalDataSigned, /**< signed data */ - OMX_NumericalDataUnsigned, /**< unsigned data */ - OMX_NumercialDataMax = 0x7FFFFFFF -} OMX_NUMERICALDATATYPE; - - -/** Unsigned bounded value type */ -typedef struct OMX_BU32 { - OMX_U32 nValue; /**< actual value */ - OMX_U32 nMin; /**< minimum for value (i.e. nValue >= nMin) */ - OMX_U32 nMax; /**< maximum for value (i.e. nValue <= nMax) */ -} OMX_BU32; - - -/** Signed bounded value type */ -typedef struct OMX_BS32 { - OMX_S32 nValue; /**< actual value */ - OMX_S32 nMin; /**< minimum for value (i.e. nValue >= nMin) */ - OMX_S32 nMax; /**< maximum for value (i.e. nValue <= nMax) */ -} OMX_BS32; - - -/** Structure representing some time or duration in microseconds. This structure - * must be interpreted as a signed 64 bit value. The quantity is signed to accommodate - * negative deltas and preroll scenarios. The quantity is represented in microseconds - * to accomodate high resolution timestamps (e.g. DVD presentation timestamps based - * on a 90kHz clock) and to allow more accurate and synchronized delivery (e.g. - * individual audio samples delivered at 192 kHz). The quantity is 64 bit to - * accommodate a large dynamic range (signed 32 bit values would allow only for plus - * or minus 35 minutes). - * - * Implementations with limited precision may convert the signed 64 bit value to - * a signed 32 bit value internally but risk loss of precision. - */ -#ifndef OMX_SKIP64BIT -typedef OMX_S64 OMX_TICKS; -#else -typedef struct OMX_TICKS -{ - OMX_U32 nLowPart; /** low bits of the signed 64 bit tick value */ - OMX_U32 nHighPart; /** high bits of the signed 64 bit tick value */ -} OMX_TICKS; -#endif -#define OMX_TICKS_PER_SECOND 1000000 - -/** Define the public interface for the OMX Handle. The core will not use - this value internally, but the application should only use this value. - */ -typedef void* OMX_HANDLETYPE; - -typedef struct OMX_MARKTYPE -{ - OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will - generate a mark event upon - processing the mark. */ - OMX_PTR pMarkData; /**< Application specific data associated with - the mark sent on a mark event to disambiguate - this mark from others. */ -} OMX_MARKTYPE; - - -/** OMX_NATIVE_DEVICETYPE is used to map a OMX video port to the - * platform & operating specific object used to reference the display - * or can be used by a audio port for native audio rendering */ -typedef void* OMX_NATIVE_DEVICETYPE; - -/** OMX_NATIVE_WINDOWTYPE is used to map a OMX video port to the - * platform & operating specific object used to reference the window */ -typedef void* OMX_NATIVE_WINDOWTYPE; - -/** The OMX_VERSIONTYPE union is used to specify the version for - a structure or component. For a component, the version is entirely - specified by the component vendor. Components doing the same function - from different vendors may or may not have the same version. For - structures, the version shall be set by the entity that allocates the - structure. For structures specified in the OMX 1.1 specification, the - value of the version shall be set to 1.1.0.0 in all cases. Access to the - OMX_VERSIONTYPE can be by a single 32 bit access (e.g. by nVersion) or - by accessing one of the structure elements to, for example, check only - the Major revision. - */ -typedef union OMX_VERSIONTYPE -{ - struct - { - OMX_U8 nVersionMajor; /**< Major version accessor element */ - OMX_U8 nVersionMinor; /**< Minor version accessor element */ - OMX_U8 nRevision; /**< Revision version accessor element */ - OMX_U8 nStep; /**< Step version accessor element */ - } s; - OMX_U32 nVersion; /**< 32 bit value to make accessing the - version easily done in a single word - size copy/compare operation */ -} OMX_VERSIONTYPE; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ diff --git a/third_party/openmax/include/OMX_Video.h b/third_party/openmax/include/OMX_Video.h deleted file mode 100644 index 64dbe87b43..0000000000 --- a/third_party/openmax/include/OMX_Video.h +++ /dev/null @@ -1,1082 +0,0 @@ -/** - * Copyright (c) 2008 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** - * @file OMX_Video.h - OpenMax IL version 1.1.2 - * The structures is needed by Video components to exchange parameters - * and configuration data with OMX components. - */ -#ifndef OMX_Video_h -#define OMX_Video_h - -/** @defgroup video OpenMAX IL Video Domain - * @ingroup iv - * Structures for OpenMAX IL Video domain - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/** - * Each OMX header must include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ - -#include - - -/** - * Enumeration used to define the possible video compression codings. - * NOTE: This essentially refers to file extensions. If the coding is - * being used to specify the ENCODE type, then additional work - * must be done to configure the exact flavor of the compression - * to be used. For decode cases where the user application can - * not differentiate between MPEG-4 and H.264 bit streams, it is - * up to the codec to handle this. - */ -typedef enum OMX_VIDEO_CODINGTYPE { - OMX_VIDEO_CodingUnused, /**< Value when coding is N/A */ - OMX_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ - OMX_VIDEO_CodingMPEG2, /**< AKA: H.262 */ - OMX_VIDEO_CodingH263, /**< H.263 */ - OMX_VIDEO_CodingMPEG4, /**< MPEG-4 */ - OMX_VIDEO_CodingWMV, /**< all versions of Windows Media Video */ - OMX_VIDEO_CodingRV, /**< all versions of Real Video */ - OMX_VIDEO_CodingAVC, /**< H.264/AVC */ - OMX_VIDEO_CodingMJPEG, /**< Motion JPEG */ - OMX_VIDEO_CodingVP8, /**< Google VP8, formerly known as On2 VP8 */ - OMX_VIDEO_CodingVP9, /**< Google VP9 */ - OMX_VIDEO_CodingHEVC, /**< HEVC */ - OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_CodingMax = 0x7FFFFFFF -} OMX_VIDEO_CODINGTYPE; - - -/** - * Data structure used to define a video path. The number of Video paths for - * input and output will vary by type of the Video component. - * - * Input (aka Source) : zero Inputs, one Output, - * Splitter : one Input, 2 or more Outputs, - * Processing Element : one Input, one output, - * Mixer : 2 or more inputs, one output, - * Output (aka Sink) : one Input, zero outputs. - * - * The PortDefinition structure is used to define all of the parameters - * necessary for the compliant component to setup an input or an output video - * path. If additional vendor specific data is required, it should be - * transmitted to the component using the CustomCommand function. Compliant - * components will prepopulate this structure with optimal values during the - * GetDefaultInitParams command. - * - * STRUCT MEMBERS: - * cMIMEType : MIME type of data for the port - * pNativeRender : Platform specific reference for a display if a - * sync, otherwise this field is 0 - * nFrameWidth : Width of frame to be used on channel if - * uncompressed format is used. Use 0 for unknown, - * don't care or variable - * nFrameHeight : Height of frame to be used on channel if - * uncompressed format is used. Use 0 for unknown, - * don't care or variable - * nStride : Number of bytes per span of an image - * (i.e. indicates the number of bytes to get - * from span N to span N+1, where negative stride - * indicates the image is bottom up - * nSliceHeight : Height used when encoding in slices - * nBitrate : Bit rate of frame to be used on channel if - * compressed format is used. Use 0 for unknown, - * don't care or variable - * xFramerate : Frame rate to be used on channel if uncompressed - * format is used. Use 0 for unknown, don't care or - * variable. Units are Q16 frames per second. - * bFlagErrorConcealment : Turns on error concealment if it is supported by - * the OMX component - * eCompressionFormat : Compression format used in this instance of the - * component. When OMX_VIDEO_CodingUnused is - * specified, eColorFormat is used - * eColorFormat : Decompressed format used by this component - * pNativeWindow : Platform specific reference for a window object if a - * display sink , otherwise this field is 0x0. - */ -typedef struct OMX_VIDEO_PORTDEFINITIONTYPE { - OMX_STRING cMIMEType; - OMX_NATIVE_DEVICETYPE pNativeRender; - OMX_U32 nFrameWidth; - OMX_U32 nFrameHeight; - OMX_S32 nStride; - OMX_U32 nSliceHeight; - OMX_U32 nBitrate; - OMX_U32 xFramerate; - OMX_BOOL bFlagErrorConcealment; - OMX_VIDEO_CODINGTYPE eCompressionFormat; - OMX_COLOR_FORMATTYPE eColorFormat; - OMX_NATIVE_WINDOWTYPE pNativeWindow; -} OMX_VIDEO_PORTDEFINITIONTYPE; - -/** - * Port format parameter. This structure is used to enumerate the various - * data input/output format supported by the port. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Indicates which port to set - * nIndex : Indicates the enumeration index for the format from - * 0x0 to N-1 - * eCompressionFormat : Compression format used in this instance of the - * component. When OMX_VIDEO_CodingUnused is specified, - * eColorFormat is used - * eColorFormat : Decompressed format used by this component - * xFrameRate : Indicates the video frame rate in Q16 format - */ -typedef struct OMX_VIDEO_PARAM_PORTFORMATTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nIndex; - OMX_VIDEO_CODINGTYPE eCompressionFormat; - OMX_COLOR_FORMATTYPE eColorFormat; - OMX_U32 xFramerate; -} OMX_VIDEO_PARAM_PORTFORMATTYPE; - - -/** - * This is a structure for configuring video compression quantization - * parameter values. Codecs may support different QP values for different - * frame types. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version info - * nPortIndex : Port that this structure applies to - * nQpI : QP value to use for index frames - * nQpP : QP value to use for P frames - * nQpB : QP values to use for bidirectional frames - */ -typedef struct OMX_VIDEO_PARAM_QUANTIZATIONTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nQpI; - OMX_U32 nQpP; - OMX_U32 nQpB; -} OMX_VIDEO_PARAM_QUANTIZATIONTYPE; - - -/** - * Structure for configuration of video fast update parameters. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version info - * nPortIndex : Port that this structure applies to - * bEnableVFU : Enable/Disable video fast update - * nFirstGOB : Specifies the number of the first macroblock row - * nFirstMB : specifies the first MB relative to the specified first GOB - * nNumMBs : Specifies the number of MBs to be refreshed from nFirstGOB - * and nFirstMB - */ -typedef struct OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnableVFU; - OMX_U32 nFirstGOB; - OMX_U32 nFirstMB; - OMX_U32 nNumMBs; -} OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE; - - -/** - * Enumeration of possible bitrate control types - */ -typedef enum OMX_VIDEO_CONTROLRATETYPE { - OMX_Video_ControlRateDisable, - OMX_Video_ControlRateVariable, - OMX_Video_ControlRateConstant, - OMX_Video_ControlRateVariableSkipFrames, - OMX_Video_ControlRateConstantSkipFrames, - OMX_Video_ControlRateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_Video_ControlRateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_Video_ControlRateMax = 0x7FFFFFFF -} OMX_VIDEO_CONTROLRATETYPE; - - -/** - * Structure for configuring bitrate mode of a codec. - * - * STRUCT MEMBERS: - * nSize : Size of the struct in bytes - * nVersion : OMX spec version info - * nPortIndex : Port that this struct applies to - * eControlRate : Control rate type enum - * nTargetBitrate : Target bitrate to encode with - */ -typedef struct OMX_VIDEO_PARAM_BITRATETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_VIDEO_CONTROLRATETYPE eControlRate; - OMX_U32 nTargetBitrate; -} OMX_VIDEO_PARAM_BITRATETYPE; - - -/** - * Enumeration of possible motion vector (MV) types - */ -typedef enum OMX_VIDEO_MOTIONVECTORTYPE { - OMX_Video_MotionVectorPixel, - OMX_Video_MotionVectorHalfPel, - OMX_Video_MotionVectorQuarterPel, - OMX_Video_MotionVectorEighthPel, - OMX_Video_MotionVectorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_Video_MotionVectorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_Video_MotionVectorMax = 0x7FFFFFFF -} OMX_VIDEO_MOTIONVECTORTYPE; - - -/** - * Structure for configuring the number of motion vectors used as well - * as their accuracy. - * - * STRUCT MEMBERS: - * nSize : Size of the struct in bytes - * nVersion : OMX spec version info - * nPortIndex : port that this structure applies to - * eAccuracy : Enumerated MV accuracy - * bUnrestrictedMVs : Allow unrestricted MVs - * bFourMV : Allow use of 4 MVs - * sXSearchRange : Search range in horizontal direction for MVs - * sYSearchRange : Search range in vertical direction for MVs - */ -typedef struct OMX_VIDEO_PARAM_MOTIONVECTORTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_VIDEO_MOTIONVECTORTYPE eAccuracy; - OMX_BOOL bUnrestrictedMVs; - OMX_BOOL bFourMV; - OMX_S32 sXSearchRange; - OMX_S32 sYSearchRange; -} OMX_VIDEO_PARAM_MOTIONVECTORTYPE; - - -/** - * Enumeration of possible methods to use for Intra Refresh - */ -typedef enum OMX_VIDEO_INTRAREFRESHTYPE { - OMX_VIDEO_IntraRefreshCyclic, - OMX_VIDEO_IntraRefreshAdaptive, - OMX_VIDEO_IntraRefreshBoth, - OMX_VIDEO_IntraRefreshKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_IntraRefreshVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_IntraRefreshRandom, - OMX_VIDEO_IntraRefreshMax = 0x7FFFFFFF -} OMX_VIDEO_INTRAREFRESHTYPE; - - -/** - * Structure for configuring intra refresh mode - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eRefreshMode : Cyclic, Adaptive, or Both - * nAirMBs : Number of intra macroblocks to refresh in a frame when - * AIR is enabled - * nAirRef : Number of times a motion marked macroblock has to be - * intra coded - * nCirMBs : Number of consecutive macroblocks to be coded as "intra" - * when CIR is enabled - */ -typedef struct OMX_VIDEO_PARAM_INTRAREFRESHTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_VIDEO_INTRAREFRESHTYPE eRefreshMode; - OMX_U32 nAirMBs; - OMX_U32 nAirRef; - OMX_U32 nCirMBs; -} OMX_VIDEO_PARAM_INTRAREFRESHTYPE; - - -/** - * Structure for enabling various error correction methods for video - * compression. - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * bEnableHEC : Enable/disable header extension codes (HEC) - * bEnableResync : Enable/disable resynchronization markers - * nResynchMarkerSpacing : Resynch markers interval (in bits) to be - * applied in the stream - * bEnableDataPartitioning : Enable/disable data partitioning - * bEnableRVLC : Enable/disable reversible variable length - * coding - */ -typedef struct OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnableHEC; - OMX_BOOL bEnableResync; - OMX_U32 nResynchMarkerSpacing; - OMX_BOOL bEnableDataPartitioning; - OMX_BOOL bEnableRVLC; -} OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE; - - -/** - * Configuration of variable block-size motion compensation (VBSMC) - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * b16x16 : Enable inter block search 16x16 - * b16x8 : Enable inter block search 16x8 - * b8x16 : Enable inter block search 8x16 - * b8x8 : Enable inter block search 8x8 - * b8x4 : Enable inter block search 8x4 - * b4x8 : Enable inter block search 4x8 - * b4x4 : Enable inter block search 4x4 - */ -typedef struct OMX_VIDEO_PARAM_VBSMCTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL b16x16; - OMX_BOOL b16x8; - OMX_BOOL b8x16; - OMX_BOOL b8x8; - OMX_BOOL b8x4; - OMX_BOOL b4x8; - OMX_BOOL b4x4; -} OMX_VIDEO_PARAM_VBSMCTYPE; - - -/** - * H.263 profile types, each profile indicates support for various - * performance bounds and different annexes. - * - * ENUMS: - * Baseline : Baseline Profile: H.263 (V1), no optional modes - * H320 Coding : H.320 Coding Efficiency Backward Compatibility - * Profile: H.263+ (V2), includes annexes I, J, L.4 - * and T - * BackwardCompatible : Backward Compatibility Profile: H.263 (V1), - * includes annex F - * ISWV2 : Interactive Streaming Wireless Profile: H.263+ - * (V2), includes annexes I, J, K and T - * ISWV3 : Interactive Streaming Wireless Profile: H.263++ - * (V3), includes profile 3 and annexes V and W.6.3.8 - * HighCompression : Conversational High Compression Profile: H.263++ - * (V3), includes profiles 1 & 2 and annexes D and U - * Internet : Conversational Internet Profile: H.263++ (V3), - * includes profile 5 and annex K - * Interlace : Conversational Interlace Profile: H.263++ (V3), - * includes profile 5 and annex W.6.3.11 - * HighLatency : High Latency Profile: H.263++ (V3), includes - * profile 6 and annexes O.1 and P.5 - */ -typedef enum OMX_VIDEO_H263PROFILETYPE { - OMX_VIDEO_H263ProfileBaseline = 0x01, - OMX_VIDEO_H263ProfileH320Coding = 0x02, - OMX_VIDEO_H263ProfileBackwardCompatible = 0x04, - OMX_VIDEO_H263ProfileISWV2 = 0x08, - OMX_VIDEO_H263ProfileISWV3 = 0x10, - OMX_VIDEO_H263ProfileHighCompression = 0x20, - OMX_VIDEO_H263ProfileInternet = 0x40, - OMX_VIDEO_H263ProfileInterlace = 0x80, - OMX_VIDEO_H263ProfileHighLatency = 0x100, - OMX_VIDEO_H263ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_H263ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_H263ProfileMax = 0x7FFFFFFF -} OMX_VIDEO_H263PROFILETYPE; - - -/** - * H.263 level types, each level indicates support for various frame sizes, - * bit rates, decoder frame rates. - */ -typedef enum OMX_VIDEO_H263LEVELTYPE { - OMX_VIDEO_H263Level10 = 0x01, - OMX_VIDEO_H263Level20 = 0x02, - OMX_VIDEO_H263Level30 = 0x04, - OMX_VIDEO_H263Level40 = 0x08, - OMX_VIDEO_H263Level45 = 0x10, - OMX_VIDEO_H263Level50 = 0x20, - OMX_VIDEO_H263Level60 = 0x40, - OMX_VIDEO_H263Level70 = 0x80, - OMX_VIDEO_H263LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_H263LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_H263LevelMax = 0x7FFFFFFF -} OMX_VIDEO_H263LEVELTYPE; - - -/** - * Specifies the picture type. These values should be OR'd to signal all - * pictures types which are allowed. - * - * ENUMS: - * Generic Picture Types: I, P and B - * H.263 Specific Picture Types: SI and SP - * H.264 Specific Picture Types: EI and EP - * MPEG-4 Specific Picture Types: S - */ -typedef enum OMX_VIDEO_PICTURETYPE { - OMX_VIDEO_PictureTypeI = 0x01, - OMX_VIDEO_PictureTypeP = 0x02, - OMX_VIDEO_PictureTypeB = 0x04, - OMX_VIDEO_PictureTypeSI = 0x08, - OMX_VIDEO_PictureTypeSP = 0x10, - OMX_VIDEO_PictureTypeEI = 0x11, - OMX_VIDEO_PictureTypeEP = 0x12, - OMX_VIDEO_PictureTypeS = 0x14, - OMX_VIDEO_PictureTypeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_PictureTypeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_PictureTypeMax = 0x7FFFFFFF -} OMX_VIDEO_PICTURETYPE; - - -/** - * H.263 Params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nPFrames : Number of P frames between each I frame - * nBFrames : Number of B frames between each I frame - * eProfile : H.263 profile(s) to use - * eLevel : H.263 level(s) to use - * bPLUSPTYPEAllowed : Indicating that it is allowed to use PLUSPTYPE - * (specified in the 1998 version of H.263) to - * indicate custom picture sizes or clock - * frequencies - * nAllowedPictureTypes : Specifies the picture types allowed in the - * bitstream - * bForceRoundingTypeToZero : value of the RTYPE bit (bit 6 of MPPTYPE) is - * not constrained. It is recommended to change - * the value of the RTYPE bit for each reference - * picture in error-free communication - * nPictureHeaderRepetition : Specifies the frequency of picture header - * repetition - * nGOBHeaderInterval : Specifies the interval of non-empty GOB - * headers in units of GOBs - */ -typedef struct OMX_VIDEO_PARAM_H263TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nPFrames; - OMX_U32 nBFrames; - OMX_VIDEO_H263PROFILETYPE eProfile; - OMX_VIDEO_H263LEVELTYPE eLevel; - OMX_BOOL bPLUSPTYPEAllowed; - OMX_U32 nAllowedPictureTypes; - OMX_BOOL bForceRoundingTypeToZero; - OMX_U32 nPictureHeaderRepetition; - OMX_U32 nGOBHeaderInterval; -} OMX_VIDEO_PARAM_H263TYPE; - - -/** - * MPEG-2 profile types, each profile indicates support for various - * performance bounds and different annexes. - */ -typedef enum OMX_VIDEO_MPEG2PROFILETYPE { - OMX_VIDEO_MPEG2ProfileSimple = 0, /**< Simple Profile */ - OMX_VIDEO_MPEG2ProfileMain, /**< Main Profile */ - OMX_VIDEO_MPEG2Profile422, /**< 4:2:2 Profile */ - OMX_VIDEO_MPEG2ProfileSNR, /**< SNR Profile */ - OMX_VIDEO_MPEG2ProfileSpatial, /**< Spatial Profile */ - OMX_VIDEO_MPEG2ProfileHigh, /**< High Profile */ - OMX_VIDEO_MPEG2ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_MPEG2ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_MPEG2ProfileMax = 0x7FFFFFFF -} OMX_VIDEO_MPEG2PROFILETYPE; - - -/** - * MPEG-2 level types, each level indicates support for various frame - * sizes, bit rates, decoder frame rates. No need - */ -typedef enum OMX_VIDEO_MPEG2LEVELTYPE { - OMX_VIDEO_MPEG2LevelLL = 0, /**< Low Level */ - OMX_VIDEO_MPEG2LevelML, /**< Main Level */ - OMX_VIDEO_MPEG2LevelH14, /**< High 1440 */ - OMX_VIDEO_MPEG2LevelHL, /**< High Level */ - OMX_VIDEO_MPEG2LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_MPEG2LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_MPEG2LevelMax = 0x7FFFFFFF -} OMX_VIDEO_MPEG2LEVELTYPE; - - -/** - * MPEG-2 params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nPFrames : Number of P frames between each I frame - * nBFrames : Number of B frames between each I frame - * eProfile : MPEG-2 profile(s) to use - * eLevel : MPEG-2 levels(s) to use - */ -typedef struct OMX_VIDEO_PARAM_MPEG2TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nPFrames; - OMX_U32 nBFrames; - OMX_VIDEO_MPEG2PROFILETYPE eProfile; - OMX_VIDEO_MPEG2LEVELTYPE eLevel; -} OMX_VIDEO_PARAM_MPEG2TYPE; - - -/** - * MPEG-4 profile types, each profile indicates support for various - * performance bounds and different annexes. - * - * ENUMS: - * - Simple Profile, Levels 1-3 - * - Simple Scalable Profile, Levels 1-2 - * - Core Profile, Levels 1-2 - * - Main Profile, Levels 2-4 - * - N-bit Profile, Level 2 - * - Scalable Texture Profile, Level 1 - * - Simple Face Animation Profile, Levels 1-2 - * - Simple Face and Body Animation (FBA) Profile, Levels 1-2 - * - Basic Animated Texture Profile, Levels 1-2 - * - Hybrid Profile, Levels 1-2 - * - Advanced Real Time Simple Profiles, Levels 1-4 - * - Core Scalable Profile, Levels 1-3 - * - Advanced Coding Efficiency Profile, Levels 1-4 - * - Advanced Core Profile, Levels 1-2 - * - Advanced Scalable Texture, Levels 2-3 - */ -typedef enum OMX_VIDEO_MPEG4PROFILETYPE { - OMX_VIDEO_MPEG4ProfileSimple = 0x01, - OMX_VIDEO_MPEG4ProfileSimpleScalable = 0x02, - OMX_VIDEO_MPEG4ProfileCore = 0x04, - OMX_VIDEO_MPEG4ProfileMain = 0x08, - OMX_VIDEO_MPEG4ProfileNbit = 0x10, - OMX_VIDEO_MPEG4ProfileScalableTexture = 0x20, - OMX_VIDEO_MPEG4ProfileSimpleFace = 0x40, - OMX_VIDEO_MPEG4ProfileSimpleFBA = 0x80, - OMX_VIDEO_MPEG4ProfileBasicAnimated = 0x100, - OMX_VIDEO_MPEG4ProfileHybrid = 0x200, - OMX_VIDEO_MPEG4ProfileAdvancedRealTime = 0x400, - OMX_VIDEO_MPEG4ProfileCoreScalable = 0x800, - OMX_VIDEO_MPEG4ProfileAdvancedCoding = 0x1000, - OMX_VIDEO_MPEG4ProfileAdvancedCore = 0x2000, - OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000, - OMX_VIDEO_MPEG4ProfileAdvancedSimple = 0x8000, - OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_MPEG4ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_MPEG4ProfileMax = 0x7FFFFFFF -} OMX_VIDEO_MPEG4PROFILETYPE; - - -/** - * MPEG-4 level types, each level indicates support for various frame - * sizes, bit rates, decoder frame rates. No need - */ -typedef enum OMX_VIDEO_MPEG4LEVELTYPE { - OMX_VIDEO_MPEG4Level0 = 0x01, /**< Level 0 */ - OMX_VIDEO_MPEG4Level0b = 0x02, /**< Level 0b */ - OMX_VIDEO_MPEG4Level1 = 0x04, /**< Level 1 */ - OMX_VIDEO_MPEG4Level2 = 0x08, /**< Level 2 */ - OMX_VIDEO_MPEG4Level3 = 0x10, /**< Level 3 */ - OMX_VIDEO_MPEG4Level4 = 0x20, /**< Level 4 */ - OMX_VIDEO_MPEG4Level4a = 0x40, /**< Level 4a */ - OMX_VIDEO_MPEG4Level5 = 0x80, /**< Level 5 */ - OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_MPEG4LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF -} OMX_VIDEO_MPEG4LEVELTYPE; - - -/** - * MPEG-4 configuration. This structure handles configuration options - * which are specific to MPEG4 algorithms - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nSliceHeaderSpacing : Number of macroblocks between slice header (H263+ - * Annex K). Put zero if not used - * bSVH : Enable Short Video Header mode - * bGov : Flag to enable GOV - * nPFrames : Number of P frames between each I frame (also called - * GOV period) - * nBFrames : Number of B frames between each I frame - * nIDCVLCThreshold : Value of intra DC VLC threshold - * bACPred : Flag to use ac prediction - * nMaxPacketSize : Maximum size of packet in bytes. - * nTimeIncRes : Used to pass VOP time increment resolution for MPEG4. - * Interpreted as described in MPEG4 standard. - * eProfile : MPEG-4 profile(s) to use. - * eLevel : MPEG-4 level(s) to use. - * nAllowedPictureTypes : Specifies the picture types allowed in the bitstream - * nHeaderExtension : Specifies the number of consecutive video packet - * headers within a VOP - * bReversibleVLC : Specifies whether reversible variable length coding - * is in use - */ -typedef struct OMX_VIDEO_PARAM_MPEG4TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nSliceHeaderSpacing; - OMX_BOOL bSVH; - OMX_BOOL bGov; - OMX_U32 nPFrames; - OMX_U32 nBFrames; - OMX_U32 nIDCVLCThreshold; - OMX_BOOL bACPred; - OMX_U32 nMaxPacketSize; - OMX_U32 nTimeIncRes; - OMX_VIDEO_MPEG4PROFILETYPE eProfile; - OMX_VIDEO_MPEG4LEVELTYPE eLevel; - OMX_U32 nAllowedPictureTypes; - OMX_U32 nHeaderExtension; - OMX_BOOL bReversibleVLC; -} OMX_VIDEO_PARAM_MPEG4TYPE; - - -/** - * WMV Versions - */ -typedef enum OMX_VIDEO_WMVFORMATTYPE { - OMX_VIDEO_WMVFormatUnused = 0x01, /**< Format unused or unknown */ - OMX_VIDEO_WMVFormat7 = 0x02, /**< Windows Media Video format 7 */ - OMX_VIDEO_WMVFormat8 = 0x04, /**< Windows Media Video format 8 */ - OMX_VIDEO_WMVFormat9 = 0x08, /**< Windows Media Video format 9 */ - OMX_VIDEO_WMFFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_WMFFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_WMVFormatMax = 0x7FFFFFFF -} OMX_VIDEO_WMVFORMATTYPE; - - -/** - * WMV Params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eFormat : Version of WMV stream / data - */ -typedef struct OMX_VIDEO_PARAM_WMVTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_VIDEO_WMVFORMATTYPE eFormat; -} OMX_VIDEO_PARAM_WMVTYPE; - - -/** - * Real Video Version - */ -typedef enum OMX_VIDEO_RVFORMATTYPE { - OMX_VIDEO_RVFormatUnused = 0, /**< Format unused or unknown */ - OMX_VIDEO_RVFormat8, /**< Real Video format 8 */ - OMX_VIDEO_RVFormat9, /**< Real Video format 9 */ - OMX_VIDEO_RVFormatG2, /**< Real Video Format G2 */ - OMX_VIDEO_RVFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_RVFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_RVFormatMax = 0x7FFFFFFF -} OMX_VIDEO_RVFORMATTYPE; - - -/** - * Real Video Params - * - * STUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * eFormat : Version of RV stream / data - * nBitsPerPixel : Bits per pixel coded in the frame - * nPaddedWidth : Padded width in pixel of a video frame - * nPaddedHeight : Padded Height in pixels of a video frame - * nFrameRate : Rate of video in frames per second - * nBitstreamFlags : Flags which internal information about the bitstream - * nBitstreamVersion : Bitstream version - * nMaxEncodeFrameSize: Max encoded frame size - * bEnablePostFilter : Turn on/off post filter - * bEnableTemporalInterpolation : Turn on/off temporal interpolation - * bEnableLatencyMode : When enabled, the decoder does not display a decoded - * frame until it has detected that no enhancement layer - * frames or dependent B frames will be coming. This - * detection usually occurs when a subsequent non-B - * frame is encountered - */ -typedef struct OMX_VIDEO_PARAM_RVTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_VIDEO_RVFORMATTYPE eFormat; - OMX_U16 nBitsPerPixel; - OMX_U16 nPaddedWidth; - OMX_U16 nPaddedHeight; - OMX_U32 nFrameRate; - OMX_U32 nBitstreamFlags; - OMX_U32 nBitstreamVersion; - OMX_U32 nMaxEncodeFrameSize; - OMX_BOOL bEnablePostFilter; - OMX_BOOL bEnableTemporalInterpolation; - OMX_BOOL bEnableLatencyMode; -} OMX_VIDEO_PARAM_RVTYPE; - - -/** - * AVC profile types, each profile indicates support for various - * performance bounds and different annexes. - */ -typedef enum OMX_VIDEO_AVCPROFILETYPE { - OMX_VIDEO_AVCProfileBaseline = 0x01, /**< Baseline profile */ - OMX_VIDEO_AVCProfileMain = 0x02, /**< Main profile */ - OMX_VIDEO_AVCProfileExtended = 0x04, /**< Extended profile */ - OMX_VIDEO_AVCProfileHigh = 0x08, /**< High profile */ - OMX_VIDEO_AVCProfileHigh10 = 0x10, /**< High 10 profile */ - OMX_VIDEO_AVCProfileHigh422 = 0x20, /**< High 4:2:2 profile */ - OMX_VIDEO_AVCProfileHigh444 = 0x40, /**< High 4:4:4 profile */ - OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_AVCProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_AVCProfileMax = 0x7FFFFFFF -} OMX_VIDEO_AVCPROFILETYPE; - - -/** - * AVC level types, each level indicates support for various frame sizes, - * bit rates, decoder frame rates. No need - */ -typedef enum OMX_VIDEO_AVCLEVELTYPE { - OMX_VIDEO_AVCLevel1 = 0x01, /**< Level 1 */ - OMX_VIDEO_AVCLevel1b = 0x02, /**< Level 1b */ - OMX_VIDEO_AVCLevel11 = 0x04, /**< Level 1.1 */ - OMX_VIDEO_AVCLevel12 = 0x08, /**< Level 1.2 */ - OMX_VIDEO_AVCLevel13 = 0x10, /**< Level 1.3 */ - OMX_VIDEO_AVCLevel2 = 0x20, /**< Level 2 */ - OMX_VIDEO_AVCLevel21 = 0x40, /**< Level 2.1 */ - OMX_VIDEO_AVCLevel22 = 0x80, /**< Level 2.2 */ - OMX_VIDEO_AVCLevel3 = 0x100, /**< Level 3 */ - OMX_VIDEO_AVCLevel31 = 0x200, /**< Level 3.1 */ - OMX_VIDEO_AVCLevel32 = 0x400, /**< Level 3.2 */ - OMX_VIDEO_AVCLevel4 = 0x800, /**< Level 4 */ - OMX_VIDEO_AVCLevel41 = 0x1000, /**< Level 4.1 */ - OMX_VIDEO_AVCLevel42 = 0x2000, /**< Level 4.2 */ - OMX_VIDEO_AVCLevel5 = 0x4000, /**< Level 5 */ - OMX_VIDEO_AVCLevel51 = 0x8000, /**< Level 5.1 */ - OMX_VIDEO_AVCLevel52 = 0x10000, /**< Level 5.2 */ - OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF -} OMX_VIDEO_AVCLEVELTYPE; - - -/** - * AVC loop filter modes - * - * OMX_VIDEO_AVCLoopFilterEnable : Enable - * OMX_VIDEO_AVCLoopFilterDisable : Disable - * OMX_VIDEO_AVCLoopFilterDisableSliceBoundary : Disabled on slice boundaries - */ -typedef enum OMX_VIDEO_AVCLOOPFILTERTYPE { - OMX_VIDEO_AVCLoopFilterEnable = 0, - OMX_VIDEO_AVCLoopFilterDisable, - OMX_VIDEO_AVCLoopFilterDisableSliceBoundary, - OMX_VIDEO_AVCLoopFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_AVCLoopFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_AVCLoopFilterMax = 0x7FFFFFFF -} OMX_VIDEO_AVCLOOPFILTERTYPE; - - -/** - * AVC params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nSliceHeaderSpacing : Number of macroblocks between slice header, put - * zero if not used - * nPFrames : Number of P frames between each I frame - * nBFrames : Number of B frames between each I frame - * bUseHadamard : Enable/disable Hadamard transform - * nRefFrames : Max number of reference frames to use for inter - * motion search (1-16) - * nRefIdxTrailing : Pic param set ref frame index (index into ref - * frame buffer of trailing frames list), B frame - * support - * nRefIdxForward : Pic param set ref frame index (index into ref - * frame buffer of forward frames list), B frame - * support - * bEnableUEP : Enable/disable unequal error protection. This - * is only valid of data partitioning is enabled. - * bEnableFMO : Enable/disable flexible macroblock ordering - * bEnableASO : Enable/disable arbitrary slice ordering - * bEnableRS : Enable/disable sending of redundant slices - * eProfile : AVC profile(s) to use - * eLevel : AVC level(s) to use - * nAllowedPictureTypes : Specifies the picture types allowed in the - * bitstream - * bFrameMBsOnly : specifies that every coded picture of the - * coded video sequence is a coded frame - * containing only frame macroblocks - * bMBAFF : Enable/disable switching between frame and - * field macroblocks within a picture - * bEntropyCodingCABAC : Entropy decoding method to be applied for the - * syntax elements for which two descriptors appear - * in the syntax tables - * bWeightedPPrediction : Enable/disable weighted prediction shall not - * be applied to P and SP slices - * nWeightedBipredicitonMode : Default weighted prediction is applied to B - * slices - * bconstIpred : Enable/disable intra prediction - * bDirect8x8Inference : Specifies the method used in the derivation - * process for luma motion vectors for B_Skip, - * B_Direct_16x16 and B_Direct_8x8 as specified - * in subclause 8.4.1.2 of the AVC spec - * bDirectSpatialTemporal : Flag indicating spatial or temporal direct - * mode used in B slice coding (related to - * bDirect8x8Inference) . Spatial direct mode is - * more common and should be the default. - * nCabacInitIdx : Index used to init CABAC contexts - * eLoopFilterMode : Enable/disable loop filter - */ -typedef struct OMX_VIDEO_PARAM_AVCTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nSliceHeaderSpacing; - OMX_U32 nPFrames; - OMX_U32 nBFrames; - OMX_BOOL bUseHadamard; - OMX_U32 nRefFrames; - OMX_U32 nRefIdx10ActiveMinus1; - OMX_U32 nRefIdx11ActiveMinus1; - OMX_BOOL bEnableUEP; - OMX_BOOL bEnableFMO; - OMX_BOOL bEnableASO; - OMX_BOOL bEnableRS; - OMX_VIDEO_AVCPROFILETYPE eProfile; - OMX_VIDEO_AVCLEVELTYPE eLevel; - OMX_U32 nAllowedPictureTypes; - OMX_BOOL bFrameMBsOnly; - OMX_BOOL bMBAFF; - OMX_BOOL bEntropyCodingCABAC; - OMX_BOOL bWeightedPPrediction; - OMX_U32 nWeightedBipredicitonMode; - OMX_BOOL bconstIpred ; - OMX_BOOL bDirect8x8Inference; - OMX_BOOL bDirectSpatialTemporal; - OMX_U32 nCabacInitIdc; - OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode; -} OMX_VIDEO_PARAM_AVCTYPE; - -typedef struct OMX_VIDEO_PARAM_PROFILELEVELTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 eProfile; /**< type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE, - or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ - OMX_U32 eLevel; /**< type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE, - or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ - OMX_U32 nProfileIndex; /**< Used to query for individual profile support information, - This parameter is valid only for - OMX_IndexParamVideoProfileLevelQuerySupported index, - For all other indices this parameter is to be ignored. */ -} OMX_VIDEO_PARAM_PROFILELEVELTYPE; - -/** - * Structure for dynamically configuring bitrate mode of a codec. - * - * STRUCT MEMBERS: - * nSize : Size of the struct in bytes - * nVersion : OMX spec version info - * nPortIndex : Port that this struct applies to - * nEncodeBitrate : Target average bitrate to be generated in bps - */ -typedef struct OMX_VIDEO_CONFIG_BITRATETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nEncodeBitrate; -} OMX_VIDEO_CONFIG_BITRATETYPE; - -/** - * Defines Encoder Frame Rate setting - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * xEncodeFramerate : Encoding framerate represented in Q16 format - */ -typedef struct OMX_CONFIG_FRAMERATETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 xEncodeFramerate; /* Q16 format */ -} OMX_CONFIG_FRAMERATETYPE; - -typedef struct OMX_CONFIG_INTRAREFRESHVOPTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL IntraRefreshVOP; -} OMX_CONFIG_INTRAREFRESHVOPTYPE; - -typedef struct OMX_CONFIG_MACROBLOCKERRORMAPTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nErrMapSize; /* Size of the Error Map in bytes */ - OMX_U8 ErrMap[1]; /* Error map hint */ -} OMX_CONFIG_MACROBLOCKERRORMAPTYPE; - -typedef struct OMX_CONFIG_MBERRORREPORTINGTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bEnabled; -} OMX_CONFIG_MBERRORREPORTINGTYPE; - -typedef struct OMX_PARAM_MACROBLOCKSTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nMacroblocks; -} OMX_PARAM_MACROBLOCKSTYPE; - -/** - * AVC Slice Mode modes - * - * OMX_VIDEO_SLICEMODE_AVCDefault : Normal frame encoding, one slice per frame - * OMX_VIDEO_SLICEMODE_AVCMBSlice : NAL mode, number of MBs per frame - * OMX_VIDEO_SLICEMODE_AVCByteSlice : NAL mode, number of bytes per frame - */ -typedef enum OMX_VIDEO_AVCSLICEMODETYPE { - OMX_VIDEO_SLICEMODE_AVCDefault = 0, - OMX_VIDEO_SLICEMODE_AVCMBSlice, - OMX_VIDEO_SLICEMODE_AVCByteSlice, - OMX_VIDEO_SLICEMODE_AVCKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_VIDEO_SLICEMODE_AVCVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_VIDEO_SLICEMODE_AVCLevelMax = 0x7FFFFFFF -} OMX_VIDEO_AVCSLICEMODETYPE; - -/** - * AVC FMO Slice Mode Params - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nNumSliceGroups : Specifies the number of slice groups - * nSliceGroupMapType : Specifies the type of slice groups - * eSliceMode : Specifies the type of slice - */ -typedef struct OMX_VIDEO_PARAM_AVCSLICEFMO { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U8 nNumSliceGroups; - OMX_U8 nSliceGroupMapType; - OMX_VIDEO_AVCSLICEMODETYPE eSliceMode; -} OMX_VIDEO_PARAM_AVCSLICEFMO; - -/** - * AVC IDR Period Configs - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nIDRPeriod : Specifies periodicity of IDR frames - * nPFrames : Specifies internal of coding Intra frames - */ -typedef struct OMX_VIDEO_CONFIG_AVCINTRAPERIOD { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nIDRPeriod; - OMX_U32 nPFrames; -} OMX_VIDEO_CONFIG_AVCINTRAPERIOD; - -/** - * AVC NAL Size Configs - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nNaluBytes : Specifies the NAL unit size - */ -typedef struct OMX_VIDEO_CONFIG_NALSIZE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nNaluBytes; -} OMX_VIDEO_CONFIG_NALSIZE; - - -/** - * Deinterlace Config - * - * STRUCT MEMBERS: - * nSize : Size of the structure in bytes - * nVersion : OMX specification version information - * nPortIndex : Port that this structure applies to - * nEnable : Specifies to enable deinterlace - */ -typedef struct OMX_VIDEO_CONFIG_DEINTERLACE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_U32 nEnable; -} OMX_VIDEO_CONFIG_DEINTERLACE; - -/** @} */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -/* File EOF */ - diff --git a/third_party/openmax/include/OMX_VideoExt.h b/third_party/openmax/include/OMX_VideoExt.h deleted file mode 100644 index 5bf6fd4878..0000000000 --- a/third_party/openmax/include/OMX_VideoExt.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2010 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** OMX_VideoExt.h - OpenMax IL version 1.1.2 - * The OMX_VideoExt header file contains extensions to the - * definitions used by both the application and the component to - * access video items. - */ - -#ifndef OMX_VideoExt_h -#define OMX_VideoExt_h - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Each OMX header shall include all required header files to allow the - * header to compile without errors. The includes below are required - * for this header file to compile successfully - */ -#include - -/** NALU Formats */ -typedef enum OMX_NALUFORMATSTYPE { - OMX_NaluFormatStartCodes = 1, - OMX_NaluFormatOneNaluPerBuffer = 2, - OMX_NaluFormatOneByteInterleaveLength = 4, - OMX_NaluFormatTwoByteInterleaveLength = 8, - OMX_NaluFormatFourByteInterleaveLength = 16, - OMX_NaluFormatCodingMax = 0x7FFFFFFF -} OMX_NALUFORMATSTYPE; - -/** NAL Stream Format */ -typedef struct OMX_NALSTREAMFORMATTYPE{ - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_NALUFORMATSTYPE eNaluFormat; -} OMX_NALSTREAMFORMATTYPE; - -/** VP8 profiles */ -typedef enum OMX_VIDEO_VP8PROFILETYPE { - OMX_VIDEO_VP8ProfileMain = 0x01, - OMX_VIDEO_VP8ProfileUnknown = 0x6EFFFFFF, - OMX_VIDEO_VP8ProfileMax = 0x7FFFFFFF -} OMX_VIDEO_VP8PROFILETYPE; - -/** VP8 levels */ -typedef enum OMX_VIDEO_VP8LEVELTYPE { - OMX_VIDEO_VP8Level_Version0 = 0x01, - OMX_VIDEO_VP8Level_Version1 = 0x02, - OMX_VIDEO_VP8Level_Version2 = 0x04, - OMX_VIDEO_VP8Level_Version3 = 0x08, - OMX_VIDEO_VP8LevelUnknown = 0x6EFFFFFF, - OMX_VIDEO_VP8LevelMax = 0x7FFFFFFF -} OMX_VIDEO_VP8LEVELTYPE; - -/** VP8 Param */ -typedef struct OMX_VIDEO_PARAM_VP8TYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_VIDEO_VP8PROFILETYPE eProfile; - OMX_VIDEO_VP8LEVELTYPE eLevel; - OMX_U32 nDCTPartitions; - OMX_BOOL bErrorResilientMode; -} OMX_VIDEO_PARAM_VP8TYPE; - -/** Structure for configuring VP8 reference frames */ -typedef struct OMX_VIDEO_VP8REFERENCEFRAMETYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bPreviousFrameRefresh; - OMX_BOOL bGoldenFrameRefresh; - OMX_BOOL bAlternateFrameRefresh; - OMX_BOOL bUsePreviousFrame; - OMX_BOOL bUseGoldenFrame; - OMX_BOOL bUseAlternateFrame; -} OMX_VIDEO_VP8REFERENCEFRAMETYPE; - -/** Structure for querying VP8 reference frame type */ -typedef struct OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_BOOL bIsIntraFrame; - OMX_BOOL bIsGoldenOrAlternateFrame; -} OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE; - -/** HEVC Profiles */ -typedef enum OMX_VIDEO_HEVCPROFILETYPE { - OMX_VIDEO_HEVCProfileMain = 0x01, - OMX_VIDEO_HEVCProfileMain10 = 0x02, - OMX_VIDEO_HEVCProfileUnknown = 0x6EFFFFFF, - OMX_VIDEO_HEVCProfileMax = 0x7FFFFFFF -} OMX_VIDEO_HEVCPROFILETYPE; - -/** HEVC levels */ -typedef enum OMX_VIDEO_HEVCLEVELTYPE { - OMX_VIDEO_HEVCLevel_Version0 = 0x0, - OMX_VIDEO_HEVCMainTierLevel1 = 0x1, - OMX_VIDEO_HEVCHighTierLevel1 = 0x2, - OMX_VIDEO_HEVCMainTierLevel2 = 0x4, - OMX_VIDEO_HEVCHighTierLevel2 = 0x8, - OMX_VIDEO_HEVCMainTierLevel21 = 0x10, - OMX_VIDEO_HEVCHighTierLevel21 = 0x20, - OMX_VIDEO_HEVCMainTierLevel3 = 0x40, - OMX_VIDEO_HEVCHighTierLevel3 = 0x80, - OMX_VIDEO_HEVCMainTierLevel31 = 0x100, - OMX_VIDEO_HEVCHighTierLevel31 = 0x200, - OMX_VIDEO_HEVCMainTierLevel4 = 0x400, - OMX_VIDEO_HEVCHighTierLevel4 = 0x800, - OMX_VIDEO_HEVCMainTierLevel41 = 0x1000, - OMX_VIDEO_HEVCHighTierLevel41 = 0x2000, - OMX_VIDEO_HEVCMainTierLevel5 = 0x4000, - OMX_VIDEO_HEVCHighTierLevel5 = 0x8000, - OMX_VIDEO_HEVCMainTierLevel51 = 0x10000, - OMX_VIDEO_HEVCHighTierLevel51 = 0x20000, - OMX_VIDEO_HEVCMainTierLevel52 = 0x40000, - OMX_VIDEO_HEVCHighTierLevel52 = 0x80000, - OMX_VIDEO_HEVCMainTierLevel6 = 0x100000, - OMX_VIDEO_HEVCHighTierLevel6 = 0x200000, - OMX_VIDEO_HEVCMainTierLevel61 = 0x400000, - OMX_VIDEO_HEVCHighTierLevel61 = 0x800000, - OMX_VIDEO_HEVCMainTierLevel62 = 0x1000000, - OMX_VIDEO_HEVCLevelUnknown = 0x6EFFFFFF, - OMX_VIDEO_HEVCLevelMax = 0x7FFFFFFF -} OMX_VIDEO_HEVCLEVELTYPE; - -/** HEVC Param */ -typedef struct OMX_VIDEO_PARAM_HEVCTYPE { - OMX_U32 nSize; - OMX_VERSIONTYPE nVersion; - OMX_U32 nPortIndex; - OMX_VIDEO_HEVCPROFILETYPE eProfile; - OMX_VIDEO_HEVCLEVELTYPE eLevel; -} OMX_VIDEO_PARAM_HEVCTYPE; - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* OMX_VideoExt_h */ -/* File EOF */ diff --git a/third_party/qt-plugins/build_qtlocation.sh b/third_party/qt-plugins/build_qtlocation.sh deleted file mode 100755 index 09e6182d1f..0000000000 --- a/third_party/qt-plugins/build_qtlocation.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env sh - -# Qtlocation plugin with extra fields parsed from api response -cd /tmp -git clone https://github.com/commaai/qtlocation.git -cd qtlocation -qmake -make -j$(nproc) diff --git a/third_party/qt-plugins/x86_64/geoservices/.gitattributes b/third_party/qt-plugins/x86_64/geoservices/.gitattributes deleted file mode 100644 index 51b1d333fe..0000000000 --- a/third_party/qt-plugins/x86_64/geoservices/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -libqtgeoservices_mapbox.so filter=lfs diff=lfs merge=lfs -text diff --git a/third_party/qt-plugins/x86_64/geoservices/libqtgeoservices_mapbox.so b/third_party/qt-plugins/x86_64/geoservices/libqtgeoservices_mapbox.so deleted file mode 100755 index 375fc0e012..0000000000 --- a/third_party/qt-plugins/x86_64/geoservices/libqtgeoservices_mapbox.so +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5c8bda321dc524e753f67823cb5353358e756cfc1c5328e22e32920e80dd9e9b -size 12166248 diff --git a/tools/camerastream/compressed_vipc.py b/tools/camerastream/compressed_vipc.py index 040c2e18f0..290610e45f 100755 --- a/tools/camerastream/compressed_vipc.py +++ b/tools/camerastream/compressed_vipc.py @@ -1,118 +1,104 @@ #!/usr/bin/env python3 +import av import os import sys +import argparse import numpy as np import multiprocessing +import time -from cereal.visionipc.visionipc_pyx import VisionIpcServer, VisionStreamType # pylint: disable=no-name-in-module, import-error -W, H = 1928, 1208 +import cereal.messaging as messaging +from cereal.visionipc import VisionIpcServer, VisionStreamType +W, H = 1928, 1208 V4L2_BUF_FLAG_KEYFRAME = 8 -def writer(fn, addr, sock_name): - import cereal.messaging as messaging - HEADER = b"\x00\x00\x00\x01\x40\x01\x0c\x01\xff\xff\x01\x60\x00\x00\x03\x00\xb0\x00\x00\x03\x00\x00\x03\x00\x96\xac\x09\x00\x00\x00\x01\x42\x01\x01\x01\x60\x00\x00\x03\x00\xb0\x00\x00\x03\x00\x00\x03\x00\x96\xa0\x03\xd0\x80\x13\x07\x1b\x2e\x5a\xee\x4c\x92\xea\x00\xbb\x42\x84\xa0\x00\x00\x00\x01\x44\x01\xc0\xe2\x4f\x09\xc1\x80\xc6\x08\x40\x00" - fifo_file = open(fn, "wb") - fifo_file.write(HEADER) - fifo_file.flush() +def decoder(addr, sock_name, vipc_server, vst, nvidia): + print("start decoder for %s" % sock_name) + if nvidia: + os.environ["NV_LOW_LATENCY"] = "3" # both bLowLatency and CUVID_PKT_ENDOFPICTURE + sys.path += os.environ["LD_LIBRARY_PATH"].split(":") + import PyNvCodec as nvc # pylint: disable=import-error + + nvDec = nvc.PyNvDecoder(W, H, nvc.PixelFormat.NV12, nvc.CudaVideoCodec.HEVC, 0) + cc1 = nvc.ColorspaceConversionContext(nvc.ColorSpace.BT_709, nvc.ColorRange.JPEG) + conv_yuv = nvc.PySurfaceConverter(W, H, nvc.PixelFormat.NV12, nvc.PixelFormat.YUV420, 0) + nvDwn_yuv = nvc.PySurfaceDownloader(W, H, nvc.PixelFormat.YUV420, 0) + img_yuv = np.ndarray((H*W//2*3), dtype=np.uint8) + else: + codec = av.CodecContext.create("hevc", "r") os.environ["ZMQ"] = "1" messaging.context = messaging.Context() - sock = messaging.sub_sock(sock_name, None, addr=addr, conflate=False) + cnt = 0 last_idx = -1 seen_iframe = False + + time_q = [] while 1: msgs = messaging.drain_sock(sock, wait_for_one=True) for evt in msgs: evta = getattr(evt, evt.which()) - lat = ((evt.logMonoTime/1e9) - (evta.timestampEof/1e6))*1000 - print("%2d %4d %.3f %.3f latency %.2f ms" % (len(msgs), evta.idx, evt.logMonoTime/1e9, evta.timestampEof/1e6, lat), len(evta.data), sock_name) - if evta.idx != 0 and evta.idx != (last_idx+1): - print("DROP!") - last_idx = evta.idx - if evta.flags & V4L2_BUF_FLAG_KEYFRAME or evta.flags == 0x7f001030: - seen_iframe = True - if not seen_iframe: + if evta.idx.encodeId != 0 and evta.idx.encodeId != (last_idx+1): + print("DROP PACKET!") + last_idx = evta.idx.encodeId + if not seen_iframe and not (evta.idx.flags & V4L2_BUF_FLAG_KEYFRAME): print("waiting for iframe") continue - fifo_file.write(evta.data) - fifo_file.flush() + time_q.append(time.monotonic()) + network_latency = (int(time.time()*1e9) - evta.unixTimestampNanos)/1e6 + frame_latency = ((evta.idx.timestampEof/1e9) - (evta.idx.timestampSof/1e9))*1000 + process_latency = ((evt.logMonoTime/1e9) - (evta.idx.timestampEof/1e9))*1000 -def decoder_nvidia(fn, vipc_server, vst, yuv=True, rgb=False): - sys.path.append("/raid.dell2/PyNvCodec") - import PyNvCodec as nvc # pylint: disable=import-error - decoder = nvc.PyNvDecoder(fn, 0, {"probesize": "32"}) - cc1 = nvc.ColorspaceConversionContext(nvc.ColorSpace.BT_709, nvc.ColorRange.JPEG) + # put in header (first) + if not seen_iframe: + if nvidia: + nvDec.DecodeSurfaceFromPacket(np.frombuffer(evta.header, dtype=np.uint8)) + else: + codec.decode(av.packet.Packet(evta.header)) + seen_iframe = True - if rgb: - conv = nvc.PySurfaceConverter(W, H, nvc.PixelFormat.NV12, nvc.PixelFormat.BGR, 0) - nvDwn = nvc.PySurfaceDownloader(W, H, nvc.PixelFormat.BGR, 0) - img = np.ndarray((H,W,3), dtype=np.uint8) + if nvidia: + rawSurface = nvDec.DecodeSurfaceFromPacket(np.frombuffer(evta.data, dtype=np.uint8)) + if rawSurface.Empty(): + print("DROP SURFACE") + continue + convSurface = conv_yuv.Execute(rawSurface, cc1) + nvDwn_yuv.DownloadSingleSurface(convSurface, img_yuv) + else: + frames = codec.decode(av.packet.Packet(evta.data)) + if len(frames) == 0: + print("DROP SURFACE") + continue + assert len(frames) == 1 + img_yuv = frames[0].to_ndarray(format=av.video.format.VideoFormat('yuv420p')).flatten() - if yuv: - conv_yuv = nvc.PySurfaceConverter(W, H, nvc.PixelFormat.NV12, nvc.PixelFormat.YUV420, 0) - nvDwn_yuv = nvc.PySurfaceDownloader(W, H, nvc.PixelFormat.YUV420, 0) - img_yuv = np.ndarray((H*W//2*3), dtype=np.uint8) + vipc_server.send(vst, img_yuv.data, cnt, int(time_q[0]*1e9), int(time.monotonic()*1e9)) + cnt += 1 - cnt = 0 - while 1: - rawSurface = decoder.DecodeSingleSurface() - if rawSurface.Empty(): - continue - if rgb: - convSurface = conv.Execute(rawSurface, cc1) - nvDwn.DownloadSingleSurface(convSurface, img) - vipc_server.send(vst, img.flatten().data, cnt, 0, 0) - if yuv: - convSurface = conv_yuv.Execute(rawSurface, cc1) - nvDwn_yuv.DownloadSingleSurface(convSurface, img_yuv) - vipc_server.send(vst+3, img_yuv.flatten().data, cnt, 0, 0) - cnt += 1 + pc_latency = (time.monotonic()-time_q[0])*1000 + time_q = time_q[1:] + print("%2d %4d %.3f %.3f roll %6.2f ms latency %6.2f ms + %6.2f ms + %6.2f ms = %6.2f ms" % (len(msgs), evta.idx.encodeId, evt.logMonoTime/1e9, evta.idx.timestampEof/1e6, frame_latency, process_latency, network_latency, pc_latency, process_latency+network_latency+pc_latency ), len(evta.data), sock_name) -def decoder_ffmpeg(fn, vipc_server, vst, yuv=True, rgb=False): - import av # pylint: disable=import-error - container = av.open(fn, options={"probesize": "32"}) - cnt = 0 - for frame in container.decode(video=0): - if rgb: - img = frame.to_ndarray(format=av.video.format.VideoFormat('bgr24')) - vipc_server.send(vst, img.flatten().data, cnt, 0, 0) - if yuv: - img_yuv = frame.to_ndarray(format=av.video.format.VideoFormat('yuv420p')) - vipc_server.send(vst+3, img_yuv.flatten().data, cnt, 0, 0) - cnt += 1 - -import argparse if __name__ == "__main__": - parser = argparse.ArgumentParser(description='Decode video streams and broacast on VisionIPC') - parser.add_argument("addr", help="Address of comma 3") - parser.add_argument('--nvidia', action='store_true', help='Use nvidia instead of ffmpeg') - parser.add_argument('--rgb', action='store_true', help='Also broadcast RGB') + parser = argparse.ArgumentParser(description="Decode video streams and broacast on VisionIPC") + parser.add_argument("addr", help="Address of comma three") + parser.add_argument("--nvidia", action="store_true", help="Use nvidia instead of ffmpeg") parser.add_argument("--cams", default="0,1,2", help="Cameras to decode") args = parser.parse_args() all_cams = [ - ("roadEncodeData", VisionStreamType.VISION_STREAM_RGB_ROAD), - ("wideRoadEncodeData", VisionStreamType.VISION_STREAM_RGB_WIDE_ROAD), - ("driverEncodeData", VisionStreamType.VISION_STREAM_RGB_DRIVER), + ("roadEncodeData", VisionStreamType.VISION_STREAM_ROAD), + ("wideRoadEncodeData", VisionStreamType.VISION_STREAM_WIDE_ROAD), + ("driverEncodeData", VisionStreamType.VISION_STREAM_DRIVER), ] cams = dict([all_cams[int(x)] for x in args.cams.split(",")]) vipc_server = VisionIpcServer("camerad") for vst in cams.values(): - if args.rgb: - vipc_server.create_buffers(vst, 4, True, W, H) - vipc_server.create_buffers(vst+3, 4, False, W, H) + vipc_server.create_buffers(vst, 4, False, W, H) vipc_server.start_listener() for k,v in cams.items(): - FIFO_NAME = "/tmp/decodepipe_"+k - if os.path.exists(FIFO_NAME): - os.unlink(FIFO_NAME) - os.mkfifo(FIFO_NAME) - multiprocessing.Process(target=writer, args=(FIFO_NAME, sys.argv[1], k)).start() - if args.nvidia: - multiprocessing.Process(target=decoder_nvidia, args=(FIFO_NAME, vipc_server, v, True, args.rgb)).start() - else: - multiprocessing.Process(target=decoder_ffmpeg, args=(FIFO_NAME, vipc_server, v, True, args.rgb)).start() + multiprocessing.Process(target=decoder, args=(args.addr, k, vipc_server, v, args.nvidia)).start() diff --git a/tools/joystick/README.md b/tools/joystick/README.md index 5a45785db6..c74e51146c 100644 --- a/tools/joystick/README.md +++ b/tools/joystick/README.md @@ -45,6 +45,17 @@ In order to use a joystick over the network, we need to run joystickd locally fr tools/joystick/joystickd.py ``` +### Web joystick on your mobile device + +A browser-based virtual joystick designed for touch screens. Starts automatically when installed on comma body (non-car robotics platform). +For cars, start the web joystick service manually via SSH before starting the car. + +```shell +tools/joystick/web.py +``` + +After starting the car/body, open the web joystick app at this URL: `http://[comma three IP address]:5000` + --- Now start your car and openpilot should go into joystick mode with an alert on startup! The status of the axes will display on the alert, while button statuses print in the shell. diff --git a/tools/joystick/web.py b/tools/joystick/web.py index 5db48eea24..5cba4e938d 100755 --- a/tools/joystick/web.py +++ b/tools/joystick/web.py @@ -16,11 +16,24 @@ index = """