1. 程式人生 > >最簡單的基於FFmpeg的移動端例子附件:SDL Android HelloWorld

最簡單的基於FFmpeg的移動端例子附件:SDL Android HelloWorld

=====================================================

最簡單的基於FFmpeg的移動端例子系列文章列表:

=====================================================


本文記錄一個安卓平臺下SDL的例子。該例子讀取並顯示了一張BMP圖片,通過該例子可以瞭解SDL在安卓平臺下的使用。本文中使用的SDL版本為2.0。


Android程式SDL2類庫使用說明

簡單記錄一下Android程式使用SDL2類庫的方法。這部分的資訊可以參考SDL2原始碼目錄中的README-android.txt檔案。SDL2使用的步驟可以分為以下步驟:

(1)配置Android工程

a) 新建Android工程

可以直接使用SDL2原始碼目錄中的android-project工程,也可以自己新建工程。如果自己新建工程,則需要拷貝android-project工程中src目錄下的SDLActivity.java檔案。該檔案中的SDLActivity定義比較長,目前還沒有研究過。

b) 拷貝SDL2原始碼
將SDL2原始碼目錄中下列內容拷貝至Android工程的jni目錄下:
src目錄
include目錄
Android.mk

(2)編譯C語言程式碼

a) 編寫C語言程式碼

在Android工程的jni目錄下新建C語言檔案並編寫呼叫SDL2的程式碼。在這裡需要注意C語言程式碼的主函式名稱和命令列程式是一樣的,依然是“main(int argc, char *argv[])”。

b) 修改Android.mk檔案

在Android.mk檔案後面追加一段程式碼,用來編譯一個libSDL2main.so的庫。該庫可以呼叫自己的C語言程式。在這裡需要注意,“libSDL2main”這個名稱是可以隨意起的,但是要和SDLActivity中LoadLibrary()函式中的庫名稱相對應(預設名稱應該是libmain.so)。程式碼內容如下所示。

#libSDL2main=======================================
# Lei Xiaohua
include $(CLEAR_VARS)
LOCAL_MODULE := SDL2main
SDL_PATH := ./
LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include
# Add your application source files here...
LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \
	$(SDL_PATH)/simplest_showbmp.c
LOCAL_SHARED_LIBRARIES := SDL2
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog
include $(BUILD_SHARED_LIBRARY)
PS:上述程式碼修改自SDL2原始碼目錄中android-project工程的jni\src目錄下的Android.mk檔案。

c) 編寫Application.mk檔案(可選)
Application.mk中的APP_ABI設定了編譯後庫檔案支援的指令集,預設使用“armeabi”,這裡使用預設值就可以了。
d) 執行ndk-build
編寫完C語言程式碼和Android.mk之後就可以執行ndk-build命令進行編譯了。ndk-build命令執行成功後,會在根目錄下的“libs/armeabi”目錄中生成2個庫檔案:
libSDL2.so
libSDL2main.so
接下來就可以在Android手機或者虛擬機器上對整個Android工程進行測試了。

原始碼

專案的目錄結構如圖所示。Java原始碼位於src目錄,而C程式碼位於jni目錄。


Android程式Java端程式碼位於src\org\libsdl\app\SDLActivity.java。該Activity取自於SDL2原始碼目錄中的android-project工程,在這裡不再記錄。

jni目錄中的src和include資料夾分別是SDL2的原始碼目錄中的src資料夾和include資料夾。

C語言端原始碼位於jni/simplest_showbmp.c,如下所示。該原始碼讀取了儲存卡中的一張test.bmp檔案,並顯示出來。

/**
 * 移植SDL到安卓平臺的HelloWorld程式
 * Simplest SDL Android Helloworld
 *
 * 雷霄驊 Lei Xiaohua
 * [email protected]
 * 中國傳媒大學/數字電視技術
 * Communication University of China / Digital TV Technology
 * http://blog.csdn.net/leixiaohua1020
 *
 *
 * 本程式是移植SDL到安卓平臺的最簡單程式。它可以讀取並顯示一張BMP圖片。
 *
 * This software is the simplest program transplant SDL2 to Android platform.
 * It shows a BMP file on the screen.
 */

#ifdef __ANDROID__

