

# Adding background filters to your application for the Amazon Chime SDK
<a name="add-filters"></a>

The process of adding background filters follows these broad steps:
+ Check for supported browsers.
+ Create a `VideoFxConfig` object with the configuration you want to use.
+ Use the configuration object to create a `VideoFxProcessor` object.
+ Include the `VideoFxProcessor` object in a `VideoTransformDevice` .
+ Use the `VideoTransformDevice` to start the video input.

**Note**  
To complete those steps, you must first:  
Create a `Logger`.
Choose a video device of class `MediaDeviceInfo`.
Successfully join a `MeetingSession`.

Steps in the following sections explain how to complete the process.

**Topics**
+ [Checking for support before offering a filter for the Amazon Chime SDK](support-check.md)
+ [Creating a VideoFxConfig object for the Amazon Chime SDK](create-videofxconfig.md)
+ [Creating a VideoFxProcessor object for the Amazon Chime SDK](create-videofxprocessor.md)
+ [Configuring the VideoFxProcessor object for the Amazon Chime SDK](configure-videofxprocessor.md)
+ [Creating the VideoTransformDevice object for the Amazon Chime SDK](create-video-transform.md)
+ [Starting video input for the Amazon Chime SDK](start-video-input.md)
+ [Tuning resource utilization for the Amazon Chime SDK](tuning.md)

# Checking for support before offering a filter for the Amazon Chime SDK
<a name="support-check"></a>

The Amazon Chime SDK provides an asynchronous static method that checks for supported browsers and attempts to download the required assets. However, it does not check for device performance. As a best practice, always ensure the users' browsers and devices can support the filters before you offer the filters.

```
import {
    VideoFxProcessor
} from 'amazon-chime-sdk-js';

if (!await VideoFxProcessor.isSupported(logger)) {     
    // logger is optional for isSupported
}
```

# Creating a VideoFxConfig object for the Amazon Chime SDK
<a name="create-videofxconfig"></a>

You can define configurations for `backgroundBlur` and `backgroundReplacement` in the same object. However, you can't set `isEnabled` to `true` for both filters at the same time. That's an invalid configuration.

The `VideoFxConfig` class does no validation of its own. Validation occurs in the next step.

The following example shows a valid `VideoFxConfig`.

```
const videoFxConfig: VideoFxConfig = {
    backgroundBlur: {
        isEnabled: false,
        strength: 'medium'
    },
    backgroundReplacement: {
        isEnabled: false,
        backgroundImageURL: 'space.jpg',
        defaultColor: undefined,
    }
}
```

The following tables list the `VideoFxProcessor` properties that you can specify in the `VideoFxConfig` object.

**Background blur filter properties**


| Property | Type | Description | 
| --- | --- | --- | 
| `isEnabled` | `boolean` |  When `true`, the filter blurs the background. | 
| `strength` | `string` | Determines the extent of blurring. Valid values: `low` \$1 `medium` \$1 `high`. | 

**Background replacement filter properties**


| Property | Type | Description | 
| --- | --- | --- | 
| `isEnabled` | `boolean` |  When `true`, the filter replaces the background\$1. | 
| `backgroundImageURL` | `string` | The URL of the background image. The filter resizes the image dynamically to the dimensions of the current screen. You can use a string such as `https://...` or a data URL such as `data:image/jpeg;base64`. | 
| `defaultColor` | `string` | A hex color string such as `000000` or `FFFFFF`, or a string such as `black` or `white`. If you don't specify an image URL, the processor uses the `defaultColor` as the background. If you don't specify a `defaultColor`, the processor defaults to black. | 

# Creating a VideoFxProcessor object for the Amazon Chime SDK
<a name="create-videofxprocessor"></a>

When creating the `VideoFxProcessor` object, AWS servers download the runtime assets, or a browser cache loads the assets. If network or CSP configurations prevent access to the assets, the `VideoFx.create` operation throws an exception. The resulting VideoFxProcessor is configured as a no-op processor, which won’t affect the video stream.

```
let videoFxProcessor: VideoFxProcessor | undefined = undefined;
try {
  videoFxProcessor = await VideoFxProcessor.create(logger, videoFxConfig);
} catch (error) {
  logger.warn(error.toString());
}
```

`VideoFxProcessor.create` also attempts to load the image from `backgroundReplacement.backgroundImageURL`. If the image fails to load, the processor throws an exception. The processor also throws exceptions for other reasons, such as invalid configurations, unsupported browsers, or underpowered hardware. 

# Configuring the VideoFxProcessor object for the Amazon Chime SDK
<a name="configure-videofxprocessor"></a>

