Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android app crashes on HEVC 10-bit video playback #15014

Open
1 of 3 tasks
witchcraftsman opened this issue Jan 1, 2025 · 17 comments
Open
1 of 3 tasks

Android app crashes on HEVC 10-bit video playback #15014

witchcraftsman opened this issue Jan 1, 2025 · 17 comments

Comments

@witchcraftsman
Copy link

The bug

Android app crashes on HEVC 10-bit video playback, after a couple of tries Android suggests to clean app cache but it doesn't help.
The same video on web app plays ok.

The OS that Immich Server is running on

Ubuntu 22.04.5

Version of Immich Server

v1.123.0

Version of Immich Mobile App

v1.123.0

Platform with the issue

  • Server
  • Web
  • Mobile

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}
    user: "www-data"
    # extends:
    #   file: hwaccel.transcoding.yml
    #   service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
    volumes:
      # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - #plus some external mounts mounted in /mnt/media/..
      #- /etc/localtime:/etc/localtime:ro
    env_file:
      - .env
    ports:
      - '2283:2283'
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      disable: false

  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}-cuda
    #user: "www-data"
    user: "root"
    extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration
      file: hwaccel.ml.yml
      service: cuda # 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
    healthcheck:
      disable: false

  redis:
    container_name: immich_redis
    image: docker.io/redis:6.2-alpine@sha256:2ba50e1ac3a0ea17b736ce9db2b0a9f6f8b85d4c27d5f5accc6a416d8f42c6d5
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: docker.io/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:
      # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    healthcheck:
      test: pg_isready --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT COALESCE(SUM(checksum_failures), 0) 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=########### some external mount 
# The location where your database files are stored
DB_DATA_LOCATION=./postgres

# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
TZ=Europe/Amsterdam

# 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
# Please use only the characters `A-Za-z0-9`, without special characters or spaces
DB_PASSWORD=#########

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

NVIDIA_VISIBLE_DEVICES=all

Reproduction steps

  1. Upload some video with properties similar to defined in Additional information
  2. Open Immich app (for Android) and tap on the uploaded video
  3. Notice the app crashes (with no error description)

Relevant log output

No response

Additional information

Android version: Android 14 (OneUI, Samsung S23 Ultra)
Properties of the video that causes Android app crashing:
Screenshot 2025-01-01 at 17 06 50

@bo0tzz
Copy link
Member

bo0tzz commented Jan 1, 2025

Have you changed any of the transcoding settings in Immich?

@witchcraftsman
Copy link
Author

witchcraftsman commented Jan 1, 2025

Have you changed any of the transcoding settings in Immich?

No
Transcode policy:
Screenshot 2025-01-01 at 19 54 36

@tye-mustafa
Copy link

tye-mustafa commented Jan 1, 2025

Have you changed any of the transcoding settings in Immich?

No Transcode policy: Screenshot 2025-01-01 at 19 54 36

This includes all transcode settings not just policy

@pretubedongit
Copy link

I can confirm this is happening. Android app crashes every time for these certain videos.

@EssGeeEich
Copy link

EssGeeEich commented Jan 4, 2025

