美文网首页
「ffmpeg」Android Studio编译SDL2.0

「ffmpeg」Android Studio编译SDL2.0

作者: 叨码 | 来源:发表于2019-08-12 10:03 被阅读0次

本系列文章由刀码旦编写,转载请注明出处

引言

前面文章中我们实现了将MP4文件解码成YUV数据格式的文件,接下来我们尝试通过ffmpeg+SDL2.0编写一个简单的播放器来播放这个文件。

什么是SDL呢?
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
前面我们已经成功编译了ffmpeg的库,这里的SDL也是需要先编译下,本文就是讲解下SDL2.0的编译过程。

开始

1.SDL 下载
这里我选择的是最新的2.0版本源码

sdl2.0.png
2.解压后,将源码中的android-project拷贝出来另存到其他路径下,然后直接导入android studio中
image.png

3.在jni下创建一个sdl文件夹,将sdl源码中的include、src、Android.mk
拷贝到sdl文件夹下


sdl.png
PS:注意下jni的路径,NDK版本不同生成的目录结构是有区别的。建议放到main目录下,可以减少后续脚本的改动。

同时build.gradle配置如下

def buildAsLibrary = project.hasProperty('BUILD_AS_LIBRARY');
def buildAsApplication = !buildAsLibrary
if (buildAsApplication) {
    apply plugin: 'com.android.application'
}
else {
    apply plugin: 'com.android.library'
}

android {
    compileSdkVersion 26
    defaultConfig {
        if (buildAsApplication) {
            applicationId "org.libsdl.app"
        }
        minSdkVersion 16
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        externalNativeBuild {
            ndkBuild {
                arguments "APP_PLATFORM=android-16"
                //支持的abi的类型
                abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    //配置构建脚本路径,同时指定jni
    if (!project.hasProperty('EXCLUDE_NATIVE_LIBS')) {
        sourceSets.main {
            jniLibs.srcDir 'src/main/jni'
        }
        externalNativeBuild {
            ndkBuild {
                path 'src/main/jni/Android.mk'
            }
        }

    }
    lintOptions {
        abortOnError false
    }
    
    if (buildAsLibrary) {
        libraryVariants.all { variant ->
            variant.outputs.each { output ->
                def outputFile = output.outputFile
                if (outputFile != null && outputFile.name.endsWith(".aar")) {
                    def fileName = "org.libsdl.app.aar";
                    output.outputFile = new File(outputFile.parent, fileName);
                }
            }
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
}

4.在项目jni/src目录下,创一个名为YourSourceHere.c(这里文件名随便定义)的源代码,其实可以简单实现一个main函数

 int main(int argc, char *argv[]) {
}

函数内什么都不做,保证运行不报错即可。我这里是简单调用了sdl的api方法实现了一张图片的展示
在main目录下新建一个assets目录,将官网提到的一个图片地址 保存为image.bmp文件,并放入 assets中。

//
// Created by ing on 2019/8/9.
//
#include "SDL.h"
 int main(int argc, char *argv[]) {
     SDL_Window *window;
     SDL_Renderer *renderer;
     SDL_Event event;
     //配置一个图像缩放的效果,linear效果更平滑,也叫抗锯齿
     //SDL_setenv(SDL_HINT_RENDER_SCALE_QUALITY,"linear",0);
     // 初始化SDL
     if (SDL_Init(SDL_INIT_VIDEO) < 0)
         return 1;
     // 创建一个窗口
     window = SDL_CreateWindow("SDL_RenderClear" , SDL_WINDOWPOS_CENTERED,
                               SDL_WINDOWPOS_CENTERED, 0, 0, SDL_WINDOW_SHOWN);
     // 创建一个渲染器
     renderer = SDL_CreateRenderer(window, -1, 0);
     // 创建一个Surface,加载刚才下载的图片
     SDL_Surface *bmp = SDL_LoadBMP("image.bmp" );
     //设置图片中的白色为透明色
     SDL_SetColorKey(bmp, SDL_TRUE, 0xffffff);
     // 创建一个Texture
     SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, bmp);
     //清除所有事件
     SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT);
     //进入主循环
     while  (1) {
         if  (SDL_PollEvent(&event)) {
             if  (event.type == SDL_QUIT || event.type == SDL_KEYDOWN || event.type == SDL_FINGERDOWN)
                 break;
         }
         //使用红色填充背景
         SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
         SDL_RenderClear(renderer);
         // 将纹理布置到渲染器
         SDL_RenderCopy(renderer, texture, NULL, NULL);
         // 刷新屏幕
         SDL_RenderPresent(renderer);
     }
      // 释放Surface
     SDL_FreeSurface(bmp);
     //  释放Texture
     SDL_DestroyTexture(texture);
     //释放渲染器
     SDL_DestroyRenderer(renderer);
     //释放窗口
     SDL_DestroyWindow(window);
     //延时
     //SDL_Delay(8000);
     //退出
     SDL_Quit();
     return  0;
}

5.最后要做的也是最关键的,就是配置jni/src/Android.mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := main

SDL_PATH := ../sdl

LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include

# Add your application source files here...
LOCAL_SRC_FILES := YourSourceHere.c

LOCAL_SHARED_LIBRARIES := SDL2

LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog

include $(BUILD_SHARED_LIBRARY)

6.修改Application.mk文件,打开APP_STL注释表示使用标准库,根据需要修改其他值,这里其他就默认了。

# Uncomment this if you're using STL in your project
# You can find more information here:
# https://developer.android.com/ndk/guides/cpp-support
APP_STL := c++_shared

APP_ABI := armeabi-v7a arm64-v8a x86 x86_64

# Min runtime API level
APP_PLATFORM=android-16

7.构建项目,生成so动态库【build】--【make project】


image.png

可以已经成功生成了libSDL2.so,运行之后效果图如下


效果图.png
题外话

1.刚开始尝试使用CMake来实现编译。但新的NDK已经改变了编译clang来编译不再是gcc了,直接移植源码发现编译到了和OpenGL相关的库时就报错了,找不到相应的引用,暂时无解。

参考

https://www.jianshu.com/p/ff60dc41f876
https://blog.csdn.net/leixiaohua1020/article/details/25430425
https://www.cnblogs.com/yongfengnice/p/7827040.html
https://developer.android.com/studio/projects/add-native-code?hl=zh-cn#create-cmake-script

相关文章

网友评论

      本文标题:「ffmpeg」Android Studio编译SDL2.0

      本文链接:https://www.haomeiwen.com/subject/isohjctx.html