###############################
AN00127: USB Video Class Device
###############################

************
Introduction
************

This application note shows how to create a USB device compliant to
the standard USB Video Class (UVC) on an `xcore` device.

The code associated with this application note provides an example of
using the XMOS USB Device Library (`lib_xud <https://www.xmos.com/file/lib_xud>`_) and associated USB class descriptors
to provide a framework for the creation of USB video devices like webcam, video player,
camcorders etc.

This example USB video class implementation provides a video camera device running over high
speed USB. It supports standard requests associated with the class. The application doesn't
connect a camera sensor device but emulates it by creating simple video data which is streamed
to the host PC. Any host software that supports viewing UVC compliant video capture devices can
be used to view the video streamed out of the XMOS device. This demonstrates the simple way in
which USB video devices can easily be deployed using an `xcore` device.

.. note::

    This application note provides a standard USB video class device and as a
    result does not require external drivers to run on Windows, macOS or Linux.

This application note is designed to run on `xcore-200` or `xcore.ai` series devices.

The example code provided with the application has been implemented and tested
on the `XK-EVK-XU316` board but there is no dependency on this board and it can be
modified to run on any development board which uses an `xcore-200` or `xcore.ai` series device.

- This document assumes familiarity with the `XMOS xcore` architecture, the Universal Serial Bus 2.0 Specification and related specifications, the `XMOS` tool chain and the xC language. Documentation related to these aspects which are not specific to this application note are linked to in :ref:`further_reading`.

