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

ProRes Hardware Acceleration #3874

Closed
ectoplasmosis opened this issue Jul 16, 2022 · 12 comments
Closed

ProRes Hardware Acceleration #3874

ectoplasmosis opened this issue Jul 16, 2022 · 12 comments

Comments

@ectoplasmosis
Copy link

Is there a plan to enable IINA to support ProRes hardware acceleration on M1 Pro/Max and M2 devices which have hardware ProRes video encode/decode engines?

VideoToolbox framework has supported this natively for a while now, via Quicktime Player.

@low-batt
Copy link
Contributor

Similar to many open source projects IINA is layered on top of code from many other projects. For video/audio playback IINA uses mpv and FFmpeg. This means that IINA developers categorize feature requests and bug requests based on whether they are "pure IINA", as in something that can be fully completed by changing IINA code, or something that requires changes to other projects. When changes are required to projects IINA is dependent upon it is considered an "upstream" issue. Decoding using hardware acceleration lands in FFmpeg.

From FFmpeg HWAccelIntro:

VideoToolbox

H.263, H.264, HEVC, MPEG1, MPEG2, MPEG4, ProRes decoding is available in FFmpeg/libavcodec.

Seems like it should already be supported.

Checking the FFmpeg Bug Tracker I found ticket 9546, "Videotoolbox Prores and VP9 does not work". That was fixed 2021-12-22. Not clear when the problem was introduced.

This brings up the question of the version of FFmpeg IINA is using. The latest FFmpeg release is version 5.0.1 which was released 2022-04-04 and should have the fix. IINA is using FFmpeg 4.4.2 which was released 2022-04-14, but was built from the 4.4 release branch, which may or may not have the fix. IINA is not using FFmpeg 5 due to reports of regressions under Intel Macs related to hardware acceleration.

Currently we are watching these FFmpeg tickets for fixes:

  • VideoToolbox VP9 hwaccel freezes ffmpeg FFmpeg #9599
  • Hardware decode fails reporting VideoToolbox malfunction, FFmpeg #9809

Upgrading to FFmpeg 5.0.1 may provide support for ProRes decode using hardware acceleration, but may introduce some regressions.

Would be good to have a small ProRes video sample that reproduces the failure to use hardware acceleration.

@Jerry23011
Copy link

Try the demo in the Apple Store, where they use Apple ProRes 4444, I have a five second copy on my laptop, and the hardware acceleration is not working

@ectoplasmosis
Copy link
Author

Thank you for the detailed reply!

I can confirm that an out-of-the-box install of IINA does NOT support ProRes hardware acceleration. I have tested this with all types of ProRes files (422LT, 422, 4444 etc, many different resolutions), and all of them use significant CPU resources to play back. If I play any of these files in Quicktime Player, CPU usage is near-zero.

Upgrading to FFmpeg 5.0.1 may provide support for ProRes decode using hardware acceleration, but may introduce some regressions.

How can I upgrade the FFmpeg version that IINA uses? I only use Apple Silicon Macs these days, so any Intel-related regressions do not apply.

Thanks again.

@Jerry23011
Copy link

Jerry23011 commented Jul 28, 2022

Sorry, I'm currently using a MBP with M1 Pro, and I'm experiencing the exact same thing; however, I have no idea how to switch the FFmpeg version of IINA, guess we'll have to wait for a Pro to reply.

@low-batt
Copy link
Contributor

I always dislike posting a half-done rushed analysis, but I ran out of time looking into this today. So this reply has some useful information, but more investigation is needed.

Executive Summary

The quick answer...

  • FFmpeg is embedded in the IINA application and can not be upgraded by the user
  • The problem extends beyond the version of FFmpeg being used

More details than you probably care to know follows...

IINA & mpv & FFmpeg

The IINA application embeds code from many open source projects. You can view the code that is embedded in the application, but you must not alter these files in any way whatsoever. Any changes will invalidate Code Signing causing macOS to terminate IINA at startup with a Code Signature Invalid error.

Listing the 3rd party code embedded in IINA using Terminal:

