Installing Ubuntu Rootfs on NXP i.MX6 boards

Document created by Bio_TICFSL Employee on Mar 31, 2016Last modified by Bio_TICFSL Employee on Jun 30, 2016
Version 2Show Document
  • View in full screen mode

This post describes the setup detail for installing Ubuntu based distro in any i.Mx6x NXP Boards. Details are described on:

1. Select your board, Setting the host, Download and compile uboot , dtb and and the Kernel version on your board.

2. Installing the Ubuntu core, Lubuntu graphics desktop version and/or Build your own Ubuntu rootfs with debootstrap.

3. Modify rootfs and Installing needed packages

4. Setting with SD image.

5. Setting Ubuntu on target

6. Adding GPU acceleration

 

 

1: Select your board, Setting the host, Download and compile uboot , dtb and and the Kernel version on your board.

Supported NXP HW boards:

  • i.MX 6QuadPlus SABRE-SD Board and Platform
  • i.MX 6Quad SABRE-SD Board and Platform
  • i.MX 6DualLite SABRE-SD Board
  • i.MX 6Quad SABRE-AI Board
  • i.MX 6DualLite SABRE-AI Board
  • i.MX 6SoloX SABRE-SD Board
  • i.MX 6SoloX SABRE-AI Board

 

Install host dependences (version tested 14.04):

$ sudo apt-get install gparted git build-essential libncurses5 wget u-boot-tools zlib1g-dev ncurses-dev \
cmake libc-dev-armhf-cross pkg-config-arm-linux-gnueabihf build-essential checkinstall cmake \
pkg-config lzop libc6 libstdc++6 debootstrap qemu-user-static binfmt-support

 

Download the compiler toolchain and extract it:

$ cd ~/
$ wget -c https://releases.linaro.org/14.09/components/toolchain/binaries/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux.tar.xz
$ tar xf gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux.tar.xz
Create general variable environments:
$ export target=mx6q (e.g. processor: mx6sx, mx6d, mx6dl,etc)
$ export board=sabresd (e.g. sabresd, sabreauto)
$ export ARCH=arm
$ export CROSS_COMPILE=../gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf-
$ unset LDFLAGS

 

Download u-boot

At the release of this document, latest uboot version was imx_3.14.52, it should work with other version as well, so please check the proper version for your board:

$ cd ~/
$ wget –c http://git.freescale.com/git/cgit.cgi/imx/uboot-imx.git/snapshot/uboot-imx-rel_imx_3.14.52_1.1.0_ga.tar.gz
$ tar -xf uboot-imx-rel_imx_3.14.52_1.1.0_ga.tar.gz
$ cd uboot-imx-rel_imx_3.14.52_1.1.0_ga
$ make $targetboard_config    # e.g. mx6qsabresd_config
$ make

Linux Kernel, Firmware, headers, modules and DTS files

$ cd ~/
$ wget –c http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/snapshot/linux-2.6-imx-rel_imx_3.14.52_1.1.0_ga.tar.gz
$ tar xf linux-2.6-imx-rel_imx_3.14.52_1.1.0_ga.tar.gz
$ cd linux-2.6-imx-rel_imx_3.14.52_1.1.0_ga
$ make imx_v7_defconfig
$ make menuconfig
$ make -j4 zImage modules dtbs
$ cd ~/

move your image to binary folder:

$ sudo cp –v uboot-imx-rel_imx_3.14.52_1.1.0_ga/u-boot.imx binary/
$ sudo cp –v linux-2.6-imx-rel_imx_3.14.52_1.1.0_ga/arch/arm/boot/zImage binary/
$ sudo cp –v linux-2.6-imx-rel_imx_3.14.52_1.1.0_ga/arch/arm/boot/dts/i$target-$board.dtb binary/

Now you have the bootloader, device tree and kernel image of your board ready, let’s create the rootfs.

 

2: Installing the Ubuntu core, Lubuntu graphics desktop version and/or Build your own Ubuntu rootfs with debootstrap.

Installing ubuntu core:

