Android integration using mediapipe
Introduction
The previous post on mediapipe integration explored how to integrate Lluvia with Mediapipe to create complex Computer Vision pipelines leveraging mediapipe’s integration with other frameworks such as OpenCV and Tensorflow. This post expands this integration to run Lluvia on Android systems.
The video below shows the Optical Flow Filter algorithm running on a Samsung Galaxy S22+ phone.
Graph for mobile applications
The figure below illustrates the pipeline used on Android for running the LluviaCalculator. First, a FlowLimiter calculator receives the images from the input_stream. This calculator controls the rate at which packets are sent downstream; it receives an additional input from the last calculator, ImageFrameToGpuBuffer, that indicates processing has been completed and that a new packet can be received.
The GpuBufferToImageFrame and ImageFrameToGpuBuffer calculators convert packets from GpuBuffer to ImageFrame and vice-versa. They are needed for two reasons:
- On Android, the
input_streamandoutput_streamports of the pipeline expectGpuBuffertypes. - Currently, the
Lluviacalculator cannot handleGpuBufferpackets.
Finally, the Lluvia calculator runs the configured GPU pipeline.

GpuBuffer support
Support for transferring data to and fromGpuBuffer packets in the LluviaCalculator is planned. This will avoid the use of GpuBufferToImageFrame and ImageFrameToGpuBuffer calculators, thus reducing the memory copy overhead.Android application
The mediapipe repository provides examples on how to build Android applications that run the framework. The dataflow is as follows:
- In Java/Kotlin, configure the app to open the camera. Camera2 or CameraX APIs can be used.
- Camera frames are received on Surface objects, opaque objects that hold reference to the image pixel data.
- The surface objects are transferred to the mediapipe graph, entering through the
input_stream. In there, the packets are sent asGpuBufferto be consumed by the calculators. - The graph execution takes place, and the output packets are received by the application through the
output_stream. TheGpuBufferpackets are transformed to Android surface objects. - The surface objects are rendered in the screen.
Mediapipe Android archive
Build instructions
The mediapipe integration guide includes new instructions on how to configure the project to support Android builds.Apps can consume medipipe libraries through Android Archive files (AAR). Archives are a special type of library containing JVM classes, assets, and native libraries (compiled for x86, arm64, or other architectures). Archives can be imported to the app either by placing them within the app source tree, or by declaring a dependency to a remote repository (e.g. Maven).
Mediapipe bazel rules include targets to build AAR files than be used on Android. The lluvia-mediapipe repo uses these rules to compile an archive that compiles lluvia along with mediapipe, and export all the required assets (node library, scripts and graphs). The AAR is created by running:
| |
where --fat_apk_cpu=arm64-v8a defines the CPU architectures that the native code will be compiled to. The archive is available at:
bazel-bin/mediapipe/lluvia-mediapipe/java/ai/lluvia/lluvia_aar.aar
which can directly be copied to the App’s libraries, or exported to a remote repository.
Discussion
This post explained how to use Mediapipe to run Lluvia compute pipelines on Android systems. The mobile graph uses the FlowLimiter calculator to control the rate at which image packets are consumed by the pipeline. Future work includes:
- Support
GpuBufferinput and output packets in theLluviacalculator. - Fully working Android code example.
- Use the Android GPU Inspector to profile the performance of the app.