AndroidFFmpegVideoPlayer
This is a video player integrated with super-resolution enhancement on Android devices implemented using ffmpeg
Install / Use
/learn @Monaco12138/AndroidFFmpegVideoPlayerREADME
AndroidFFmpegVideoPlayer
这是一个集成了超分增强的视频播放器,使用了ffmpeg进行拉流,将得到的视频流超分增强并渲染展示出来。 该项目使用Android NDK开发,集成ffmpeg方法,可以获取拉流完后的每一帧视频数据,方便后续部署属于你的神经网络模型。具体如何训练,量化导出测试自定义的模型可以见此仓库
环境配置
下载Android studio, clone本仓库用Android studio打开,确保./app/build.gradle.kts 相关依赖库能正常下载,重新Rebuild Project.
因为拉流是用ffmpeg进行的,我们需要重新源码编译一份适用于Android的ffmpeg,才能使用<libavformat/avformat.h>等库,这里使用ffmpeg-android-maker提供的Docker进行编译,将arm64-v8a的结果放在在main/cpp/ffmpeg目录下,如果需要其它的版本,可自行手动编译后替换
拉流
定义了Streamplayer类,集成了拉流,拉流过程在C++代码中实现
StreamPlayer player(javaVM, video_address);
player.start();
值得注意的是,在C++代码中直接开线程用NDK相关接口调用Java中的函数会有些问题,故我们是采用在Java中开线程调用C++的拉流代码
模型推理
这里以超分增强模型为例,模型推理这块放在Java中实现,使用
BlockingQueue<int[]> rgbBytesQueue = new ArrayBlockingQueue<>(QUEUE_CAPACITY)
作为通信,C++代码中将得到的avFrame视频帧数据转换为int*的数组后放入调用Java中的接口,将数据放入该队列中,Java中代码从该队列中读数据进行增强处理
in C++:
int avFrameYUV420ToARGB8888(AVFrame* frame) {
int width = frame->width;
int height = frame->height;
jintArray outFrame = env->NewIntArray(width * height);
if (outFrame == nullptr) {
LOGI("Failed to allocate memory");
return -1;
}
jint* outData = env->GetIntArrayElements(outFrame, nullptr);
if (outData == nullptr) {
LOGI("outData is nullptr");
return -1;
}
/* avFrame to jint*
...
*/
// call jni to putData
env->ReleaseIntArrayElements(outFrame, outData, 0);
env->CallStaticVoidMethod(this->cls, this->funcMethod, outFrame);
env->DeleteLocalRef(outFrame);
return 0;
}
in Java:
public static void putData(int[] data) {
try {
rgbBytesQueue.put(data);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public void ModelInference() {
new Thread(new Runnable()) {
@Override
public void run() {
while (true) {
int [] rgbData = rgbBytesQueue.take();
Bitmap rgbBitmap = Bitmap.createBitmap(outputShape[0], outputShape[1], Bitmap.Config.ARGB_8888);
rgbBitmap.setPixels(rgbData, 0, outputShape[0], 0, 0, outputShape[0], outputShape[1]);
/* model inference: input Bitmap, output Bitmap
...
*/
/* output Bitmap to ImageView
...
*/
}
}
}
}
自此就是一个拉流到模型推理的框架
Related Skills
docs-writer
99.6k`docs-writer` skill instructions As an expert technical writer and editor for the Gemini CLI project, you produce accurate, clear, and consistent documentation. When asked to write, edit, or revie
model-usage
341.8kUse CodexBar CLI local cost usage to summarize per-model usage for Codex or Claude, including the current (most recent) model or a full model breakdown. Trigger when asked for model-level usage/cost data from codexbar, or when you need a scriptable per-model summary from codexbar cost JSON.
ddd
Guía de Principios DDD para el Proyecto > 📚 Documento Complementario : Este documento define los principios y reglas de DDD. Para ver templates de código, ejemplos detallados y guías paso
arscontexta
2.9kClaude Code plugin that generates individualized knowledge systems from conversation. You describe how you think and work, have a conversation and get a complete second brain as markdown files you own.
