Skip to main content

FilterVideoProcessor

The FilterVideoProcessor is a helper class that simplifies the process of applying visual effects to video streams. It extends the NoDropVideoProcessor class, providing a convenient way to apply VideoFilter implementations.

info

You will need to create a VideoFilter implementation to use this class and pass an EglBase instance to the constructor.

We provide two primary VideoFilter types:

  • BitmapVideoFilter, and
  • RawVideoFilter

BitmapVideoFilter​

The BitmapVideoFilter provides a Bitmap of each frame for easy manipulation.

NOTE

This is less performant than using the RawVideoFilter because we do YUV to ARGB conversions internally.

Usage Example​

This example shows how to create a custom BitmapVideoFilter that inverts the colors of the video.

class SampleVideoFilter : BitmapVideoFilter() {
override fun applyFilter(bitmap: Bitmap) {
val width = bitmap.width
val height = bitmap.height

for (y in 0 until height) {
for (x in 0 until width) {
val pixel = bitmap[x, y]

val r = 255 - Color.red(pixel)
val g = 255 - Color.green(pixel)
val b = 255 - Color.blue(pixel)

bitmap[x, y] = Color.rgb(r, g, b)
}
}
}
}

RawVideoFilter​

The RawVideoFilter is quite similar to creating a custom VideoProcessor. It allows you to get frames directly from WebRTC and modify them.

Usage Example​

Here's how to implement a RawVideoFilter that dims the brightness of the video.

class CustomFilter : RawVideoFilter() {
override fun applyFilter(
videoFrame: VideoFrame,
surfaceTextureHelper: SurfaceTextureHelper,
): VideoFrame {
val buffer = videoFrame.buffer
val i420 = buffer.toI420()

if (i420 == null) return videoFrame

val width = i420.width
val height = i420.height

val yPlane = i420.dataY
val yStride = i420.strideY

// Dim brightness: halve all Y (luma) values
for (y in 0 until height) {
for (x in 0 until width) {
val index = y * yStride + x
yPlane.put(index, (yPlane.get(index).toInt() / 2).toByte())
}
}

return VideoFrame(i420, videoFrame.rotation, videoFrame.timestampNs)
}
}

Using the Filter​

After creating a VideoFilter, you can create an instance of FilterVideoProcessor and pass it down to the RealtimeKitMeetingBuilder object.

val eglBase = EglBase.create()

// Create the filter which will be used to process the video frames.
val bgFilter = CustomFilter()

// Create the processor that will execute the filter.
val filterProcessor = FilterVideoProcessor(eglBase = eglBase, filter = bgFilter)

val meeting = RealtimeKitMeetingBuilder()
.setVideoProcessor(filterProcessor)
.build(activity)