原文 http://blog.csdn.net/wscem/article/details/7698634 linux
havlenapetr的項目使用的是ffmpeg 0.81版本,ndk用的早期的版本ndk_1.6_r1,用ndk_r7編譯通不過,用ndk_r5或者r8卻能經過 android
首先編譯ffmpeg,最好是在純linux環境下編譯,window下用cygwin會出莫名其妙的問題 shell
1.configure ffmpeg 緩存
新建config.sh文件,內容以下(針對armv7-acpu優化過的,--enable-runtime-cpudetect 是開啓全部的cpu支持,enable參數都是能夠隨便改的) ide
#!/bin/sh PREBUILT=/usr/local/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86 PLATFORMS=/usr/local/android-ndk-r8/platforms/android-9/arch-arm ./configure --target-os=linux \ --arch=arm \ --cpu=armv7-a \ --disable-yasm \ --disable-asm \ --enable-gpl \ --enable-version3 \ --enable-nonfree \ --enable-cross-compile \ --enable-runtime-cpudetect \ --cc=$PREBUILT/bin/arm-linux-androideabi-gcc \ --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \ --nm=$PREBUILT/bin/arm-linux-androideabi-nm \ --extra-cflags="-fPIC -DANDROID -mfpu=neon -mfloat-abi=softfp " \ --enable-static \ --disable-shared \ --prefix=/home/wangsc/android_ffmpeg_sndu \ --extra-ldflags="-Wl,-T,$PREBUILT/arm-linux-androideabi/lib/ldscripts/armelf_linux_eabi.x -Wl,-rpath-link=$PLATFORMS/usr/lib -L$PLATFORMS/usr/lib -nostdlib $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/armv7-a/crtbegin.o $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/armv7-a/crtend.o -lc -lm -ldl"
而後修改生成的config.h文件 函數
#define restrict restrict post
改成 #define restrict (ndk-build不支持restrict關鍵字,因此刪除後面的一個restrict) 優化
#define HAVE_SYS_RESOURCE_H 0 ui
改成 #define HAVE_SYS_RESOURCE_H 1 idea
#define CONFIG_AVDEVICE 1
改爲
#define CONFIG_AVDEVICE 0
修改jni/Android.mk 靜態庫增長libavfliter
LOCAL_STATIC_LIBRARIES := libavcodec libavformat libavutil libpostproc libswscale libmediaplayer
改爲
LOCAL_STATIC_LIBRARIES := libavformat libavcodec libavfilter libavutil libpostproc libswscale libmediaplayer
而後轉到havlenapetr 項目的根目錄執行ndk-build就能夠編譯成功了(注意ndk版本要是r5或r8)
因爲havlenapetr自帶的libaudio和libvideo庫是在android 2.2系統中編譯出來的 , 因此編譯成功的庫只能在2.2系統上運行,若要在其餘系統上運行,還須要在相應的系統源碼樹種編譯這兩個文件。 這兩個是調用系統輸出視頻與音頻的庫,2.2和2.3的源碼改動挺大的。因此互不支持。
源文件能夠再havlenapetr之前的工程中找到,,(忘記在什麼地方了~~~~(>_<)~~~~ )
音視頻不一樣步問題:
同步通常有三種方法:音頻同步視頻,視頻同步音頻,音視頻外部時鐘同步
這裏用的視頻同步音頻,
在音視頻解碼的線程中分別添加獲取時間戳的函數,解碼視頻的時候調用音頻解碼線程中的該函數,獲得當前音頻的時間戳,與當前的視頻時間戳比較,而後使用pthread->wait線程休眠。
播放暫停:
havlenapetr的工程中使用了5個線程,每一個線程都有獨立的緩存,分別是 讀取媒體流、音頻解碼、音頻播放、視頻解碼、視頻播放,暫停功能須要將全部的線程都休眠掉,
畫面傾斜:
mediaplayer添加一個OnVideoSizeChangedListener,,改變surfaceView的大小,setFixSize(width,height);
快進快退:
av_seek_frame() 傳入要跳轉的位置。
記得清空播放線程的緩存,要否則還會繼續播放幾秒鐘。
播放進度:
這個用時間戳就能夠了
(時間戳是微秒級別的,進度條是毫秒級別的)