Tuesday, April 6, 2010

HOWTO: Nvidia Driver + VDPAU + Smplayer +Mplayer

Update for Karmic:

This PPA contains updated mplayer/smplayer builds, xine-vdpau, all the latest Nvidia drivers, a kaffeine build for DVB-S2 users, the latest libvdpau library and vdpauinfo packaged for Ubuntu. A lot of it is packaged for multiple distros. You still must configure smplayer as described below.

If you know you want this, skip the preamble. If not, indulge me. Why should you want this? The h.264/x.264 decoding. This codec is extremely CPU intensive. My system, which is a Quad core with an 8800GT, can't play 1080 x264 files if the bitrate is ~10mbps. Not with a guarantee of smoothness the whole way through. So if that rig can't do it, yours probably can't either. With the setup described below, my system plays those files smoothly as an android's bottom. And mplayer's CPU usage is 1% every time, no exceptions. This is what it's like when your video card's manufacturer cares about their customers. Before you proceed: VDPAU does not work with Xinerama, but does work with Twinview.

With these instructions, I'm assuming some knowledge of the terminal and package installation, Synaptic and PPAs. These instructions are not basic enough for a total newbie. That's intentional on my part. You should not be trying to bugger around with this stuff unless you know what you're doing to start with.

If you want to use the Restricted Drivers Manager to enable the driver, make sure you install the modaliases package. If not, make sure the nvidia driver is in the /etc/X11/xorg.conf file. Not much else needs to be there. Something like this would be sufficient:


Quote:
Section "Screen"
Identifier "Default Screen"
DefaultDepth 24
EndSection

Section "Module"
Load "glx"
EndSection

Section "Device"
Identifier "Default Device"
Driver "nvidia"
Option "NoLogo" "True"
EndSection
There's something about Nvidia's numbering system that should be understood. The 8800GTX won't work with VDPAU. Why? Because it was actually released before some of the other 8k series cards that have the newer PureVideo 2 hardware. The 8800GTS 512 will work though. Confusing enough? All 9k cards and GTX cards will work, as well as all other 8k cards (that I know of). No 7k or older cards will work, nor will any AGP card that I know of.

I would avoid installing the regular mplayer package, because it contains the long-obfuscated gmplayer gui. Use another gui. After you install mplayer-nogui run:

Quote:
$mplayer -vo vdpau -vc ffh264vdpau path/to/file
Test your x264-encoded MKV files.

Now to Smplayer. This, for those that don't know, is a QT frontend to mplayer with lots of neat options. The best frontend for mplayer in my view. Gnome-Mplayer is also very good, and is a new gtk gui. The Nvidia VDPAU Team PPA has Smplayer and so does Karmic.

If you don't want to use it, fine. If you do, read on. Once you've got it installed, select Options>Preferences. Click on the Video tab. Change the output driver to VDPAU. You should now be able to use Smplayer with the mplayer backend and play all x264 flicks and standard DVDs with little or no CPU usage. For all other files, Smplayer will automatically select the appropriate codec.

VDPAU support has been added to Xine and the aforementioned PPA has xine-vdpau packages.

Mythbuntu builds with vpdau: http://mythbuntu.org/auto-builds
XBMC builds with vdpau: https://launchpad.net/~team-xbmc/+archive/ppa

And so we arrive, as you knew we must, at VLC. VLC is available with vdpau by way of VA-API, in this PPA: https://launchpad.net/~nvidia-vdpau/...dge-multimedia
However, to install it you'll have to upgrade your precious and very touchy ffmpeg packages. There have been a couple of SONAME upgrades since Karmic's ffmpeg was released, and this will inevitably result in breakage of anything that A) uses dynamic ffmpeg, and B) is not rebuilt against the new version, ie. every package that's on your system that didn't come from that PPA. The gstreamer-ffmpeg package will ensure that your gstreamer system will still work, and there's a build of xine-1.2 (currently unstable) for KDE users. It's possible that in the near future the intel 965 va-api driver might appear in that PPA as well.

Feed me Seymour, Feed me!

References:
Stephen Warren talking about level 4.1 limits in the previous drivers
Line 94 and 704 hacks
Wikipedia page on PureVideo
List of supported Cards/Chips

Nvidia VDPAU thread

*Official* Nvidia VDPAU thread

EDIT: Please see this thread because this guide has become outdated (yay!), but I've left it here for giggles.

Instructions for using nvidia's VDPAU video acceleration (180.29 has been released stable ):

I'm using Kubuntu 8.10 with a 9300GS, so YMMV. Also, version numbers change, so be aware of that before you copy/paste commands.

* Intrepid and Jaunty PPA repositories for nvidia beta driver and mplayer-vdpau --> https://launchpad.net/~thomas-creutz/+archive

To manually install:

INSTALL THE NVIDIA DRIVER

Always check the nvidia thread for the current driver versions and information about cards supported, etc. --> http://www.nvnews.net/vbulletin/showthread.php?t=122606
As of this writing, the current version is 180.16.