#include <jni.h>
#include <android/log.h>
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , "(^_^)", __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , "(^_^)", __VA_ARGS__)
#else
#define LOGE(format, ...)  printf("(>_<) " format "\n", ##__VA_ARGS__)
#define LOGI(format, ...)  printf("(^_^) " format "\n", ##__VA_ARGS__)
#endif

#include "SDL.h"
#include "SDL_log.h"
#include "SDL_main.h"

int main(int argc, char *argv[]) {
	struct SDL_Window *window = NULL;
	struct SDL_Renderer *render = NULL;
	struct SDL_Surface *bmp = NULL;
	struct SDL_Texture *texture = NULL;

    char *filepath = "/storage/emulated/0/test.bmp";

    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) == -1) {
        LOGE("SDL_Init failed %s", SDL_GetError());
    }

    window = SDL_CreateWindow("SDL HelloWorld!", 100, 100, 640, 480,
            SDL_WINDOW_SHOWN);
    if (window == NULL) {
        LOGE("SDL_CreateWindow failed  %s", SDL_GetError());
    }

    render = SDL_CreateRenderer(window, -1,
            SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (render == NULL) {
        LOGE("SDL_CreateRenderer failed  %s", SDL_GetError());
    }

    bmp = SDL_LoadBMP(filepath);
    if (bmp == NULL) {
        LOGE("SDL_LoadBMP failed: %s", SDL_GetError());
    }

    texture = SDL_CreateTextureFromSurface(render, bmp);
    SDL_FreeSurface(bmp);

    SDL_RenderClear(render);
    SDL_RenderCopy(render, texture, NULL, NULL);
    SDL_RenderPresent(render);

    SDL_Delay(10000);

    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(render);
    SDL_DestroyWindow(window);

    //Quit SDL
    SDL_Quit();
    return 0;
}

Android.mk檔案位於jni/Android.mk,如下所示。
LOCAL_PATH := $(call my-dir)

###########################
#
# SDL shared library
#
###########################

include $(CLEAR_VARS)

LOCAL_MODULE := SDL2

LOCAL_C_INCLUDES := $(LOCAL_PATH)/include

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)