NOTE: The comment below reflects a different issue (#14945), and I'm only leaving it as a reference for other users that might end up here for a different issue altogether (I have firstly stumbled upon this issue trying to play an old HDR video that I didn't have locally)

Can confirm, S22 Ultra, same behavior, HOWEVER this seems to happen with all the videos I take, not just HDR, and it doesn't seem to be related to HEVC either.

I'd like to ask if this behavior seems to happen for you guys too.

On the web, the videos play fine.

Locally stored videos play fine, but as soon as I remove the local copy and try to play the same video from the server, the app crashes.

Logs don't help as nothing is transcribed, not even in regards to the video being opened, transferred, or accessed at all... maybe the Finest log level should display these operations.

On a side note, I have nginx as a reverse proxy in the middle, and apparently cannot download any file from the app. I'm wondering if others have the same setup and/or issues, maybe there is some correlation there.

The nginx logs don't see anything being accessed from the app at all, not during a video stream request, nor when I try to download a file...

I don't believe that transcode settings should have much of an impact here, seeing as how the videos play fine from the web app.

@bo0tzz
Copy link
Member

bo0tzz commented Jan 4, 2025

Locally stored videos play fine, but as soon as I remove the local copy and try to play the same video from the server, the app crashes.

This is a different bug, where the app tries to play the local file (which no longer exists).

I don't believe that transcode settings should have much of an impact here, seeing as how the videos play fine from the web app.

The web and the mobile app don't have identical support for video formats, so yes the transcode settings do have an impact.

@tye-mustafa
Copy link

actually i have nearly 4 phones, only one phone app crashes: rest are ok dont know what to do! tried re encoding to different setting but problem is same

@EssGeeEich
Copy link

This is a different bug, where the app tries to play the local file (which no longer exists).

Yup, sorry, I just realized this. I'm editing the original comment to reflect that.

@pretubedongit
Copy link

I have an iPhone 14 and a Xiaomi phone connected to the same immich server. iPhone never had crashing issue playing the videos. Xiaomi always crashes.

@eduardmolnar
Copy link

This is the relevant log output on GrapheneOS 15 (Pixel 7a) when trying to view an online-only video. Latest immich version (1.123.0) on both server and android.

01-05 01:27:17.616  8852  8852 W InteractionJankMonitor: Initializing without READ_DEVICE_CONFIG permission. enabled=false, interval=1, missedFrameThreshold=3, frameTimeThreshold=64, package=app.alextran.immich
--------- switch to events
01-05 01:27:17.616  8852  9062 I jank_cuj_events_begin_request: [CUJ Type=81,Unix Time Ns=1736040437616815s,Elapsed Time Ns=1903850576.597s,Uptime Ns=721255784.816s,Tag=1@[email protected]]
01-05 01:27:17.624  8852  9062 I jank_cuj_events_end_request: [CUJ Type=81,Unix Time Ns=1736040437624291s,Elapsed Time Ns=1903858049.904s,Uptime Time Ns=721263257.513s]
--------- switch to main
01-05 01:27:17.631  8852  8852 W WindowOnBackDispatcher: OnBackInvokedCallback is not enabled for the application.
01-05 01:27:17.631  8852  8852 W WindowOnBackDispatcher: Set 'android:enableOnBackInvokedCallback="true"' in the application manifest.
01-05 01:27:17.667  8852  8852 I ExoPlayerImpl: Init 8d8cf1b [AndroidXMedia3/1.5.0] [lynx, Pixel 7a, Google, 35]
01-05 01:27:17.710  8852  9068 D CompatChangeReporter: Compat change id reported: 312399441; UID 10184; state: ENABLED
01-05 01:27:17.862  8852  9068 D TrafficStats: tagSocket(160) with statsTag=0xffffffff, statsUid=-1
01-05 01:27:17.913  8852  9068 D TrafficStats: tagSocket(132) with statsTag=0xffffffff, statsUid=-1
--------- switch to events
01-05 01:27:17.939  8852  8852 I surfaceview_layout: [window=SV[42459521 MainActivity],format=4,width=1079,height=607,z=-2,sizeFrom=layout,attached=1,lifecycleStrategy=0,viewVisible=1]
01-05 01:27:17.941  8852  8852 I surfaceview_callback: [window=SV[42459521 MainActivity],callback=surfaceCreated]
01-05 01:27:17.942  8852  8852 I surfaceview_callback: [window=SV[42459521 MainActivity],callback=surfaceChanged -- format=4 w=1079 h=607]
01-05 01:27:17.942  8852  8852 I surfaceview_callback: [window=SV[42459521 MainActivity],callback=surfaceRedrawNeeded]
--------- switch to main
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal: Playback error
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:   k0.C: Source error
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at k0.w0.L(Unknown Source:16)
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at k0.w0.handleMessage(Unknown Source:322)
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at android.os.Handler.dispatchMessage(Handler.java:105)
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at android.os.Looper.loopOnce(Looper.java:232)
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at android.os.Looper.loop(Looper.java:317)
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at android.os.HandlerThread.run(HandlerThread.java:85)
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:   Caused by: i0.s: Response code: 403
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at i0.l.f(Unknown Source:260)
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at i0.w.f(Unknown Source:12)
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at r0.U$b.b(Unknown Source:25)
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at u0.k$d.run(Unknown Source:45)
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
01-05 01:27:21.364  8852  9067 E ExoPlayerImplInternal:       at java.lang.Thread.run(Thread.java:1117)
01-05 01:27:21.383  8852  8852 D AndroidRuntime: Shutting down VM
--------- switch to crash
01-05 01:27:21.384  8852  8852 E AndroidRuntime: FATAL EXCEPTION: main
01-05 01:27:21.384  8852  8852 E AndroidRuntime: Process: app.alextran.immich, PID: 8852
01-05 01:27:21.384  8852  8852 E AndroidRuntime: java.lang.ClassCastException: i0.s cannot be cast to java.lang.Error
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at k5.b.b0(Unknown Source:35)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at k0.i0.C1(Unknown Source:2)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at k0.i0.c0(Unknown Source:0)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at k0.g0.b(Unknown Source:4)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at g0.n$c.a(Unknown Source:17)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at g0.n.h(Unknown Source:16)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at g0.n.a(Unknown Source:0)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at g0.m.run(Unknown Source:6)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at g0.n.f(Unknown Source:67)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at k0.i0.f2(Unknown Source:422)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at k0.i0.n1(Unknown Source:192)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at k0.i0.s1(Unknown Source:0)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at k0.i0.m0(Unknown Source:0)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at k0.Y.run(Unknown Source:4)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at android.os.Handler.handleCallback(Handler.java:991)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:102)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at android.os.Looper.loopOnce(Looper.java:232)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:317)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:8826)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:591)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at com.android.internal.os.ExecInit.main(ExecInit.java:50)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
01-05 01:27:21.384  8852  8852 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:369)
--------- switch to main
01-05 01:27:21.394  8852  8852 I Process : Sending signal. PID: 8852 SIG: 9