- For the full API listing of the XMOS USB Device (XUD) Library please see the document XMOS USB Device (XUD) Library [#]_.

.. [#] https://www.xmos.com/file/lib_xud


********
Overview
********

USB Video Class (UVC) is a standard class specification that standardises video streaming
functionality on the USB. It enables devices like webcams, digital camcorders, analog video
converters, analog and digital television tuners etc to connect seamlessly with host machines.

UVC supports streaming multiple video formats including YUV, MJPEG, MPEG-2 TS, H.264, DV etc.
It provides structures for describing the functionalities of the video device to the host and
defines USB requests to control different parameters of the device and characteristics of the video
stream. It also provides flexibility for a video device to support multiple video resolutions,
formats and frame rates, which highly influence the bandwidth negotiation between the device and
the host.

Many OS platforms have native support for UVC drivers which greatly reduces the time required for
developers to create USB video devices.

This application note provides a detailed explanation of the UVC implementation for the `xcore` device,
enabling developers to build their own USB video devices.

The standard USB Video Class specification can be found on the USB-IF website.

.. note::

   This application note addresses v1.1 of the specification (https://www.usb.org/document-library/video-class-v11-document-set)

Block diagram
=============

:numref:`block_diagram` shows the block diagram of a USB video class application

.. _block_diagram:
.. figure:: ../images/an00127-block_diagram.drawio.png
   :scale: 100%
   :align: center

   Block diagram of USB video class application

The 'Camera Sensor' shown in the above figure is not interfaced in the demo example but it is
emulated by creating color video frames inside the device.

*******************
Example application
*******************

The example in this application note uses the XMOS USB device library (`lib_xud`) and shows a
simple program that enumerates a USB Video Class device in a host machine and streams uncompressed
video frames in YUV format at a rate of thirty frames per second to video capture software running
on the host.

For this USB Video device application example, the system comprises three tasks running on separate
threads of an `xcore` device.

The tasks perform the following operations:

- A task containing the USB library functionality to communicate over USB.

- A task implementing Endpoint 0 responding to both standard and video class-specific USB
     requests.

- A task implementing the application code to send video data over streaming endpoints.

These tasks communicate via the use of `xCONNECT` channels which allow data to be passed between
application code running on separate logical cores.

:numref:`task_diagram` shows the task and communication structure for this USB video class
application example.

.. _task_diagram:
.. figure:: ../images/an00127-task_diagram.drawio.png
   :scale: 100%
   :align: center

   Task diagram of the USB video device example

|newpage|

CMakeLists.txt additions
========================

To start using the USB library, ``lib_xud`` needs adding to an application `CMakeLists.txt` file::

    set (APP_DEPENDENT_MODULES "lib_xud")

The USB functions can then be accesed via the ``xud_device.h`` header file::

	#include "xud_device.h"

Source code files
=================

The example application consists of multiple source code files and the following list provides an
overview of how the source code is organised.

- ``usb_video.xc``, ``usb_video.h`` - Contains the USB video class descriptors and endpoint
  handler tasks (functions).

- ``uvc_req.c``, ``uvc_req.h`` - Contains functions and data structures to handle
  class-specific USB requests.

- ``uvc_defs.h`` - This header file has defines that are used for USB descriptors,
  class-specific requests and video details like resolution, payload size and frame rate etc.

- ``main.xc`` - Contains ``main()`` function and some USB related definitions.

Setting up the USB components
=============================

``main.xc`` has some arrays in it that are used to configure the endpoints for the the `XMOS` USB
device library. These are displayed below.

.. literalinclude:: ../../app_an00127/src/main.xc
   :start-at: /* Endpoint count defines
   :end-before: int main(

The tables above describe the endpoint configurations for this device. This example
has bi-directional communication with the host machine via the standard endpoint 0 and two other
`IN` endpoints for implementing the part of our video class.

These tables are passed to the function for the USB library which is called from ``main()``.

|newpage|

The main() function
===================

Below is the source code for the main function of this application, which is taken from
the source file ``main.xc``

.. literalinclude:: ../../app_an00127/src/main.xc
   :start-at: int main

Looking at this in more detail, the following can be observed:

- The par statement starts three separate tasks in parallel.

- There is a task to configure and execute the USB library: ``XUD_Main()``. This library
  call runs in an infinite loop and handles all the underlying USB communications and provides
  abstraction at the endpoints level.

- There is a task to start and run the Endpoint 0 code: ``Endpoint0()``. It handles the
  control endpoint zero and must be run in a separate task in order to provide timely
  response to control requests from the host.

- There is a task to handle two other endpoints required for the Video class:
  ``VideoEndpointsHandler()``. This function handles one Isochronous IN
  endpoint for video streaming and one interrupt IN endpoint for sending notifications to host.

- The define ``USB_TILE`` describes the tile on which the individual tasks will run.

- In this example all tasks run on the same tile. Any tasks that directly communicate with `lib_xud`
  must reside on the same tile as ``XUD_Main()``.

- The xCONNECT communication channels used for inter-task communication are setup at the
  beginning of ``main()`` and passed on to respective tasks.

- The USB definitions discussed earlier are passed into the function ``XUD_Main()``.

Configuring the USB device ID
=============================

The USB ID values used for vendor ID and product ID are defined in the file
``uvc_defs.h``. These are used by the host machine to uniquely determine the device. In this case
the vendor of the device is `XMOS`. The product ID is set to a value unique to this example.

This file also contains a define for the version number of the device.

.. literalinclude:: ../../app_an00127/src/uvc_defs.h
   :start-at: USB Video device
   :end-before: USB Sub class

Video device topology
=====================

This section provides a brief overview of the representation of video device in a topology.
It introduces the terms used in the video class specification, which help the reader to
understand the further sections of this application note.

A video device is represented as an interconnection of multiple addressable entities. Each entity
represents a functionality and has properties which are controlled by the USB host. The following
are the different entities:

- **Units**
   - Selector Unit
      - Processing Unit
      - Extension Unit
- **Terminals**
   - Input Terminal
   - Output Terminal
   - Special Terminals (extends the I/O terminal)
      - Media Transport Terminal
      - Camera Terminal

These entities are interconnected by means of *Input Pins* and *Output Pins*.
A Unit has one or more Input Pins and a single Output Pin, where each Pin represents logical data
streams inside the video device. A Terminal has either a single Input Pin or a single Output Pin.
An *Input Terminal(IT)* represents a starting point for data streams of the video device.
An *Output Terminal(OT)* represents an ending point for data streams.

The functionality of a Unit or Terminal is further described through Video Controls. A Control
typically provides access to a specific video property. Video properties include brightness,
contrast, sharpness, digital zoom etc. Each Control has a set of attributes that can be manipulated
or that provide additional information, they are:

- Current setting
- Minimum setting
- Maximum setting
- Resolution
- Size
- Default

For example, the brightness of the video stream could be controlled by the USB host by changing the
current setting of the Brightness Control inside a Processing unit.

:numref:`topology` shows the topology of the demo application

.. _topology:
.. figure:: ../images/an00127-uvc_topology.drawio.png
   :scale: 100%
   :align: center

   Topology of the UVC example

No Units are involved in the demo application example. More information on Units can be found in
the USB Video Class specification documents.

This video device topology is communicated to the host through USB descriptors which are discussed
in the following section.

USB Descriptors
===============

USB Video Class device has to support class-specific descriptors apart from the standard descriptors
defined in the USB specifications. The class specific descriptors are customised according to the
need of the USB Video device.

:numref:`usb_descriptors` shows the descriptors used in the example code.

.. _usb_descriptors:
.. figure:: ../images/an00127-UVC_descriptors.drawio.png
   :scale: 80%

   Hierarchical structure of USB descriptors of UVC example

The above figure is discussed in detail in the following sections.

|newpage|

USB Device Descriptor
---------------------

The standard USB device descriptor is declared for the Video class device in the file ``usb_video.xc``.
Below is the structure which contains this descriptor. This will be requested by the host when the
device is enumerated by the USB host.

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: USB Device Descriptor
   :end-at: }

It can be seen that product, vendor and device firmware revision are all coded
into this structure.

For a Video Class device, it is mandatory to set the ``bDeviceClass``, ``bDeviceSubClass`` and
``bDeviceProtocol`` fields to `0xEF`, `0x02` and `0x01` respectively.

|newpage|

USB Configuration Descriptor
----------------------------

The USB configuration descriptor is used to configure the device in terms of the device class and
the endpoints setup. The hierarchy of descriptors under a configuration includes interface
association descriptor, interfaces descriptors, class-specific descriptors and endpoints descriptors.

When a host requests a configuration descriptor, the entire configuration hierarchy including all
the related descriptors are returned to the host. The following code shows the configuration
hierarchy of the demo application.

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: USB Configuration Descriptor
   :end-at: }

The *configuration descriptor* tells host about the power requirements of the device and the number
of interfaces it supports.

Multiple interfaces together provides the video functionality. This group of interfaces is
called Video Interface Collection. The Video Interface Collection is described by an
*interface association descriptor* (IAD). In the example application, the IAD defines
that the interface zero and one group to form the USB Video device. These two interfaces are:

- Video Control Interface (VC Interface)
- Video Streaming Interface (VS Interface)

Note: A video function must have one VideoControl interface and zero or more VideoStreaming interfaces.

VideoControl Interface
----------------------

This interface controls the functional behavior of the video device. It is described by both
standard and class-specific descriptors.

The *Standard VC interface descriptor* identifies the interface number and class and provides
the number of endpoints that belongs to this interface. The default *Endpoint 0* is used by
this interface for control purpose through class-specific requests. Another optional endpoint
called *Status Interrupt Endpoint* is used to send asynchronous status notifications to the
host. This interrupt endpoint is described by both standard and class-specific endpoint descriptors.

The *Class-Specific VC interface descriptor* describes the whole topology of the video device.
It includes *Unit descriptors* and *Terminal descriptors*. The example application doesn't
include any Units and hence only Terminal descriptors can be found in the
descriptors hierarchy structure.

The Class-Specific descriptors starts with a header called VC Interface Header descriptor.
This descriptor mentions the version of UVC specification followed and the collection of
streaming interfaces to which this VideoControl interface belongs.

The *Input Terminal descriptor* provides information on the functional aspects of the input source
of the video device. Following code shows the fields of this descriptor:

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: USB_VC_INPUT_TERMINAL
   :end-at: /* 6 bAssocTerminal

In the above code, the ``bTerminalID`` is an unique identifier of this terminal and ``bTerminalType``
declares camera as the input type.

The *Output Terminal descriptor* is shown in the following code.

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: USB_VC_OUPUT_TERMINAL
   :end-at: /* 8 iTerminal

The above descriptor shows that the ``bSourceID`` is defined as 0x01 which is the ``bTerminalID`` of
the input terminal. This information shows the interconnection between the entities, which the host
uses to identify the topology of the video device.

VideoStreaming Interface
------------------------

VideoStreaming interfaces are used to interchange video data streams between the Host and the Video
device. Each interface can have one isochronous or bulk data endpoint. Interfaces supporting
isochronous video transfer must have alternate settings which enables host to change the bandwidth
requirements imposed by an active isochronous pipe. It is also mandatory to provide a zero-bandwidth
alternate setting as the default alternate setting(alternate setting zero) that provides the host
software the option to temporarily relinquish USB bandwidth by switching to this alternate setting.

In the UVC example, the zero-bandwidth alternate setting of the VideoStreaming interface is
described by standard interface descriptor and class-specific VS interface descriptors.

The *Standard VS interface descriptor* provides the interface number, the number of endpoints that
belongs to this interface etc. In case of zero-bandwidth alternate setting the number of endpoints
is set to zero.

The *Class-Specific VS interface descriptors* are used to describe the supported video stream
formats, video frame details, still image frame details, color profile of video data etc. The
following is the list of these class-specific descriptors:

- Input Header descriptor
- Output Header descriptor
- Payload Format descriptor
- Video Frame descriptor
- Still Image frame descriptor
- Color Matching descriptor

The *Input Header descriptor* is meant for interfaces that contain IN endpoint and *Output Header*
is for interfaces that contain OUT endpoint.

The following code shows the fields of Input Header descriptor:

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: USB_VS_INPUT_HEADER,
   :end-at: /* 8 bTerminalLink

The above code shows the number of formats supported, the address of endpoint which streams video
data and the output terminal ID which links to this streaming interface.

The *Payload Format descriptor* describes the video format. The fields of this descriptor is shown
below:

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: USB_VS_FORMAT_UNCOMPRESSED,
   :end-at: /* 22 bDefaultFrameIndex

The above code shows that the video stream is of uncompressed YUY2 format and uses 16-bits per pixel.

The *Video Frame descriptor* mentions the frame resolution, frame rate, video buffer size etc.
The following code shows the fields of this descriptor:

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: USB_VS_FRAME_UNCOMPRESSED
   :end-at: /* 26 dwFrameInterval

The defines used in the above code are present in the *uvc_defs.h* file and they are shown below:

.. literalinclude:: ../../app_an00127/src/uvc_defs.h
   :start-at: /* USB Video resolution
   :end-at: #define FRAME_INTERVAL

The other alternate setting of this interface has the data streaming isochronous endpoint and it is
the operational alternate setting. The class-specific descriptors are not repeated in this alternate
setting.

The *Standard VS Isochronous Endpoint descriptor* of the alternate setting 1 of the UVC example is
shown below:

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: /* Standard VS Isochronous Video Data
   :end-at: /* 6 bInterval

The above code shows that the maximum packet size of the endpoint ('wMaxPacketSize') is ``VS_ISO_EP_DESC_WMAXPACKETSIZE``, which encodes the
maximum packet size per transaction in bytes (1024) and the number of transaction opportunities per microframe (``XUD_USB_ISO_MAX_TXNS_PER_MICROFRAME``).
The 'bInterval' of `0x01` requests host to poll the endpoint every microframe (125 us).

In general, USB video devices supports a set of video parameter combinations (including video
format, frame size and frame rate) and multiple alternate settings with different maximum packet
size endpoints. This enables the host to select the appropriate alternate setting that provides
only the required bandwidth for a given video parameter combination.

USB String Descriptors
----------------------

String descriptors provide human readable information for the device and can be configured
with specific USB product information. The descriptors are placed in an array as shown below:

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: String table
   :end-at: }

The XMOS USB library will take care of encoding the strings into Unicode and structure the content
into USB string descriptor format.

|newpage|

USB Standard and Class-Specific requests
========================================

In *usb_video.xc* there is a function *Endpoint0()* which handles all the USB control requests sent by host to the control endpoint 0. USB control requests includes both standard USB requests and the UVC class-specific requests.

In *Endpoint0()* function, a USB request is received as a setup packet by calling *USB_GetSetupPacket()* library function. The setup packet structure is then examined to distinguish between standard and class-specific requests.

The XMOS USB library provides a function *USB_StandardRequests()* to handle the standard USB requests. This function is called with Setup packet and descriptors structures as shown below

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: /* Returns  XUD_RES_OKAY if handled okay,
   :end-at: }

The video class interfaces use endpoint 0 as the control element and receives all class-specific requests on it. The class-specific requests are used to set and get video related controls. These request are divided into:

- VideoControl requests
- VideoStreaming requests

The function *UVC_InterfaceClassRequests()* present in *uvc_req.c* handles the class-specific
requests. The defines corresponding to the class-specific request codes are present in
*uvc_defs.h* as shown below.

.. literalinclude:: ../../app_an00127/src/uvc_defs.h
   :start-at: /* Video Class-specific
   :end-before: /* Video Streaming Interface Control selectors

In the UVC example, the SET and GET requests for Video Probe and Commit Controls are handled.
The Video Probe and Commit Controls are involved in the negotiation of streaming parameters between the host and the device.
The following code shows the structure of the streaming parameters that are negotiated with those Controls.

.. literalinclude:: ../../app_an00127/src/uvc_req.h
   :start-at: /* Video Probe and Commit Controls
   :end-before: extern UVC_ProbeCommit_Ctrl_t

The demo application doesn't have multiple set of streaming parameters and therefore the GET_DEF, GET_MIN, GET_MAX and GET_CUR requests are handled similarly and return same values to the host.

This source code can be easily extended to support more class-specific requests.

Video data streaming
====================

Streaming video data between device and host takes place through the streaming endpoint of the VideoStreaming interface.
The video is streamed by continuously transmitting the video samples at a particular rate.
A video sample refers to an encoded block of video data that the format-specific decoder is able to accept and interpret in a single transmission.

In the UVC example, the video data is packed in 4:2:2 YUV format (YUY2) and a video sample corresponds to a single video frame of 480x270 pixels.
Each video sample is split into multiple class-defined Payload Transfers.
A Payload Transfer is composed of the class-defined payload header followed by the video payload data. The payload format is as shown below:

.. figure:: ../images/an00127-payload_format_uncompressed.drawio.png
   :scale: 100%
   :align: center

   Payload format for uncompressed streams

For an isochronous endpoint, each (micro)frame will contain a single payload transfer.
Each payload transfer consists of the payload header followed by the payload data.

The maximum packet size of the isochronous endpoint in the example code is ``1024 * XUD_USB_ISO_MAX_TXNS_PER_MICROFRAME`` bytes.
The provided application builds two configurations - the ``30fps`` configuration with ``XUD_USB_ISO_MAX_TXNS_PER_MICROFRAME`` set to its default value of 1,
which allows 1 USB IN transaction per payload transfer, and a ``60fps`` configuration with ``XUD_USB_ISO_MAX_TXNS_PER_MICROFRAME`` set to 2,
allowing for 2 USB transactions per payload transfer. Note that the ``60fps`` configuration utilises the high bandwidth ISO endpoint capability.

Excluding the 12 bytes of payload header, 1012 bytes are available for the video
data in a single payload transfer for the ``30fps`` configuration and 2036 bytes are available for video data in the ``60fps`` configuration.

The video payload data in each payload transfer consists of either a single scan line of the image (``30fps`` configuration) or two scan lines
of the image (``60fps`` configuration).

The function *VideoEndpointsHandler()* present in *usb_video.xc* handles the isochronous video data endpoint.
Each payload transfer is carried out by using the *XUD_SetBuffer()* API of the USB library.

For demonstration, a predefined image of size 480x270 pixels in YUV2 format is stored in `app_an00127/imgs/img.h` file.
Each time a full frame is transmitted over USB, the starting position of each row shifts by one pixel, creating a motion effect that simulates video.

The code below fills the payload buffer with the payload header:

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: /* Fill the payload buffer with payload header
   :end-before: /* Fill the payload buffer with payload data

In the above code, the ``pts`` is Presentation timestamp and it is obtained from a timer running in the xCORE device at 100MHz.
The ``pts`` and ``sofCounts`` (count of USB SOF) are used to arrive at the Source Clock reference field.

This is followed by filling the payload data in the the payload buffer with either one or two lines of the image.
The line start pixel for a give frame transfer is governed by ``increment`` which is incremented by 1
every frame transfer to simulate a rolling effect.

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: /* Fill the payload buffer with payload data
   :end-before: line_count += 1;

The payload transfer is carried out by calling ``XUD_SetBuffer()`` as shown below:

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-at: /* Payload transfer
   :end-before: }

When the complete image is transferred, ``line_count`` rolls back to 0 and ``increment`` is incremented by one
to move the line start pixel for the next transfer.

.. literalinclude:: ../../app_an00127/src/usb_video.xc
   :start-after: line_count += 1;
   :end-before: presentationTimer

|newpage|

Demo hardware setup
===================

To setup the demo hardware the following boards are required.

- `XK-EVK-XU316` board (:numref:`hw_board`)
- 2 x Micro-B USB cable

.. _hw_board:
.. figure:: ../images/xk-evk-xu316.png
   :scale: 50%
   :align: center

   XMOS `XK-EVK-316` Board

The hardware should be configured as follows:

- Connect the **USB** receptacle of the `XK-EVK-XU316` to the host machine using a USB cable

- Connect the **DEBUG** receptacle `XK-EVK-XU316` to the host machine using a USB cable

Building the application
========================

The application uses the `xcommon-cmake <https://www.xmos.com/file/xcommon-cmake-documentation/?version=latest>`_
build system as bundled with the XTC tools.

To configure the build run the following from an XTC command prompt::

    cd app_an00127
    cmake -G "Unix Makefiles" -B build

If any dependencies are missing it is at this configure step that they will be downloaded by the build system.

Finally, the application binary can be built using ``xmake``::

    xmake -C build

This command will cause a binary `app_an00127.xe` to be generated in the `app_an00127/bin` directory,

Launching the demo device
=========================

Once the demo example has been built the application can be executed on the `XK-EVK-XU316`.

Once built, the binaries `30fps/app_an00127_30fps.xe` will be generated in the `60fps/app_an00127_60fps.xe` directory.

Launching from the command line
-------------------------------

From the command line the ``xrun`` tool is used to download and run the code on the `xcore` device.

In a terminal with XTC tools sourced, from the ``app_an00127/bin`` directory, run::

  xrun --xscope 30fps/app_an00127_30fps.xe

or run::

   xrun --xscope 60fps/app_an00127_60fps.xe

Once this command has executed the application will be running on the `xcore` device and the XMOS USB video device should have
enumerated on the host machine.

|newpage|

Running the demo
================

The demo can be run on any OS that has support for USB Video class driver. Windows, Linux and macOS
have native support for UVC driver. The following sections describe in detail on how to run the demo
on those OS platforms.

Running on Windows
------------------

- In Microsoft Windows, When the USB Video device enumerates the host driver will be
  installed to get the device ready for operation. :numref:`windows_driver_install` shows the dialog
  that completes installation of driver for the *XMOS USB Video Device*.

.. _windows_driver_install:
.. figure:: ../images/windows_driver_install.*
   :scale: 80%

   Driver installation for the Video device

- After the driver is installed properly, use any video capture softwares like VLC
  Media player, AmCap etc to open the *XMOS USB Video Device*.

- Open VLC Media player, select *Media* menu and click *Open Capture Device...*. This will
  open a dialog window on which you can select the Video device as shown in :numref:`win_vlc_select`

.. _win_vlc_select:
.. figure:: ../images/windows_vlc_select.*
   :scale: 80%

   Open Video device in VLC Media player

- Click *Play* to see the demo video streamed out of the Video device.
  The video is a rolling image of a skyline. :numref:`win_vlc_demo` shows a snapshot of the video.

.. _win_vlc_demo:
.. figure:: ../images/windows_vlc_demo.*
   :scale: 80%

   Video streamed from the XMOS USB Video device

Running on macOS
----------------

- On macOS, once the USB Video device is enumerated the UVC driver will be loaded by the
  host to get the device ready for operation. The device will have enumerated as
  *XMOS USB Video Device*.

- The Video device can be opened using any video capture software. *Photo Booth* is one
  such application that comes by default with Mac. Open Photo Booth application, click on
  'Camera' menu and then select *XMOS USB Video Device*. The application will then show
  the video streamed out of the USB device. The demo video shows the skyline of a city moving horizontally in a continuous loop.

Running on Linux
----------------

- Under Linux, when the device enumerates the native UVC driver will be loaded and the
  device will be mounted as */dev/videoX* where 'X' is a number.

- Use any video capture software like VLC Media player, Cheese, luvcview etc
  to open the Video device.

- Open VLC Media player, select *Media* menu and click *Open Capture Device...*. This will
  open a dialog window on which the video device can be selected as shown in :numref:`linux_vlc_select`

.. _linux_vlc_select:
.. figure:: ../images/linux_vlc_select.*
    :scale: 60%

    Open Video device in VLC Media player

- Click *Play* to see the demo video streamed out of the *XMOS USB Video Device*.
  The demo video shows the skyline moving horizontally in a continuous loop

|newpage|

.. _further_reading:

***************
Further reading
***************

* `XMOS` XTC Tools Installation Guide

  https://xmos.com/xtc-install-guide

* `XMOS` XTC Tools User Guide

  https://www.xmos.com/view/Tools-15-Documentation

* `XMOS` application build and dependency management system; `xcommon-cmake`

  https://www.xmos.com/file/xcommon-cmake-documentation/?version=latest

* USB 2.0 Specification

  https://www.usb.org/document-library/usb-20-specification

* USB Video Class Specification v1.1, USB.org:

  https://www.usb.org/document-library/video-class-v11-document-set

* YUV Video Format

  http://en.wikipedia.org/wiki/YUV

  https://www.kernel.org/doc/html/v4.8/media/uapi/v4l/pixfmt-yuyv.html