LOCAL_SRC_FILES := \
	$(subst $(LOCAL_PATH)/,, \
	$(wildcard $(LOCAL_PATH)/src/*.c) \
	$(wildcard $(LOCAL_PATH)/src/audio/*.c) \
	$(wildcard $(LOCAL_PATH)/src/audio/android/*.c) \
	$(wildcard $(LOCAL_PATH)/src/audio/dummy/*.c) \
	$(LOCAL_PATH)/src/atomic/SDL_atomic.c \
	$(LOCAL_PATH)/src/atomic/SDL_spinlock.c.arm \
	$(wildcard $(LOCAL_PATH)/src/core/android/*.c) \
	$(wildcard $(LOCAL_PATH)/src/cpuinfo/*.c) \
	$(wildcard $(LOCAL_PATH)/src/dynapi/*.c) \
	$(wildcard $(LOCAL_PATH)/src/events/*.c) \
	$(wildcard $(LOCAL_PATH)/src/file/*.c) \
	$(wildcard $(LOCAL_PATH)/src/haptic/*.c) \
	$(wildcard $(LOCAL_PATH)/src/haptic/dummy/*.c) \
	$(wildcard $(LOCAL_PATH)/src/joystick/*.c) \
	$(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \
	$(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c) \
	$(wildcard $(LOCAL_PATH)/src/power/*.c) \
	$(wildcard $(LOCAL_PATH)/src/power/android/*.c) \
	$(wildcard $(LOCAL_PATH)/src/filesystem/dummy/*.c) \
	$(wildcard $(LOCAL_PATH)/src/render/*.c) \
	$(wildcard $(LOCAL_PATH)/src/render/*/*.c) \
	$(wildcard $(LOCAL_PATH)/src/stdlib/*.c) \
	$(wildcard $(LOCAL_PATH)/src/thread/*.c) \
	$(wildcard $(LOCAL_PATH)/src/thread/pthread/*.c) \
	$(wildcard $(LOCAL_PATH)/src/timer/*.c) \
	$(wildcard $(LOCAL_PATH)/src/timer/unix/*.c) \
	$(wildcard $(LOCAL_PATH)/src/video/*.c) \
	$(wildcard $(LOCAL_PATH)/src/video/android/*.c) \
    $(wildcard $(LOCAL_PATH)/src/test/*.c))

LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES
LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog -landroid

include $(BUILD_SHARED_LIBRARY)

###########################
#
# SDL static library
#
###########################

LOCAL_MODULE := SDL2_static

LOCAL_MODULE_FILENAME := libSDL2

LOCAL_SRC_FILES += $(LOCAL_PATH)/src/main/android/SDL_android_main.c

LOCAL_LDLIBS := 
LOCAL_EXPORT_LDLIBS := -Wl,--undefined=Java_org_libsdl_app_SDLActivity_nativeInit -ldl -lGLESv1_CM -lGLESv2 -llog -landroid

include $(BUILD_STATIC_LIBRARY)


#libSDL2main=======================================
# Lei Xiaohua
include $(CLEAR_VARS)
LOCAL_MODULE := SDL2main
SDL_PATH := ./
LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include
# Add your application source files here...
LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \
	$(SDL_PATH)/simplest_showbmp.c
LOCAL_SHARED_LIBRARIES := SDL2
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog
include $(BUILD_SHARED_LIBRARY)

執行結果

App在手機上執行後的結果如下圖所示。可以看出App讀取了test.bmp檔案並且顯示出來。

注意需要把BMP檔案拷貝至儲存卡相應的目錄中。程式預設情況下會讀取根目錄下的“test.bmp”檔案。



下載


simplest ffmpeg mobile

專案主頁

開源中國:https://git.oschina.net/leixiaohua1020/simplest_ffmpeg_mobile
CSDN工程下載地址:http://download.csdn.net/detail/leixiaohua1020/8924391


本解決方案包含了使用FFmpeg在移動端處理多媒體的各種例子:
[Android]
simplest_android_player: 基於安卓介面的視訊播放器
simplest_ffmpeg_android_helloworld: 安卓平臺下基於FFmpeg的HelloWorld程式
simplest_ffmpeg_android_decoder: 安卓平臺下最簡單的基於FFmpeg的視訊解碼器
simplest_ffmpeg_android_decoder_onelib: 安卓平臺下最簡單的基於FFmpeg的視訊解碼器-單庫版
simplest_ffmpeg_android_streamer: 安卓平臺下最簡單的基於FFmpeg的推流器
simplest_ffmpeg_android_transcoder: 安卓平臺下移植的FFmpeg命令列工具
simplest_sdl_android_helloworld: 移植SDL到安卓平臺的最簡單程式
[IOS]
simplest_ios_player: 基於IOS介面的視訊播放器
simplest_ffmpeg_ios_helloworld: IOS平臺下基於FFmpeg的HelloWorld程式
simplest_ffmpeg_ios_decoder: IOS平臺下最簡單的基於FFmpeg的視訊解碼器
simplest_ffmpeg_ios_streamer: IOS平臺下最簡單的基於FFmpeg的推流器
simplest_ffmpeg_ios_transcoder: IOS平臺下移植的ffmpeg.c命令列工具
simplest_sdl_ios_helloworld: 移植SDL到IOS平臺的最簡單程式





相關推薦

簡單基於FFmpeg移動例子附件SDL Android HelloWorld

=====================================================最簡單的基於FFmpeg的移動端例子系列文章列表:=====================================================本文記錄一個安

簡單基於FFmpeg移動例子附件Android 自帶播放器

=====================================================最簡單的基於FFmpeg的移動端例子系列文章列表:=====================================================前幾篇文章記錄

簡單基於FFmpeg移動樣例附件SDL Android HelloWorld

apt 圖片 va_arg dlopen info net src sdn 文件夾 =========================================

簡單基於FFmpeg移動例子IOS HelloWorld

=====================================================最簡單的基於FFmpeg的移動端例子系列文章列表:=====================================================本文記錄IOS

簡單基於FFmpeg移動例子Android 視訊轉碼器

=====================================================最簡單的基於FFmpeg的移動端例子系列文章列表:=====================================================本文記錄一個安

簡單基於FFmpeg移動樣例IOS HelloWorld

目的 mes 真機 roo mux 能夠 ted 配置 details =====================================================最簡單的基於FFmpeg的移動端樣例系列文章列表:最簡單的基於FFmpeg的移動端樣例:An

簡單基於FFmpeg移動樣例IOS 視頻解碼器

視頻播放 contex avcodec video pad align b+ getc tar =====================================================最簡單的基於FFmpeg的移動端樣例系列文章列表:最簡單的基於FFm

簡單基於FFmpeg的AVfilter例子(水印疊加

                =====================================================最簡單的基於FFmpeg的AVfilter例子系列文章:=====================================================FFMPE

簡單基於FFmpeg的AVDevice例子 讀取攝像頭

                =====================================================最簡單的基於FFmpeg的AVDevice例子文章列表:最簡單的基於FFmpeg的AVDevice例子(螢幕錄製)=============================

簡單基於FFmpeg的AVDevice例子(讀取攝像頭)解讀

本文轉載自最簡單的基於FFmpeg的AVDevice例子(讀取攝像頭) 在此基礎上對程式的流程進行解讀,閱讀前請先閱讀原文。 ============================= /** * 最簡單的基於FFmpeg的AVDevice例子(讀取攝像頭) * Simplest F

簡單基於FFmpeg的封裝格式處理視音訊分離器簡化版(demuxer-simple)

=====================================================最簡單的基於FFmpeg的封裝格式處理系列文章列表:=====================================================簡介打算記錄

[轉]Netty入門(簡單的Netty客戶/服務器程序)

serve exc new final 綁定 title graceful 關閉連接 listener  Java中的NIO是一種解決阻塞式IO問題的基本技術,但是NIO的編寫對java程序員是有比較高的要求的。那麽Netty就是一種簡化操作的一個成熟的網絡IO編程框架。這

vue2 + iview-admin 1.3 + django 2.0 一個簡單的增刪改查例子

iview-admin axios django 前後端分離 api 以下為利用iview-admin + django 做的一個最基本的增刪改查例子。 前端iview-admin git clone https://github.com/iview/iview-admin.git cd

基於VUE移動UI好用框架

1. vonic 一個基於 vue.js 和 ionic 樣式的 UI 框架,用於快速構建移動端單頁應用,很簡約,是我喜歡的風格 star 2.3k 中文文件 線上預覽 2.vux 基於WeUI和Vue(2.x)開發的移動端UI元件庫 star 10k 基於webpack+vue-loader+v

分享幾個簡單的bat指令碼的例子

兩個小時後自動關機 echo off shutdown /s /t 7200 進入C盤一個資料夾執行一個程式,接收使用者兩個輸入,一個是百度文庫某一個文件的連結,一個是該文件的型別,然後根據該程式執行的規則:FreeForWenku.exe + URL + 型

基於vue移動UI框架

1.vux 基於WeUI和Vue(2.x)開發的移動端UI元件庫 基於webpack+vue-loader+vux可以快速開發移動端頁面,配合vux-loader方便你在WeUI的基礎上定製需要的樣式。 中文文件 線上預覽 特性 star數最多 這可能跟

WebRTC中簡單loopback攝像頭&麥克風的例子【轉】

peerconnection_client本地回放原理 預設的client已經集成了本地回放程式碼,但是要想實現該功能,需要做少許修改。預設的點選介面上的"connect"按鈕是連線到另一臺peer,其最終執行的函式為Conductor::StartLogin。現在我們想

簡單寫一個移動touch事件

var mybody = document.getElementsByTagName('body')[0];         //滑動處理     var startX, startY, moveEndX, mov

Shiro中簡單的一個身份驗證例子

Shiro作為一個Java安全框架,身份驗證是它最基本的功能。 首先給出shiro的Maven配置 <dependencies> <dependency>

如何用react+react-router+fetch+webpack2簡單整合一個移動專案

前言:根據公司業務的要求,我最近用react寫了一個專案,已經上線,把道路中遇到的一些坑和一些專案中的經驗分享和大家共勉。 ***這是目錄結構*** 當然結構是根據自己專案的複雜程度來定義的,但是大體上都是這樣。 1.技術選型 為什