天天看點

android 編譯 sdl,「ffmpeg」Android Studio編譯SDL2.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版本源碼

android 編譯 sdl,「ffmpeg」Android Studio編譯SDL2.0

sdl2.0.png

2.解壓後,将源碼中的android-project拷貝出來另存到其他路徑下,然後直接導入android studio中

android 編譯 sdl,「ffmpeg」Android Studio編譯SDL2.0

image.png

3.在jni下建立一個sdl檔案夾,将sdl源碼中的include、src、Android.mk

拷貝到sdl檔案夾下

android 編譯 sdl,「ffmpeg」Android Studio編譯SDL2.0

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】

android 編譯 sdl,「ffmpeg」Android Studio編譯SDL2.0

image.png

可以已經成功生成了libSDL2.so,運作之後效果圖如下

android 編譯 sdl,「ffmpeg」Android Studio編譯SDL2.0

效果圖.png

題外話

1.剛開始嘗試使用CMake來實作編譯。但新的NDK已經改變了編譯clang來編譯不再是gcc了,直接移植源碼發現編譯到了和OpenGL相關的庫時就報錯了,找不到相應的引用,暫時無解。

參考