@witchcraftsman
Copy link
Author

witchcraftsman commented Jan 6, 2025

This includes all transcode settings not just policy

As I said - no, I was not able to make a screenshot of all the settings, but I assure you I didn't change anything.
Later I tried to change some of them, but to no success

@ckuyehar
Copy link

ckuyehar commented Jan 8, 2025

_Can confirm, S22 Ultra, same behavior, HOWEVER this seems to happen with all the videos I take, not just HDR, and it doesn't seem to be related to HEVC either.

On the web, the videos play fine.

Pixel 9 here... I also experience video crashing using the android app v1.123.0 build.172

On a side note, I have nginx as a reverse proxy in the middle, and apparently cannot download any file from the app.

Great news... I also have a reverse proxy in the middle. When I bypass the reverse proxy and connect directly to port 2283 the android app works fine, video plays successfully.

@witchcraftsman - you running reverse proxy?
@EssGeeEich - if you connect directly to immich on 2283, does video continue to crash?


my nginx config...

server {
    server_name [redacted];

    # allow large file uploads
    client_max_body_size 50000M;

    # Set headers
    proxy_set_header Host              $http_host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # enable websockets: http://nginx.org/en/docs/http/websocket.html
    proxy_http_version 1.1;
    proxy_set_header   Upgrade    $http_upgrade;
    proxy_set_header   Connection "upgrade";
    proxy_redirect     off;

    # set timeout
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
    send_timeout       600s;

    location / {
        proxy_pass http://[redacted]:2283;
    }
}

@pretubedongit
Copy link

_Can confirm, S22 Ultra, same behavior, HOWEVER this seems to happen with all the videos I take, not just HDR, and it doesn't seem to be related to HEVC either.

On the web, the videos play fine.

Pixel 9 here... I also experience video crashing using the android app v1.123.0 build.172

On a side note, I have nginx as a reverse proxy in the middle, and apparently cannot download any file from the app.

Great news... I also have a reverse proxy in the middle. When I bypass the reverse proxy and connect directly to port 2283 the android app works fine, video plays successfully.

@witchcraftsman - you running reverse proxy?
@EssGeeEich - if you connect directly to immich on 2283, does video continue to crash?


my nginx config...