The following tables list the `VideoFxProcessor` properties that you can configure. The example below the tables shows a typical runtime configuration.

**Background blur**  
Background blur takes the following properties:


| Property | Type | Description | 
| --- | --- | --- | 
| `isEnabled` | `boolean` | When `true`, the filter blurs the background. | 
| `strength` | `string` | Determines the extent of blurring. Valid values: `low` \$1 `medium` \$1 `high`. | 

**Background replacement**  
Background replacement takes the following parameters:


| Property | Type | Description | 
| --- | --- | --- | 
| `isEnabled` | `boolean` | When `true`, the filter replaces the background. | 
| `backgroundImageURL` | `string` | The URL of the background image. The filter resizes the image dynamically to the dimensions of the current screen. You can use a string such as `https://...` or a data URL such as `data:image/jpeg;base64`. | 
| `defaultColor` | `string` | A hex color string such as `000000` or `FFFFFF`, or a string such as `black` or `white`. If you don't specify an image URL, the processor uses the `defaultColor` as the background. If you don't specify a `defaultColor` the processor defaults to black. | 

**Changing a configuration at runtime**  
You can change a `VideoFxProcessor` configuration at runtime by using the `videoFxProcessor.setEffectConfig` parameter. The following example shows how to enable background replacement and disable background blur.

**Note**  
You can only specify one type of background replacement at a time. Specify a value for `backgroundImageURL` or `defaultColor`, but not both.

```
videoFxConfig.backgroundBlur.isEnabled = false;
videoFxConfig.backgroundReplacement.isEnabled = true;
try {
  await videoFxProcessor.setEffectConfig(videoFxConfig);
} catch(error) {
  logger.error(error.toString())
}
```

If `setEffectConfig` throws an exception, the previous configuration remains in effect. `setEffectConfig` throws exceptions under conditions similar to those that cause `VideoFxProcessor.create` to throw exceptions.

The following example shows how to change a background image while the video runs.

```
videoFxConfig.backgroundReplacement.backgroundImageURL = "https://my-domain.com/my-other-image.jpg";
try {
  await videoFxProcessor.setEffectConfig(videoFxConfig);
} catch(error) {
  logger.error(error.toString())
}
```

# Creating the VideoTransformDevice object for the Amazon Chime SDK
<a name="create-video-transform"></a>

The following example shows how to create a `VideoTransformDevice` object that contains the `VideoFxProcessor`.

```
// assuming that logger and videoInputDevice have already been set    
const videoTransformDevice = new DefaultVideoTransformDevice(
  logger,
  videoInputDevice,
  [videoFxProcessor]
);
```

# Starting video input for the Amazon Chime SDK
<a name="start-video-input"></a>

The following example shows how to use the `VideoTransformDevice` object to start video input. 

```
// assuming that meetingSession has already been created
await meetingSession.audioVideo.startVideoInput(videoTransformDevice);
meetingSession.audioVideo.start();
meetingSession.audioVideo.startLocalVideoTile();
```

# Tuning resource utilization for the Amazon Chime SDK
<a name="tuning"></a>

When creating the `VideoFxProcessor`, you can supply the optional `processingBudgetPerFrame` parameter and control the amount of CPU and GPU that the filters use.

```
let videoFxProcessor: VideoFxProcessor | undefined = undefined;
const processingBudgetPerFrame = 50;
try {
  videoFxProcessor = await VideoFxProcessor.create(logger, videoFxConfig, processingBudgetPerFrame);
} catch (error) {
  logger.warn(error.toString());
}
```

The `VideoFxProcessor` requires time to process a frame. The amount of time depends on the device, the browser, and what else is running in the browser or on the device. The processor uses the concept of a *budget* to target the amount of time used to process and render each frame.

Processing time is in milliseconds. As an example of how to use a budget, 1 second has 1000ms. Targeting 15 frames per second of video capture results in a total budget of 1000ms/15fps = 66ms. You can set a budget of 50% of that, or 33ms, by supplying the value `50` in the `processingBudgetPerFrame` parameter, as shown in the example above.

The `VideoFxProcessor` then tries to process the frames within the budget specified. If processing runs over budget, the processor reduces visual quality to stay within budget. The processor continues to reduce visual quality to a minimum, at which point it stops reducing. This processing duration is measured continually, so if more resources become available, such as another app closing and freeing up CPU, the processor raises visual quality again until it hits the budget, or maximum visual quality is achieved.

If you don't supply a value to `processingBudgetPerFrame`, the `VideoFxProcessor` defaults to `50`.