当前位置:网站首页>NDK learning notes (14) create an avi video player using avilib+window
NDK learning notes (14) create an avi video player using avilib+window
2022-06-11 05:34:00 【Come and go】
List of articles
1.window api
(1) from surface Object window
from surface Retrieve objects from window
ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface);
(2) Get native window Application in the example
void ANativeWindow_acquire(ANativeWindow* window);
(3) Release native window quote
void ANativeWindow_release(ANativeWindow* window);
(4) Retrieve native window Information
Width
int32_t ANativeWindow_getWidth(ANativeWindow* window);
Width
int32_t ANativeWindow_getHeight(ANativeWindow* window);
Pixel format
int32_t ANativeWindow_getFormat(ANativeWindow* window);
(5) Set native window Buffer Geometry
int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,
int32_t width, int32_t height, int32_t format);
(6) Access native window buffer
int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
ARect* inOutDirtyBounds);
(7) Release native window buffer
int32_t ANativeWindow_unlockAndPost(ANativeWindow* window);
2. Main code
java
public class NativeWindowPlayerActivity extends AbstractPlayerActivity {
private final AtomicBoolean isPlaying = new AtomicBoolean();
private SurfaceHolder surfaceHolder;
SurfaceView surfaceView;
@Override
protected 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);
}
@Override
protected void onStart() {
super.onStart();
int w = getWidth(avi);
int h = getHeight(avi);
// Set up surfaceView Band size of , Prevent autofill
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() {
@Override
public void surfaceRedrawNeeded(SurfaceHolder holder) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
isPlaying.set(true);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
isPlaying.set(true);
new Thread(renderer).start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
isPlaying.set(false);
}
};
private Runnable renderer = new Runnable() {
@Override
public 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;
}
}
}
};
/** * Initialize native window * * @param avi * @param surface */
private native static void init(long avi, Surface surface);
/** * Rendering * @param avi * @param surface * @return */
private native static boolean render(long avi, Surface surface);
}
Native code
#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) {
// from surface Get native from window
ANativeWindow *nativeWindow = ANativeWindow_fromSurface(env, surface);
if (0 == nativeWindow) {
ThrowException(env, "java/io/RuntimeException", " Can't all get window");
goto exit;
}
// Set up buffer The size is avi Resolution of video frames
// If and window The physical size of is inconsistent
//buffer Will be scaled to match this size
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", " Cannot set 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", " Can't get window");
goto exit;
}
// Lock native window And access the original buffer
ANativeWindow_Buffer windowBuffer;
if (0 > ANativeWindow_lock(nativeWindow, &windowBuffer, 0)) {
ThrowException(env, "java/io/RuntimeException", " Cannot be locked window");
goto release;
}
// take avi The bit stream of the frame is read to the original buffer
frameSize = AVI_read_frame((avi_t *) avi, (char *) windowBuffer.bits, &keyFrame);
// Whether the reading is successful
if (0 < frameSize) {
isFrameRead = JNI_TRUE;
}
// Unlock and output buffer to display
if (0 > ANativeWindow_unlockAndPost(nativeWindow)) {
ThrowException(env, "java/io/RuntimeException", " Cannot unlock window");
goto release;
}
release:
ANativeWindow_release(nativeWindow);
nativeWindow = 0;
exit:
return isFrameRead;
}
To configure cmake
jnigraphics And android There will be conflict , So the prefix is added -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.cpp
Common.cpp
cn_study_aviplayer_BitmapPlayerActivity.cpp
cn_study_aviplayer_OpenGLPlayerActivity.cpp
cn_study_aviplayer_NativeWindowPlayerActivity.cpp)
# Add subdirectories
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# Turn on jnigraphics
${
android-lib}# Use window
${
log-lib}
${
GLESv2-lib}
avi-lib)
3. Realization effect

边栏推荐
- Chapter I: Net architecture (1)
- Multithreading tutorial (XXVI) field updater and atomic accumulator
- Handle double quotation mark escape in JSON string
- Customize the layout of view Foundation
- Oh my Zsh correct installation posture
- Swap numbers (no temporary variables)
- Opencv learning path (2-2) -- Deep parsing namedwindow function
- Concurrent search set
- 27、移除元素
- [go deep into kotlin] - get to know flow for the first time
猜你喜欢

PCB走線到底能承載多大電流

Analysis while experiment - a little optimization of memory leakage in kotlin

1. use alicloud object OSS (basic)

(十五)红外通信

lower_ Personal understanding of bound function

6 questions to ask when selecting a digital asset custodian

MySQL string to array, merge result set, and convert to array

English digital converter

Topological sorting

Wechat applet, automatic line feed for purchasing commodity attributes, fixed number of divs, automatic line feed for excess parts
随机推荐
[go deep into kotlin] - get to know flow for the first time
【深入kotlin】 - 初识 Flow
项目-智慧城市
WinForm (I) introduction to WinForm and use of basic controls
NDK learning notes (I)
BERT知识蒸馏
NDK learning notes (II)
Solving graph problems with union search set
SQLite installation and configuration tutorial +navicat operation
(15) Infrared communication
Intercept file extension
Recommend a free intranet penetration open source software that can be used in the local wechat official account under test
Section V: Recycling Application of asphalt pavement materials
Use acme SH automatically apply for a free SSL certificate
Customize the layout of view Foundation
Multi threading tutorial (XXIV) cas+volatile
NDK learning notes (IV) functions, classes and exceptions of swig
深度学习分布式训练
Combination sum Ⅳ -- leetcode exercise
Bert knowledge distillation