文章目录

  • 1.window api
  • 2.主要代码
  • 3.实现效果

1.window api

(1)从surface对象中检索原生window

从surface中检索对象window
ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface);

(2)获取原生window实例中的应用

void ANativeWindow_acquire(ANativeWindow* window);

(3)释放原生window引用

void ANativeWindow_release(ANativeWindow* window);

(4)检索原生window信息

宽度
int32_t ANativeWindow_getWidth(ANativeWindow* window);
宽度
int32_t ANativeWindow_getHeight(ANativeWindow* window);
像素格式
int32_t ANativeWindow_getFormat(ANativeWindow* window);

(5)设置原生window缓冲区的几何形状

int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,int32_t width, int32_t height, int32_t format);

(6)访问原生window缓冲区

int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,ARect* inOutDirtyBounds);

(7)释放原生window缓冲区

int32_t ANativeWindow_unlockAndPost(ANativeWindow* window);

2.主要代码

java

public class NativeWindowPlayerActivity extends AbstractPlayerActivity {private final AtomicBoolean isPlaying = new AtomicBoolean();private SurfaceHolder surfaceHolder;SurfaceView surfaceView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_native_window_player);surfaceView = findViewById(R.id.surface_view);surfaceHolder = surfaceView.getHolder();surfaceHolder.addCallback(callback);}@Overrideprotected void onStart() {super.onStart();int w = getWidth(avi);int h = getHeight(avi);//设置surfaceView的带大小,防止自动填充ViewGroup.LayoutParams viewGroup = surfaceView.getLayoutParams();viewGroup.width = w;viewGroup.height = h;surfaceView.setX(50);surfaceView.setY(50);}private final SurfaceHolder.Callback callback = new SurfaceHolder.Callback2() {@Overridepublic void surfaceRedrawNeeded(SurfaceHolder holder) {}@Overridepublic void surfaceCreated(SurfaceHolder holder) {isPlaying.set(true);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {isPlaying.set(true);new Thread(renderer).start();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {isPlaying.set(false);}};private Runnable renderer = new Runnable() {@Overridepublic void run() {Surface surface = surfaceHolder.getSurface();init(avi, surface);long frameDelay = (long) (1000 / getFrameRate(avi));while (isPlaying.get()) {render(avi, surface);try {Thread.sleep(frameDelay);} catch (InterruptedException e) {break;}}}};/*** 初始化原生window** @param avi* @param surface*/private native static void init(long avi, Surface surface);/*** 渲染* @param avi* @param surface* @return*/private native static boolean render(long avi, Surface surface);
}

原生代码