Embedded:
low-batt@gag ~$ ls /Applications/IINA.app/Contents/Frameworks/
Sparkle.framework		libfontconfig.1.dylib		liblept.5.dylib			libsodium.23.dylib		libswiftFoundation.dylib	libuchardet.0.dylib
libXau.6.dylib			libfreetype.6.dylib		libluajit-5.1.2.dylib		libsoxr.0.dylib			libswiftIOKit.dylib		libunistring.2.dylib
libXdmcp.6.dylib		libfribidi.0.dylib		liblz4.1.dylib			libspeex.1.dylib		libswiftMetal.dylib		libvidstab.1.1.dylib
libarchive.13.dylib		libgif.dylib			liblzma.5.dylib			libswiftAVFoundation.dylib	libswiftObjectiveC.dylib	libwebp.7.dylib
libass.9.dylib			libglib-2.0.0.dylib		libmpv.1.dylib			libswiftAppKit.dylib		libswiftQuartzCore.dylib	libwebpmux.3.dylib
libavcodec.58.dylib		libgmp.10.dylib			libmujs.dylib			libswiftCore.dylib		libswiftSafariServices.dylib	libxcb-shape.0.dylib
libavdevice.58.dylib		libgnutls.30.dylib		libnettle.8.dylib		libswiftCoreAudio.dylib		libswiftXPC.dylib		libxcb-shm.0.dylib
libavfilter.7.dylib		libgraphite2.3.dylib		libopenjp2.7.dylib		libswiftCoreData.dylib		libswiftos.dylib		libxcb-xfixes.0.dylib
libavformat.58.dylib		libharfbuzz.0.dylib		libp11-kit.0.dylib		libswiftCoreFoundation.dylib	libswiftsimd.dylib		libxcb.1.dylib
libavutil.56.dylib		libhogweed.6.dylib		libpcre.1.dylib			libswiftCoreGraphics.dylib	libswresample.3.dylib		libzimg.2.dylib
libb2.1.dylib			libidn2.0.dylib			libpng16.16.dylib		libswiftCoreImage.dylib		libswscale.5.dylib		libzmq.5.dylib
libbluray.2.dylib		libintl.8.dylib			libpostproc.55.dylib		libswiftCoreMedia.dylib		libtasn1.6.dylib		libzstd.1.dylib
libdav1d.5.dylib		libjpeg.9.dylib			librubberband.2.dylib		libswiftDarwin.dylib		libtesseract.5.dylib
libffi.8.dylib			liblcms2.2.dylib		libsnappy.1.dylib		libswiftDispatch.dylib		libtiff.5.dylib
low-batt@gag ~$ 

Many open source project use Autoconf configure scripts that provide many options as to how the source is built. In the case FFmpeg the configure script determines what features the resulting binary supports. An example from the FFmpeg configure script:

  --enable-libx265         enable HEVC encoding via x265 [no]

The [no] at the end is the default. Unless you enable x265 the resulting binary will not support HEVC encoding.

Most of the embedded code is built from sources by the IINA project specifically for embedding into IINA. Since IINA does not need FFmpeg encoding support the IINA build does not enable this feature.

And of course for IINA these must be universal binaries:

low-batt@gag Frameworks$ otool -L  libavcodec.58.dylib | grep architecture
libavcodec.58.dylib (architecture x86_64):
libavcodec.58.dylib (architecture arm64):
low-batt@gag Frameworks$

And support running under macOS 10.11+.

So upgrading/building dependencies is "interesting".

Testing FFmpeg & mpv

I am using this ProRes video file to test with:

mediainfo:
low-batt@gag issue-3874$ mediainfo DJI_0023.MOV 
General
Complete name                            : DJI_0023.MOV
Format                                   : MPEG-4
Format profile                           : QuickTime
Codec ID                                 : qt   0000.02 (qt  )
File size                                : 8.34 GiB
Duration                                 : 50 s 752 ms
Overall bit rate mode                    : Variable
Overall bit rate                         : 1 411 Mb/s
Encoded date                             : UTC 2021-11-03 14:15:51
Tagged date                              : UTC 2021-11-03 14:15:51
Writing application                      : DJIMavic3Cine
Cover                                    : Yes
snal                                     : (Binary)