$ cd ~/
$ sudo mkdir –p core /media/rootfs /media/kernel
$ wget –c http://cdimage.ubuntu.com/ubuntu-core/releases/14.04/release/ubuntu-core-14.04.4-core-armhf.tar.gz
$ sudo tar –xf ubuntu-core-14.04.4-core-armhf.tar.gz –C core
$ sudo cp -vr core/* /media/rootfs 
$ cd linux-2.6-imx-rel_imx_3.14.52_1.1.0_ga

$ sudo make modules_install firmware_install INSTALL_MOD_PATH=/media/rootfs/ ARCH=arm CROSS_COMPILE=../../gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf-


$ sudo make ARCH=arm CROSS_COMPILE=../../gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf- headers_install INSTALL_HDR_PATH=/media/rootfs/usr




Now you should have your ubuntu rootfs on /media/rootfs folder. and you can pass to part 3 of this post.

 

Installing ubuntu Linaro LXDE:

$ cd ~/
$ sudo mkdir –p core /media/rootfs /media/kernel
$ wget https://releases.linaro.org/14.10/ubuntu/trusty-images/alip/linaro-trusty-alip-20141024-684.tar.gz
$ sudo tar -xf linaro-trusty-alip-20141024-684.tar.gz –C core
$ sudo mv core/binary/* core/
$ sudo rm –rf core/binary
$ sudo cp -vr core/* /media/rootfs
$ cd linux-2.6-imx-rel_imx_3.14.52_1.1.0_ga

$ sudo make modules_install firmware_install INSTALL_MOD_PATH=/media/rootfs/ ARCH=arm CROSS_COMPILE=../../gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf-

$ sudo make ARCH=arm CROSS_COMPILE=../../gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf- headers_install INSTALL_HDR_PATH=/media/rootfs/usr


Now you should have your ubuntu rootfs on /media/rootfs folder. and you can pass to part 3 of this post.

 

Installing with debootstrap

$ cd ~/
$ target=rootfs
$ distro=trusty
$ sudo debootstrap --arch=armhf --foreign --include=ubuntu-keyring,apt-transport-https,ca-certificates,openssl $distro "$target" http://ports.ubuntu.com
$ sudo cp /usr/bin/qemu-arm-static $target/usr/bin
$ sudo cp /etc/resolv.conf $target/etc


Now have a minimal Ubuntu rootfs - chroot to it and perform the 2nd stage install:

$ sudo chroot $target  //Now we are in chroot

# distro=trusty
# export LC_ALL=C LANGUAGE=C LANG=C
# /debootstrap/debootstrap --second-stage

Edit the sources.list repositories
# cat <<EOT > /etc/apt/sources.list
deb http://ports.ubuntu.com/ubuntu-ports/ $distro main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ $distro-updates main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ $distro-security main restricted universe multiverse
EOT
# apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 40976EAF437D05B5
# apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 3B4FE6ACC0B21F32
# apt-get update
# apt -y -f install
# apt-get upgrade
# apt-get install nano
Now you should be able to login without password, then use passwd command to set one. If you like to add custom users:
# passwd root
# adduser <myuser>
# usermod -a -G tty myuser 
# usermod -a -G dialout, adm, sudo, dip, plugdev myuser 

# visudo
Under the line that looks like:
root ALL=(ALL:ALL) ALL

add the following (change user with your actual username)
<myuser> ALL=(ALL) ALL

your rootfs is ready, exit chroot
# exit
$ sudo rm $target/etc/resolv.conf
$ sudo rm $target/usr/bin/qemu-arm-static
$ sudo mv rootfs/* /media/rootfs

$ cd linux-2.6-imx-rel_imx_3.14.52_1.1.0_ga
$ sudo make modules_install firmware_install INSTALL_MOD_PATH=/media/rootfs/ ARCH=arm CROSS_COMPILE=../../gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf-

$ sudo make ARCH=arm CROSS_COMPILE=../../gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf- headers_install INSTALL_HDR_PATH=/media/rootfs/usr




Now you should have your ubuntu rootfs on /media/root.

 

3: Modify Rootfs and Install needed packages

Edit and verify the sources.list repositories

$ cd /media/rootfs
$ sudo cat <<EOT > etc/apt/sources.list
deb http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ trusty-updates main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse
EOT

Edit networks interfaces and append in the existing file:

$ sudo nano etc/network/interfaces
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp

If you require Serial Console, remove and include an additional line at the end of the file for  ttymxc0 output as below,

$ sudo nano etc/init/tty1.conf
exec /sbin/getty -8 38400 tty1
exec /sbin/getty -L 115200 ttymxc0

If you like to change the localhostname:

$ sudo nano etc/hostname
and change to “your name” e.g. imx6Q. 

Set the date and time clock and update

$ sudo nano /etc/rc.local  
Add this:
if [ `date +"%Y"` -eq "1970" ]; then
                    date --set="2016-04-01"
fi
exit 0

(optional for Linaro rootfs)
Edit passwd and remove the x in root and linaro lines
$ sudo nano etc/passwd
root:x:0:0:root:/root:/bin/bash
linaro:x:0:0..
and change like this:                                   
root::0:0:root:/root:/bin/bash
linaro:::0:..

Now you are ready to program your sd image.

 

4: Setup microSD/SD card

For these instructions, we are assuming: DISK=/dev/sdg on your HOST, cat /proc/partitions is very useful for determining the device id.

$ cd ~/
$ export DISK=/dev/sdg

Erase microSD/SD card:

$ sudo dd if=/dev/zero of=${DISK} bs=1M count=10

Install Bootloader

$ cd binary/ 
$ sudo dd if=u-boot.imx of=${DISK} bs=512 seek=2
$ sync

Create Partition layout:

$ cd ~/
$ sudo fdisk ${DISK}
steps:        
d ///delete all partitions currently on sd
n // create new partition
p // Primary partition
1 // partition number 1
2048 //default
+1G //
n // created 2d parition
p
2
default
default
1 // firts
B // to be fat32
W // write partiotions


$ sudo mkfs.vfat ${DISK}1
$ sudo mkfs.ext3  ${DISK}2

 

Mount ext3 SD partition to /media/rootfs:

$ sudo mount ${DISK1} /media/kernel_target
$ sudo mount ${DISK}2 /media/rootfs_target

Copy Files on the SD.

$ cd ~/
$ sudo cp –v binary/ i$target-$board.dtb /media/kernel_target
$ sudo cp –v binary/zImage /media/kernel_target
$ sudo mv /media/rootfs/* /media/rootfs_target

Remove SD:

$ sync
$ sudo umount /media/kernel_target
$ sudo umount /media/rootfs_target

Boot the target, in console you should be login as root.

root@imx6QSabreSD:~#

 

5: Setting Ubuntu on target

Note: If you have issues with sudo on user UID, need to logout and log as root:

imx6Q login: root
Welcome to Ubuntu 14.04.4 LTS (GNU/Linux 3.14.52 armv7l)
root@imx6Q:~# chown root:root /usr/bin/sudo
root@imx6Q:~# chmod 4755 /usr/bin/sudo
root@imx6Q:~# exit

Login with <user $> or root #

# apt-get update 
# apt-get –f install
# apt-get install locales dialog wget
# dpkg-reconfigure locales
# apt-get upgrade
Optional – install some useful packages:
# apt-get install openssh-server can-utils usbutils build-essential automake autoconf libtool

Get and Install the BSP packages (EULA required)

# cd /home/user
# mkdir –p vpu_pack
# cd vpu_pack
# wget http://www.nxp.com/lgfiles/NMG/MAD/YOCTO//firmware-imx-5.3.bin
# wget http://www.nxp.com/lgfiles/NMG/MAD/YOCTO//imx-vpu-5.4.32.bin
# wget http://www.nxp.com/lgfiles/NMG/MAD/YOCTO//libfslcodec-4.0.8.bin
# wget http://www.nxp.com/lgfiles/NMG/MAD/YOCTO//imx-lib-5.1.tar.gz
# chmod +x * 

# ./firmware-imx-5.3.bin --auto-accept --force
# mkdir –p /lib/firmware/vpu
# cp -ravf firmware-imx-5.3/firmware/* /lib/firmware/

# ./imx-vpu-5.4.32.bin --auto-accept --force
# cd imx-vpu-*
# make PLATFORM=IMX6Q all
# make install

# tar -xf imx-lib-5.1.tar.gz
# cd  imx-lib-5.1/
# make -j1 PLATFORM="IMX6Q"
# make PLATFORM="IMX6Q" install 
# cd ..

# ./libfslcodec-4.0.8 --auto-accept –force
# cd libfslcodec-*
# ./autogent.sh --prefix=/usr --enable-fhw --enable-vpu
# make 
# make install

# mv /usr/lib/imx-mm/video-codec/* /usr/lib 
# mv /usr/lib/imx-mm/audio-codec/* /usr/lib
# rm –rf /usr/lib/imx-mm/

# cd ..
# mkdir –p gpu_pack
# cd gpu_pack
# wget http://www.nxp.com/lgfiles/NMG/MAD/YOCTO//imx-gpu-viv-5.0.11.p7.4-hfp.bin
# wget http://www.nxp.com/lgfiles/NMG/MAD/YOCTO//xserver-xorg-video-imx-viv-5.0.11.p7.4.tar.gz

# chmod +x *
# ./imx-gpu-viv-5.0.11.p7.4-hfp –-auto-accept -–force
# cd imx-gpu* 
# cp g2d/usr/include/* /usr/include/
# cp -d g2d/usr/lib/* /usr/lib/
# cp -Pr gpu-core/usr/* /usr
# optional: install demos
# cp -r gpu-demos/opt /
# optional: install gpu tools
# cp -axr gpu-tools/gmem-info/usr/bin/* /usr/bin/
# cd ..

Installing gstreamer-imx, IPU, VPU and GPU support:

Install build deps, gstreamer1.x, this step could take some time (~350MB): 
# apt-get install python pkg-config git gstreamer1.0-x gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-alsa libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-good1.0-dev g++-multilib
# git clone git://github.com/Freescale/gstreamer-imx.git
# cd gstreamer-imx
# ln –s /usr/lib/arm-linux-gnueabihf/gstreamer-1.0/ /usr/lib/gstreamer-1.0
# ./waf configure --prefix=/usr --kernel-headers=/include
# ./waf
# ./waf install
# cd ../../

(optional) Install libimxvpuapi library: This library provides a community based open-source API to the NXP imx-vpu library (the low-level IMX6 VPU interface).

# git clone git://github.com/Freescale/libimxvpuapi.git
# cd libimxvpu*
# ./waf configure –-prefix=/usr
# ./waf
# ./waf install
# cd ..
  • note './waf install' installs artifacts to its prefix + /lib/gstreamer-1.0 but they need to be installed to /usr/lib/arm-linux-gnueabihf/gstreamer-1.0 which is why we created a symlink above before installing
  • note g2d lib required to build G2D
  • note that x11 library is required to build EGL sink with Vivante direct textures (only needed for X11 support)
  • note that libfslaudiocodec is required to build audio plugins

Now you are ready to test gstreamer

 

6: Add GPU HW Acceleration for X11

NOTE: The original version of these build instructions can be found in the Gateworks wiki . Many thanks to them for writing this!

IMX6 IPU, VPU, and GPU support via GStreamer and Gstreamer-imx plugins. Many of the pieces needed (firmware and source-code) are from NXP and not freely redistributable thus must be downloaded from their mirror and extracted from a shell script that forces you to read and agree to their End User License Agreement (EULA).

The following instructions can be used on top of the debootstrap and should work on other sources of Ubuntu or other Linux distributions root filesystems as well

You can easily add X11 support to a base image created with the debootstrap instructions above by adding a few package groups. You will need the following:

  • X11 server - ie Xorg
  • Display Manager - this controls the login to the X session
  • Window Manager - manages window position, re-sizing, decorations, etc for X clients

If in any case you have installed the Linaro LXDE rootfs, it includes the Xorg X11 server, the lxdm Display Manager, the openbox Window Manager, and others useful user applications including the Chromium browser, if you do not install linaro lxde and want to install it please do:

this step could take some time (~650MB) 
  # apt-get install xinit lxde lxterminal lxappearance lxrandr lxshortcut lxinput xinit  xserver-xorg-dev mesa-utils mesa-utils-extra 

Notes:

  • you will need to add a non-root user with adduser for Chromium browser to work. You may choose to set up auto-login for that user by editing /etc/lxdm/default.conf and setting the autologin property in the base section at the beginning of the config file. /etc/xdg/lubuntu/lxdm/lxdm.conf
  • This document takes as based kernel version 3.14.52v, vivante 5.0.11p7.4 correspond to the kernel version used. you should check the BSP release notes in order to know which xserver and Vivante GPU files need to be downloaded from the NXP repos.
$ sudo nano /etc/lxdm/default.conf
   [base]
   autologin=user

To add hardware GPU acceleration to X11 you need to add some libraries and drivers provided by Freescale from the imx-gpu-viv package. This requires signing Freescales End User License Agreement (EULA). This package provides the following:

  • libg2d - a documented low-level API to the GPU (used by things like libimxvpuapi for gstreamer-imx and the gpu-core drivers)
  • gpu-core - provides all the various OpenGL libs (libGL, libGLESv1_CM, libGLESv1_CL, libGLESv2, libGLSLC, libCLC, libEGL, libGAL, libOpenCL, ls
  • libOpenVG) typically provided by the mesa project. Note that several versions of libEGL/libGAL/libGLESv2/libVIVANTE are provided for different backend rendering systems: dfb, fb, wl, x11.
# cd gpu_pack
#cd imx-gpu-*
# cp gpu-core/usr/lib/dri/vivante_dri.so /usr/lib/xorg/modules/drivers/
# chmod 644 /usr/lib/xorg/modules/drivers/vivante_dri.so
# rm /usr/lib/arm-linux-gnueabihf/mesa/libGL.so*
# rm /usr/lib/arm-linux-gnueabihf/mesa-egl/libEGL.so*
# rm /usr/lib/arm-linux-gnueabihf/mesa-egl/libGLESv2.so*
# rm /usr/lib/arm-linux-gnueabihf/mesa-egl/libOpenVG.so*
# cd ../../

# cd gpu-pack
# wget http://www.nxp.com/lgfiles/NMG/MAD/YOCTO//xserver-xorg-video-imx-viv-5.0.11.p7.4.tar.gz

# tar –xf xserver*
# cd xserver-org-video-imx*
#looks lik have to made #git init

# ./fastbuild.sh  BUILD_HARD_VFP=1 XSERVER_GREATER_THAN_13=1
# cd..

# cd kernel-modu*
# make
Switch to gpu-core x11 backend:
# backend=x11
# ln -sf libEGL-${backend}.so /usr/lib/libEGL.so
# ln -sf libEGL-${backend}.so /usr/lib/libEGL.so.1
# ln -sf libEGL-${backend}.so /usr/lib/libEGL.so.1.0
# ln -sf libGAL-${backend}.so /usr/lib/libGAL.so
# ln -sf libGLESv2-${backend}.so /usr/lib/libGLESv2.so
# ln -sf libGLESv2-${backend}.so /usr/lib/libGLESv2.so.2
# ln -sf libGLESv2-${backend}.so /usr/lib/libGLESv2.so.2.0.0
# ln -sf libVIVANTE-${backend}.so /usr/lib/libVIVANTE.so
# ln -sf libGAL_egl.dri.so /usr/lib/libGAL_egl.so
# for i in egl glesv1_cm glesv2 vg; do
        cp /usr/lib/pkgconfig/${i}_${backend}.pc/usr/lib/pkgconfig/${i}.pc
    done
#rm /usr/lib/*-dfb.so /usr/lib/*-fb.so /usr/lib/*-wl.so

(Optional in case you deploy your kernel version with GPU as module) make vivante kernel module (GPU kernel driver) load on boot:

# echo vivante >> /etc/modules
# nano /etc/udev/rules.d/10-imx.rules
KERNEL=="galcore",  MODE="0660", GROUP="video"
KERNEL=="mxc_asrc",  MODE="0666"

Create an xorg.conf configured for the Vivante fbdev driver:

# nano /etc/X11/xorg.conf
Section "Device"
    Identifier "i.MX Accelerated Framebuffer Device"
    Driver "vivante"
    Option "fbdev" "/dev/fb0"
    Option "vivante_fbdev" "/dev/fb0"
    Option "HWcursor" "false"
EndSection

Section "ServerFlags"
    Option "BlankTime"  "0"
    Option "StandbyTime"  "0"
    Option "SuspendTime"  "0"
    Option "OffTime"  "0"
EndSection
# cd ..

Make sure the files copied into the correct places.

If all compiled and copied, you should now see a bunch of new libraries in /usr/lib! Congratulations! After you finish you can reboot your system and start playing.

Testing Gstreamer examples:

  • show gstreamer-imx plugins:
# gst-inspect-1.0 | grep imx
imxvpu:  imxvpuenc_mjpeg: Freescale VPU motion JPEG video encoder
imxvpu:  imxvpuenc_mpeg4: Freescale VPU MPEG-4 video encoder
imxvpu:  imxvpuenc_h264: Freescale VPU h.264 video encoder
imxvpu:  imxvpuenc_h263: Freescale VPU h.263 video encoder
imxvpu:  imxvpudec: Freescale VPU video decoder
imxv4l2videosrc:  imxv4l2videosrc: V4L2 CSI Video Source
imxg2d:  imxg2dcompositor: Freescale G2D video compositor
imxg2d:  imxg2dvideotransform: Freescale G2D video transform
imxg2d:  imxg2dvideosink: Freescale G2D video sink
imxipu:  imxipucompositor: Freescale IPU video compositor
imxipu:  imxipuvideosink: Freescale IPU video sink
imxipu:  imxipuvideotransform: Freescale IPU video transform
imxpxp:  imxpxpvideotransform: Freescale PxP video transform
imxpxp:  imxpxpvideosink: Freescale PxP video sink

 

  • imxipuvideosink:
# gst-launch-1.0 videotestsrc ! imxipuvideosink

imxg2dvideosink:

# gst-launch-1.0 videotestsrc ! imxg2dvideosink

The imxeglvivsink allows hardware accelerated display to a window on the X11 host

# export DISPLAY=:0.0 
# gst-launch-1.0 videotestsrc ! imxeglvivsink

To test if you have graphics support you can run any glmark2 and/or mesa-utils or can run example of the next route:

# cd /opt/viv_samples/vdk/
# ./tutorial1                                                                      //any example

root@imx6Q:~# glxgears -info
GL_RENDERER   = Vivante GC2000
GL_VERSION    = 2.1 2.0.1
GL_VENDOR     = Vivante Corporation
GL_EXTENSIONS = WGL_ARB_extensions_string WGL_EXT_extensions_string WGL_EXT_swap_control GL_EXT_texture_env_add GL_ARB_multitexture GL_ARB_multisample GL_ARB_texture_env_add GL_ARB_texture_compression GL_ARB_texture_env_combine GL_ARB_depth_texture GL_ARB_window_pos ….
1606 frames in 5.0 seconds = 321.130 FPS
1650 frames in 5.0 seconds = 329.834 FPS
L_RENDERER   = Vivante GC2000
GL_VERSION    = 2.1 2.0.1
GL_VENDOR     = Vivante Corporation1629 frames in 5.0 seconds = 325.644 FPS
1621 frames in 5.0 seconds = 324.072 FPS
1650 frames in 5.0 seconds = 329.806 FPS
1651 frames in 5.0 seconds = 330.079 FPS

9 people found this helpful

Attachments

    Outcomes