immich-app / immich

High performance self-hosted photo and video management solution.
https://immich.app
GNU Affero General Public License v3.0
38.87k stars 1.84k forks source link

Max bitrate setting is not working #10544

Open Goodwu opened 1 week ago

Goodwu commented 1 week ago

The bug

This is the setting: image This is the output video file: image The original file format is MTS. And I see the ffmpeg command line, it's just copy the video stream instead of transcoding.

The OS that Immich Server is running on

OMV7

Version of Immich Server

v1.106.4

Version of Immich Mobile App

v1.106.4

Platform with the issue

Your docker-compose.yml content

#
# WARNING: Make sure to use the docker-compose.yml of the current release:
#
# https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
#
# The compose file on main may not be compatible with the latest release.
#

name: immich

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    extends:
      file: hwaccel.transcoding.yml
      service: quicksync # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
      - ${EXT_LOCATION}:/media/photos
    env_file:
      - .env
    ports:
      - 2283:3001
    depends_on:
      - redis
      - database
    restart: always

  immich-machine-learning:
    container_name: immich_machine_learning
    # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag.
    # Example tag: ${IMMICH_VERSION:-release}-cuda
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
    # extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration
    #   file: hwaccel.ml.yml
    #   service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable
    volumes:
      - model-cache:/cache
    env_file:
      - .env
    restart: always

  redis:
    container_name: immich_redis
    image: redis:6.2-alpine@sha256:d6c2911ac51b289db208767581a5d154544f2b2fe4914ea5056443f62dc6e900
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
    volumes:
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    healthcheck:
      test: pg_isready --dbname='${DB_DATABASE_NAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT SUM(checksum_failures) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1
      interval: 5m
      start_interval: 30s
      start_period: 5m
    command: ["postgres", "-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
    restart: always

volumes:
  model-cache:

Your .env content

# You can find documentation for all the supported env variables at https://immich.app/docs/install/environment-variables

# The location where your uploaded files are stored
UPLOAD_LOCATION=./library
# The location where your database files are stored
DB_DATA_LOCATION=./postgres

# The Immich version to use. You can pin this to a specific version like "v1.71.0"
IMMICH_VERSION=release

# Connection secret for postgres. You should change it to a random password
DB_PASSWORD=postgres

EXT_LOCATION=/srv/dev-disk-by-uuid-2bf642cf-adb7-4ec8-9291-13bc77208fb0/store/WuStor_1/photo

# The values below this line do not need to be changed
###################################################################################
DB_USERNAME=postgres
DB_DATABASE_NAME=immich

Reproduction steps

1. Video file format MTS, max bit rate exceed the settings value.
2. Transcode.
3. The output file video track is copied instead of transcoded.
...

Relevant log output

No response

Additional information

No response

AngelaDMerkel commented 1 week ago

This seems correct to me. The unit is different in each of those. You requested 4000 Kilobytes and are getting results in Megabits which are a different unit. 4000 Kilobytes is 32 Megabits and you are well within that range based on what you've shown us.

Bits v Bytes

Goodwu commented 1 week ago

This seems correct to me. The unit is different in each of those. You requested 4000 Kilobytes and are getting results in Megabits which are a different unit. 4000 Kilobytes is 32 Megabits and you are well within that range based on what you've shown us.

Bits v Bytes

This setting is for "max bitrate". So the unit should be kilo bit. And this setting also appear at ffmpeg command line: /usr/bin/ffmpeg -hwaccel qsv -hwaccel_output_format qsv -async_depth 4 -threads 1 -i /media/photos/xxx.mp4 -y -c:v h264_qsv -c:a aac -movflags faststart -fps_mode passthrough -map 0:1 -map 0:0 -bf 7 -refs 5 -g 256 -v verbose -vf scale_qsv=-1:720:async_depth=4:mode=hq:format=nv12 -preset 1 -global_quality:v 5 -maxrate 4000k -bufsize 8000k xxx.mp4 The ffmpeg manual also indicate the unit is kilo bit. I add -b:v 1000k argument to ffmpeg command line and calculate the bitrate of output file, it shows 1000k is 1000kilo bit. It's not reasonable that the unit of -b:v is different from -maxrate in the single command line. So I request for 4000kilo bits here and immich also treat it as 4000 kilo bits on ffmpeg command line but treat it as 4000 kilo bytes on examing the orinal video file?

AngelaDMerkel commented 4 days ago

There are two things that could be causing this problem:

  1. The final bitrate is including the aac which you are not transcoding into something smaller like opus
  2. QSV isn't compliant with all the filters and other flags you've set and is misbehaving. I don't have access to anything with QSV enable and generally don't use quicksync so I can't test this on my machine either. Sorry.

I have always had problems with NVENC and more complex transcodes and just don't bother. Also, I understand that ffmpeg likes two pass encoding to achieve a desired max bitrate.

AngelaDMerkel commented 2 days ago

I have taken a quick look at some of the documentation and there is no mention of support for ffmpeg filters in QSV but the ffmpeg wiki seems like it should include support for scaling and most of the other filters you are using.