Video
ID                                       : 1
Format                                   : ProRes
Format version                           : Version 0
Format profile                           : 422 HQ
Codec ID                                 : apch
Duration                                 : 50 s 751 ms
Bit rate mode                            : Variable
Bit rate                                 : 1 409 Mb/s
Width                                    : 5 120 pixels
Height                                   : 2 700 pixels
Display aspect ratio                     : 1.896
Frame rate mode                          : Constant
Frame rate                               : 29.970 (30000/1001) FPS
Color space                              : YUV
Chroma subsampling                       : 4:2:2
Scan type                                : Progressive
Bits/(Pixel*Frame)                       : 3.401
Stream size                              : 8.33 GiB (100%)
Writing library                          : DJI0
Language                                 : English
Encoded date                             : UTC 2021-11-03 14:15:51
Tagged date                              : UTC 2021-11-03 14:15:51
Color primaries                          : BT.709
Transfer characteristics                 : BT.709
Matrix coefficients                      : BT.709

Other #1
Type                                     : meta
Duration                                 : 50 s 752 ms
Bit rate mode                            : Variable
Default                                  : No

Other #2
Type                                     : dbgi
Duration                                 : 50 s 751 ms
Bit rate mode                            : Variable
Default                                  : No


low-batt@gag issue-3874$ 

The tests are being run on a MacBookPro18,2 with the M1 Max chip under macOS 12.4. The FFmpeg binary is 5.0.1 installed using Homebrew, so native code.

Hardware decoding is disabled by default, so I'm passing -hwaccel videotoolbox to enable it:

low-batt@gag issue-3874$ ffmpeg -hwaccel videotoolbox -i DJI_0023.MOV -map 0:a:0? -f null -

Montoring CPU usage showed hardware decoding is being used.

The mpv binary I'm using for testing is the 0.34.1 build from stolendata, running under Rosetta 2 using FFmpeg 4.4.1.

Hardware decoding is disabled by default, so I'm passing --hwdec=auto to enable it:

low-batt@gag issue-3874$ /Applications/mpv.app/Contents/MacOS/mpv --hwdec=auto --log-file=mpv.log DJI_0023.MOV 

And the mpv.log shows hardware decoding was not used:

[   0.047][v][vd] Codec list:
[   0.047][v][vd]     prores - Apple ProRes (iCodec Pro)
[   0.047][v][vd] Opening decoder prores
[   0.047][v][vd] Not trying to use hardware decoding: codec prores is not on whitelist.
[   0.047][v][vd] Using software decoding.

I'm confused.

From section options-hwdec of the mpv manual:

auto: forcibly enable any hw decoder found (see below)
auto-safe: enable any whitelisted hw decoder (see below)

Why is mpv enforcing using of the whitelist when auto is used? Shouldn't that only happen when auto-safe is specified?

From section options-hwdec-codecs of the mpv manual:

--hwdec-codecs=<codec1,codec2,...|all>

Allow hardware decoding for a given list of codecs only. The special value all always allows all codecs.

You can get the list of allowed codecs with mpv --vd=help. Remove the prefix, e.g. instead of lavc:h264 use h264.

By default, this is set to h264,vc1,hevc,vp8,vp9,av1. Note that the hardware acceleration special codecs like h264_vdpau are not relevant anymore, and in fact have been removed from Libav in this form.

Looks like this PR mpv-player/mpv#9537 that adds prores to the whitelist was merged a bit after 0.34.0 was released. They missed the need to update the manual. Still I don't understand why auto is enforcing the whitelist.

Trying again with --hwdec-codecs=all:

low-batt@gag issue-3874$ /Applications/mpv.app/Contents/MacOS/mpv --hwdec=auto --hwdec-codecs=all --log-file=mpv.log DJI_0023.MOV 

And the mpv.log shows hardware decoding was not used:

[   0.049][v][vd] Container reported FPS: 29.970030
[   0.049][v][vd] Codec list:
[   0.049][v][vd]     prores - Apple ProRes (iCodec Pro)
[   0.049][v][vd] Opening decoder prores
[   0.049][v][vd] No hardware decoding available for this codec.
[   0.049][v][vd] Using software decoding.

Adding --hwdec-codecs=all eliminated the whitelist issue, but for some reason mpv thinks hardware decoding is not available. Testing FFmpeg 4.4.1 downloaded from More ffmpeg releases and monitoring CPU usage showed hardware decoding was not used. Possibly that is why this build if mpv thinks hardware decoding is not available?