* Deactiviate the nvidia driver (if you're using it) in the "Hardware Drivers" system utility.
* Download the driver and remember where you put it.
* Use to switch to a console.
* Log in as "root" or use "sudo su" to become root if you log in as normal user.
* Stop the display manager (in Ubuntu/Gnome, replace "kdm" with "gdm"):
Code:
/etc/init.d/kdm stop
* Remove the nvidia module:
Code:
modprobe -r nvidia
* Make sure some dependencies are installed:
Code:
apt-get install build-essential linux-headers-`uname -r`
* Go to the directory where you saved the drivers, e.g.:
Code:
cd /home/user/src/nvidia/16
* Run the installer:
Code:
sh NVIDIA-Linux-x86-180.16-pkg1.run
* When it's done, start the display manager:
Code:
/etc/init.d/kdm start
* Open a terminal and verify that you're using the new drivers:
Code:
cat /var/log/Xorg.0.log | grep NVIDIA
-----

TEST VDPAU CAPABILITIES OF YOUR VIDEO CARD
From the nvnews forums --> http://www.nvnews.net/vbulletin/showthread.php?t=124978

* Download and extract the file somewhere (here's a direct link) --> http://www.cs.rug.nl/~wladimir/vdpin...o-0.0.4.tar.gz
* in a terminal, cd to the directory where you extracted it (vdpinfo)
* you'll need the X headers:
Code:
sudo apt-get install xorg-dev
* run "make"
* run "./vdpinfo"

My 9300GS produces the following output:
Code:
display: :0   screen: 0                               API version: 0                                        Information string: Unknown                            Video surface:  name   width height types ------------------------------------------- 420     4096  4096  NV12 YV12               422     4096  4096  UYVY YUYV                Decoder capabilities:  name          level ref width height ------------------------------------ MPEG1             0  2  4096  4096   MPEG2_SIMPLE      3  2  4096  4096   MPEG2_MAIN        3  2  4096  4096   H264_MAIN        41 16  4096  4096   H264_HIGH        41 16  4096  4096   VC1_SIMPLE        1  2  4096  4096   VC1_MAIN          2  2  4096  4096   VC1_ADVANCED      4  2  4096  4096    Output surface:  name              width height nat types ---------------------------------------------------- B8G8R8A8          8192  8192    y  Y8U8V8A8 V8U8Y8A8  R10G10B10A2       8192  8192    y  Y8U8V8A8 V8U8Y8A8   Bitmap surface:  name              width height ------------------------------ B8G8R8A8          8192  8192 R8G8B8A8          8192  8192 R10G10B10A2       8192  8192 B10G10R10A2       8192  8192 A8                8192  8192  Video mixer:  feature name                    sup ------------------------------------ DEINTERLACE_TEMPORAL             y DEINTERLACE_TEMPORAL_SPATIAL     y INVERSE_TELECINE                 y NOISE_REDUCTION                  y SHARPNESS                        y LUMA_KEY                         y  parameter name                  sup      min      max ----------------------------------------------------- VIDEO_SURFACE_WIDTH              y         1     4096 VIDEO_SURFACE_HEIGHT             y         1     4096 CHROMA_TYPE                      y LAYERS                           y         0        4  attribute name                  sup      min      max ----------------------------------------------------- BACKGROUND_COLOR                 y CSC_MATRIX                       y NOISE_REDUCTION_LEVEL            y      0.00     1.00 SHARPNESS_LEVEL                  y     -1.00     1.00 LUMA_KEY_MIN_LUMA                y LUMA_KEY_MAX_LUMA                y
-----

PATCH AND BUILD MPLAYER

NOTE: As of today, VDPAU support is officially in mplayer svn (r28617).

* Download the patchset from nvidia. You'll want the latest one. All of them are here --> ftp://download.nvidia.com/XFree86/vdpau/
* Open a terminal and cd to the directory where your put them.
* Unpack (adapt for version number):
Code:
tar jxfv mplayer-vdpau-3219724.tar.bz2
* Go to the directory that was created:
Code:
cd mplayer-vdpau-3219724
* Make sure some dependencies are installed:
Code:
sudo apt-get build-dep mplayer
Code:
sudo apt-get install subversion
* For a faster build on a multi-core machine, edit the script and add -j3 (or higher) to the make command.
* Run the script (this will download mplayer sources, patch, and build):
Code:
./checkout-patch-build.sh
* Copy the codecs.conf file to your mplayer directory:
Code:
cp etc/codecs.conf ~/.mplayer/
-----

TEST VDPAU WITH MPLAYER

* In a terminal, cd to the new mplayer directory:
Code:
cd mplayer-vdpau
* I found a good blog post for this --> http://blog.mymediasystem.net/avchd/...cceleration/3/

-----

BUILD MYTHTV FROM SVN

Follow the instructions from the mythtv wiki --> http://www.mythtv.org/wiki/index.php...Source_Install. Don't forget to add "--enable-vdpau --enable-opengl-vsync" to "./configure" in the mythtv directory. See also the mythtv vdpau wiki page --> http://www.mythtv.org/wiki/VDPAU

-----

HD channels use ~10-12% cpu.

Last edited by mythmaster; 04-04-09 at 11:09 PM.. Reason: updates

NVIDIA VDPAU Benchmarks

Published on November 14, 2008
Written by Michael Larabel
Page 1 of 2
Discuss This Article

Earlier today we shared that NVIDIA is bringing PureVideo features to Linux through a major update in their binary display driver. The NVIDIA 180.06 driver adds VDPAU support on Linux, Solaris, and FreeBSD operating systems, with VDPAU being a set of APIs designed by NVIDIA to accelerate video decoding, provide post-processing capabilities, timestamp-based presentation of video frames, and compositing of sub-picture elements. We have now had the time to benchmark the Video Decode and Presentation API for Unix and have seen the benefits of PureVideo features finally arriving on alternative platforms.

We had used the latest MPlayer SVN code and used the NVIDIA-supplied patches that add VDPAU support to mplayer, libavcodec, libavutil, and ffmpeg. This was done on an Ubuntu 8.10 system with the Linux 2.6.27 kernel, X Server 1.5.2, and the NVIDIA 180.08 driver. We had monitored the CPU usage while playing back a sample H.264 video using the GL2, X-Video, and finally VDPAU. The graphics card in use was a NVIDIA GeForce 9800GTX 512MB running at its stock frequencies. The motherboard in use was the ASUS P5E64 Professional and the processor being used was an Intel Core 2 Duo E8400. This processor is clocked at 3.00GHz by default, but we had down-clocked it to 1.80GHz so that the CPU usage would be more measurable during video playback. The system had 2GB of DDR3 memory.

The sample H.264 video used for testing out the Video Decode and Presentation API for Unix was the one referenced by NVIDIA's VDPAU read-me file and is available from the H.264 sample collection on the MPlayer web-site (Grey.ts). To use VDPAU for the codec and output module with mplayer, the -vo vdpau -vc ffh264vdpau arguments are needed. Today we are focusing on H.264 but MPEG, WMV3, and VC-1 (on select GPUs) is supported. To monitor the CPU usage we had used the Phoronix Test Suite and run MONITOR=all ./phoronix-test-suite benchmark idle. The system had idled for two minutes and during that time the CPU usage (as a percent) was being logged and then graphed. We had played the H.264 sample video with all three modules twice during the two-minute period. On the next page are the results.

VDPAU

General

What is it

VDPAU (Video Decode and Presentation API for Unix) provides a large subset of PureVideo HD functionality for NVIDIA Linux, Solaris, and FreeBSD users. It in essence provides what PureVideo/DirectX Video Acceleration is on the Windows platform. In addition to updated NVIDIA binary drivers that support the API, extensive documentation is available.

Some highlights of VDPAU:

  • Defines an API for GPU-accelerated decode of MPEG-1, MPEG-2, H.264, and VC-1 bitstreams.
    • GT2xx and newer GPUs can additionally decode ASP (divx/xvid/mpeg4)
  • Defines an API for post-processing of decoded video, including temporal and spatial deinterlacing, inverse telecine, and noise reduction.
  • Defines an API for timestamp-based presentation of final video frames.
  • Defines an API for compositing sub-picture, on-screen display, and other UI elements.

Note that VDPAU does not address content protection issues.

Some highlights/limitations of NVIDIA's current implementation:

  • Supported on NVIDIA GPUs with the NVIDIA second generation video processors (see list further below)
  • Currently, only one video stream can be decoded at a time; NVIDIA hopes to lift this restriction eventually.

Supported Cards

VDPAU is currently supported on the following NVIDIA GPUs (driver version 180.44). An up-to-date list is available at the Nvidia link given below under 'External Links'. Feature Set, when known, is reflected in parenthesis (). See more details regarding feature set capabilities here.

Desktop GPUs Mobile GPUs Motherboard GPUs Professional GPUs
  • GeForce Go 7700
  • GeForce 2xx Series (C)
  • GeForce 9 Series
  • GeForce 8300 GS
  • GeForce 84xx Series (G92/G94 Core) (A)
  • GeForce 8400 GS (G98 Core) (B)
  • GeForce 85xx Series (A)
  • GeForce 86xx Series (A)
  • GeForce 8800 GTS 512 (A)
  • GeForce 8800 GT (A)
  • GeForce 8800 GS (A)
  • GeForce 9500 GT (A)
  • GeForce 9800 GT (A)
  • GeForce 96xxM
  • GeForce 8200M G
  • GeForce 8800M
  • GeForce 8800M GTS
  • GeForce 8800M GTX
  • GeForce 8600M
  • GeForce 8400M
  • GeForce 9200M
  • GeForce 9300M
  • GeForce 9400M
  • GeForce 9500M
  • GeForce 9650M GT
  • GeForce 9700M
  • GeForce 9700M GT
  • GeForce 98xxM
  • GeForce 9800M GTX
  • GeForce 9800M GT
  • GeForce 9800M GS
  • Quadro NVS 140M
  • GeForce 8200 (B)
  • GeForce 8300 (B)
  • GeForce 9100
  • GeForce 9300 (B)
  • GeForce 9400 (A)
  • Quadro FX 370 LP
  • Quadro NVS 450
  • Quadro FX 470
  • Quadro FX 2700M
  • Quadro FX 4800
  • Quadro FX 5800
  • Quadro CX

Rules of thumb: anything from before the 8xxx series is unsupported ; anything with the original G80 GPU (8800 GTX, 8800 Ultra, Quadro FX5600, the first 8800 GTS) is unsupported ; everything newer in the 8xxx, 9xxx and 2xx series should work if the driver supports the card.

Since video decoding is done in dedicated hardware, all supported cards have the same level of performance. Specifically, this means H.264 High 4.1, VC-1 Advanced 3, or MPEG-2 MP@HL at up to 40Mbps. Deinterlacing is performed within the shader hardware, so a more powerful card will be capable of more advanced filters at higher resolutions and framerates Increased memory bandwidth will also help. Detailed specs on shaders, memory bandwidth, etc. can be found at this GeForce Chipsets page. Just click on the link for the relevant chipset to see the details.(see User results table below for examples).

High Def 1080i De-interlacing capabilities On Each Card

GPU None One Field (1x) Bob (2x) Temporal (1x) Temporal (2x) Advanced (1x) Advanced (2x)
Example X X X X X X X
8200 X X X (>= 512Mb) (SD only) (>= 512Mb) (SD only)
8400 PCI X X X ? (SD only) (SD only) (SD only)
8400 PCI-e X X X X X (SD only) (SD only)
8500 GT X X X X X X -
8600 GT X X X X X X X
9300 X X X X X X (SD only)
9400 X X X X X X (SD only)
9500 GT X X X X X X X (occasional stutter, skip_chroma helps)
9600 GT X X X X X X X
GT 210 X X X X X X (SD only, maybe HD at PAL frame-rates)
GT 220 X X X X X X X
GT 240 X X X X X X X

/* Should do all of the rest but I have not tried them.

Supported Drivers

Support started with version 180.06. Latest version available here 32bit and 64bit. Bugs are fixed with every new release.

MythTV Support

Fully supported in MythTV .22 and above

What works?

  • Any codec support by VDPAU can be offloaded with the MythTV video player.
  • Color OSD
  • OSD Menus
  • PiP

What doesn't?

  • No known problems.

Enabling VDPAU in MythFrontend

Navigate to:

 "Utilities -> Setup -> TV Settings -> Playback -> Playback Profiles (3/9)" 

VDPAU Playback Profiles are automatically created in current versions.

  • VDPAU High Quality: use Temporal Spatial 2X (Advanced 2X) for all content. To be used with nvidia cards >= 8600GT, >= 9500GT, GT120 or >= GT220
  • VDPAU Normal: use Temporal 2X for HD content, and Temporal Spatial 2X (Advanced 2X) for SD content. To be used with nvidia cards >= 8400, >= 9300, GT110 or >= GT210
  • VDPAU Slim: use Bob 2X with skip chroma option, with One Field as fall back, to be used with nvidia cards >= 8200 or when VDPAU Normal doesn't work for some reasons.

Profiles using 2X deinterlacers give better motion playback than 1X ones.

VDPAU filters

Add filters there:

 "Utilities/Setup -> Setup -> TV Settings -> Playback -> Playback Profiles -> Custom Filters" 

Some options will hurt performance, so don't enable unnecessarily.

This is a comma seperated list of options such as:

 vdpauivtc, vdpauskipchroma, vdpaudenoise=0.5, vdpausharpen=1.0 
  • vdpaucolorspace
    • Sets ITU BT601 and ITU BT709 (BT709 for HD videos and BT601 for SD) colour spaces, by default or automatically
    • Why/when it should be used: always, used in MythTV default profiles
    • Set as vdpaucolorspace=[auto|itu709|itu601]
    • example: vdpaucolorspace=auto
  • vdpaustudio
    • Will prevent converting RGB studio (16-235) levels to RGB PC levels (0-255)
    • Why/when it should be used: If you are using a TV/projector for playback: almost always. Set by default in default playback profiles
    • Type: toggle
    • Example: vdpaustudio
  • vdpaubuffersize
    • VDPAU video buffer size
    • Why/when it should be used: If some H264 videos don't play properly
    • The valid range is X to Y
    • Example: vdpaubuffersize=14
  • vdpauivtc
    • Enabling VDPAU inverse telecine, requires Basic or Advanced deinterlacer
    • Why/when it should be used: When playing telecined content.
    • Type: toggle
    • Example: vdpauivtc
  • vdpauskipchroma
    • Enabling Skip Chroma Deinterlace
    • Why/when it should be used: It may help with lower-end graphic cards. This is the default for VDPAU Low quality profile
    • Type: toggle
    • Example: vdpauskipchroma
  • vdpaudenoise
    • VDPAU Denoise
    • Why/when it should be used:
    • Will hurt performance
    • The valid range is 0.0 to 1.0, with 0.0 disabling it
    • Example: vdpaudenoise=0.5
  • vdpausharpen
    • VDPAU Sharpen
    • Why/when it should be used:
    • Will hurt performance
    • The valid range is -1.0 to 1.0, with 0.0 disabling it
    • Example: vdpausharpen=0.7
  • vdpauhqscaling
    • enables High Quality scaling
    • Why/when it should be used: If you have a VDPAU features C card (nVidia 210, 220)
    • Type: toggle
    • Example: vdpauhqscaling

Compiling MythTV with VDPAU

For Myth to support VDPAU it must be built in. MythTV's compilation script supports this. To enable it use the configure script and the --enable-vdpau option.

The following is an example of how to compile MythTV with VDPAU:

MythTV

  ./configure --prefix=/usr --enable-proc-opt --disable-joystick-menu \   --disable-firewire --disable-hdhomerun --disable-xvmcw --enable-xvmc-opengl \    --enable-vdpau  --disable-directfb --enable-opengl-vsync 

MythPlugins

  ./configure --prefix=/usr --enable-opengl --enable-mytharchive \    --disable-mythbrowser --disable-mythcontrols --disable-mythflix \    --enable-mythgallery --disable-mythgame --enable-mythmusic --disable-mythnews \   --disable-mythphone --enable-mythvideo --disable-mythweather \   --disable-mythzoneminder --disable-mythmovies 

Caveats

  • No AGP cards support this feature (PCI cards exist but lack the necessary bandwidth for non-VDPAU HD)
  • Warning: Do not install the vdpau beta driver unless you intend to use an NVidia-based video cards exclusively thereafter. Merely installing the nvidia driver breaks digital playback on Intel (and probably any other) video/graphics cards. The nvidia installer *replaces* standard header files (/usr/include/glext.h, glext.h,glxext.h and glx.h) and library files (/usr/lib/libGLcore.so, libGL,so, libGLU.so and libGL.la), with nvidia specific versions which breaks OpenGL playback on other graphic cards. (The 180 series drivers do appear to be usable with non-vdpau capable nvidia GPUs (6200 etc.))
  • If you wish to try an nvidia video board instead of your other video/graphic chipset, be careful. Make a mythconverg database backup, and note the SVN of your present working version. In addition, it would be wise to extract the NVidia pkg.run file (NVIDIA-LINUX....pkg.run -x) and make backups of the original files for which copies exist in the ../include/GL, ../lib and ../X11R6 folders. The package help states that the option '--no-opengl-headers' will skip installing the Nvidia OpenGL headers, however it appears that the other libraries will be replaced anyway. It also does not appear to be the case that the '--uninstall' option actually reverses the install, as the orginal files do not appear to be retained. This is a real time-killer ( and WAF killer) and may require a complete re-installation of the system if you wish to revert to a different family of GPU chip.
  • Video profiles can not filter based on video format (only by resolution). So if you wanted to use VDPAU for H.264/HD-PVR and Xv for Mpeg2 this is not currently possible.
  • Off loading to the GPU may increase its heat out-put. It may seem obvious, but check your GPU temperature and cooling arrangements.
  • Many playback issues can be resolved by making sure enough memory has been allocated to the video card, 256MB is a bare minimum requirement and 512MB is strongly recommended. For on-board video this is usually configured via the "GPU Window" BIOS option.

Troubleshooting

Tearing of the OSD over a perfect video playback can be avoided by stopping playback, exiting playback, and re-starting playback of the stream. (No idea why this works..only that it does.)

To prevent vertical and horizontal tearing of the image when viewing live tv or recordings, run the following to disable X Composite Extension (may also cure the all white/gray OSD):

   sudo nvidia-xconfig --no-composite 

or with the following lines in /etc/X11/xorg.conf:

   Section "Extensions"        Option "Composite" "Disabled"    EndSection 

This may also help eliminate sporadic single-frame stuttering glitches (e.g. slight jerks in long panning shots or scrolling backgrounds).

The following configuration changes should be used to prevent issues with VDPAU when used with MythTV:

  • Enable OpenGL VSync within MythTV at Setup -> TV Settings -Playback (Page 1) - This may no longer be required - I haved this disabled with no playback issues (Dave K - 05/10/2009)
  • Enable Extra Audio Buffering (same page)
  • Disable Real-Time Priority (same page) (or limits.conf) if you have intermittent playback freezes (playback stops for about 30 seconds,the computer is COMPLETELY unresponsive during this period and then playback resumes as is nothing had happened)
  • Adding 'Option "TripleBuffer" "true"' to the Device section of xorg.conf (following the 'Driver nvidia' line) will allocate more memory buffers to 2D playback (and less to 3D).
   Option         "TripleBuffer" "True" 

Artefacts

  • If you have problems with Artefacts while playing, you can try to add "vdpaubuffersize=32" in the special filters on the Playback Settings Page!

CPU Frequency Scaling

If you are using CPU frequency scaling and are having problems playing HD video with VDPAU (stuttering video or audio) then it maybe that your processor is causing a bottleneck. Two known issues exist:

  • Some AMD processors reduce the bus speed along with the CPU clock, at the lowest scaling level this may be enough to cause VDPAU problems in transferring data fast enough across the bus. One solution is to increase the minimum speed by changing the value in /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq, see sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies for a list of valid values. e.g. On for a CPU with a min speed of 1000Mhz you may need to bump the min speed to 1800Mhz.

As root:

echo 1800000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
  • If frequency scaling is still causing problems then it may be due to too high a threshold being set for frequency changes. Ubuntu for example uses a ridiculous threshold of 95% utilisation per core which is beyond what many userspace applications are even allowed to achieve at their priority level. So an application like MythTV would be choking and the ondemand governor would never increase the CPU frequency to cope. You should first check that your distribution has a reasonable value configured for the 'up threshold', what's reasonable will vary but 50% is a good place to start.

External Links

NVIDIA Linux Forum

More info on VDPAU from NVIDIA

List of all NVIDIA chipsets and level of VDPAU support

Note: This list is dependent on the driver version. This currently points to the version 190.53 README file appendix. Newer versions of the driver may add other GPUs to the list and other capabilities.

Link to the newest driver versions: stable and beta

Nvidia Vdpau Team PPA

Nvidia Vdpau Team PPA

PPA description

This PPA contains updated mplayer/smplayer builds geared towards use with Nvidia's VDPAU hardware accelerated playback of Mpeg2/VC1/WMV3/H.264.

Turn off Post-Processing and multithreading.

----------------------------------------------------------------------------

----------------------------------------------------------------------------

Xine-vdpau is a replacement for Xine which contains vdpau support. Most of the frontends for Xine should use the vdpau driver and codecs automatically, but Totem-Xine needs a bit of a push. To use with Totem-Xine, go to ~/.config/totem and open xine_config. change #video.driver:auto to video.driver:vdpau.

Note that Xine-vdpau is based on libxine 1.1.16 as it was approximately in December of 2008.

----------------------------------------------------------------------------

The 190 series is currently the official stable release.
The 190 series has support for OpenGL 3.2 and GLSL 1.5.

----------------------------------------------------------------------------

To report bugs with the packages in this PPA, use the team email link. If you have a display bug in the Nvidia driver, please report bugs in the nvforums site here: http://www.nvnews.net/vbulletin/forumdisplay.php?s&forumid=14

Also, for XBMC users see this PPA: https://launchpad.net/~team-xbmc/+archive/ppa
For Mythtv users see this PPA: http://mythbuntu.org/auto-builds

Video Decode and Presentation API for Unix

Video Decode and Presentation API for Unix

Introduction

The Video Decode and Presentation API for Unix (VDPAU) provides a complete solution for decoding, post-processing, compositing, and displaying compressed or uncompressed video streams. These video streams may be combined (composited) with bitmap content, to implement OSDs and other application user interfaces.

API Partitioning

VDPAU is split into two distinct modules:

The intent is that most VDPAU functionality exists and operates identically across all possible Windowing Systems. This functionality is the Core API.

However, a small amount of functionality must be included that is tightly coupled to the underlying Windowing System. This functionality is the Window System Integration Layer. Possibly examples include:

  • Creation of the initial VDPAU VdpDevice handle, since this act requires intimate knowledge of the underlying Window System, such as specific display handle or driver identification.
  • Conversion of VDPAU surfaces to/from underlying Window System surface types, e.g. to allow manipulation of VDPAU-generated surfaces via native Window System APIs.

Object Types

VDPAU is roughly object oriented; most functionality is exposed by creating an object (handle) of a certain class (type), then executing various functions against that handle. The set of object classes supported, and their purpose, is discussed below.

Device Type

A VdpDevice is the root object in VDPAU's object system. The Window System Integration Layer allows creation of a VdpDevice object handle, from which all other API entry points can be retrieved and invoked.

Surface Types

A surface stores pixel information. Various types of surfaces existing for different purposes:

  • VdpVideoSurfaces store decompressed YCbCr video frames in an implementation-defined internal format.
  • VdpOutputSurfaces store RGB 4:4:4 data. They are legal render targets for video post-processing and compositing operations.
  • VdpBitmapSurfaces store RGB 4:4:4 data. These surfaces are designed to contain read-only bitmap data, to be used for OSD or application UI compositing.

Transfer Types

A data transfer object reads data from a surface (or surfaces), processes it, and writes the result to another surface. Various types of processing are possible:

Data Flow

Compressed video data originates in the application's memory space. This memory is typically obtained using malloc, and filled via regular file or network read system calls. Alternatively, the application may mmap a file.

The compressed data is then processed using a VdpDecoder, which will decompress the field or frame, and write the result into a VdpVideoSurface. This action may require reading pixel data from some number of other VdpVideoSurface objects, depending on the type of compressed data and field/frame in question.

If the application wishes to display any form of OSD or user-interface, this must be created in a VdpOutputSurface.

This process begins with the creation of VdpBitmapSurface objects to contain the OSD/UI's static data, such as individual glyphs.

VdpOutputSurface rendering functionality may be used to composite together various VdpBitmapSurfaces and VdpOutputSurfaces, into another VdpOutputSurface "VdpOutputSurface".

Once video has been decoded, it must be post-processed. This involves various steps such as color space conversion, de-interlacing, and other video adjustments. This step is performed using an VdpVideoMixer object. This object can not only perform the aforementioned video post-processing, but also composite the video with a number of VdpOutputSurfaces, thus allowing complex user interfaces to be built. The final result is written into another VdpOutputSurface.

Note that at this point, the resultant VdpOutputSurface may be fed back through the above path, either using VdpOutputSurface rendering functionality, or as input to the VdpVideoMixer object.

Finally, the resultant VdpOutputSurface must be displayed on screen. This is the job of the VdpPresentationQueue object.

vdpau_data_flow.png

Entry Point Retrieval

VDPAU is designed so that multiple implementations can be used without application changes. For example, VDPAU could be hosted on X11, or via direct GPU access.

The key technology behind this is the use of function pointers and a "get proc address" style API for all entry points. Put another way, functions are not called directly via global symbols set up by the linker, but rather through pointers.

In practical terms, the Window System Integration Layer provides factory functions which not only create and return VdpDevice objects, but also a function pointer to a VdpGetProcAddress function, through which all entry point function pointers will be retrieved.

Philosophy

It is entirely possible to envisage a simpler scheme whereby such function pointers are hidden. That is, the application would link against a wrapper library that exposed "real" functions. The application would then call such functions directly, by symbol, like any other function. The wrapper library would handle loading the appropriate back-end, and implementing a similar "get proc address" scheme internally.

However, the above scheme does not work well in the context of separated Core API and Window System Integration Layer. In this scenario, one would require a separate wrapper library per Window System, since each Window System would have a different function name and prototype for the main factory function. If an application then wanted to be Window System agnostic (making final determination at run-time via some form of plugin), it may then need to link against two wrapper libraries, which would cause conflicts for all symbols other than the main factory function.

Another disadvantage of the wrapper library approach is the extra level of function call required; the wrapper library would internally implement the existing "get proc address" and "function pointer" style dispatch anyway. Exposing this directly to the application is slightly more efficient.

Multi-threading

All VDPAU functionality is fully thread-safe; any number of threads may call into any VDPAU functions at any time. VDPAU may not be called from signal-handlers.

Note, however, that this simply guarantees that internal VDPAU state will not be corrupted by thread usage, and that crashes and deadlocks will not occur. Completely arbitrary thread usage may not generate the results that an application desires. In particular, care must be taken when multiple threads are performing operations on the same VDPAU objects.

VDPAU implementations guarantee correct flow of surface content through the rendering pipeline, but only when function calls that read from or write to a surface return to the caller prior to any thread calling any other function(s) that read from or write to the surface. Invoking multiple reads from a surface in parallel is OK.

Note that this restriction is placed upon VDPAU function invocations, and specifically not upon any back-end hardware's physical rendering operations. VDPAU implementations are expected to internally synchronize such hardware operations.

In a single-threaded application, the above restriction comes naturally; each function call completes before it is possible to begin a new function call.

In a multi-threaded application, threads may need to be synchronized. For example, consider the situation where:

In this case, the threads must synchronize to ensure that thread 1's call to VdpDecoderRender has returned prior to thread 2's call(s) to VdpVideoMixerRender that use that specific surface. This could be achieved using the following pseudo-code:

 Queue q_full_surfaces;  Queue q_empty_surfaces;   thread_1() {      for (;;) {          VdpVideoSurface s = q_empty_surfaces.get();          // Parse compressed stream here          VdpDecoderRender(s, ...);          q_full_surfaces.put(s);      }  }   // This would need to be more complex if  // VdpVideoMixerRender were to be provided with more  // than one field/frame at a time.  thread_2() {      for (;;) {          // Possibly, other rendering operations to mixer          // layer surfaces here.          VdpOutputSurface t = ...;          VdpPresentationQueueBlockUntilSurfaceIdle(t);          VdpVideoSurface s = q_full_surfaces.get();          VdpVideoMixerRender(s, t, ...);          q_empty_surfaces.put(s);          // Possibly, other rendering operations to "t" here          VdpPresentationQueueDisplay(t, ...);      }  } 

Finally, note that VDPAU makes no guarantees regarding any level of parallelism in any given implementation. Put another way, use of multi-threading is not guaranteed to yield any performance gain, and in theory could even slightly reduce performance due to threading/synchronization overhead.

However, the intent of the threading requirements is to allow for e.g. video decoding and video mixer operations to proceed in parallel in hardware. Given a (presumably multi-threaded) application that kept each portion of the hardware busy, this would yield a performance increase.

Surface Endianness

When dealing with surface content, i.e. the input/output of Put/GetBits functions, applications must take care to access memory in the correct fashion, so as to avoid endianness issues.

By established convention in the 3D graphics world, RGBA data is defined to be an array of 32-bit pixels containing packed RGBA components, not as an array of bytes or interleaved RGBA components. VDPAU follows this convention. As such, applications are expected to access such surfaces as arrays of 32-bit components (i.e. using a 32-bit pointer), and not as interleaved arrays of 8-bit components (i.e. using an 8-bit pointer.) Deviation from this convention will lead to endianness issues, unless appropriate care is taken.

The same convention is followed for some packed YCbCr formats such as VDP_YCBCR_FORMAT_Y8U8V8A8; i.e. they are considered arrays of 32-bit pixels, and hence should be accessed as such.

For YCbCr formats with chroma decimation and/or planar formats, however, this convention is awkward. Therefore, formats such as VDP_YCBCR_FORMAT_NV12 are defined as arrays of (potentially interleaved) byte-sized components. Hence, applications should manipulate such data 8-bits at a time, using 8-bit pointers.

Note that one common usage for the input/output of Put/GetBits APIs is file I/O. Typical file I/O APIs treat all memory as a simple array of 8-bit values. This violates the rule requiring surface data to be accessed in its true native format. As such, applications may be required to solve endianness issues. Possible solutions include:

  • Authoring static UI data files according to the endianness of the target execution platform.
  • Conditionally byte-swapping Put/GetBits data buffers at run-time based on execution platform.

Note: Complete details regarding each surface format's precise pixel layout is included with the documentation of each surface type. For example, see VDP_RGBA_FORMAT_B8G8R8A8.

Video Decoder Usage

VDPAU is a slice-level API. Put another way, VDPAU implementations accept "slice" data from the bitstream, and perform all required processing of those slices (e.g VLD decoding, IDCT, motion compensation, in-loop deblocking, etc.).

The client application is responsible for:

  • Extracting the slices from the bitstream (e.g. parsing/demultiplexing container formats, scanning the data to determine slice start positions and slice sizes).
  • Parsing various bitstream headers/structures (e.g. sequence header, sequence parameter set, picture parameter set, entry point structures, etc.) Various fields from the parsed header structures needs to be provided to VDPAU alongside the slice bitstream in a "picture info" structure.
  • Surface management (e.g. H.264 DPB processing, display re-ordering)

It is recommended that applications pass solely the slice data to VDPAU; specifically that any header data structures be excluded from the portion of the bitstream passed to VDPAU. VDPAU implementations must operate correctly if non-slice data is included, at least for formats employing start codes to delimit slice data. However, any extra data may need to be uploaded to hardware for parsing thus lowering performance, and/or, in the worst case, may even overflow internal buffers that are sized solely for slice data.

The exact data that should be passed to VDPAU is detailed below for each supported format:

MPEG-1 and MPEG-2

Include all slices beginning with start codes 0x00000101 through 0x000001AF. The slice start code must be included for all slices.

H.264

Include all NALs with nal_unit_type of 1 or 5 (coded slice of non-IDR/IDR picture respectively). The complete slice start code (including 0x000001 prefix) must be included for all slices, even when the prefix is not included in the bitstream.

Note that if desired:

  • The slice start code prefix may be included in a separate bitstream buffer array entry to the actual slice data extracted from the bitstream.
  • Multiple bitstream buffer array entries (e.g. one per slice) may point at the same physical data storage for the slice start code prefix.

VC-1 Simple and Main Profile

VC-1 simple/main profile bitstreams always consist of a single slice per picture, and do not use start codes to delimit pictures. Instead, the container format must indicate where each picture begins/ends.

As such, no slice start codes should be included in the data passed to VDPAU; simply pass in the exact data from the bitstream.

Header information contained in the bitstream should be parsed by the application and passed to VDPAU using the "picture info" data structure; this header information explicitly must not be included in the bitstream data passed to VDPAU for this encoding format.

VC-1 Advanced Profile

Include all slices beginning with start codes 0x0000010D (frame), 0x0000010C (field) or 0x0000010B (slice). The slice start code should be included in all cases.

Some VC-1 advanced profile streams do not contain slice start codes; again, the container format must indicate where picture data begins and ends. In this case, pictures are assumed to be progressive and to contain a single slice. It is highly recommended that applications detect this condition, and add the missing start codes to the bitstream passed to VDPAU. However, VDPAU implementations must allow bitstreams with missing start codes, and act as if a 0x0000010D (frame) start code had been present.

Note that pictures containing multiple slices, or interlace streams, must contain a complete set of slice start codes in the original bitstream; without them, it is not possible to correctly parse and decode the stream.

The bitstream passed to VDPAU should contain all original emulation prevention bytes present in the original bitstream; do not remove these from the bitstream.

MPEG-4 Part 2 and DivX

Include all slices beginning with start codes 0x000001B6. The slice start code must be included for all slices.

Video Mixer Usage

VdpVideoSurface Content

Each VdpVideoSurface is expected to contain an entire frame's-worth of data, irrespective of whether an interlaced of progressive sequence is being decoded.

Depending on the exact encoding structure of the compressed video stream, the application may need to call VdpDecoderRender twice to fill a single VdpVideoSurface. When the stream contains an encoded progressive frame, or a "frame coded" interlaced field-pair, a single VdpDecoderRender call will fill the entire surface. When the stream contains separately encoded interlaced fields, two VdpDecoderRender calls will be required; one for the top field, and one for the bottom field.

Implementation note: When VdpDecoderRender renders an interlaced field, this operation must not disturb the content of the other field in the surface.

VdpVideoMixer Surface List

An video stream is logically composed of a sequence of fields. An example is shown below, in display order, assuming top field first:

t0 b0 t1 b1 t2 b2 t3 b3 t4 b4 t5 b5 t6 b6 t7 b7 t8 b8 t9 b9

The canonical usage is to call VdpVideoMixerRender once for decoded field, in display order, to yield one post-processed frame for display.

For each call to VdpVideoMixerRender, the field to be processed should be provided as the video_surface_current parameter.

To enable operation of advanced de-interlacing algorithms and/or post-processing algorithms, some past and/or future surfaces should be provided as context. These are provided in the video_surface_past and video_surface_future lists. In general, these lists may contain any number of surfaces. Specific implementations may have specific requirements determining the minimum required number of surfaces for optimal operation, and the maximum number of useful surfaces, beyond which surfaces are not used. It is recommended that in all cases other than plain bob/weave, at least 2 past and 1 future frame be provided.

Note that it is entirely possible, in general, for any of the VdpVideoMixer post-processing steps other than de-interlacing to require access to multiple input fields/frames. For example, an motion-sensitive noise-reduction algorithm.

For example, when processing field t4, the VdpVideoMixerRender parameters may contain the following values, if the application chose to provide 3 fields of context for both the past and future:

 current_picture_structure: VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD  past:    [b3, t3, b2]  current: t4  future:  [b4, t5, b5]  

Note that for both the past/future lists, array index 0 represents the field temporally closest to current, in display order.

The VdpVideoMixerRender parameter current_picture_structure applies to video_surface_current. The picture structure for the other surfaces will be automatically derived from that for the current picture. The derivation algorithm is extremely simple; the concatenated list past/current/future is simply assumed to have an alternating top/bottom pattern throughout.

Continuing the example above, subsequent calls to VdpVideoMixerRender would provide the following sets of parameters:

 current_picture_structure: VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD  past:    [t4, b3, t3]  current: b4  future:  [t5, b5, t6]  

then:

 current_picture_structure: VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD  past:    [b4, t4, b3]  current: t5  future:  [b5, t6, b7]  

In other words, the concatenated list of past/current/future frames simply forms a window that slides through the sequence of decoded fields.

It is syntactically legal for an application to choose not to provide a particular entry in the past or future lists. In this case, the "slot" in the surface list must be filled with the special value VDP_INVALID_HANDLE, to explicitly indicate that the picture is missing; do not simply shuffle other surfaces together to fill in the gap. Note that entries should only be omitted under special circumstances, such as failed decode due to bitstream error during picture header parsing, since missing entries will typically cause advanced de-interlacing algorithms to experience significantly degraded operation.

Specific examples for different de-interlacing types are presented below.

Weave De-interlacing

Weave de-interlacing is the act of interleaving the lines of two temporally adjacent fields to form a frame for display.

To disable de-interlacing for progressive streams, simply specify current_picture_structure as VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; no de-interlacing will be applied.

Weave de-interlacing for interlaced streams is identical to disabling de-interlacing, as describe immediately above, because each VdpVideoSurface; Video Surface object already contains an entire frame's worth (i.e. two fields) of picture data.

Inverse telecine is disabled when using weave de-interlacing.

Weave de-interlacing produces one output frame for each input frame. The application should make one VdpVideoMixerRender call per pair of decoded fields, or per decoded frame.

Weave de-interlacing requires no entries in the past/future lists.

All implementations must support weave de-interlacing.

Bob De-interlacing

Bob de-interlacing is the act of vertically scaling a single field to the size of a single frame.

To achieve bob de-interlacing, simply provide a single field as video_surface_current, and set current_picture_structure appropriately, to indicate whether a top or bottom field was provided.

Inverse telecine is disabled when using bob de-interlacing.

Bob de-interlacing produces one output frame for each input field. The application should make one VdpVideoMixerRender call per decoded field.

Bob de-interlacing requires no entries in the past/future lists.

Bob de-interlacing is the default when no advanced method is requested and enabled. Advanced de-interlacing algorithms may fall back to bob e.g. when required past/future fields are missing.

All implementations must support bob de-interlacing.

Advanced De-interlacing

Operation of both temporal and temporal-spatial de-interlacing is identical; the only difference is the internal processing the algorithm performs in generating the output frame.

These algorithms use various advanced processing on the pixels of both the current and various past/future fields in order to determine how best to de-interlacing individual portions of the image.

Inverse telecine may be enabled when using advanced de-interlacing.

Advanced de-interlacing produces one output frame for each input field. The application should make one VdpVideoMixerRender call per decoded field.

Advanced de-interlacing requires entries in the past/future lists.

Availability of advanced de-interlacing algorithms is implementation dependent.

De-interlacing Rate

For all de-interlacing algorithms except weave, a choice may be made to call VdpVideoMixerRender for either each decoded field, or every second decoded field.

If VdpVideoMixerRender is called for every decoded field, the generated post-processed frame rate is equal to the decoded field rate. Put another way, the generated post-processed nominal field rate is equal to 2x the decoded field rate. This is standard practice.

If VdpVideoMixerRender is called for every second decoded field (say every top field), the generated post-processed frame rate is half to the decoded field rate. This mode of operation is thus referred to as "half-rate".

Implementations may choose whether to support half-rate de-interlacing or not. Regular full-rate de-interlacing should be supported by any supported advanced de-interlacing algorithm.

The descriptions of de-interlacing algorithms above assume that regular (not half-rate) operation is being performed, when detailing the number of VdpVideoMixerRender calls.

Recall that the concatenation of past/current/future surface lists simply forms a window into the stream of decoded fields. To achieve standard de-interlacing, the window is slid through the list of decoded fields one field at a time, and a call is made to VdpVideoMixerRender for each movement of the window. To achieve half-rate de-interlacing, the window is slid through the* list of decoded fields two fields at a time, and a call is made to VdpVideoMixerRender for each movement of the window.

Inverse Telecine

Assuming the implementation supports it, inverse telecine may be enabled alongside any advanced de-interlacing algorithm. Inverse telecine is never active for bob or weave.

Operation of VdpVideoMixerRender with inverse telecine active is identical to the basic operation mechanisms describe above in every way; all inverse telecine processing is performed internally to the VdpVideoMixer.

In particular, there is no provision way for VdpVideoMixerRender to indicate when identical input fields have been observed, and consequently identical output frames may have been produced.

De-interlacing (and inverse telecine) may be applied to streams that are marked as being progressive. This will allow detection of, and correct de-interlacing of, mixed interlace/progressive streams, bad edits, etc. To implement de-interlacing/inverse-telecine on progressive material, simply treat the stream of decoded frames as a stream of decoded fields, apply any telecine flags (see the next section), and then apply de-interlacing to those fields as described above.

Implementations are free to determine whether inverse telecine operates in conjunction with half-rate de-interlacing or not. It should always operate with regular de-interlacing, when advertized.

Telecine (Pull-Down) Flags

Some media delivery formats, e.g. DVD-Video, include flags that are intended to modify the decoded field sequence before display. This allows e.g. 24p content to be encoded at 48i, which saves space relative to a 60i encoded stream, but still displayed at 60i, to match target consumer display equipment.

If the inverse telecine option is not activated in the VdpVideoMixer, these flags should be ignored, and the decoded fields passed directly to VdpVideoMixerRender as detailed above.

However, to make full use of the inverse telecine feature, these flags should be applied to the field stream, yielding another field stream with some repeated fields, before passing the field stream to VdpVideoMixerRender. In this scenario, the sliding window mentioned in the descriptions above applies to the field stream after application of flags.

Extending the API

Enumerations and Other Constants

VDPAU defines a number of enumeration types.

When modifying VDPAU, existing enumeration constants must continue to exist (although they may be deprecated), and do so in the existing order.

The above discussion naturally applies to "manually" defined enumerations, using pre-processor macros, too.

Structures

In most case, VDPAU includes no provision for modifying existing structure definitions, although they may be deprecated.

New structures may be created, together with new API entry points or feature/attribute/parameter values, to expose new functionality.

A few structures are considered plausible candidates for future extension. Such structures include a version number as the first field, indicating the exact layout of the client-provided data. Such structures may only be modified by adding new fields to the end of the structure, so that the original structure definition is completely compatible with a leading subset of fields of the extended structure.

Functions

Existing functions may not be modified, although they may be deprecated.

New functions may be added at will. Note the enumeration requirements when modifying the enumeration that defines the list of entry points.

Display Preemption

Please note that the display may be preempted away from VDPAU at any time. See Display Preemption for more details.

Trademarks

VDPAU is a trademark of NVIDIA Corporation. You may freely use the VDPAU trademark, as long as trademark ownership is attributed to NVIDIA Corporation.

Vdpau

VDPAU (Video Decode and Presentation API for Unix) is an open source library (libvdpau) and API originally designed by NVIDIA for its GeForce 8 series and later GPU hardware,[2][3] targeted at the X Window System on Unix operating-systems (including Linux, FreeBSD, and Solaris).[4][5][6] This VDPAU API allows video programs to offload portions of the video decoding process and video post-processing to the GPU video-hardware.
Currently, the portions capable of being offloaded by VDPAU onto the GPU are motion compensation (mo comp), inverse discrete cosine transform (iDCT), VLD (Variable-Length Decoding) and Deblocking for MPEG-1, MPEG-2, MPEG-4 ASP (MPEG-4 Part 2), MPEG-4 AVC (H.264 / DivX 6), VC-1, WMV3/WMV9, Xvid / OpenDivX (DivX 4), and DivX 5 encoded videos.[4] Which specific codecs of these that can be offloaded to the GPU depends on the generation version of the GPU hardware, specifically to also decode MPEG-4 ASP (MPEG-4 Part 2), Xvid / OpenDivX (DivX 4), and DivX 5 formats a GeForce 200M (2xxM) Series (the eleventh generation of NVIDIA's GeForce graphics processing units) or newer GPU hardware is required.[7]
VDPAU can be described as the X Window System equivalent of the Microsoft's DxVA (DirectX Video Acceleration) API for Windows.[4]