#include "cn_study_aviplayer_NativeWindowPlayerActivity.h"extern "C" {#include  "avilib/avilib.h"
}#include <android/native_window.h>
#include <android/native_window_jni.h>
#include "Common.h"extern "C"
JNIEXPORT void JNICALL
Java_cn_study_aviplayer_NativeWindowPlayerActivity_init(JNIEnv *env, jclass clazz, jlong avi,jobject surface) {//从surface中获取原生windowANativeWindow *nativeWindow = ANativeWindow_fromSurface(env, surface);if (0 == nativeWindow) {ThrowException(env, "java/io/RuntimeException", "不能都获取window");goto exit;}//设置buffer大小为avi视频帧的分辨率//如果和window的物理大小不一致//buffer会被缩放来匹配这个大小if (0 > ANativeWindow_setBuffersGeometry(nativeWindow, AVI_video_width((avi_t *) avi),AVI_video_height((avi_t *) avi),WINDOW_FORMAT_RGB_565)) {ThrowException(env, "java/io/RuntimeException", "不能够设置buffers");nativeWindow = 0;}exit:return;}extern "C"
JNIEXPORT jboolean JNICALL
Java_cn_study_aviplayer_NativeWindowPlayerActivity_render(JNIEnv *env, jclass clazz, jlong avi,jobject surface) {jboolean isFrameRead = JNI_FALSE;long frameSize = 0;int keyFrame = 0;ANativeWindow *nativeWindow = ANativeWindow_fromSurface(env, surface);if (0 == nativeWindow) {ThrowException(env, "java/io/RuntimeException", "不能够获取window");goto exit;}//锁定原生window并访问原始bufferANativeWindow_Buffer windowBuffer;if (0 > ANativeWindow_lock(nativeWindow, &windowBuffer, 0)) {ThrowException(env, "java/io/RuntimeException", "不能锁住window");goto release;}//将avi帧的比特流读至原始缓冲区frameSize = AVI_read_frame((avi_t *) avi, (char *) windowBuffer.bits, &keyFrame);//是否读取成功if (0 < frameSize) {isFrameRead = JNI_TRUE;}//解锁并且输出缓冲区来显示if (0 > ANativeWindow_unlockAndPost(nativeWindow)) {ThrowException(env, "java/io/RuntimeException", "不能够解锁window");goto release;}release:ANativeWindow_release(nativeWindow);nativeWindow = 0;exit:return isFrameRead;}

配置cmake
jnigraphics与android会冲突,所以加了前缀-l。

cmake_minimum_required(VERSION 3.4.1)add_library( # Sets the name of the library.native-lib# Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).native-lib.cppCommon.cppcn_study_aviplayer_BitmapPlayerActivity.cppcn_study_aviplayer_OpenGLPlayerActivity.cppcn_study_aviplayer_NativeWindowPlayerActivity.cpp)
#添加子目录
add_subdirectory(avilib)find_library( # Sets the name of the path variable.log-lib# Specifies the name of the NDK library that# you want CMake to locate.log)find_library(GLESv2-lib-lGLESv2)find_library(android-lib-landroid)target_link_libraries( # Specifies the target library.native-lib# Links the target library to the log library# included in the NDK.-ljnigraphics#开启jnigraphics${android-lib}#使用window${log-lib}${GLESv2-lib}avi-lib)

3.实现效果

NDK学习笔记(十四) 使用AVILib+window创建一个AVI视频播放器相关推荐

  1. NDK学习笔记(十二) 原生图形api,使用AVILib创建一个AVI视频播放器

    文章目录 1.练练手,使用AVILib创建一个AVI视频播放器 (1)首先下载transcode,并配置avilib. (2)创建AbstractPlayerActivity并实现native方法 ( ...

  2. 吴恩达《机器学习》学习笔记十四——应用机器学习的建议实现一个机器学习模型的改进

    吴恩达<机器学习>学习笔记十四--应用机器学习的建议实现一个机器学习模型的改进 一.任务介绍 二.代码实现 1.准备数据 2.代价函数 3.梯度计算 4.带有正则化的代价函数和梯度计算 5 ...

  3. Polyworks脚本开发学习笔记(十四)-WORKSPACE信息读取及管理

    Polyworks脚本开发学习笔记(十四)-WORKSPACE信息读取及管理 Polyworks的工作任务存储分为工作区和项目两级,通过WORKSPACE命令获取工作任务信息,实现更好的任务管理. 下 ...

  4. 【神经网络】学习笔记十四——Seq2Seq模型

    本文简要介绍seq2seq,即序列到序列的基本知识,是深度学习和NLP中一个重要的知识. 从三部分来说,seq2seq基本简介,应用场景和原理解析. 一.什么是Seq2Seq 所谓Seq2Seq(Se ...

  5. 重新认识错过(通向财富自由之路学习笔记十四)

    本周学习<通向财富自由之路>专栏重新认识错过的文章,在文章中作者介绍了自己是如何错过一次升级的.对于这种错过,非常有同感.比如在中学时候,需要学习生物.历史.地理等学科,而这些学科不需要计 ...

  6. 【theano-windows】学习笔记十四——堆叠去噪自编码器

    前言 前面已经学习了softmax,多层感知器,CNN,AE,dAE,接下来可以仿照多层感知器的方法去堆叠自编码器 国际惯例,参考文献: Stacked Denoising Autoencoders ...

  7. Mr.J-- jQuery学习笔记(十四)--动画显示隐藏

    eq()函数 定义和用法 :eq() 选择器选取带有指定 index 值的元素. index 值从 0 开始,所有第一个元素的 index 值是 0(不是 1). 经常与其他元素/选择器一起使用,来选 ...

  8. openGL学习笔记十四: 透视投影

    透视投影   三维空间物体显示近大远小. 透视投影区域是个棱锥体: 透视投影显示效果: opengl透视投影函数: void APIENTRY gluPerspective (GLdouble fov ...

  9. linux学习笔记十四:安装SAMBA(Server Message Block)

    NFS:仅用于Linux之间 CIFS:仅用于Windows之间 SAMBA:可用于Linux与Windows之间,基于NetBIOS协议(用于LAN内部,不能跨路由),没有IP地址的概念,根据 Ne ...

最新文章

  1. 线程间操作无效: 从不是创建控件的线程访问它
  2. Vue el-menu高亮设置及点击菜单项实现路由跳转
  3. 项目: 推箱子游戏【c/c++】
  4. qt 一个线程接收数据 主线程更新界面 会造成界面退出 怎么解决_打造一个好产品...
  5. java 对象流传输socket_Java Socket(二)使用TCP传输对象
  6. Dubbo SPI的基础Cooma微容器
  7. 使用AirDrop将文件从iPhone或iPad传送到Mac电脑教程
  8. idea使用mvn命令打包报错 不可用
  9. linux 查询文件大小大于1g_必备linux命令有哪些?你了解多少
  10. 把ubuntu20装在移动固态硬盘
  11. 使用赫夫曼编码进行解码
  12. 线性代数(1)- 向量空间
  13. 【C++】getchar()有什么用
  14. ubuntu 挂载文件后,文件权限属于root,只能读不能写解决办法
  15. html图片上下居中的源代码,纯CSS实现元素的自适应上下居中
  16. 软件系统复杂性灾难及解决方案探究
  17. Python-MongoDB
  18. 第11回 我猜小曹不会用Broadcast
  19. 尚硅谷--Mysql--高级篇
  20. nopi设置excel单元格的格式汇总

热门文章

  1. 三帧差分法 - 运动物体检测 - 行人检测 - 学习研究过程
  2. python分布式存储系统_主流分布式存储技术的对比分析与应用
  3. [PHP]int长度限制
  4. Linux按压缩率大小排序,Linux下经常使用压缩 解压命令和压缩比率对比
  5. JavaScript--ES6学习笔记
  6. 国瀚实业|上班族怎么选择理财产品
  7. ssh: connect to host 192.168.101.34 port 22: Connection timed out
  8. 5.docker从指定(私有)仓库拉取镜像、推送镜像
  9. webstorm打开的页面如何通过手机访问?
  10. c语言开发需要付专利费吗,专利每年年要维护费吗-专利费是不是每年都要付