Conclusions

The main conclusion I have is some more investigation and testing is needed. It does seem like upgrading FFmpeg would provide hardware support for decoding ProRes. Apparently IINA will also need to be changed to add prores to the hwdec-codecs mpv configuration with the current release of mpv.

@low-batt
Copy link
Contributor

Took a while, but I was able to build mpv from master with FFmpeg built from master. Playing the ProRes video DJI_0023.MOV I have been using for testing:

low-batt@gag mpv-build (master %=)$ mpv/build/mpv --fullscreen --hwdec=auto --log-file=mpv.log ~/Documents/builds/iina/issue-3874/DJI_0023.MOV 
[ffmpeg/demuxer] mov,mp4,m4a,3gp,3g2,mj2: stream 0, timescale not set
 (+) Video --vid=1 (*) (prores 5120x2700 29.970fps)
     Video --vid=2 [P] (mjpeg 1.000fps)
Using hardware decoding (videotoolbox).
VO: [libmpv] 5120x2700 videotoolbox[p210]
V: 00:00:50 / 00:00:50 (100%)

Exiting... (End of file)
low-batt@gag mpv-build (master %=)$ 

From mpv.log:

[   0.037][v][vd] Codec list:
[   0.037][v][vd]     prores - Apple ProRes (iCodec Pro)
[   0.037][v][vd] Opening decoder prores
[   0.037][v][vd] Looking at hwdec prores-videotoolbox...
[   0.037][v][vd] Trying hardware decoding via prores-videotoolbox.
[   0.037][v][vd] Selected codec: prores (Apple ProRes (iCodec Pro))
[   0.037][v][vf] User filter list:
[   0.037][v][vf]   (empty)
[   0.037][v][cplayer] Starting playback...
[   0.037][v][file] stream level seek from 8952012458 to 12300
[   0.038][v][vd] Pixel formats supported by decoder: videotoolbox_vld yuv422p10le
[   0.038][v][vd] Codec profile: HQ (0x3)
[   0.038][v][vd] Requesting pixfmt 'videotoolbox_vld' from decoder.
[   0.123][i][vd] Using hardware decoding (videotoolbox).

This confirms that IINA should be able to get ProRes hardware decoding to work after upgrading FFmpeg. If at that point IINA is still using mpv 0.34.1 then IINA will need to set hwdec-codecs to workaround the whitelist issue. That will not be needed after the next release of mpv.

@low-batt low-batt self-assigned this Oct 17, 2022
@low-batt
Copy link
Contributor

low-batt commented Mar 2, 2023

Ran a test of IINA modified to use mpv v0.35.1 and FFmpeg 5.1.2 and confirmed ProRes hardware decoding was used playing the DJI_0023.MOV test video I mentioned above. No changes to IINA were required.

@Jerry23011
Copy link

So all IINA needs to do is to update the dependencies and hw for ProRes will be enabled?

@low-batt
Copy link
Contributor

low-batt commented Mar 2, 2023

That was a note to other developers that no changes to IINA will be needed. I thought that important to note as In a post above I mentioned IINA needing to change thehwdec-codecs property to workaround the whitelist issue. That would be needed if we did not upgrade mpv. But as mpv v0.35.1 has some important fixes I'm expecting we will be upgrading in the next IINA release. FFmpeg just released version 6. IINA 1.3.1 is using FFmpeg 4.4.2 as FFmpeg 5 had just been released and there were reports of regressions. As IINA is so far behind I'm expecting we will be at least upgrading to FFmpeg 5.2.1. So I am expecting we will be able to close this issue with the next release of IINA.

The above test was very rough. I will be testing again once IINA has officially upgraded dependencies.

@Jerry23011
Copy link

Thank you :)

@low-batt
Copy link
Contributor

Just ran a test with the upgraded dependencies and:

[  57.277][v][vd] Trying hardware decoding via prores-videotoolbox.
[  57.277][v][vd] Selected codec: prores (Apple ProRes (iCodec Pro))

ProRes Hardware Acceleration will work in the next release of IINA.

@low-batt
Copy link
Contributor

low-batt commented Jan 2, 2024

This is fixed in the released version of IINA.

@low-batt low-batt closed this as completed Jan 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants