日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

【Android FFMPEG 开发】FFMPEG ANativeWindow 原生绘制 ( Java 层获取 Surface | 传递画布到本地 | 创建 ANativeWindow )

發布時間:2025/6/17 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android FFMPEG 开发】FFMPEG ANativeWindow 原生绘制 ( Java 层获取 Surface | 传递画布到本地 | 创建 ANativeWindow ) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

        • I . FFMPEG ANativeWindow 原生繪制
        • II . FFMPEG 原生繪制流程
        • III . Java 層獲取 Surface 畫布
        • IV . 傳遞 Surface 畫布到 Native 層
        • V . Native 層創建 ANativeWindow 原生繪制窗口



I . FFMPEG ANativeWindow 原生繪制



FFMPEG ANativeWindow 原生繪制前置操作 :


① FFMPEG 初始化 : 參考博客 【Android FFMPEG 開發】FFMPEG 初始化 ( 網絡初始化 | 打開音視頻 | 查找音視頻流 )

② FFMPEG 獲取 AVStream 音視頻流 : 參考博客 【Android FFMPEG 開發】FFMPEG 獲取 AVStream 音視頻流 ( AVFormatContext 結構體 | 獲取音視頻流信息 | 獲取音視頻流個數 | 獲取音視頻流 )

③ FFMPEG 獲取 AVCodec 編解碼器 : 參考博客 【Android FFMPEG 開發】FFMPEG 獲取編解碼器 ( 獲取編解碼參數 | 查找編解碼器 | 獲取編解碼器上下文 | 設置上下文參數 | 打開編解碼器 )

④ FFMPEG 讀取音視頻流中的數據到 AVPacket : 參考博客 【Android FFMPEG 開發】FFMPEG 讀取音視頻流中的數據到 AVPacket ( 初始化 AVPacket 數據 | 讀取 AVPacket )

⑤ FFMPEG 解碼 AVPacket 數據到 AVFrame : 參考博客 【Android FFMPEG 開發】FFMPEG 解碼 AVPacket 數據到 AVFrame ( AVPacket->解碼器 | 初始化 AVFrame | 解碼為 AVFrame 數據 )

⑥ FFMPEG AVFrame 圖像格式轉換 YUV -> RGBA : 參考博客 【Android FFMPEG 開發】FFMPEG AVFrame 圖像格式轉換 YUV -> RGBA ( 獲取 SwsContext | 初始化圖像數據存儲內存 | 圖像格式轉換 )



II . FFMPEG 原生繪制流程



FFMPEG 解碼 AVPacket 數據到 AVFrame 流程 :


〇 前置操作 : FFMPEG 環境初始化 , 獲取 AVStream 音視頻流 , 獲取 AVCodec 編解碼器 , 讀取音視頻流中的數據到 AVPacket , 解碼 AVPacket 數據到 AVFrame , AVFrame 圖像格式轉換 YUV -> RGBA , 然后才能進行下面的操作 ;


① Java 層獲取 Surface 對象 : Surface 畫布可以在 SurfaceView 的 SurfaceHolder 中獲取

//繪制圖像的 SurfaceView SurfaceView surfaceView;//在 SurfaceView 回調函數中獲取 SurfaceHolder surfaceHolder = surfaceView.getHolder() ; //獲取 Surface 畫布 Surface surface = surfaceHolder.getSurface() ;

② 將 Surface 對象傳遞到 Native 層 : 在 SurfaceHolder.Callback 接口的 surfaceChanged 實現方法中 , 將 Surface 畫布傳遞給 Native 層 ;

@Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {//畫布改變 , 橫豎屏切換 , 按下 Home 鍵 , 按下菜單鍵//將 Surface 傳到 Native 層 , 在 Native 層繪制圖像native_set_surface(holder.getSurface()); }//調用該方法將 Surface 傳遞到 Native 層 native void native_set_surface(Surface surface);

③ 創建 ANativeWindow : 在 Native 層的 C++ 代碼中 , 接收 Surface 畫布 , 并創建 ANativeWindow 本地繪制窗口 , 原生繪制主要在 ANativeWindow 中進行 ;

//CPP 中接收 Surface 畫布 , 并創建 ANativeWindow extern "C" JNIEXPORT void JNICALL Java_kim_hsl_ffmpeg_Player_native_1set_1surface(JNIEnv *env, jobject instance, jobject surface) {// 將從 Java 層傳遞的 Surface 對象轉換成 ANativeWindow 結構體// 如果之前已經有了 ANativeWindow 結構體 , 那么先將原來的釋放掉//釋放原來的 ANativeWindowif(aNativeWindow){ANativeWindow_release(aNativeWindow);}//轉換新的 ANativeWindowaNativeWindow = ANativeWindow_fromSurface(env, surface); }

III . Java 層獲取 Surface 畫布



1 . Surface 畫布 : 這里的 Surface 畫布從 SurfaceView 中獲得 , SurfaceHolder.Callback 的監聽方法中獲取 SurfaceHolder 及 Surface ;


2 . 設置 SurfaceHolder 回調函數 : 首先要獲取 SurfaceView 的 SurfaceHolder ; 設置 SurfaceHolder 監聽回調函數 SurfaceHolder.Callback ;

//監聽獲取畫布this.surfaceHolder = this.surfaceView.getHolder();surfaceHolder.addCallback(this);

3 . 獲取 Surface 畫布 : 在 surfaceChanged 回調方法中 , 獲取 Surface 畫布 , 這樣可以保證在橫豎屏切換時可以實時獲取到最新畫布 ;

@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {//畫布改變 , 橫豎屏切換 , 按下 Home 鍵 , 按下菜單鍵//holder.getSurface() 就是 Surface 畫布 ; }

4 . Surface 畫布獲取 代碼示例 :

package kim.hsl.ffmpeg;import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView;/*** Java 層與 Native 層交互 接口*/ public class Player implements SurfaceHolder.Callback {private static final String TAG = "Player";// 加載動態庫static {System.loadLibrary("native-lib");}/*** 視頻顯示組件*/private SurfaceView surfaceView;/*** 控制 Surface 畫布接口*/private SurfaceHolder surfaceHolder;...public void setSurfaceView(SurfaceView surfaceView) {this.surfaceView = surfaceView;//監聽獲取畫布this.surfaceHolder = this.surfaceView.getHolder();surfaceHolder.addCallback(this);}@Overridepublic void surfaceCreated(SurfaceHolder holder) {//畫布創建}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {//畫布改變 , 橫豎屏切換 , 按下 Home 鍵 , 按下菜單鍵//holder.getSurface() 就是 Surface 畫布 ; }@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {//畫布銷毀} }

IV . 傳遞 Surface 畫布到 Native 層



1 . 原生繪制需求 : 在 Native 層使用 C/C++ 進行原生繪制需要將 Surface 畫布傳遞到 Native 層進行繪制 ;


2 . 定義傳遞方法 : 在 Java 層定義傳遞 Surface 畫布的 Native 方法 ;

native void native_set_surface(Surface surface);

3 . 實現 Surface 傳遞方法 : 在 Native 層實現 Java 中定義的方法 ;

extern "C" JNIEXPORT void JNICALL Java_kim_hsl_ffmpeg_Player_native_1set_1surface(JNIEnv *env, jobject instance, jobject surface) {... }

4 . 傳遞 Surface 畫布操作 : 在 surfaceChanged 函數中 , 通過調用 SurfaceHolder 的 getSurface ( ) 方法獲取 Surface 畫布 , 再調用 native_set_surface(holder.getSurface()) , 將畫布傳遞到 Surface 層 ;

@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {//畫布改變 , 橫豎屏切換 , 按下 Home 鍵 , 按下菜單鍵//將 Surface 傳到 Native 層 , 在 Native 層繪制圖像native_set_surface(holder.getSurface());}

V . Native 層創建 ANativeWindow 原生繪制窗口



1 . ANativeWindow 創建 : 在 Native 層實現 Java 中定義的本地方法 native_set_surface ( ) , 在該方法中傳入了 Surface 對象作為參數 ; 在該 Native 方法中 , 調用了 ANativeWindow_fromSurface ( ) 方法 , 將 Surface 對象轉為了 ANativeWindow 原生繪制窗口 ;


2 . ANativeWindow_fromSurface ( ) 函數原型 :


① JNIEnv* env 參數 : JNI 環境 , 在 JNI 方法中自帶 ;

② jobject surface 參數 : Java 層傳入的 Surface 對象 ;

/*** Return the ANativeWindow associated with a Java Surface object,* for interacting with it through native code. This acquires a reference* on the ANativeWindow that is returned; be sure to use ANativeWindow_release()* when done with it so that it doesn't leak.*/ ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface);

3 . Native 層創建 ANativeWindow 原生繪制窗口 代碼示例 :

/*** 原生繪制窗口*/ ANativeWindow * aNativeWindow;extern "C" JNIEXPORT void JNICALL Java_kim_hsl_ffmpeg_Player_native_1set_1surface(JNIEnv *env, jobject instance, jobject surface) {//加同步鎖pthread_mutex_lock(&mutex);// 將從 Java 層傳遞的 Surface 對象轉換成 ANativeWindow 結構體// 如果之前已經有了 ANativeWindow 結構體 , 那么先將原來的釋放掉//釋放原來的 ANativeWindowif(aNativeWindow){ANativeWindow_release(aNativeWindow);}//轉換新的 ANativeWindowaNativeWindow = ANativeWindow_fromSurface(env, surface);//解除同步鎖pthread_mutex_unlock(&mutex);}

總結

以上是生活随笔為你收集整理的【Android FFMPEG 开发】FFMPEG ANativeWindow 原生绘制 ( Java 层获取 Surface | 传递画布到本地 | 创建 ANativeWindow )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产欧美日韩精品在线观看 | 全毛片| 日韩91 | 欧美性猛交69 | 欧美做爰全过程免费观看 | 亚洲第五页 | 91蝌蚪在线观看 | 九九热在线视频免费观看 | 亚洲欧美激情另类 | 97香蕉超级碰碰久久免费软件 | 日韩国产欧美在线视频 | 黄色网址在线免费 | 久久综合国产精品 | 91黄色影视 | 久久亚洲一区二区 | 久久久免费电影 | 国产无遮挡18禁无码网站不卡 | 91视频看| h视频免费在线 | 久久久久久18 | 一区二区三区日韩电影 | 51嘿嘿嘿国产精品伦理 | 强侵犯の奶水授乳羞羞漫虐 | 女性喷水视频 | 欧美一区二区三区激情视频 | 亚洲第一色网 | 国产免费自拍视频 | 国产精品美女久久久久 | 成人激情久久 | 亚洲欧美日韩一区在线观看 | 成人免费观看av | 日本中文字幕影院 | 91叼嘿视频 | 爱情岛亚洲首页论坛小巨 | 久久99国产综合精品免费 | 浮生影视在线观看免费 | 午夜神马福利 | av福利院| 国产亚洲精品久久久久久打不开 | 成人av高清在线 | 国产福利片一区二区 | 免费人成年激情视频在线观看 | 中文字幕日日夜夜 | 免费观看黄色网址 | а天堂中文在线官网 | 亚洲精品视频免费在线观看 | 999色综合 | 欧美黄色三级视频 | 在线观看日本中文字幕 | 97视频免费在线观看 | 四虎在线免费 | 深爱五月综合网 | 天干夜天干天天天爽视频 | 美女写真福利视频 | av美女网站| 亚洲精品在线观看免费 | 黄色xxxxxx | 精品一区二区免费看 | 91在线播| 久久伊人一区 | 欧美人妻一区二区三区 | 蜜桃av噜噜一区二区三区小说 | 不卡的av网站| 精品国产一区二区三区久久久蜜臀 | 色婷婷国产精品综合在线观看 | 日韩福利影院 | 黄色一级视频网站 | 美女a视频 | 国产淫片 | 嫩草国产在线 | 色污网站 | 国产日产亚洲系列最新 | 欧美色xxxx | 日本三级日本三级日本三级极 | heyzo国产| 精品国产一级久久 | 久久入口| 精品国产一区二区三区四区精华 | 波多野结衣在线免费观看视频 | 黄色大片日本 | 国产成人av一区 | www.日韩欧美 | 国产盗摄在线观看 | 国产亚洲精品美女 | 香蕉av777xxx色综合一区 | 午夜三级av| 日韩在线播放中文字幕 | 免费三片在线观看网站v888 | 影音先锋在线视频观看 | 69视频免费| 久久久久久久亚洲精品 | 国产区一区二区三区 | 成人精品一区二区三区电影黑人 | 久久久久人妻一区 | 成人亚洲一区 | 黑人玩弄人妻一区二区绿帽子 | www日韩| 国产乱人乱精一区二视频国产精品 | 性――交――性――乱睡觉 |