havlenapetr,ffmpeg 播放器 編譯、以及bug修改

havlenapetr的項目使用的是ffmpeg 0.81版本,ndk用的早期的版本ndk_1.6_r1,用ndk_r7編譯通不過,用ndk_r5或者r8卻能通過

首先編譯ffmpeg,最好是在純linux環境下編譯,window下用cygwin會出莫名其妙的問題

1.configure ffmpeg

新建config.sh文件,內容如下(針對armv7-acpu優化過的,--enable-runtime-cpudetect 是開啓所有的cpu支持,enable參數都是可以隨便改的)

#!/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

改爲 #define restrict (ndk-build不支持restrict關鍵字,所以刪除後面的一個restrict)

#define HAVE_SYS_RESOURCE_H 0

改爲 #define HAVE_SYS_RESOURCE_H 1

#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() 傳入要跳轉的位置。

記得清空播放線程的緩存,要不然還會繼續播放幾秒鐘。

播放進度:

這個用時間戳就可以了

(時間戳是微秒級別的,進度條是毫秒級別的)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章