server {
    server_name [redacted];

    # allow large file uploads
    client_max_body_size 50000M;

    # Set headers
    proxy_set_header Host              $http_host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # enable websockets: http://nginx.org/en/docs/http/websocket.html
    proxy_http_version 1.1;
    proxy_set_header   Upgrade    $http_upgrade;
    proxy_set_header   Connection "upgrade";
    proxy_redirect     off;

    # set timeout
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
    send_timeout       600s;

    location / {
        proxy_pass http://[redacted]:2283;
    }
}

Hey I am on reverse proxy also. I tried connecting directly with http://IP:2283 after reading your post, but it didn't make any differences, those videos still crashes. At least in my case it's not caused by reverse proxy.

@EssGeeEich
Copy link

EssGeeEich commented Jan 9, 2025

@ckuyehar The issue I am facing is different from this one (see #14945) so my answer should be irrelevant...

@flokli
Copy link

flokli commented Jan 12, 2025

I'm running into the same issue. Video is a HEVC 10-bit video, the media is only available on the server, not locally.

mediainfo reports:

Video
ID                                       : 1
Format                                   : HEVC
Format/Info                              : High Efficiency Video Coding
Format profile                           : Main 10@L6@Main
Codec ID                                 : hvc1
Codec ID/Info                            : High Efficiency Video Coding
Duration                                 : 15 s 949 ms
Bit rate                                 : 119 Mb/s
Width                                    : 5 312 pixels
Height                                   : 2 988 pixels
Display aspect ratio                     : 16:9
Frame rate mode                          : Constant
Frame rate                               : 59.940 (60000/1001) FPS
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 10 bits
Bits/(Pixel*Frame)                       : 0.125
Stream size                              : 226 MiB (100%)
Title                                    : GoPro H.265
Language                                 : English
Encoded date                             : 2024-12-06 09:08:33 UTC
Tagged date                              : 2024-12-06 09:08:33 UTC
Color range                              : Full
Color primaries                          : BT.709
Transfer characteristics                 : BT.709
Matrix coefficients                      : BT.709
Conformance errors                       : 1
 HEVC                                    : Yes
  General compliance                     : Bitstream parsing ran out of data to read before the end of the syntax was reached, most probably the bitstream is malformed (frame [3..7]+9+11+13+15, time [11:08:33.090..11:08:33.156]+11:08:33.190+11:08:33.223+11:08:33.257+11:08:33.290, offset [0x2A8969..0x36223C]+0x3CEAC6+0x44A5EF+0x4BC020+0x52ACB9)
Codec configuration box                  : hvcC

Phone is a Pixel 9 Pro, stock Android.

No custom mTLS / self-signed certs etc, so not #14945.

@pretubedongit
Copy link

pretubedongit commented Jan 25, 2025

Hey I found the root cause in my case. I was using non-root docker by "user: 1000:1000", I suggest you try to delete this line.

user: "www-data"

To break it up:

  1. I tried inside Android app settings to enable "force playing original video", it stopped crashing but took a while to buffer the original video to play. This narrowed to the transcoding.
  2. I forced transcoding all videos from web admin, checked intel_gpu_top, it is not using hardware acceleration at all. In the docker compose and admin settings all were correct. This narrowed it to the permission. The user "node" with id 1000 inside the container has no access to /dev/dri/, which was passed from the host, and belongs to user group 105.
  3. I could have given 105 a group name and add node into the group, but I didn't bother to do it. Instead, I just went back to the docker compose and commented out "user: 1000:1000" and tested immich as root.
  4. Tested force transcoding all videos again, it's using QSV. (My host is an intel N100).
  5. Tested Android app by disabling "force play original video", and playing the previous video which crashed my Android app, it's playing well.

Consequence of this fix:

On the host machine, all newly uploaded files belong to uid:gid = root:root. This will cause problem if you use non-root backup like syncthing. However I found a permanent solution for this type of issue while messing around my Nexcloud docker setup. If you have come to this step and want details, let me know. In short: Use "setgid" function on host to force all new files to belong to your desired group, it will be enough for cross-container backups.

@witchcraftsman
Copy link
Author

you running reverse proxy?

yes, but as I stated I have no issues playing those videos on the web, what's the difference?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants