├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ └── layout
│ │ │ │ ├── activity_player.xml
│ │ │ │ └── activity_main.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── wodekouwei
│ │ │ └── demo
│ │ │ ├── MainActivity.java
│ │ │ └── PlayerAty.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── wodekouwei
│ │ │ └── demo
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── wodekouwei
│ │ └── demo
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── oarplayer
├── .gitignore
├── src
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── cpp
│ │ │ ├── srs_readthread.h
│ │ │ ├── oar_player_gl_thread.h
│ │ │ ├── util.h
│ │ │ ├── oar_player_video_hw_decode_thread.h
│ │ │ ├── oar_jni_reflect.h
│ │ │ ├── oar_player_audio_hw_decode_thread.h
│ │ │ ├── oar_audio_player.h
│ │ │ ├── oar_glsl_program.h
│ │ │ ├── oar_video_render.h
│ │ │ ├── oar_audio_mediacodec_ctx.h
│ │ │ ├── oar_frame_queue.h
│ │ │ ├── oar_clock.h
│ │ │ ├── util.c
│ │ │ ├── oar_audio_mediacodec_ctx.c
│ │ │ ├── oar_texture.h
│ │ │ ├── oar_player.h
│ │ │ ├── oar_audio_mediacodec_java.h
│ │ │ ├── oar_video_mediacodec_java.h
│ │ │ ├── oar_video_mediacodec_ndk.h
│ │ │ ├── oar_packet_queue.h
│ │ │ ├── oar_audio_mediacodec_ndk.h
│ │ │ ├── oar_clock.c
│ │ │ ├── _android.h
│ │ │ ├── oar_video_mediacodec_ctx.h
│ │ │ ├── oar_video_render.c
│ │ │ ├── oar_native_mediacodec.h
│ │ │ ├── oar_macro.h
│ │ │ ├── oar_player_audio_hw_decode_thread.c
│ │ │ ├── oar_texture.c
│ │ │ ├── oar_frame_queue.c
│ │ │ ├── oar_player_video_hw_decode_thread.c
│ │ │ ├── oar_audio_mediacodec_ndk.c
│ │ │ ├── jni_utils.h
│ │ │ ├── oar_jni_reflect.c
│ │ │ ├── oar_packet_queue.c
│ │ │ ├── oar_video_mediacodec_ndk.c
│ │ │ ├── oarplayer_jni.c
│ │ │ ├── oar_video_mediacodec_ctx.c
│ │ │ ├── oar_audio_mediacodec_java.c
│ │ │ └── oar_video_mediacodec_java.c
│ │ └── java
│ │ │ └── com
│ │ │ └── wodekouwei
│ │ │ └── srsrtmpplayer
│ │ │ ├── proxy
│ │ │ ├── SurfaceTextureWrapper.java
│ │ │ ├── HwAudioDecodeWrapper.java
│ │ │ └── HwVideoDecodeWrapper.java
│ │ │ └── OARPlayer.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── wodekouwei
│ │ │ └── srsrtmpplayer
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── wodekouwei
│ │ └── srsrtmpplayer
│ │ └── ExampleInstrumentedTest.java
├── jni_lib_src
│ ├── libs
│ │ ├── x86
│ │ │ └── libmediacodec-lib.so
│ │ ├── x86_64
│ │ │ └── libmediacodec-lib.so
│ │ ├── arm64-v8a
│ │ │ └── libmediacodec-lib.so
│ │ └── armeabi-v7a
│ │ │ └── libmediacodec-lib.so
│ ├── armeabi-v7a
│ │ └── libmediacodec-lib.so
│ └── include
│ │ └── oar_native_mediacodec.h
├── proguard-rules.pro
├── gradle.properties
├── build.gradle
├── CMakeLists.txt
└── gradle-mvn-push.gradle
├── nativemediacodec
├── .gitignore
├── src
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ └── cpp
│ │ │ ├── _android.h
│ │ │ ├── oar_native_mediacodec.h
│ │ │ └── oar_native_mediacodec.c
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── wodekouwei
│ │ │ └── nativemediacodec
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── wodekouwei
│ │ └── nativemediacodec
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
├── build.gradle
└── CMakeLists.txt
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── gradle.properties
├── LICENSE
├── README.md
├── gradlew.bat
└── gradlew
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/oarplayer/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /.cxx
3 | /.externalNativeBuild
4 |
--------------------------------------------------------------------------------
/nativemediacodec/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /.cxx
3 | /.externalNativeBuild
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':oarplayer', ':nativemediacodec'
2 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | oar播放器
3 |
4 |
--------------------------------------------------------------------------------
/oarplayer/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/nativemediacodec/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/oarplayer/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SrsRtmpPlayer
3 |
4 |
--------------------------------------------------------------------------------
/nativemediacodec/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | nativemediacodec
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/oarplayer/jni_lib_src/libs/x86/libmediacodec-lib.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/oarplayer/jni_lib_src/libs/x86/libmediacodec-lib.so
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/oarplayer/jni_lib_src/armeabi-v7a/libmediacodec-lib.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/oarplayer/jni_lib_src/armeabi-v7a/libmediacodec-lib.so
--------------------------------------------------------------------------------
/oarplayer/jni_lib_src/libs/x86_64/libmediacodec-lib.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/oarplayer/jni_lib_src/libs/x86_64/libmediacodec-lib.so
--------------------------------------------------------------------------------
/oarplayer/jni_lib_src/libs/arm64-v8a/libmediacodec-lib.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/oarplayer/jni_lib_src/libs/arm64-v8a/libmediacodec-lib.so
--------------------------------------------------------------------------------
/oarplayer/jni_lib_src/libs/armeabi-v7a/libmediacodec-lib.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qingkouwei/oarplayer/HEAD/oarplayer/jni_lib_src/libs/armeabi-v7a/libmediacodec-lib.so
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 | .idea
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Dec 26 11:42:55 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/wodekouwei/demo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.wodekouwei.demo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/oarplayer/src/test/java/com/wodekouwei/srsrtmpplayer/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.wodekouwei.srsrtmpplayer;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/nativemediacodec/src/test/java/com/wodekouwei/nativemediacodec/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.wodekouwei.nativemediacodec;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_player.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/oarplayer/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/nativemediacodec/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 | org.gradle.java.home=/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/wodekouwei/demo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.wodekouwei.demo;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.wodekouwei.demo", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/oarplayer/gradle.properties:
--------------------------------------------------------------------------------
1 | PROJ_GROUP=com.github.qingkouwei
2 | PROJ_ARTIFACTID=oarplayer
3 | PROJ_POM_NAME=an android rtmp player without ffmpeg
4 | POM_PACKAGING=aar
5 | # !!!the following can move to ~/.gradle/gradle.properties
6 | # replace with your info
7 | RELEASE_REPOSITORY_URL=https://oss.sonatype.org/service/local/staging/deploy/maven2
8 | SNAPSHOT_REPOSITORY_URL=https://oss.sonatype.org/content/repositories/snapshots
9 | PROJ_VERSION=0.0.1
10 | PROJ_WEBSITEURL=https://github.com/qingkouwei/oarplayer
11 | PROJ_ISSUETRACKERURL=https://github.com/qingkouwei/oarplayer/issues
12 | PROJ_VCSURL=https://github.com/qingkouwei/oarplayer.git
13 | PROJ_DESCRIPTION=an android rtmp player without ffmpeg
14 | PROJ_LICENCE_NAME=The MIT License (MIT)
15 | PROJ_LICENCE_URL=https://www.mit-license.org/
16 | PROJ_LICENCE_DEST=repo
17 | DEVELOPER_ID=wodekouwei
18 | DEVELOPER_NAME=junweishen
19 | DEVELOPER_EMAIL=282537740@qq.com
20 |
--------------------------------------------------------------------------------
/oarplayer/src/androidTest/java/com/wodekouwei/srsrtmpplayer/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.wodekouwei.srsrtmpplayer;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.wodekouwei.srsrtmpplayer.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/nativemediacodec/src/androidTest/java/com/wodekouwei/nativemediacodec/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.wodekouwei.nativemediacodec;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.wodekouwei.nativemediacodec.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/shenjunwei/program/android-sdk-macosx/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
17 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017-2022 oarplayer(qingkouwei)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 33
5 |
6 | defaultConfig {
7 | applicationId "com.wodekouwei.demo"
8 | minSdkVersion 16
9 | targetSdkVersion 33
10 | versionCode 1
11 | versionName "1.0"
12 | ndk {
13 | //abiFilters 'armeabi-v7a'
14 | }
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 | buildTypes {
19 | release {
20 | minifyEnabled true
21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | namespace 'com.wodekouwei.demo'
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
30 | exclude group: 'com.android.support', module: 'support-annotations'
31 | })
32 | implementation 'com.android.support:appcompat-v7:28.0.0'
33 | implementation 'com.android.support.constraint:constraint-layout:1.0.2'
34 | testImplementation 'junit:junit:4.12'
35 | implementation project(':oarplayer')
36 | }
37 |
--------------------------------------------------------------------------------
/nativemediacodec/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 33
5 |
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion 21
10 | targetSdkVersion 33
11 | ndkVersion "21.4.7075529"
12 | externalNativeBuild {
13 | cmake {
14 | cppFlags "-frtti -fexceptions"
15 | }
16 | }
17 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
18 |
19 | }
20 |
21 | buildTypes {
22 | release {
23 | minifyEnabled false
24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
25 | }
26 | }
27 | externalNativeBuild {
28 | cmake {
29 | path "CMakeLists.txt"
30 | }
31 | }
32 | namespace 'com.wodekouwei.nativemediacodec'
33 | }
34 |
35 | dependencies {
36 | implementation fileTree(dir: 'libs', include: ['*.jar'])
37 |
38 | implementation 'com.android.support:appcompat-v7:28.0.0'
39 | testImplementation 'junit:junit:4.12'
40 | androidTestImplementation 'com.android.support.test:runner:1.0.1'
41 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Android Rtmp 播放器
2 | oarplayer(only android rtmp player)是一款简单到毫无特色的纯rtmp播放器,
3 | 不依赖ffmpeg,仅依赖srs-librtmp第三方库,体积小,可调整性强.
4 |
5 | ## 功能介绍
6 | - 未依赖ffmpeg框架,基于srs-librtmp的rtmp拉流,编译打包更简单;
7 | - 支持Android API level 16及以上系统;
8 | - 完全使用Android硬件解码,支持FLV封装的H264+AAC音视频编码直播;
9 | - Android API level 21以下使用java层创建的Mediacodec解码,API level21及以上使用NdkMediaCodec,解码不需要与java交互,效率更高;
10 | - 视频显示使用MediaCodec(Android 硬解)->SurfaceTexture->OpenGL ES工作模式,性能优异;
11 | - 音频播放使用OpenSL ES,直接native层读取音频解码帧播放;
12 | - 支持后台播放(只播放声音);
13 | - 支持设置缓存时长.
14 |
15 | ## 已知问题及优化计划
16 | - [x] srs-librtmp库裁剪以及增加读超时时间配置接口;
17 | - [x] 音频未支持重采样,对于部分对声音播放采样率有要求的手机支持不好;
18 | - [x] x264以及libaac软解码库支持(未确定);
19 | - [x] 视频绘制滤镜增加(配置接口与各滤镜效果shader);
20 | - [x] 实时截图功能;
21 | - [x] 视频边看边下载功能;
22 | - [x] 播放统计
23 |
24 |
25 | ## 使用说明
26 | gradle中导入:
27 | ```
28 | compile 'com.github.qingkouwei:oarplayer:0.0.1-SNAPSHOT'
29 | ```
30 | 通过以下几步即可完成rtmp播放:
31 |
32 | 1. 实例化OARPlayer:`OARPlayer player = new OARPlayer();`
33 | 2. 设置视频源:`player.setDataSource(rtmp_url);`
34 | 3. 设置surface:`player.setSurface(surfaceView.getHolder());`
35 | 4. 开始播放:`player.start();`
36 | 5. 停止播放:`player.stop();`
37 | 6. 释放资源:`player.release();`
38 | ## 联系方式
39 | email:turn.shen@gmail.com
40 |
41 | OARPlayer is licenced under [MIT](https://github.com/qingkouwei/oarplayer/blob/master/LICENSE).
42 | **欢迎使用,欢迎star**
43 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/srs_readthread.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef __OARPLAYER_SRS_PLAYER_H__
24 | #define __OARPLAYER_SRS_PLAYER_H__
25 |
26 | void *read_thread(void *data);
27 |
28 | #endif //__OARPLAYER_SRS_PLAYER_H__
29 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_player_gl_thread.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef __OAR_PLAYER_GL_THREAD_H__
24 | #define __OAR_PLAYER_GL_THREAD_H__
25 |
26 | void * oar_player_gl_thread(void *data);
27 |
28 | #endif //__OAR_PLAYER_GL_THREAD_H__
29 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/util.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #ifndef __OARPLAYER_UTIL_H__
25 | #define __OARPLAYER_UTIL_H__
26 |
27 | #include
28 |
29 | int get_int(uint8_t *buf);
30 | int64_t get_long(uint8_t *buf);
31 | #endif //__OARPLAYER_UTIL_H__
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/wodekouwei/demo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.wodekouwei.demo;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.text.TextUtils;
7 | import android.view.View;
8 | import android.view.WindowManager;
9 | import android.widget.Button;
10 | import android.widget.EditText;
11 | import android.widget.Toast;
12 |
13 | public class MainActivity extends AppCompatActivity {
14 |
15 | private Button btn;
16 | private EditText et;
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | setContentView(R.layout.activity_main);
22 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
23 | btn = (Button) findViewById(R.id.btn);
24 | et = (EditText) findViewById(R.id.et);
25 | btn.setOnClickListener(new View.OnClickListener() {
26 | @Override
27 | public void onClick(View view) {
28 | String rtmpUrl = et.getText().toString();
29 | if (TextUtils.isEmpty(rtmpUrl)) {
30 | Toast.makeText(MainActivity.this, "请输入播放地址", Toast.LENGTH_SHORT).show();
31 | } else {
32 | Intent intent = new Intent(MainActivity.this, PlayerAty.class);
33 | intent.putExtra("rtmp_url", rtmpUrl);
34 | startActivity(intent);
35 | }
36 | }
37 | });
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/oarplayer/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 33
5 | sourceSets {
6 | main {
7 | jniLibs.srcDirs = ['jni_lib_src/libs']
8 | }
9 | }
10 |
11 |
12 | defaultConfig {
13 | minSdkVersion 16
14 | targetSdkVersion 33
15 | ndkVersion "21.4.7075529"
16 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
17 | externalNativeBuild {
18 | cmake {
19 | //cppFlags "-std=c++11 -frtti -fexceptions -Wformat -Werror=format-security"
20 | }
21 | }
22 | }
23 |
24 | buildTypes {
25 | release {
26 | minifyEnabled false
27 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
28 | }
29 | }
30 | externalNativeBuild {
31 | cmake {
32 | path "CMakeLists.txt"
33 | }
34 | }
35 | namespace 'com.wodekouwei.srsrtmpplayer'
36 | }
37 |
38 | dependencies {
39 | implementation fileTree(dir: 'libs', include: ['*.jar'])
40 |
41 | implementation 'com.android.support:appcompat-v7:28.0.0'
42 | testImplementation 'junit:junit:4.12'
43 | androidTestImplementation 'com.android.support.test:runner:1.0.1'
44 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
45 | }
46 | //apply from: 'gradle-mvn-push.gradle'
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_player_video_hw_decode_thread.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #ifndef __OAR_PLAYER_VIDEO_HW_DECODE_THREAD_H__
25 | #define __OAR_PLAYER_VIDEO_HW_DECODE_THREAD_H__
26 | #include "oarplayer_type_def.h"
27 |
28 | void * video_decode_hw_thread(void * data);
29 | #endif //__OAR_PLAYER_VIDEO_HW_DECODE_THREAD_H__
30 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_jni_reflect.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef __OAR_JNI_REFLECT_H
24 | #define __OAR_JNI_REFLECT_H
25 | #include "oarplayer_type_def.h"
26 |
27 | void oar_jni_reflect_java_class(oar_java_class ** p_jc, JNIEnv *jniEnv);
28 | void oar_jni_free(oar_java_class **p_jc, JNIEnv *jniEnv);
29 | #endif //__OAR_JNI_REFLECT_H
30 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_player_audio_hw_decode_thread.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #ifndef __OAR_PLAYER_AUDIO_HW_DECODE_THREAD_H__
25 | #define __OAR_PLAYER_AUDIO_HW_DECODE_THREAD_H__
26 |
27 | #include "oarplayer_type_def.h"
28 |
29 | void * audio_decode_thread(void * data);
30 |
31 | #endif //__OAR_PLAYER_AUDIO_HW_DECODE_THREAD_H__
32 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_audio_player.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef OARPLAYER_OAR_AUDIO_PLAYER_H
24 | #define OARPLAYER_OAR_AUDIO_PLAYER_H
25 |
26 | #include "oarplayer_type_def.h"
27 |
28 | oar_audio_player_context* oar_audio_engine_create();
29 | void oar_audio_player_create(int rate, int channel, oarplayer* oar);
30 |
31 | #endif //OARPLAYER_OAR_AUDIO_PLAYER_H
32 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_glsl_program.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef __OAR_GLSL_PROGRAM_H__
24 | #define __OAR_GLSL_PROGRAM_H__
25 |
26 | #include "oarplayer_type_def.h"
27 |
28 | oar_glsl_program * oar_glsl_program_get(int pixel_format);
29 | void oar_glsl_program_clear_all();
30 |
31 | oar_model *createModel();
32 | void freeModel(oar_model *model);
33 | #endif //__OAR_GLSL_PROGRAM_H__
34 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_video_render.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef OAR_VIDEO_RENDER_H
24 | #define OAR_VIDEO_RENDER_H
25 |
26 |
27 | #include "oarplayer_type_def.h"
28 | void oar_video_render_ctx_reset(oar_video_render_context * ctx);
29 | oar_video_render_context * oar_video_render_ctx_create();
30 | void oar_video_render_ctx_release(oar_video_render_context * ctx);
31 |
32 | #endif //OAR_VIDEO_RENDER_H
33 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_audio_mediacodec_ctx.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | //
24 | // Created by qingkouwei on 2018/1/5.
25 | //
26 |
27 | #ifndef OARPLAYER_OAR_AUDIO_MEDIACODEC_CTX_H
28 | #define OARPLAYER_OAR_AUDIO_MEDIACODEC_CTX_H
29 |
30 | #include "oarplayer_type_def.h"
31 |
32 | oar_audio_mediacodec_context * oar_create_audio_mediacodec_context(
33 | oarplayer *oar);
34 | #endif //OARPLAYER_OAR_AUDIO_MEDIACODEC_CTX_H
35 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_frame_queue.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef __OAR_FRAME_QUEUE_H_
24 | #define __OAR_FRAME_QUEUE_H_
25 | #include "oarplayer_type_def.h"
26 | oar_frame_queue * oar_frame_queue_create(unsigned int size);
27 | void oar_frame_queue_free(oar_frame_queue *queue);
28 | int oar_frame_queue_put(oar_frame_queue *queue, OARFrame *frame);
29 | OARFrame * oar_frame_queue_get(oar_frame_queue *queue);
30 | #endif //__OAR_FRAME_QUEUE_H_
31 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_clock.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef __OAR_CLOCK_H__
24 | #define __OAR_CLOCK_H__
25 | #include
26 | #include "oarplayer_type_def.h"
27 |
28 | uint64_t oar_clock_get_current_time();
29 | oar_clock * oar_clock_create();
30 | int64_t oar_clock_get(oar_clock * clock);
31 | void oar_clock_set(oar_clock * clock, int64_t pts);
32 | void oar_clock_free(oar_clock * clock);
33 | void oar_clock_reset(oar_clock * clock);
34 | #endif //__OAR_CLOCK_H__
35 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/util.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #include "util.h"
25 | int get_int(uint8_t *buf) {
26 | return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
27 | }
28 |
29 | int64_t get_long(uint8_t *buf) {
30 | return (((int64_t) buf[0]) << 56)
31 | + (((int64_t) buf[1]) << 48)
32 | + (((int64_t) buf[2]) << 40)
33 | + (((int64_t) buf[3]) << 32)
34 | + (((int64_t) buf[4]) << 24)
35 | + (((int64_t) buf[5]) << 16)
36 | + (((int64_t) buf[6]) << 8)
37 | + ((int64_t) buf[7]);
38 | }
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_audio_mediacodec_ctx.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | //
24 | // Created by qingkouwei on 2018/1/5.
25 | //
26 |
27 | #include
28 | #include "oar_audio_mediacodec_ctx.h"
29 |
30 | oar_audio_mediacodec_context *oar_create_audio_mediacodec_context(
31 | oarplayer *oar) {
32 | oar_audio_mediacodec_context *ctx = (oar_audio_mediacodec_context *) malloc(sizeof(oar_audio_mediacodec_context));
33 | ctx->channel_count = oar->metadata->channels;
34 | ctx->sample_rate = oar->metadata->sample_rate;
35 | ctx->codec_id = oar->metadata->audio_codec;
36 | return ctx;
37 | }
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_texture.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #ifndef __OAR_TEXTURE_H__
25 | #define __OAR_TEXTURE_H__
26 | #include "oarplayer_type_def.h"
27 |
28 |
29 | void initTexture(oarplayer * oar);
30 | void oar_texture_delete(oarplayer * oar);
31 | void update_texture_yuv420p(oar_model *model, OARFrame *frame);
32 | void update_texture_nv12(oar_model *model, OARFrame *frame);
33 | void bind_texture_yuv420p(oar_model *model);
34 | void bind_texture_nv12(oar_model *model);
35 | void bind_texture_oes(oar_model *model);
36 | void update_texture_oes(oar_model *model, OARFrame *frame);
37 |
38 | #endif //__OAR_TEXTURE_H__
39 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_player.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #ifndef OARPLAYER_OAR_PLAYER_H
25 | #define OARPLAYER_OAR_PLAYER_H
26 |
27 | #include
28 | #include "oarplayer_type_def.h"
29 |
30 | oarplayer *
31 | oar_player_create(JNIEnv *env, jobject instance, int run_android_version, int best_samplerate);
32 | void oar_player_set_buffer_time(oarplayer *oar, float buffer_time);
33 | void oar_player_set_play_background(oarplayer *oar, bool play_background);
34 | int oar_player_play(oarplayer *oar);
35 | void oar_player_resume(oarplayer *oar);
36 | int oar_player_stop(oarplayer *oar);
37 | int oar_player_release(oarplayer *oar);
38 | #endif //OARPLAYER_OAR_PLAYER_H
39 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_audio_mediacodec_java.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef __OAR_AUDIO_MEDIACODEC_H__
24 | #define __OAR_AUDIO_MEDIACODEC_H__
25 |
26 | #include
27 | #include
28 | #include "oarplayer_type_def.h"
29 | #include "endian.h"
30 |
31 | void oar_audio_mediacodec_release_buffer(oarplayer *oar, int index);
32 | int oar_audio_mediacodec_receive_frame(oarplayer *oar, OARFrame **frame);
33 | int oar_audio_mediacodec_send_packet(oarplayer *oar, OARPacket *packet);
34 | void oar_audio_mediacodec_flush(oarplayer *oar);
35 | void oar_audio_mediacodec_release_context(oarplayer *oar);
36 | void oar_audio_mediacodec_start(oarplayer *oar);
37 | void oar_audio_mediacodec_stop(oarplayer *oar);
38 |
39 | #endif //__OAR_AUDIO_MEDIACODEC_H__
40 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_video_mediacodec_java.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #ifndef __OAR_VIDEO_MEDIACODEC_H__
25 | #define __OAR_VIDEO_MEDIACODEC_H__
26 |
27 | #include
28 | #include
29 | #include "oarplayer_type_def.h"
30 | #include "endian.h"
31 |
32 |
33 | void oar_video_mediacodec_release_buffer(oarplayer *oar, int index);
34 | int oar_video_mediacodec_receive_frame(oarplayer *oar, OARFrame *frame);
35 | int oar_video_mediacodec_send_packet(oarplayer *oar, OARPacket *packet);
36 | void oar_video_mediacodec_flush(oarplayer *oar);
37 | void oar_video_mediacodec_release_context(oarplayer *oar);
38 | void oar_video_mediacodec_start(oarplayer *oar);
39 | void oar_video_mediacodec_stop(oarplayer *oar);
40 |
41 | #endif //__OAR_VIDEO_MEDIACODEC_H__
42 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_video_mediacodec_ndk.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #ifndef __OAR_VIDEO_MEDIACODEC_NDK_H__
25 | #define __OAR_VIDEO_MEDIACODEC_NDK_H__
26 |
27 | #include "oarplayer_type_def.h"
28 |
29 | void oar_create_video_mediacodec_ndk(
30 | oarplayer *oar);
31 | void oar_video_mediacodec_release_buffer_ndk(oarplayer *oar, int index);
32 | int oar_video_mediacodec_receive_frame_ndk(oarplayer *oar, OARFrame *frame);
33 | int oar_video_mediacodec_send_packet_ndk(oarplayer *oar, OARPacket *packet);
34 | void oar_video_mediacodec_flush_ndk(oarplayer *oar);
35 | void oar_video_mediacodec_release_context_ndk(oarplayer *oar);
36 | void oar_video_mediacodec_start_ndk(oarplayer *oar);
37 | void oar_video_mediacodec_stop_ndk(oarplayer *oar);
38 | #endif //__OAR_VIDEO_MEDIACODEC_NDK_H__
39 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_packet_queue.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #ifndef __OAR_PACKET_QUEUE_H
25 | #define __OAR_PACKET_QUEUE_H
26 |
27 | #include
28 | #include "oarplayer_type_def.h"
29 |
30 |
31 | oar_packet_queue * oar_queue_create();
32 | void oar_queue_set_duration(oar_packet_queue * queue, uint64_t max_duration);
33 | void oar_packet_queue_free(oar_packet_queue *queue);
34 | int oar_packet_queue_put(oar_packet_queue *queue,
35 | int size,
36 | PktType_e type,
37 | int64_t dts,
38 | int64_t pts,
39 | int isKeyframe,
40 | uint8_t *data);
41 | OARPacket * oar_packet_queue_get(oar_packet_queue *queue);
42 | void freePacket(OARPacket *pkt);
43 | #endif //__OAR_PACKET_QUEUE_H
44 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_audio_mediacodec_ndk.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | //
24 | // Created by qingkouwei on 2018/1/4.
25 | //
26 |
27 | #ifndef OARPLAYER_OAR_AUDIO_MEDIACODEC_NDK_H
28 | #define OARPLAYER_OAR_AUDIO_MEDIACODEC_NDK_H
29 |
30 | #include "oarplayer_type_def.h"
31 |
32 | void oar_create_audio_mediacodec_ndk(
33 | oarplayer *oar);
34 | void oar_audio_mediacodec_release_buffer_ndk(oarplayer *oar, int index);
35 | int oar_audio_mediacodec_receive_frame_ndk(oarplayer *oar, OARFrame **frame);
36 | int oar_audio_mediacodec_send_packet_ndk(oarplayer *oar, OARPacket *packet);
37 | void oar_audio_mediacodec_flush_ndk(oarplayer *oar);
38 | void oar_audio_mediacodec_release_context_ndk(oarplayer *oar);
39 | void oar_audio_mediacodec_start_ndk(oarplayer *oar);
40 | void oar_audio_mediacodec_stop_ndk(oarplayer *oar);
41 | #endif //OARPLAYER_OAR_AUDIO_MEDIACODEC_NDK_H
42 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_clock.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #include
25 | #include
26 | #include "oar_clock.h"
27 | uint64_t oar_clock_get_current_time(){
28 | struct timeval tv;
29 | gettimeofday(&tv, NULL);
30 | return (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec;
31 | }
32 | oar_clock * oar_clock_create(){
33 | oar_clock *clock = (oar_clock*)malloc(sizeof(oar_clock));
34 | return clock;
35 | }
36 | int64_t oar_clock_get(oar_clock * clock){
37 | if(clock->update_time == 0){
38 | return INT64_MAX;
39 | }
40 | return clock->pts + oar_clock_get_current_time()-clock->update_time;
41 | }
42 | void oar_clock_set(oar_clock * clock, int64_t pts){
43 | clock->update_time = oar_clock_get_current_time();
44 | clock->pts = pts;
45 | }
46 | void oar_clock_free(oar_clock * clock){
47 | free(clock);
48 | }
49 | void oar_clock_reset(oar_clock * clock){
50 | clock->pts=0;
51 | clock->update_time = 0;
52 | }
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/_android.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef _ANDROID_H_
24 | #define _ANDROID_H_
25 |
26 | #include
27 | #include
28 | #ifndef _JNILOG_TAG
29 | #define _JNILOG_TAG __FILE__
30 | #endif
31 | #ifndef __LOG_LEVEL
32 | #define __LOG_LEVEL ANDROID_LOG_DEBUG
33 | #endif
34 |
35 | #define isDebug 0
36 |
37 | #define _JNILOG(LEVEL, FMT, ...) if (LEVEL >= __LOG_LEVEL) \
38 | __android_log_print(LEVEL,_JNILOG_TAG, "[%s():%d]" FMT, __FUNCTION__, __LINE__, ##__VA_ARGS__)
39 | #define LOGD(...) _JNILOG(ANDROID_LOG_DEBUG,__VA_ARGS__)
40 | #define LOGI(...) _JNILOG(ANDROID_LOG_INFO,__VA_ARGS__)
41 | #define LOGW(...) _JNILOG(ANDROID_LOG_WARN,__VA_ARGS__)
42 | #define LOGE(...) _JNILOG(ANDROID_LOG_ERROR,__VA_ARGS__)
43 |
44 | #define LOG_FUNC_FAIL_TRACE() do {LOGE("%s: failed\n", __func__);} while (0)
45 | #define LOG_FUNC_FAIL_TRACE1(x__) do {LOGE("%s: failed: %s\n", __func__, x__);} while (0)
46 | #define LOG_FUNC_FAIL_TRACE2(x1__, x2__) do {LOGE("%s: failed: %s %s\n", __func__, x1__, x2__);} while (0)
47 |
48 | #endif
49 |
--------------------------------------------------------------------------------
/nativemediacodec/src/main/cpp/_android.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef _ANDROID_H_
24 | #define _ANDROID_H_
25 |
26 | #include
27 | #include
28 | #ifndef _JNILOG_TAG
29 | #define _JNILOG_TAG __FILE__
30 | #endif
31 | #ifndef __LOG_LEVEL
32 | #define __LOG_LEVEL ANDROID_LOG_DEBUG
33 | #endif
34 |
35 | #define isDebug 0
36 |
37 | #define _JNILOG(LEVEL, FMT, ...) if (LEVEL >= __LOG_LEVEL) \
38 | __android_log_print(LEVEL,_JNILOG_TAG, "[%s():%d]" FMT, __FUNCTION__, __LINE__, ##__VA_ARGS__)
39 | #define LOGD(...) _JNILOG(ANDROID_LOG_DEBUG,__VA_ARGS__)
40 | #define LOGI(...) _JNILOG(ANDROID_LOG_INFO,__VA_ARGS__)
41 | #define LOGW(...) _JNILOG(ANDROID_LOG_WARN,__VA_ARGS__)
42 | #define LOGE(...) _JNILOG(ANDROID_LOG_ERROR,__VA_ARGS__)
43 |
44 | #define LOG_FUNC_FAIL_TRACE() do {LOGE("%s: failed\n", __func__);} while (0)
45 | #define LOG_FUNC_FAIL_TRACE1(x__) do {LOGE("%s: failed: %s\n", __func__, x__);} while (0)
46 | #define LOG_FUNC_FAIL_TRACE2(x1__, x2__) do {LOGE("%s: failed: %s %s\n", __func__, x1__, x2__);} while (0)
47 |
48 | #endif
49 |
--------------------------------------------------------------------------------
/nativemediacodec/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # For more information about using CMake with Android Studio, read the
2 | # documentation: https://d.android.com/studio/projects/add-native-code.html
3 |
4 | # Sets the minimum version of CMake required to build the native library.
5 |
6 | cmake_minimum_required(VERSION 3.4.1)
7 |
8 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
9 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
10 |
11 | # Creates and names a library, sets it as either STATIC
12 | # or SHARED, and provides the relative paths to its source code.
13 | # You can define multiple libraries, and CMake builds them for you.
14 | # Gradle automatically packages shared libraries with your APK.
15 | add_library( # Sets the name of the library.
16 | mediacodec-lib
17 |
18 | # Sets the library as a shared library.
19 | SHARED
20 |
21 | # Provides a relative path to your source file(s).
22 | src/main/cpp/oar_native_mediacodec.c
23 | )
24 |
25 |
26 |
27 | find_library( # Sets the name of the path variable.
28 | log-lib
29 |
30 | # Specifies the name of the NDK library that
31 | # you want CMake to locate.
32 | log )
33 |
34 | find_library(media-ndk mediandk)
35 | target_link_libraries( # Specifies the target library.
36 | mediacodec-lib
37 | ${log-lib}
38 | ${media-ndk}
39 | )
40 |
41 | set(distribution_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../oarplayer/jni_lib_src)
42 |
43 | set_target_properties(mediacodec-lib PROPERTIES
44 | LIBRARY_OUTPUT_DIRECTORY ${distribution_DIR}/libs/${ANDROID_ABI})
45 | target_include_directories(mediacodec-lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp)
46 |
47 |
48 | add_custom_command(TARGET mediacodec-lib POST_BUILD
49 | COMMAND "${CMAKE_COMMAND}" -E
50 | copy "${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/oar_native_mediacodec.h"
51 | "${distribution_DIR}/include/"
52 | # **** the following 2 lines are for potential future debug purpose ****
53 | # COMMAND "${CMAKE_COMMAND}" -E
54 | # remove_directory "${CMAKE_CURRENT_BINARY_DIR}"
55 | COMMENT "Copying gmath to output directory")
56 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_video_mediacodec_ctx.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | //
24 | // Created by qingkouwei on 2018/1/5.
25 | //
26 |
27 | #ifndef OARPLAYER_OAR_VIDEO_MEDIACODEC_CTX_H
28 | #define OARPLAYER_OAR_VIDEO_MEDIACODEC_CTX_H
29 |
30 | #include "oarplayer_type_def.h"
31 |
32 | typedef struct H264ConvertState {
33 | uint32_t nal_len;
34 | uint32_t nal_pos;
35 | } H264ConvertState;
36 |
37 | oar_video_mediacodec_context * oar_create_video_mediacodec_context(
38 | oarplayer *oar);
39 |
40 |
41 | void convert_h264_to_annexb( uint8_t *p_buf, size_t i_len,
42 | size_t i_nal_size,
43 | H264ConvertState *state );
44 | int convert_sps_pps2(const uint8_t *p_buf, size_t i_buf_size,
45 | uint8_t * out_sps_buf, size_t * out_sps_buf_size,
46 | uint8_t * out_pps_buf, size_t * out_pps_buf_size,
47 | size_t *p_nal_size
48 | );
49 | int convert_hevc_nal_units(const uint8_t *p_buf,size_t i_buf_size,
50 | uint8_t *p_out_buf,size_t i_out_buf_size,
51 | size_t *p_sps_pps_size,size_t *p_nal_size);
52 |
53 | #endif //OARPLAYER_OAR_VIDEO_MEDIACODEC_CTX_H
54 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_video_render.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #include
24 | #include
25 | #include "oar_video_render.h"
26 |
27 | void oar_video_render_set_window(oar_video_render_context *ctx, struct ANativeWindow *window) {
28 | pthread_mutex_lock(ctx->lock);
29 | ctx->window = window;
30 | ctx->cmd |= CMD_SET_WINDOW;
31 | pthread_mutex_unlock(ctx->lock);
32 | }
33 |
34 |
35 | void oar_video_render_ctx_reset(oar_video_render_context * ctx){
36 | ctx->surface = EGL_NO_SURFACE;
37 | ctx->context = EGL_NO_CONTEXT;
38 | ctx->display = EGL_NO_DISPLAY;
39 | ctx->model = NULL;
40 | ctx->require_model_scale = 1;
41 | ctx->cmd = NO_CMD;
42 | ctx->draw_mode = wait_frame;
43 | ctx->require_model_rotation[0] = 0;
44 | ctx->require_model_rotation[1] = 0;
45 | ctx->require_model_rotation[2] = 0;
46 | ctx->width = ctx->height = 1;
47 | }
48 |
49 |
50 | oar_video_render_context *oar_video_render_ctx_create() {
51 | oar_video_render_context *ctx = malloc(sizeof(oar_video_render_context));
52 | ctx->lock = malloc(sizeof(pthread_mutex_t));
53 | pthread_mutex_init(ctx->lock, NULL);
54 | ctx->set_window = oar_video_render_set_window;
55 | ctx->window = NULL;
56 | ctx->texture_window = NULL;
57 | oar_video_render_ctx_reset(ctx);
58 | return ctx;
59 | }
60 |
61 | void oar_video_render_ctx_release(oar_video_render_context *ctx) {
62 | pthread_mutex_destroy(ctx->lock);
63 | free(ctx->lock);
64 | free(ctx);
65 | }
--------------------------------------------------------------------------------
/oarplayer/src/main/java/com/wodekouwei/srsrtmpplayer/proxy/SurfaceTextureWrapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | package com.wodekouwei.srsrtmpplayer.proxy;
24 |
25 | import android.graphics.SurfaceTexture;
26 | import android.util.Log;
27 | import android.view.Surface;
28 |
29 | public class SurfaceTextureWrapper {
30 | private final static String TAG = "SurfaceTextureWrapper";
31 | private final static boolean isDebug = false;
32 | private static SurfaceTexture texture;
33 | private static Surface surface;
34 | private static float[] matrix = new float[16];
35 |
36 | public static Surface getSurface(int name){
37 | if(isDebug) Log.i(TAG, "getSurface:" + name);
38 | texture = new SurfaceTexture(name);
39 | /*texture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
40 | @Override
41 | public void onFrameAvailable(SurfaceTexture surfaceTexture) {
42 | if(isDebug) Log.e(TAG, "onFrameAvailable....");
43 | }
44 | });*/
45 | surface = new Surface(texture);
46 | HwVideoDecodeWrapper.setOutputSurface(surface);
47 | return surface;
48 | }
49 |
50 | public static void updateTexImage(){
51 | texture.updateTexImage();
52 | }
53 |
54 | public static float[] getTransformMatrix(){
55 | texture.getTransformMatrix(matrix);
56 | return matrix;
57 | }
58 |
59 | public static void release(){
60 | texture.release();
61 | surface.release();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_native_mediacodec.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | //
24 | // Created by qingkouwei on 2018/1/4.
25 | //
26 |
27 | #ifndef OARPLAYER_OAR_NATIVE_VIDEO_MEDIACODEC_H
28 | #define OARPLAYER_OAR_NATIVE_VIDEO_MEDIACODEC_H
29 |
30 | #include
31 | #include
32 | #include
33 |
34 | int oar_native_mediacodec_send_packet(void * codec,
35 | int len,
36 | int type,
37 | int64_t dts,
38 | int64_t pts,
39 | int isKeyframe,
40 | uint8_t *data);
41 | void oar_native_mediacodec_release_buffer(void * codec, int bufferID, bool render);
42 | int oar_native_mediacodec_receive_frame(void * codec,
43 | void** frame,
44 | void *oar,
45 | int type,
46 | void *(frameGenerate)(void*,void**, void*, int, int64_t,ssize_t,int, int, int));
47 | void oar_native_mediacodec_flush(void * codec);
48 | void *oar_create_native_mediacodec(int codec_id,
49 | int width, int height,
50 | int sample_rate, int channelCount,
51 | uint8_t *sps, int sps_size,
52 | uint8_t *pps, int pps_size,
53 | void *ctx,
54 | void (*formatCreated(void*, void*)));
55 | int oar_native_mediacodec_start(void * codec, void *format, void *window);
56 | void oar_native_mediacodec_stop(void * codec);
57 | void oar_native_mediacodec_release_context(void * codec, void *format);
58 | #endif //OARPLAYER_OAR_NATIVE_VIDEO_MEDIACODEC_H
59 |
--------------------------------------------------------------------------------
/nativemediacodec/src/main/cpp/oar_native_mediacodec.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | //
24 | // Created by qingkouwei on 2018/1/4.
25 | //
26 |
27 | #ifndef OARPLAYER_OAR_NATIVE_VIDEO_MEDIACODEC_H
28 | #define OARPLAYER_OAR_NATIVE_VIDEO_MEDIACODEC_H
29 |
30 | #include
31 | #include
32 | #include
33 |
34 | int oar_native_mediacodec_send_packet(void * codec,
35 | int len,
36 | int type,
37 | int64_t dts,
38 | int64_t pts,
39 | int isKeyframe,
40 | uint8_t *data);
41 | void oar_native_mediacodec_release_buffer(void * codec, int bufferID, bool render);
42 | int oar_native_mediacodec_receive_frame(void * codec,
43 | void **frame,
44 | void * oar,
45 | int type,
46 | void *(frameGenerate)(void*,void **,void*, int,int64_t,ssize_t,int, int, int));
47 | void oar_native_mediacodec_flush(void * codec);
48 | void *oar_create_native_mediacodec(int codec_id,
49 | int width, int height,
50 | int sample_rate, int channelCount,
51 | uint8_t *sps, int sps_size,
52 | uint8_t *pps, int pps_size,
53 | void *ctx,
54 | void (*formatCreated(void*, void*)));
55 | int oar_native_mediacodec_start(void * codec, void *format, void *window);
56 | void oar_native_mediacodec_stop(void * codec);
57 | void oar_native_mediacodec_release_context(void * codec, void *format);
58 | #endif //OARPLAYER_OAR_NATIVE_VIDEO_MEDIACODEC_H
59 |
--------------------------------------------------------------------------------
/oarplayer/jni_lib_src/include/oar_native_mediacodec.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | //
24 | // Created by qingkouwei on 2018/1/4.
25 | //
26 |
27 | #ifndef OARPLAYER_OAR_NATIVE_VIDEO_MEDIACODEC_H
28 | #define OARPLAYER_OAR_NATIVE_VIDEO_MEDIACODEC_H
29 |
30 | #include
31 | #include
32 | #include
33 |
34 | int oar_native_mediacodec_send_packet(void * codec,
35 | int len,
36 | int type,
37 | int64_t dts,
38 | int64_t pts,
39 | int isKeyframe,
40 | uint8_t *data);
41 | void oar_native_mediacodec_release_buffer(void * codec, int bufferID, bool render);
42 | int oar_native_mediacodec_receive_frame(void * codec,
43 | void **frame,
44 | void * oar,
45 | int type,
46 | void *(frameGenerate)(void*,void **,void*, int,int64_t,ssize_t,int, int, int));
47 | void oar_native_mediacodec_flush(void * codec);
48 | void *oar_create_native_mediacodec(int codec_id,
49 | int width, int height,
50 | int sample_rate, int channelCount,
51 | uint8_t *sps, int sps_size,
52 | uint8_t *pps, int pps_size,
53 | void *ctx,
54 | void (*formatCreated(void*, void*)));
55 | int oar_native_mediacodec_start(void * codec, void *format, void *window);
56 | void oar_native_mediacodec_stop(void * codec);
57 | void oar_native_mediacodec_release_context(void * codec, void *format);
58 | #endif //OARPLAYER_OAR_NATIVE_VIDEO_MEDIACODEC_H
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/wodekouwei/demo/PlayerAty.java:
--------------------------------------------------------------------------------
1 | package com.wodekouwei.demo;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.os.Message;
7 | import android.support.annotation.Nullable;
8 | import android.view.SurfaceHolder;
9 | import android.view.SurfaceView;
10 | import android.view.Window;
11 | import android.view.WindowManager;
12 | import android.widget.TextView;
13 |
14 | import com.wodekouwei.srsrtmpplayer.OARPlayer;
15 |
16 | import java.io.IOException;
17 |
18 | /**
19 | * Created by shenjunwei on 2018/1/5.
20 | */
21 |
22 | public class PlayerAty extends Activity {
23 |
24 | private SurfaceView surfaceView;
25 | private TextView playTime;
26 | OARPlayer player;
27 | @Override
28 | protected void onCreate(@Nullable Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | requestWindowFeature(Window.FEATURE_NO_TITLE);
31 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
32 | WindowManager.LayoutParams.FLAG_FULLSCREEN);
33 |
34 | setContentView(R.layout.activity_player);
35 | player = new OARPlayer(this);
36 | surfaceView = (SurfaceView)findViewById(R.id.surfaceview);
37 | playTime = (TextView)findViewById(R.id.playTime);
38 | surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
39 | @Override
40 | public void surfaceCreated(SurfaceHolder surfaceHolder) {
41 | try {
42 | String rtmp_url = getIntent().getStringExtra("rtmp_url");
43 | player.setDataSource(rtmp_url);
44 | playTimeHandler.sendEmptyMessageDelayed(1, 1000);
45 | } catch (IOException e) {
46 | e.printStackTrace();
47 | }
48 | player.setSurface(surfaceView.getHolder());
49 | player.start();
50 | }
51 |
52 | @Override
53 | public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
54 |
55 | }
56 |
57 | @Override
58 | public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
59 |
60 | }
61 | });
62 | }
63 | private Handler playTimeHandler = new Handler(){
64 | @Override
65 | public void handleMessage(Message msg) {
66 | playTime.setText((int) player.getCurrentTime() + "");
67 | playTimeHandler.sendEmptyMessageDelayed(1, 1000);
68 | }
69 | };
70 |
71 | @Override
72 | protected void onResume() {
73 | player.onResume();
74 | super.onResume();
75 | }
76 |
77 | @Override
78 | protected void onPause() {
79 | player.onPause();
80 | super.onPause();
81 | }
82 |
83 | @Override
84 | protected void onStop() {
85 | player.stop();
86 | super.onStop();
87 | }
88 |
89 | @Override
90 | protected void onDestroy() {
91 | playTimeHandler.removeMessages(1);
92 | player.release();
93 | super.onDestroy();
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/oarplayer/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # For more information about using CMake with Android Studio, read the
2 | # documentation: https://d.android.com/studio/projects/add-native-code.html
3 |
4 | # Sets the minimum version of CMake required to build the native library.
5 |
6 | cmake_minimum_required(VERSION 3.4.1)
7 |
8 | set(lib_src_DIR ${CMAKE_SOURCE_DIR}/jni_lib_src/libs/${ANDROID_ABI})
9 |
10 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
11 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
12 |
13 |
14 | add_library(mediacodec SHARED IMPORTED)
15 | set_target_properties(mediacodec PROPERTIES IMPORTED_LOCATION ${lib_src_DIR}/libmediacodec-lib.so)
16 |
17 |
18 | # Creates and names a library, sets it as either STATIC
19 | # or SHARED, and provides the relative paths to its source code.
20 | # You can define multiple libraries, and CMake builds them for you.
21 | # Gradle automatically packages shared libraries with your APK.
22 | add_library( # Sets the name of the library.
23 | oarp-lib
24 |
25 | # Sets the library as a shared library.
26 | SHARED
27 |
28 | # Provides a relative path to your source file(s).
29 | src/main/cpp/oarplayer_jni.c
30 | src/main/cpp/jni_utils.c
31 | src/main/cpp/srs_readthread.c
32 | src/main/cpp/srs_librtmp.cpp
33 | src/main/cpp/oar_clock.c
34 | src/main/cpp/oar_packet_queue.c
35 | src/main/cpp/oar_frame_queue.c
36 | src/main/cpp/oar_player.c
37 | src/main/cpp/oar_jni_reflect.c
38 | src/main/cpp/oar_video_mediacodec_java.c
39 | src/main/cpp/oar_audio_mediacodec_java.c
40 | src/main/cpp/oar_player_video_hw_decode_thread.c
41 | src/main/cpp/oar_player_audio_hw_decode_thread.c
42 | src/main/cpp/oar_video_render.c
43 | src/main/cpp/oar_texture.c
44 | src/main/cpp/oar_glsl_program.c
45 | src/main/cpp/oar_player_gl_thread.c
46 | src/main/cpp/oar_audio_player.c
47 | src/main/cpp/util.c
48 | src/main/cpp/oar_audio_mediacodec_ndk.c
49 | src/main/cpp/oar_video_mediacodec_ndk.c
50 | src/main/cpp/oar_audio_mediacodec_ctx.c
51 | src/main/cpp/oar_video_mediacodec_ctx.c
52 | )
53 |
54 |
55 | find_library( # Sets the name of the path variable.
56 | log-lib
57 |
58 | # Specifies the name of the NDK library that
59 | # you want CMake to locate.
60 | log )
61 | find_library(android-lib
62 | android)
63 | find_library(glesv2-lib GLESv2)
64 | find_library(egl-lib EGL)
65 | find_library(sles-lib OpenSLES)
66 |
67 | target_link_libraries( # Specifies the target library.
68 | oarp-lib
69 |
70 | # Links the target library to the log library
71 | # included in the NDK.
72 | ${log-lib}
73 | ${android-lib}
74 | ${egl-lib}
75 | ${glesv2-lib}
76 | ${sles-lib}
77 | )
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_macro.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef __OAR_MACRO_H
24 | #define __OAR_MACRO_H
25 |
26 |
27 | #define NDK_MEDIACODEC_VERSION 21
28 |
29 |
30 | #define NSEC_PER_SEC 1000000000L
31 | #define NSEC_PER_MSEC 1000000L
32 | #define USEC_PER_SEC 1000000L
33 | #define NSEC_PER_USEC 1000L
34 | #define USEC_PRE_MSEC 1000L
35 | #define MSEC_PRE_SEC 1000L
36 |
37 | #define oar_metadata_video_width "width"
38 | #define oar_metadata_video_height "height"
39 | #define oar_metadata_video_rate "videodatarate"
40 | #define oar_metadata_video_framerate "framerate"
41 | #define oar_metadata_video_codecid "videocodecid"
42 | #define oar_metadata_audio_rate "audiodatarate"
43 | #define oar_metadata_audio_samplerate "audiosamplerate"
44 | #define oar_metadata_audio_samplesize "audiosamplesize"
45 | #define oar_metadata_audio_codecid "audiocodecid"
46 |
47 |
48 | #define oar_message_stop 1
49 | #define oar_message_buffer_empty 2
50 | #define oar_message_buffer_full 3
51 | #define oar_message_decoder_configuration 4
52 | #define oar_message_error 999
53 |
54 | #define default_buffer_size 1024*1024*5
55 | #define default_buffer_time 5.0f
56 | #define default_read_timeout 3.0f
57 |
58 | // 100 ms
59 | #define NULL_LOOP_SLEEP_US 100000
60 | // 10 ms
61 | #define BUFFER_EMPTY_SLEEP_US 10000
62 | // 30 fps
63 | #define WAIT_FRAME_SLEEP_US 33333
64 |
65 | //#define OAR_PIX_FMT_EGL_EXT 10000
66 |
67 | #define OAR_ROTATION_0 0
68 | #define OAR_ROTATION_90 1
69 | #define OAR_ROTATION_180 2
70 | #define OAR_ROTATION_270 3
71 |
72 |
73 | //////// rename avframe fields
74 | #define HW_BUFFER_ID pkt_pos
75 | // 0 : 0
76 | // 1 : 90
77 | // 2 : 180
78 | // 3 : 270
79 | #define FRAME_ROTATION sample_rate
80 |
81 |
82 |
83 |
84 | // error code
85 | #define OAR_ERROR_FORMAT_VIDEO_CODEC 2001
86 | #define OAR_ERROR_FORMAT_AUDIO_CODEC 2002
87 | #define OAR_ERROR_FORMAT_VIDEO_CONFIG 2003
88 | #define OAR_ERROR_FORMAT_AUDIO_CONFIG 2004
89 |
90 | #define OAR_ERROR_AUDIO_DECODE_SEND_PACKET 3001
91 | #define OAR_ERROR_AUDIO_DECODE_CODEC_NOT_OPENED 3002
92 | #define OAR_ERROR_AUDIO_DECODE_RECIVE_FRAME 3003
93 |
94 | #define OAR_ERROR_VIDEO_SW_DECODE_SEND_PACKET 4101
95 | #define OAR_ERROR_VIDEO_SW_DECODE_CODEC_NOT_OPENED 4102
96 | #define OAR_ERROR_VIDEO_SW_DECODE_RECIVE_FRAME 4103
97 |
98 | #define OAR_ERROR_VIDEO_HW_MEDIACODEC_RECEIVE_FRAME 501
99 |
100 | #endif //__OAR_MACRO_H
101 |
--------------------------------------------------------------------------------
/oarplayer/gradle-mvn-push.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Chris Banes
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | apply plugin: 'maven'
18 | apply plugin: 'signing'
19 |
20 | def isReleaseBuild() {
21 | return PROJ_VERSION.contains("SNAPSHOT") == false
22 | }
23 |
24 | def getReleaseRepositoryUrl() {
25 | return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL :
26 | "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
27 | }
28 |
29 | def getSnapshotRepositoryUrl() {
30 | return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL :
31 | "https://oss.sonatype.org/content/repositories/snapshots/"
32 | }
33 |
34 | def getRepositoryUsername() {
35 | return hasProperty('MAVEN_USERNAME') ? MAVEN_USERNAME : ""
36 | }
37 |
38 | def getRepositoryPassword() {
39 | return hasProperty('MAVEN_PASSWORD') ? MAVEN_PASSWORD : ""
40 | }
41 |
42 | afterEvaluate { project ->
43 | uploadArchives {
44 | repositories {
45 | mavenDeployer {
46 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
47 |
48 | pom.groupId = PROJ_GROUP
49 | pom.artifactId = PROJ_ARTIFACTID
50 | pom.version = PROJ_VERSION
51 |
52 | repository(url: getReleaseRepositoryUrl()) {
53 | authentication(userName: getRepositoryUsername(),
54 | password: getRepositoryPassword())
55 | }
56 | snapshotRepository(url: getSnapshotRepositoryUrl()) {
57 | authentication(userName: getRepositoryUsername(),
58 | password: getRepositoryPassword())
59 | }
60 |
61 | pom.project {
62 | name PROJ_POM_NAME
63 | packaging POM_PACKAGING
64 | description PROJ_DESCRIPTION
65 | url PROJ_WEBSITEURL
66 |
67 | scm {
68 | url PROJ_VCSURL
69 | connection DEVELOPER_EMAIL
70 | developerConnection DEVELOPER_EMAIL
71 | }
72 |
73 | licenses {
74 | license {
75 | name PROJ_LICENCE_NAME
76 | url PROJ_LICENCE_URL
77 | distribution PROJ_LICENCE_DEST
78 | }
79 | }
80 |
81 | developers {
82 | developer {
83 | id DEVELOPER_ID
84 | name DEVELOPER_NAME
85 | }
86 | }
87 | }
88 | }
89 | }
90 | }
91 |
92 | signing {
93 | required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
94 | sign configurations.archives
95 | }
96 |
97 | task androidJavadocs(type: Javadoc) {
98 | // source = android.sourceSets.main.java.srcDirs
99 | // classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
100 | }
101 |
102 | task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
103 | // classifier = 'javadoc'
104 | // from androidJavadocs.destinationDir
105 | }
106 |
107 | task androidSourcesJar(type: Jar) {
108 | classifier = 'sources'
109 | from android.sourceSets.main.java.sourceFiles
110 | }
111 |
112 | artifacts {
113 | archives androidSourcesJar
114 | archives androidJavadocsJar
115 | }
116 | }
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_player_audio_hw_decode_thread.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #define _JNILOG_TAG "audio_decode_thread"
24 | #include "_android.h"
25 | #include
26 | #include
27 | #include
28 | #include "oar_player_audio_hw_decode_thread.h"
29 | #include "oar_packet_queue.h"
30 | #include "oar_frame_queue.h"
31 | #include "oar_audio_mediacodec_java.h"
32 |
33 | #define isDebug 0
34 | #define _LOGD if(isDebug) LOGI
35 |
36 | void * audio_decode_thread(void * data){
37 | prctl(PR_SET_NAME, __func__);
38 | oarplayer * oar = (oarplayer *)data;
39 | (*(oar->vm))->AttachCurrentThread(oar->vm, &oar->audio_mediacodec_ctx->jniEnv, NULL);
40 | oar->audio_mediacodec_ctx->oar_audio_mediacodec_start(oar);
41 | int ret;
42 | OARPacket * packet = NULL;
43 | OARFrame *frame;
44 | while (oar->error_code == 0) {
45 | if(oar->status == PAUSED){
46 | usleep(NULL_LOOP_SLEEP_US);
47 | }
48 | if(oar->error_code != 0){
49 | break;
50 | }
51 |
52 | ret = oar->audio_mediacodec_ctx->oar_audio_mediacodec_receive_frame(oar, &frame);
53 | _LOGD("audio ret:%d",ret);
54 | if (ret == 0) {
55 | oar_frame_queue_put(oar->audio_frame_queue, frame);
56 | // 触发音频播放
57 | if (oar->metadata->has_audio){
58 | oar->audio_player_ctx->play(oar);
59 | }
60 | } else if (ret == 1) {
61 | // _LOGD("start read audio...");
62 | packet = oar_packet_queue_get(oar->audio_packet_queue);
63 | // buffer empty ==> wait 10ms
64 | // eof ==> break
65 | if(packet == NULL){
66 | // _LOGD("audio deocdec sleep...");
67 | usleep(BUFFER_EMPTY_SLEEP_US);
68 | continue;
69 | }
70 | ret = oar->audio_mediacodec_ctx->oar_audio_mediacodec_send_packet(oar, packet);
71 | if(ret == 0){
72 | freePacket(packet);
73 | packet = NULL;
74 | }else{
75 | if(oar->status == PAUSED){
76 | usleep(NULL_LOOP_SLEEP_US);
77 | }
78 | }
79 | } else if (ret == -2) {
80 | // oar->on_error(oar, OAR_ERROR_AUDIO_DECODE_CODEC_NOT_OPENED);
81 | // break;
82 | } else {
83 | oar->on_error(oar, OAR_ERROR_AUDIO_DECODE_RECIVE_FRAME);
84 | break;
85 | }
86 | }
87 | packet = oar_packet_queue_get(oar->audio_packet_queue);
88 | if(packet != NULL){
89 | freePacket(packet);
90 | packet = NULL;//Avoid srs read thread waiting cannot stopped.
91 | }
92 | oar->audio_mediacodec_ctx->oar_audio_mediacodec_stop(oar);
93 | LOGI("thread ==> %s exit", __func__);
94 | (*oar->vm)->DetachCurrentThread(oar->vm);
95 | return NULL;
96 | }
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_texture.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #include "oar_texture.h"
24 |
25 | void initTexture(oarplayer * oar) {
26 | oar_video_render_context * ctx = oar->video_render_ctx;
27 | glGenTextures(1, &ctx->texture[3]);
28 | glBindTexture(GL_TEXTURE_EXTERNAL_OES, ctx->texture[3]);
29 | glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
30 | glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
31 | glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
32 | glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
33 | }
34 |
35 | void oar_texture_delete(oarplayer * oar){
36 | oar_video_render_context * ctx = oar->video_render_ctx;
37 | glDeleteTextures(1, &ctx->texture[3]);
38 | }
39 |
40 | void update_texture_yuv420p(oar_model *model, OARFrame *frame){
41 | /*glBindTexture(GL_TEXTURE_2D, model->texture[0]);
42 | glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, frame->linesize[0], frame->height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, frame->data[0]);
43 | glBindTexture(GL_TEXTURE_2D, model->texture[1]);
44 | glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, frame->linesize[1], frame->height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, frame->data[1]);
45 | glBindTexture(GL_TEXTURE_2D, model->texture[2]);
46 | glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, frame->linesize[2], frame->height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, frame->data[2]);*/
47 | }
48 |
49 | void bind_texture_yuv420p(oar_model *model){
50 | glActiveTexture(GL_TEXTURE0);
51 | glBindTexture(GL_TEXTURE_2D, model->texture[0]);
52 | glUniform1i(model->program->tex_y, 0);
53 | glActiveTexture(GL_TEXTURE1);
54 | glBindTexture(GL_TEXTURE_2D, model->texture[1]);
55 | glUniform1i(model->program->tex_u, 1);
56 | glActiveTexture(GL_TEXTURE2);
57 | glBindTexture(GL_TEXTURE_2D, model->texture[2]);
58 | glUniform1i(model->program->tex_v, 2);
59 | }
60 |
61 | void update_texture_nv12(oar_model *model, OARFrame *frame){
62 | /*glBindTexture(GL_TEXTURE_2D, model->texture[0]);
63 | glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, frame->linesize[0], frame->height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, frame->data[0]);
64 | glBindTexture(GL_TEXTURE_2D, model->texture[1]);
65 | glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, frame->linesize[1] / 2, frame->height / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, frame->data[1]);*/
66 | }
67 |
68 | void bind_texture_nv12(oar_model *model){
69 | glActiveTexture(GL_TEXTURE0);
70 | glBindTexture(GL_TEXTURE_2D, model->texture[0]);
71 | glUniform1i(model->program->tex_y, 0);
72 | glActiveTexture(GL_TEXTURE1);
73 | glBindTexture(GL_TEXTURE_2D, model->texture[1]);
74 | glUniform1i(model->program->tex_u, 1);
75 | }
76 |
77 | void bind_texture_oes(oar_model *model){
78 | glActiveTexture(GL_TEXTURE0);
79 | glBindTexture(GL_TEXTURE_EXTERNAL_OES, model->texture[3]);
80 | glUniform1i(model->program->tex_y, 0);
81 | glUniformMatrix4fv(model->program->texture_matrix_location, 1, GL_FALSE, model->texture_matrix);
82 | }
83 |
84 | void update_texture_oes(__attribute__((unused)) oar_model *model, __attribute__((unused)) OARFrame *frame){
85 |
86 | }
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_frame_queue.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #define _JNILOG_TAG "oar_frame_queue"
24 | #include "_android.h"
25 | #include
26 | #include
27 | #include
28 | #include "oar_frame_queue.h"
29 |
30 | #define isDebug 0
31 | #define _LOGD if(isDebug) LOGI
32 |
33 | /*static OARFrame *newFrame(const uint8_t *data, int size, PktType_e type)
34 | {
35 | OARFrame *frame = (OARFrame *)calloc(1, sizeof(OARFrame) + size);
36 | if (!frame) {
37 | LOGE("failed in malloc OARPacket");
38 | return NULL;
39 | }
40 | if (data) {
41 | memcpy(frame->data, data, size);
42 | frame->size = size;
43 | }
44 | else {
45 | frame->size = 0;
46 | }
47 |
48 | frame->type = type;
49 | return frame;
50 | }
51 |
52 | void freeFrame(OARFrame *frame)
53 | {
54 | //LOGI("freeFrame ");
55 | if (frame) {
56 | free(frame);
57 | //pktCreatedCount --;
58 | //LOGI("free, pktCreatedCount: %d", pktCreatedCount);
59 | }
60 | }*/
61 | oar_frame_queue * oar_frame_queue_create(unsigned int size){
62 | oar_frame_queue * queue = (oar_frame_queue *)malloc(sizeof(oar_frame_queue));
63 | queue->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
64 | queue->cond = (pthread_cond_t *)malloc(sizeof(pthread_cond_t));
65 | pthread_mutex_init(queue->mutex, NULL);
66 | pthread_cond_init(queue->cond, NULL);
67 | queue->count = 0;
68 | queue->cachedFrames = NULL;
69 | queue->lastFrame = NULL;
70 | queue->size = size;
71 | return queue;
72 | }
73 | void oar_frame_queue_free(oar_frame_queue *queue){
74 | pthread_mutex_destroy(queue->mutex);
75 | pthread_cond_destroy(queue->cond);
76 | OARFrame *tempFrame,*frame = queue->cachedFrames;
77 | while(frame){
78 | tempFrame = frame;
79 | frame = frame->next;
80 | free(tempFrame);
81 | }
82 | queue->cachedFrames = NULL;
83 | queue->lastFrame = NULL;
84 | free(queue);
85 | }
86 |
87 | int oar_frame_queue_put(oar_frame_queue *queue, OARFrame *f){
88 | //_LOGD("start oar_frame_queue_put:%d", queue->count);
89 | pthread_mutex_lock(queue->mutex);
90 | while(queue->count == queue->size){
91 | if(f->type == PktType_Audio){
92 | _LOGD("frame queue wait...");
93 | }
94 |
95 | pthread_cond_wait(queue->cond, queue->mutex);
96 | }
97 | if (queue->lastFrame) {
98 | queue->lastFrame->next = f;
99 | queue->lastFrame = f;
100 | }
101 | else {
102 | queue->lastFrame = queue->cachedFrames = f;
103 | }
104 | queue->count++;
105 | //_LOGD("oar_frame_queue_put:%d", queue->count);
106 | pthread_mutex_unlock(queue->mutex);
107 | return 0;
108 | }
109 |
110 | OARFrame * oar_frame_queue_get(oar_frame_queue *queue){
111 | //_LOGD("start oar_frame_queue_get:%d", queue->count);
112 | pthread_mutex_lock(queue->mutex);
113 | if (queue->count == 0) {
114 | pthread_mutex_unlock(queue->mutex);
115 | return NULL;
116 | }
117 | OARFrame *ret = NULL;
118 | if (queue->cachedFrames) {
119 | ret = queue->cachedFrames;
120 | if (queue->cachedFrames == queue->lastFrame) {
121 | queue->lastFrame = NULL;
122 | }
123 | queue->cachedFrames = queue->cachedFrames->next;
124 | if (queue->count > 0) {
125 | queue->count--;
126 | }
127 | }
128 | else {
129 | pthread_mutex_unlock(queue->mutex);
130 | return NULL;
131 | }
132 | pthread_cond_signal(queue->cond);
133 | pthread_mutex_unlock(queue->mutex);
134 | // _LOGD("pts=%lld", ret->pts);
135 | return ret;
136 | }
137 |
138 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_player_video_hw_decode_thread.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #define _JNILOG_TAG "video_decode_thread"
24 | #include "_android.h"
25 |
26 | #include
27 | #include
28 | #include
29 | #include "oar_player_video_hw_decode_thread.h"
30 | #include "oar_video_mediacodec_java.h"
31 | #include "oar_packet_queue.h"
32 | #include "oar_frame_queue.h"
33 |
34 | #define _LOGD if(isDebug) LOGD
35 |
36 | static inline int drop_video_packet(oarplayer * oar){
37 | OARPacket * packet = oar_packet_queue_get(oar->video_packet_queue);
38 | if(packet != NULL){
39 | int64_t time_stamp = packet->pts;
40 | int64_t diff = time_stamp - oar->audio_clock->pts;
41 | if(diff > 0){
42 | usleep((useconds_t) diff);
43 | }
44 | freePacket(packet);
45 | oar->video_mediacodec_ctx->oar_video_mediacodec_flush(oar);
46 |
47 | }else{
48 | usleep(NULL_LOOP_SLEEP_US);
49 | }
50 | return 0;
51 | }
52 |
53 | void* video_decode_hw_thread(void * data){
54 | prctl(PR_SET_NAME, __func__);
55 | oarplayer * oar = (oarplayer *)data;
56 | _LOGD("vm = %p, thread id = %d ,api = %d", oar->vm,gettid(),__ANDROID_API__);
57 | (*(oar->vm))->AttachCurrentThread(oar->vm, &oar->video_mediacodec_ctx->jniEnv, NULL);
58 | oar->video_mediacodec_ctx->oar_video_mediacodec_start(oar);
59 | int ret;
60 | OARPacket * packet = NULL;
61 | OARFrame * frame = (OARFrame*)malloc(sizeof(OARFrame));
62 | while (oar->error_code == 0) {
63 | if(oar->just_audio){
64 | // 如果只播放音频 按照音视频同步的速度丢包
65 | drop_video_packet(oar);
66 | }else{
67 | ret = oar->video_mediacodec_ctx->oar_video_mediacodec_receive_frame(oar, frame);
68 | _LOGD("video ret:%d", ret);
69 | if (ret == 0) {
70 | frame->FRAME_ROTATION = oar->frame_rotation;
71 | oar_frame_queue_put(oar->video_frame_queue, frame);
72 | frame = malloc(sizeof(OARFrame));
73 | }else if(ret == 1) {
74 | if(packet == NULL){
75 | _LOGD("start get video packet...");
76 | packet = oar_packet_queue_get(oar->video_packet_queue);
77 | _LOGD("end get video packet...");
78 | }
79 | // buffer empty ==> wait 10ms
80 | // eof ==> break
81 | if(packet == NULL){
82 | _LOGD("video packet is null...");
83 | usleep(BUFFER_EMPTY_SLEEP_US);
84 | continue;
85 | }
86 | if(0 == oar->video_mediacodec_ctx->oar_video_mediacodec_send_packet(oar, packet)){
87 | freePacket(packet);
88 | packet = NULL;
89 | }else{
90 | // some device AMediacodec input buffer ids count < frame_queue->size
91 | // when pause frame_queue not full
92 | // thread will not block in "xl_frame_queue_put" function
93 | if(oar->status == PAUSED){
94 | usleep(NULL_LOOP_SLEEP_US);
95 | }
96 | }
97 |
98 | }else if(ret == -2) {
99 | //frame = xl_frame_pool_get_frame(pd->video_frame_pool);
100 | }else {
101 | oar->on_error(oar, OAR_ERROR_VIDEO_HW_MEDIACODEC_RECEIVE_FRAME);
102 | break;
103 | }
104 | }
105 | }
106 | drop_video_packet(oar);//Avoid srs read thread waiting cannot stopped.
107 | oar->video_mediacodec_ctx->oar_video_mediacodec_stop(oar);
108 | (*oar->vm)->DetachCurrentThread(oar->vm);
109 | LOGI("thread ==> %s exit", __func__);
110 | return NULL;
111 | }
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_audio_mediacodec_ndk.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | //
24 | // Created by qingkouwei on 2018/1/4.
25 | //
26 | #define _JNILOG_TAG "oar_audio_mediacodec_ndk"
27 | #include "_android.h"
28 | #include
29 | #include
30 | #include "oar_audio_mediacodec_ndk.h"
31 | #define isDebug 0
32 | #define _LOGD if(isDebug) LOGI
33 | static void formatCreate(void *ctx, void *format){
34 | oar_audio_mediacodec_context *context = (oar_audio_mediacodec_context*)ctx;
35 | context->AFormat = format;
36 | }
37 |
38 | void oar_create_audio_mediacodec_ndk(
39 | oarplayer *oar){
40 | oar->audio_mediacodec_ctx->ACodec = oar->dl_context->create_native_mediacodec(oar->metadata->audio_codec,
41 | 0, 0,
42 | oar->metadata->sample_rate,
43 | oar->metadata->channels,
44 | oar->metadata->audio_pps, oar->metadata->audio_pps_size,
45 | NULL, 0,
46 | oar->audio_mediacodec_ctx,
47 | formatCreate);
48 | }
49 |
50 | void oar_audio_mediacodec_release_buffer_ndk(oarplayer *oar, int index){
51 | oar->dl_context->native_mediacodec_release_buffer(oar->audio_mediacodec_ctx->ACodec, index, false);
52 | }
53 | static void frameGenerate(void* player, void **frame, void *data, int size, int64_t pts,ssize_t index,int arg1, int arg2, int pix_format){
54 | oarplayer *oar = (oarplayer*)player;
55 | if (index >= 0) {
56 | OARFrame *f = (OARFrame *)malloc(sizeof(OARFrame) + size);
57 | if (data != NULL){
58 | memcpy(f->data, data, size);
59 | }
60 | f->type = PktType_Audio;
61 | f->size = size;
62 | f->pts = pts;
63 | f->HW_BUFFER_ID = index;
64 | f->next=NULL;
65 | *frame = f;
66 | }else{
67 | switch (index) {
68 | // AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED
69 | case -2: {
70 | oar->audio_mediacodec_ctx->sample_rate = arg1;
71 | oar->audio_mediacodec_ctx->channel_count = arg2;
72 | break;
73 | }
74 | // AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED
75 | case -3:
76 | break;
77 | // AMEDIACODEC_INFO_TRY_AGAIN_LATER
78 | case -1:
79 | break;
80 | default:
81 | break;
82 | }
83 | }
84 | }
85 | int oar_audio_mediacodec_receive_frame_ndk(oarplayer *oar, OARFrame **frame){
86 | return oar->dl_context->native_mediacodec_receive_frame(oar->audio_mediacodec_ctx->ACodec,
87 | frame, oar, 1, frameGenerate);
88 | }
89 | int oar_audio_mediacodec_send_packet_ndk(oarplayer *oar, OARPacket *packet){
90 | if (packet == NULL) { return -2; }
91 | return oar->dl_context->native_mediacodec_send_packet(oar->audio_mediacodec_ctx->ACodec,
92 | packet->size,
93 | packet->type,
94 | packet->pts,
95 | packet->pts,
96 | packet->isKeyframe,
97 | packet->data);
98 | }
99 | void oar_audio_mediacodec_flush_ndk(oarplayer *oar){
100 | oar->dl_context->native_mediacodec_flush(oar->audio_mediacodec_ctx->ACodec);
101 | }
102 | void oar_audio_mediacodec_release_context_ndk(oarplayer *oar){
103 | oar->dl_context->native_mediacodec_release_context(oar->audio_mediacodec_ctx->ACodec,oar->audio_mediacodec_ctx->AFormat);
104 | }
105 | void oar_audio_mediacodec_start_ndk(oarplayer *oar){
106 | oar->dl_context->native_mediacodec_start(oar->audio_mediacodec_ctx->ACodec, oar->audio_mediacodec_ctx->AFormat, NULL);
107 | }
108 | void oar_audio_mediacodec_stop_ndk(oarplayer *oar){
109 | oar->dl_context->native_mediacodec_stop(oar->audio_mediacodec_ctx->ACodec);
110 | }
111 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/oarplayer/src/main/java/com/wodekouwei/srsrtmpplayer/proxy/HwAudioDecodeWrapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | package com.wodekouwei.srsrtmpplayer.proxy;
24 |
25 | import android.media.MediaCodec;
26 | import android.media.MediaFormat;
27 | import android.util.Log;
28 |
29 | import java.io.IOException;
30 | import java.nio.ByteBuffer;
31 | import java.nio.ByteOrder;
32 |
33 | /**
34 | * Created by qingkouwei on 2017/12/28.
35 | */
36 |
37 | public class HwAudioDecodeWrapper {
38 | private final static String TAG = "HwAudioDecodeWrapper";
39 | private final static boolean isDebug = false;
40 | private static MediaCodec codec = null;
41 | private static MediaFormat format = null;
42 | public static void init(String codecName,
43 | int sample_rate,
44 | int channelCount,
45 | ByteBuffer csd0){
46 | if(isDebug) Log.i(TAG, "init audio decodec: codecName = " + codecName);
47 | try {
48 | codec = MediaCodec.createDecoderByType(codecName);
49 | format = new MediaFormat();
50 | format.setString(MediaFormat.KEY_MIME, codecName);
51 | format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, channelCount);
52 | format.setInteger(MediaFormat.KEY_SAMPLE_RATE, sample_rate);
53 | // format.setInteger(MediaFormat.KEY_IS_ADTS,1);
54 | format.setByteBuffer("csd-0", csd0);
55 | codec.configure(format, null, null, 0);
56 | codec.start();
57 | if(isDebug) Log.i(TAG, "init audio decodec success...");
58 | } catch (IOException e) {
59 | e.printStackTrace();
60 | if(isDebug) Log.e(TAG, "init audio decodec exception:" + e.getMessage());
61 | }
62 | }
63 |
64 | public static void stop(){
65 | codec.stop();
66 | }
67 |
68 | public static void flush(){
69 | codec.flush();
70 | }
71 |
72 | public static int dequeueInputBuffer(long timeout){
73 | return codec.dequeueInputBuffer(timeout);
74 | }
75 |
76 | public static ByteBuffer getInputBuffer(int id){
77 | // return codec.getInputBuffer(id);
78 | return codec.getInputBuffers()[id];
79 | }
80 | public static void queueInputBuffer(int id, int size, long pts, int flags){
81 | codec.queueInputBuffer(id, 0, size, pts, flags);
82 | }
83 |
84 | private static ByteBuffer bf = ByteBuffer.allocateDirect(20);
85 | private static ByteBuffer bf2 = ByteBuffer.allocateDirect(8);
86 | static{
87 | bf.order(ByteOrder.BIG_ENDIAN);
88 | bf2.order(ByteOrder.BIG_ENDIAN);
89 | }
90 | private static MediaCodec.BufferInfo output_buffer_info = new MediaCodec.BufferInfo();
91 | public static ByteBuffer dequeueOutputBufferIndex(long timeout){
92 | try {
93 | int id = codec.dequeueOutputBuffer(output_buffer_info, timeout);
94 | bf.position(0);
95 | bf.putInt(id);
96 | if (id >= 0) {
97 | bf.putInt(output_buffer_info.offset);
98 | bf.putLong(output_buffer_info.presentationTimeUs);
99 | bf.putInt(output_buffer_info.size);
100 | }
101 | }catch (Exception e){
102 | Log.e(TAG, "exception:" + e.getMessage());
103 | }
104 | return bf;
105 | }
106 |
107 | public static void releaseOutPutBuffer(int id){
108 | // if(isDebug) Log.i(TAG, "outputBuffer id: " + id);
109 | try{
110 | codec.releaseOutputBuffer(id, false);
111 | }catch (Exception e){
112 | if(isDebug) Log.e(TAG,"catch exception when releaseOutPutBuffer id==>" + id);
113 | e.printStackTrace();
114 | }
115 |
116 | }
117 |
118 | public static ByteBuffer formatChange(){
119 | MediaFormat newFormat = codec.getOutputFormat();
120 | // if(isDebug) Log.i(TAG, "format change:" + newFormat);
121 | int sample_rate = newFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
122 | int channel_count = newFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
123 | if(isDebug) Log.i(TAG, "newFormat:" + newFormat);
124 | bf2.position(0);
125 | bf2.putInt(sample_rate);
126 | bf2.putInt(channel_count);
127 | return bf2;
128 | }
129 |
130 | public static ByteBuffer getOutputBuffer(int id){
131 | return codec.getOutputBuffers()[id];
132 | }
133 |
134 | public static void release(){
135 | codec = null;
136 | format = null;
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/jni_utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #ifndef __JNI_UTILS_H__
24 | #define __JNI_UTILS_H__
25 | #ifdef __cplusplus
26 | extern "C" {
27 | #endif
28 |
29 | #include
30 | #include
31 |
32 | int getIntFieldValue(JNIEnv* env, jobject obj, const char *fieldName, int def);
33 | jlong getLongFieldValue(JNIEnv* env, jobject obj, const char *fieldName, jlong def);
34 |
35 | jboolean getBooleanFieldValue(JNIEnv* env, jobject obj, const char *fieldName, jlong def);
36 |
37 | int setLongFieldValue(JNIEnv* env, jobject obj,
38 | const char *fieldName, jlong value);
39 |
40 | char *getStringFieldValue(JNIEnv* env, jobject obj, const char *fieldName);
41 |
42 | jstring str2JString(JNIEnv* env, const char* str);
43 |
44 | jclass getClassRef(JNIEnv* env, const char *clsName);
45 |
46 | int getStaticIntFieldValue(JNIEnv* env, const char *clsName, const char *fieldName, int def);
47 |
48 | char *getStaticStringFieldValue(JNIEnv* env, const char *clsName, const char *fieldName);
49 |
50 | jobject getStaticObjectFieldValue(JNIEnv* env, const char *clsName,
51 | const char *fieldName,
52 | const char *fieldSigName);
53 |
54 | JNIEnv* getJNIEnv();
55 | void detachCurrentThread();
56 |
57 | int ExceptionCheck__throwAny(JNIEnv *env);
58 | int ExceptionCheck__catchAll(JNIEnv *env);
59 | int ThrowExceptionOfClass(JNIEnv* env, jclass clazz, const char* msg);
60 | int ThrowException(JNIEnv* env, const char* class_sign, const char* msg);
61 | int ThrowIllegalStateException(JNIEnv *env, const char* msg);
62 | jclass NewGlobalRef__catchAll(JNIEnv *env, jobject obj);
63 | void DeleteLocalRef(JNIEnv *env, jobject obj);
64 | void DeleteLocalRef__p(JNIEnv *env, jobject *obj);
65 | void DeleteGlobalRef(JNIEnv *env, jobject obj);
66 |
67 | void DeleteGlobalRef__p(JNIEnv *env, jobject *obj);
68 | void ReleaseStringUTFChars(JNIEnv *env, jstring str, const char *c_str);
69 | void ReleaseStringUTFChars__p(JNIEnv *env, jstring str, const char **c_str);
70 | jclass FindClass__catchAll(JNIEnv *env, const char *class_sign);
71 | jclass FindClass__asGlobalRef__catchAll(JNIEnv *env, const char *class_sign);
72 | jmethodID GetMethodID__catchAll(JNIEnv *env, jclass clazz, const char *method_name, const char *method_sign);
73 | jmethodID GetStaticMethodID__catchAll(JNIEnv *env, jclass clazz, const char *method_name, const char *method_sign);
74 | jfieldID GetFieldID__catchAll(JNIEnv *env, jclass clazz, const char *field_name, const char *field_sign);
75 |
76 | jfieldID GetStaticFieldID__catchAll(JNIEnv *env, jclass clazz, const char *field_name, const char *field_sign);
77 |
78 | jbyteArray NewByteArray__catchAll(JNIEnv *env, jsize capacity);
79 |
80 | jbyteArray NewByteArray__asGlobalRef__catchAll(JNIEnv *env, jsize capacity);
81 |
82 | int JNI_ThrowException(JNIEnv *env, const char *exception, const char* msg);
83 | int JNI_ThrowIllegalStateException(JNIEnv *env, const char* msg);
84 | bool JNI_ExceptionCheck__catchAll(JNIEnv *env);
85 | int JNI_ThrowExceptionOfClass(JNIEnv* env, jclass clazz, const char* msg);
86 |
87 | #define OAR_FIND_JAVA_CLASS(env__, var__, classsign__) \
88 | do { \
89 | jclass clazz = (*env__)->FindClass(env__, classsign__); \
90 | if (JNI_ExceptionCheck__catchAll(env) || !(clazz)) { \
91 | LOGE("FindClass failed: %s", classsign__); \
92 | return -1; \
93 | } \
94 | var__ = (*env__)->NewGlobalRef(env__, clazz); \
95 | if (JNI_ExceptionCheck__catchAll(env) || !(var__)) { \
96 | LOGE("FindClass::NewGlobalRef failed: %s", classsign__); \
97 | (*env__)->DeleteLocalRef(env__, clazz); \
98 | return -1; \
99 | } \
100 | (*env__)->DeleteLocalRef(env__, clazz); \
101 | } while(0);
102 |
103 | #define JNI_CHECK_GOTO(condition__, env__, exception__, msg__, label__) \
104 | do { \
105 | if (!(condition__)) { \
106 | if (exception__) { \
107 | JNI_ThrowException(env__, exception__, msg__); \
108 | } \
109 | goto label__; \
110 | } \
111 | }while(0)
112 |
113 | #define JNI_CHECK_RET_VOID(condition__, env__, exception__, msg__) \
114 | do { \
115 | if (!(condition__)) { \
116 | if (exception__) { \
117 | JNI_ThrowException(env__, exception__, msg__); \
118 | } \
119 | return; \
120 | } \
121 | }while(0)
122 |
123 | #define JNI_CHECK_RET(condition__, env__, exception__, msg__, ret__) \
124 | do { \
125 | if (!(condition__)) { \
126 | if (exception__) { \
127 | JNI_ThrowException(env__, exception__, msg__); \
128 | } \
129 | return ret__; \
130 | } \
131 | }while(0)
132 |
133 | #ifdef __cplusplus
134 | }
135 | #endif
136 |
137 | #endif
138 |
--------------------------------------------------------------------------------
/oarplayer/src/main/java/com/wodekouwei/srsrtmpplayer/proxy/HwVideoDecodeWrapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | package com.wodekouwei.srsrtmpplayer.proxy;
24 |
25 | import android.media.MediaCodec;
26 | import android.media.MediaFormat;
27 | import android.util.Log;
28 | import android.view.Surface;
29 |
30 | import java.io.IOException;
31 | import java.nio.ByteBuffer;
32 | import java.nio.ByteOrder;
33 |
34 | public class HwVideoDecodeWrapper {
35 | private final static String TAG = "HwVideoDecodeWrapper";
36 | private final static boolean isDebug = false;
37 | private static MediaCodec codec = null;
38 | private static MediaFormat format = null;
39 | private static Surface outputSurface = null;
40 | public static void init(String codecName, int width, int height, ByteBuffer csd0, ByteBuffer csd1){
41 | if(isDebug) Log.i(TAG, "init: codecName = " + codecName + ";width = " + width + ";height = " + height);
42 | try {
43 | codec = MediaCodec.createDecoderByType(codecName);
44 | format = new MediaFormat();
45 | format.setString(MediaFormat.KEY_MIME, codecName);
46 | format.setInteger(MediaFormat.KEY_WIDTH, width);
47 | format.setInteger(MediaFormat.KEY_HEIGHT, height);
48 | switch (codecName){
49 | case "video/avc":
50 | if(csd0 != null && csd1 != null){
51 | format.setByteBuffer("csd-0", csd0);
52 | format.setByteBuffer("csd-1", csd1);
53 | }
54 | break;
55 | case "video/hevc":
56 | if(csd0 != null){
57 | format.setByteBuffer("csd-0", csd0);
58 | }
59 | break;
60 | case "video/mp4v-es":
61 | format.setByteBuffer("csd-0", csd0);
62 | break;
63 | case "video/3gpp":
64 | format.setByteBuffer("csd-0", csd0);
65 | break;
66 | default:
67 | break;
68 | }
69 | codec.configure(format, outputSurface, null, 0);
70 | codec.start();
71 | if(isDebug) Log.i(TAG, "init decodec success...");
72 | } catch (IOException e) {
73 | e.printStackTrace();
74 | if(isDebug) Log.e(TAG, "init decodec exception:" + e.getMessage());
75 | }
76 | }
77 |
78 | public static void stop(){
79 | codec.stop();
80 | }
81 |
82 | public static void flush(){
83 | codec.flush();
84 | }
85 |
86 | public static int dequeueInputBuffer(long timeout){
87 | return codec.dequeueInputBuffer(timeout);
88 | }
89 |
90 | public static ByteBuffer getInputBuffer(int id){
91 | // return codec.getInputBuffer(id);
92 | return codec.getInputBuffers()[id];
93 | }
94 | public static void queueInputBuffer(int id, int size, long pts, int flags){
95 | codec.queueInputBuffer(id, 0, size, pts, flags);
96 | }
97 |
98 | private static ByteBuffer bf = ByteBuffer.allocateDirect(16);
99 | private static ByteBuffer bf2 = ByteBuffer.allocateDirect(12);
100 | static{
101 | bf.order(ByteOrder.BIG_ENDIAN);
102 | bf2.order(ByteOrder.BIG_ENDIAN);
103 | }
104 | private static MediaCodec.BufferInfo output_buffer_info = new MediaCodec.BufferInfo();
105 | public static ByteBuffer dequeueOutputBufferIndex(long timeout){
106 | int id = codec.dequeueOutputBuffer(output_buffer_info, timeout);
107 | bf.position(0);
108 | bf.putInt(id);
109 | if(id >= 0){
110 | bf.putInt(output_buffer_info.offset);
111 | bf.putLong(output_buffer_info.presentationTimeUs);
112 | }
113 | return bf;
114 | }
115 |
116 | public static void releaseOutPutBuffer(int id){
117 | try{
118 | codec.releaseOutputBuffer(id, true);
119 | }catch (Exception e){
120 | if(isDebug) Log.e(TAG, "catch exception when releaseOutPutBuffer id==>" + id);
121 | e.printStackTrace();
122 | }
123 |
124 | }
125 |
126 | public static ByteBuffer formatChange(){
127 | MediaFormat newFormat = codec.getOutputFormat();
128 | int width = newFormat.getInteger(MediaFormat.KEY_WIDTH);
129 | int height = newFormat.getInteger(MediaFormat.KEY_HEIGHT);
130 | int color_format = newFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);
131 | bf2.position(0);
132 | bf2.putInt(width);
133 | bf2.putInt(height);
134 | bf2.putInt(color_format);
135 | return bf2;
136 | }
137 |
138 | public static ByteBuffer getOutputBuffer(int id){
139 | // ByteBuffer ret = codec.getOutputBuffer(id);
140 | return codec.getOutputBuffers()[id];
141 | }
142 |
143 | public static void release(){
144 | codec = null;
145 | format = null;
146 | }
147 |
148 | public static void setOutputSurface(Surface sur){
149 | outputSurface = sur;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_jni_reflect.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #include
25 | #include "oar_jni_reflect.h"
26 |
27 | void oar_jni_reflect_java_class(oar_java_class ** p_jc, JNIEnv *jniEnv) {
28 | oar_java_class * jc = malloc(sizeof(oar_java_class));
29 | jclass xlPlayerClass = (*jniEnv)->FindClass(jniEnv, "com/wodekouwei/srsrtmpplayer/OARPlayer");
30 | jc->player_onPlayStatusChanged = (*jniEnv)->GetMethodID(jniEnv, xlPlayerClass,
31 | "onPlayStatusChanged", "(I)V");
32 | jc->player_onPlayError = (*jniEnv)->GetMethodID(jniEnv, xlPlayerClass,
33 | "onPlayError", "(I)V");
34 | // jc->XLPlayer_class = (*jniEnv)->NewGlobalRef(jniEnv, xlPlayerClass);
35 | (*jniEnv)->DeleteLocalRef(jniEnv, xlPlayerClass);
36 |
37 | jclass java_HwDecodeBridge = (*jniEnv)->FindClass(jniEnv, "com/wodekouwei/srsrtmpplayer/proxy/HwVideoDecodeWrapper");
38 | jc->codec_init = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwDecodeBridge, "init", "(Ljava/lang/String;IILjava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)V");
39 | jc->codec_stop = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwDecodeBridge, "stop", "()V");
40 | jc->codec_flush = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwDecodeBridge, "flush", "()V");
41 | jc->codec_dequeueInputBuffer = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwDecodeBridge, "dequeueInputBuffer", "(J)I");
42 | jc->codec_queueInputBuffer = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwDecodeBridge, "queueInputBuffer", "(IIJI)V");
43 | jc->codec_getInputBuffer = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwDecodeBridge, "getInputBuffer", "(I)Ljava/nio/ByteBuffer;");
44 | jc->codec_getOutputBuffer = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwDecodeBridge, "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;");
45 | jc->codec_releaseOutPutBuffer = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwDecodeBridge, "releaseOutPutBuffer", "(I)V");
46 | jc->codec_release = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwDecodeBridge, "release", "()V");
47 | jc->codec_formatChange = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwDecodeBridge, "formatChange", "()Ljava/nio/ByteBuffer;");
48 | jc->codec_dequeueOutputBufferIndex = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwDecodeBridge, "dequeueOutputBufferIndex", "(J)Ljava/nio/ByteBuffer;");
49 | jc->HwDecodeBridge = (*jniEnv)->NewGlobalRef(jniEnv, java_HwDecodeBridge);
50 | (*jniEnv)->DeleteLocalRef(jniEnv, java_HwDecodeBridge);
51 |
52 | jclass java_HwAudioDecodeBridge = (*jniEnv)->FindClass(jniEnv, "com/wodekouwei/srsrtmpplayer/proxy/HwAudioDecodeWrapper");
53 | jc->audio_codec_init = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwAudioDecodeBridge, "init", "(Ljava/lang/String;IILjava/nio/ByteBuffer;)V");
54 | jc->audio_codec_stop = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwAudioDecodeBridge, "stop", "()V");
55 | jc->audio_codec_flush = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwAudioDecodeBridge, "flush", "()V");
56 | jc->audio_codec_dequeueInputBuffer = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwAudioDecodeBridge, "dequeueInputBuffer", "(J)I");
57 | jc->audio_codec_queueInputBuffer = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwAudioDecodeBridge, "queueInputBuffer", "(IIJI)V");
58 | jc->audio_codec_getInputBuffer = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwAudioDecodeBridge, "getInputBuffer", "(I)Ljava/nio/ByteBuffer;");
59 | jc->audio_codec_getOutputBuffer = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwAudioDecodeBridge, "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;");
60 | jc->audio_codec_releaseOutPutBuffer = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwAudioDecodeBridge, "releaseOutPutBuffer", "(I)V");
61 | jc->audio_codec_release = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwAudioDecodeBridge, "release", "()V");
62 | jc->audio_codec_formatChange = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwAudioDecodeBridge, "formatChange", "()Ljava/nio/ByteBuffer;");
63 | jc->audio_codec_dequeueOutputBufferIndex = (*jniEnv)->GetStaticMethodID(jniEnv, java_HwAudioDecodeBridge, "dequeueOutputBufferIndex", "(J)Ljava/nio/ByteBuffer;");
64 | jc->HwAudioDecodeBridge = (*jniEnv)->NewGlobalRef(jniEnv, java_HwAudioDecodeBridge);
65 | (*jniEnv)->DeleteLocalRef(jniEnv, java_HwAudioDecodeBridge);
66 |
67 | jclass java_SurfaceTextureBridge = (*jniEnv)->FindClass(jniEnv, "com/wodekouwei/srsrtmpplayer/proxy/SurfaceTextureWrapper");
68 | jc->texture_getSurface = (*jniEnv)->GetStaticMethodID(jniEnv, java_SurfaceTextureBridge, "getSurface", "(I)Landroid/view/Surface;");
69 | jc->texture_updateTexImage = (*jniEnv)->GetStaticMethodID(jniEnv, java_SurfaceTextureBridge, "updateTexImage", "()V");
70 | jc->texture_getTransformMatrix = (*jniEnv)->GetStaticMethodID(jniEnv, java_SurfaceTextureBridge, "getTransformMatrix", "()[F");
71 | jc->texture_release = (*jniEnv)->GetStaticMethodID(jniEnv, java_SurfaceTextureBridge, "release", "()V");
72 | jc->SurfaceTextureBridge = (*jniEnv)->NewGlobalRef(jniEnv, java_SurfaceTextureBridge);
73 | (*jniEnv)->DeleteLocalRef(jniEnv, java_SurfaceTextureBridge);
74 |
75 | *p_jc = jc;
76 | }
77 |
78 | void oar_jni_free(oar_java_class **p_jc, JNIEnv *jniEnv){
79 | oar_java_class * jc = *p_jc;
80 | (*jniEnv)->DeleteGlobalRef(jniEnv, jc->HwDecodeBridge);
81 | (*jniEnv)->DeleteGlobalRef(jniEnv, jc->SurfaceTextureBridge);
82 | free(jc);
83 | *p_jc = NULL;
84 | }
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_packet_queue.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | #include
25 | #include
26 | #include "oar_packet_queue.h"
27 |
28 | #define _JNILOG_TAG "oar_packet_queue"
29 | #include "_android.h"
30 | static OARPacket *newPacket(const uint8_t *data, int size, PktType_e type)
31 | {
32 | OARPacket *pkt = (OARPacket *)calloc(1, sizeof(OARPacket) + size);
33 | if (!pkt) {
34 | LOGE("failed in malloc OARPacket");
35 | return NULL;
36 | }
37 | if (data) {
38 | memcpy(pkt->data, data, size);
39 | pkt->size = size;
40 | }
41 | else {
42 | pkt->size = 0;
43 | }
44 |
45 | pkt->type = type;
46 | pkt->next = NULL;
47 | return pkt;
48 | }
49 |
50 | void freePacket(OARPacket *pkt)
51 | {
52 | if (pkt) {
53 | free(pkt);
54 | }
55 | }
56 |
57 | oar_packet_queue *oar_queue_create(PktType_e media_type) {
58 | oar_packet_queue *queue = (oar_packet_queue *) malloc(sizeof(oar_packet_queue));
59 | queue->media_type = media_type;
60 | queue->mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
61 | queue->cond = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
62 | pthread_mutex_init(queue->mutex, NULL);
63 | pthread_cond_init(queue->cond, NULL);
64 | queue->count = 0;
65 | queue->max_duration = 0;
66 | queue->total_bytes = 0;
67 | queue->cachedPackets = NULL;
68 | queue->lastPacket = NULL;
69 | queue->full_cb = NULL;
70 | queue->empty_cb = NULL;
71 |
72 | return queue;
73 | }
74 | void oar_queue_set_duration(oar_packet_queue* queue, uint64_t max_duration){
75 | queue->max_duration = max_duration;
76 | }
77 | void oar_packet_queue_free(oar_packet_queue *queue){
78 | pthread_mutex_destroy(queue->mutex);
79 | pthread_cond_destroy(queue->cond);
80 | OARPacket *tempPacket,*packet = queue->cachedPackets;
81 | while(packet){
82 | tempPacket = packet;
83 | packet = packet->next;
84 | freePacket(tempPacket);
85 | }
86 | queue->cachedPackets = NULL;
87 | queue->lastPacket = NULL;
88 | free(queue);
89 | }
90 | int oar_packet_queue_put(oar_packet_queue *queue,
91 | int size,
92 | PktType_e type,
93 | int64_t dts,
94 | int64_t pts,
95 | int isKeyframe,
96 | uint8_t *data){
97 | int64_t cachedDur = 0;
98 | pthread_mutex_lock(queue->mutex);
99 | if (queue->cachedPackets && queue->lastPacket) {
100 | //LOGD("type = %d;last:%lld, %p, cached:%lld, %p", type, queue->lastPacket->dts, queue->cachedPackets, queue->cachedPackets->dts, queue->lastPacket);
101 | cachedDur = queue->lastPacket->dts - queue->cachedPackets->dts;
102 | //LOGD("type = %d; duration:%lld" , type, cachedDur);
103 | if (cachedDur >= queue->max_duration * USEC_PER_SEC) {
104 | if (queue->full_cb != NULL) {
105 | queue->full_cb(queue->cb_data);
106 | }
107 | // LOGD("type = %d; oar_packet_queue_put wait...", type);
108 | pthread_cond_wait(queue->cond, queue->mutex);
109 | // LOGD("type = %d; oar_packet_queue_put wait end", type);
110 | }
111 | }
112 | pthread_mutex_unlock(queue->mutex);
113 |
114 | OARPacket *p = newPacket(data, size, type);
115 | if (!p) {
116 | LOGE("failed in newPacket");
117 | return -1;
118 | }
119 |
120 | p->dts = dts;
121 | p->pts = pts;
122 | p->isKeyframe = isKeyframe;
123 |
124 | pthread_mutex_lock(queue->mutex);
125 | //LOGD("last = %p", queue->lastPacket);
126 | if (queue->lastPacket) {
127 | queue->lastPacket->next = p;
128 | queue->lastPacket = p;
129 | }
130 | else {
131 | queue->lastPacket = queue->cachedPackets = p;
132 | }
133 | queue->count++;
134 | queue->total_bytes += size;
135 | pthread_cond_signal(queue->cond);
136 | pthread_mutex_unlock(queue->mutex);
137 | return 0;
138 | }
139 | OARPacket* oar_packet_queue_get(oar_packet_queue *queue){
140 | // LOGD("oar_packet_queue_get start");
141 | pthread_mutex_lock(queue->mutex);
142 | // LOGD("oar_packet_queue_get count: %d", queue->count);
143 | if (queue->count == 0) {
144 | pthread_cond_signal(queue->cond);
145 | pthread_mutex_unlock(queue->mutex);
146 | if (queue->empty_cb != NULL) {
147 | queue->empty_cb(queue->cb_data);
148 | }
149 | return NULL;
150 | }
151 | // LOGD("oar_packet_queue_get");
152 | OARPacket *ret = NULL;
153 | if (queue->cachedPackets) {
154 | ret = queue->cachedPackets;
155 | if (queue->cachedPackets == queue->lastPacket) {
156 | queue->lastPacket = NULL;
157 | }
158 | queue->cachedPackets = queue->cachedPackets->next;
159 | if (queue->count > 0) {
160 | queue->count --;
161 | }
162 | }
163 | else {
164 | pthread_cond_signal(queue->cond);
165 | pthread_mutex_unlock(queue->mutex);
166 | if (queue->empty_cb != NULL) {
167 | queue->empty_cb(queue->cb_data);
168 | }
169 | return NULL;
170 | }
171 | queue->total_bytes -= ret->size;
172 | // LOGD("type = %d,oar_packet_queue_get cond signal", ret->type);
173 | pthread_cond_signal(queue->cond);
174 | pthread_mutex_unlock(queue->mutex);
175 | return ret;
176 | }
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_video_mediacodec_ndk.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | //
24 | // Created by qingkouwei on 2018/1/5.
25 | //
26 |
27 | #define _JNILOG_TAG "oar_video_mediacodec_ndk"
28 | #include "_android.h"
29 | #include
30 | #include
31 | #include
32 | #include "oar_video_mediacodec_ndk.h"
33 | #include "oar_video_mediacodec_ctx.h"
34 |
35 | static void formatCreate(void *ctx, void *format){
36 | oar_video_mediacodec_context *context = (oar_video_mediacodec_context*)ctx;
37 | context->AFormat = format;
38 | }
39 |
40 | void oar_create_video_mediacodec_ndk(
41 | oarplayer *oar){
42 | size_t sps_size, pps_size;
43 | uint8_t *sps_buf;
44 | uint8_t *pps_buf;
45 | sps_buf = (uint8_t *) malloc((size_t) oar->metadata->video_extradata_size + 20);
46 | pps_buf = (uint8_t *) malloc((size_t) oar->metadata->video_extradata_size + 20);
47 | if (0 != convert_sps_pps2(oar->metadata->video_extradata, (size_t) oar->metadata->video_extradata_size,
48 | sps_buf, &sps_size, pps_buf, &pps_size, &oar->video_mediacodec_ctx->nal_size)) {
49 | LOGE("%s:convert_sps_pps: failed\n", __func__);
50 | }
51 | oar->video_mediacodec_ctx->ACodec = oar->dl_context->create_native_mediacodec(oar->metadata->video_codec,
52 | oar->metadata->width, oar->metadata->height,
53 | -1,
54 | -1,
55 | sps_buf, sps_size,
56 | pps_buf, pps_size,
57 | oar->video_mediacodec_ctx,
58 | formatCreate);
59 | free(sps_buf);
60 | free(pps_buf);
61 | }
62 |
63 | void oar_video_mediacodec_release_buffer_ndk(oarplayer *oar, int index){
64 | oar->dl_context->native_mediacodec_release_buffer(oar->video_mediacodec_ctx->ACodec, index, true);
65 | }
66 | static void frameGenerate(void* player, void **frame, void *data, int size, int64_t pts,ssize_t index,int arg1, int arg2, int pix_format){
67 | oarplayer *oar = (oarplayer*)player;
68 | if (index >= 0) {
69 | OARFrame *f = (OARFrame *)(*frame);
70 | f->type = PktType_Video;
71 | f->pts = pts;
72 | f->format = PIX_FMT_EGL_EXT;
73 | f->width = oar->metadata->width;
74 | f->height = oar->metadata->height;
75 | f->HW_BUFFER_ID = index;
76 | f->next=NULL;
77 | }else{
78 | switch (index) {
79 | // AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED
80 | case -2: {
81 | oar->video_mediacodec_ctx->width = arg1;
82 | oar->video_mediacodec_ctx->height = arg2;
83 | oar->video_mediacodec_ctx->pix_format = pix_format;
84 | break;
85 | }
86 | // AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED
87 | case -3:
88 | break;
89 | // AMEDIACODEC_INFO_TRY_AGAIN_LATER
90 | case -1:
91 | break;
92 | default:
93 | break;
94 | }
95 | }
96 | }
97 | int oar_video_mediacodec_receive_frame_ndk(oarplayer *oar, OARFrame *frame){
98 | return oar->dl_context->native_mediacodec_receive_frame(oar->video_mediacodec_ctx->ACodec,
99 | &frame, oar, 0, frameGenerate);
100 | }
101 | int oar_video_mediacodec_send_packet_ndk(oarplayer *oar, OARPacket *packet){
102 | if (packet == NULL) { return -2; }
103 | if (oar->video_mediacodec_ctx->codec_id == VIDEO_CODEC_AVC) {
104 | H264ConvertState convert_state = {0, 0};
105 | convert_h264_to_annexb(packet->data, packet->size, oar->video_mediacodec_ctx->nal_size, &convert_state);
106 | }
107 | return oar->dl_context->native_mediacodec_send_packet(oar->video_mediacodec_ctx->ACodec,
108 | packet->size,
109 | packet->type,
110 | packet->pts,
111 | packet->pts,
112 | packet->isKeyframe,
113 | packet->data);
114 | }
115 | void oar_video_mediacodec_flush_ndk(oarplayer *oar){
116 | oar->dl_context->native_mediacodec_flush(oar->video_mediacodec_ctx->ACodec);
117 | }
118 | void oar_video_mediacodec_release_context_ndk(oarplayer *oar){
119 | oar->dl_context->native_mediacodec_release_context(oar->video_mediacodec_ctx->ACodec,oar->video_mediacodec_ctx->AFormat);
120 | }
121 | void oar_video_mediacodec_start_ndk(oarplayer *oar){
122 | while(oar->video_render_ctx->texture_window == NULL){
123 | usleep(10000);
124 | }
125 | oar->dl_context->native_mediacodec_start(oar->video_mediacodec_ctx->ACodec,
126 | oar->video_mediacodec_ctx->AFormat,
127 | oar->video_render_ctx->texture_window);
128 | }
129 | void oar_video_mediacodec_stop_ndk(oarplayer *oar){
130 | oar->dl_context->native_mediacodec_stop(oar->video_mediacodec_ctx->ACodec);
131 | }
132 |
133 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oarplayer_jni.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #define _JNILOG_TAG "oarplayer_jni"
24 | #include "_android.h"
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | #include "jni_utils.h"
35 | #include "oarplayer_type_def.h"
36 | #include "oar_player.h"
37 |
38 |
39 | #define JNI_CLASS_OARPLAYER "com/wodekouwei/srsrtmpplayer/OARPlayer"
40 | #ifndef NELEM
41 | #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
42 | #endif
43 |
44 | static oarplayer *oar;
45 | static int oar_run_android_version;
46 | static int oar_best_samplerate;
47 |
48 | typedef struct player_fields_t {
49 | pthread_mutex_t mutex;
50 | jclass clazz;
51 | } player_fields_t;
52 | static player_fields_t g_clazz;
53 |
54 | static void
55 | SrsPlayer_native_init(JNIEnv *env,jobject thiz,int run_android_version, int best_samplerate)
56 | {
57 | oar_run_android_version = run_android_version;
58 | oar_best_samplerate = best_samplerate;
59 | oar = oar_player_create(env,thiz,oar_run_android_version,oar_best_samplerate);
60 | oar->jniEnv = env;
61 | (*env)->GetJavaVM(env, &oar->vm);
62 | LOGI("native init...");
63 |
64 |
65 | }
66 | static void
67 | SrsPlayer_setDataSourceAndHeaders(
68 | JNIEnv *env, jobject thiz, jstring path,
69 | jobjectArray keys, jobjectArray values){
70 | const char *c_path = NULL;
71 | c_path = (*env)->GetStringUTFChars(env, path, NULL );
72 | int len = strlen(c_path);
73 | oar->url = malloc(sizeof(char)*len);
74 | strcpy(oar->url, c_path);
75 | (*env)->ReleaseStringUTFChars(env, path, c_path);
76 | }
77 | static void
78 | SrsPlayer_setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface)
79 | {
80 | if (oar != NULL) {
81 | if (oar->video_render_ctx->window != NULL) {
82 | ANativeWindow_release(oar->video_render_ctx->window);
83 | }
84 | ANativeWindow *sur = ANativeWindow_fromSurface(env, jsurface);
85 | oar->video_render_ctx->set_window(oar->video_render_ctx, sur);
86 | }
87 | }
88 | static void
89 | SrsPlayer_prepareAsync(JNIEnv *env, jobject thiz)
90 | {
91 |
92 | }
93 | static void
94 | SrsPlayer_start(JNIEnv *env, jobject thiz)
95 | {
96 | oar_player_play(oar);
97 | }
98 | static void
99 | SrsPlayer_stop(JNIEnv *env, jobject thiz)
100 | {
101 | oar_player_stop(oar);
102 | }
103 | static void
104 | SrsPlayer_release(JNIEnv *env, jobject thiz){
105 | LOGI("release...");
106 | oar_player_release(oar);
107 | oar = NULL;
108 | }
109 | static float
110 | SrsPlayer_getCurrentTime() {
111 | if (oar) {
112 | if (oar->metadata->has_audio) {
113 | return (float) oar->audio_clock->pts / 1000000;
114 | } else if (oar->metadata->has_video) {
115 | return (float) oar->video_clock->pts / 1000000;
116 | }
117 | }
118 | return 0.0f;
119 | }
120 | static void
121 | SrsPlayer_setPlayBackground(jboolean playBackground){
122 | LOGI("setPlayBackground...");
123 | oar_player_set_play_background(oar, playBackground);
124 | }
125 | static void
126 | SrsPlayer_setBufferTime(jfloat bufferTime){
127 | oar_player_set_buffer_time(oar, bufferTime);
128 | }
129 | static void
130 | SrsPlayer_onPause(){
131 | LOGI("pause...");
132 | if (oar && oar->status == PLAYING) {
133 | oar->change_status(oar, PAUSED);
134 | }
135 | }
136 | static void
137 | SrsPlayer_onResume(){
138 | if(oar && oar->status == PAUSED){
139 | oar_player_resume(oar);
140 | }
141 | }
142 | static JNINativeMethod g_methods[] = {
143 | {
144 | "_setDataSource",
145 | "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
146 | (void *) SrsPlayer_setDataSourceAndHeaders
147 | },
148 | { "_setVideoSurface", "(Landroid/view/Surface;)V", (void *) SrsPlayer_setVideoSurface },
149 | { "_prepareAsync", "()V", (void *) SrsPlayer_prepareAsync },
150 | { "_setBufferTime", "(F)V", (void *)SrsPlayer_setBufferTime},
151 | { "_start", "()V", (void *) SrsPlayer_start },
152 | { "_setPlayBackground", "(Z)V", (void *) SrsPlayer_setPlayBackground },
153 | { "_getCurrentTime", "()F", (void *) SrsPlayer_getCurrentTime },
154 | { "_onPause", "()V", (void * ) SrsPlayer_onPause },
155 | { "_onResume", "()V", (void * ) SrsPlayer_onResume },
156 | { "_stop", "()V", (void *) SrsPlayer_stop },
157 | { "_release", "()V", (void *) SrsPlayer_release },
158 | { "native_init", "(II)V", (void *) SrsPlayer_native_init },
159 | };
160 |
161 | JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
162 | {
163 | JNIEnv* env = NULL;
164 |
165 | if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
166 | return -1;
167 | }
168 | assert(env != NULL);
169 |
170 | pthread_mutex_init(&g_clazz.mutex, NULL );
171 |
172 | // FindClass returns LocalReference
173 | OAR_FIND_JAVA_CLASS(env, g_clazz.clazz, JNI_CLASS_OARPLAYER);
174 | (*env)->RegisterNatives(env, g_clazz.clazz, g_methods, NELEM(g_methods) );
175 |
176 |
177 |
178 | return JNI_VERSION_1_4;
179 | }
180 |
181 | JNIEXPORT void JNI_OnUnload(JavaVM *jvm, void *reserved)
182 | {
183 | LOGE("JNI_OnUnload....");
184 | pthread_mutex_destroy(&g_clazz.mutex);
185 | }
186 |
187 |
--------------------------------------------------------------------------------
/oarplayer/src/main/java/com/wodekouwei/srsrtmpplayer/OARPlayer.java:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | package com.wodekouwei.srsrtmpplayer;
24 |
25 | import android.content.Context;
26 | import android.media.AudioManager;
27 | import android.os.Build;
28 | import android.os.PowerManager;
29 | import android.util.Log;
30 | import android.view.Surface;
31 | import android.view.SurfaceHolder;
32 |
33 | import java.io.IOException;
34 |
35 | /**
36 | * Created by qingkouwei on 2017/12/15.
37 | */
38 |
39 | public class OARPlayer {
40 | private final static String TAG = OARPlayer.class.getName();
41 | private final static boolean isDebug = false;
42 | private PowerManager.WakeLock mWakeLock = null;
43 | private boolean mScreenOnWhilePlaying;
44 | private boolean mStayAwake;
45 |
46 | private String mDataSource;
47 | private SurfaceHolder mSurfaceHolder;
48 |
49 | private Context context;
50 |
51 | private volatile boolean mIsNativeInitialized = false;
52 | private void initNativeOnce() {
53 | int bestrate = 44100;
54 | if (android.os.Build.VERSION.SDK_INT >= 17) {
55 | AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
56 | String rate = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
57 | bestrate = Integer.parseInt(rate);
58 | }
59 | synchronized (OARPlayer.class) {
60 | if (!mIsNativeInitialized) {
61 | native_init(Build.VERSION.SDK_INT, bestrate);
62 | mIsNativeInitialized = true;
63 | }
64 | }
65 | }
66 |
67 | public OARPlayer(Context context) {
68 | this.context = context;
69 | initPlayer();
70 | }
71 | private void initPlayer() {
72 | System.loadLibrary("oarp-lib");
73 | initNativeOnce();
74 | }
75 | private native void native_init(int run_android_version, int best_samplerate);
76 |
77 | /**
78 | * setting rtmp url
79 | * @param path
80 | * @throws IOException
81 | * @throws IllegalArgumentException
82 | * @throws SecurityException
83 | * @throws IllegalStateException
84 | */
85 | public void setDataSource(String path)
86 | throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
87 | mDataSource = path;
88 | _setDataSource(path, null, null);
89 | }
90 | private native void _setDataSource(String path, String[] keys, String[] values)
91 | throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;
92 |
93 | /**
94 | * unused
95 | * @throws IllegalStateException
96 | */
97 | @SuppressWarnings("unused")
98 | public void prepareAsync() throws IllegalStateException {
99 | _prepareAsync();
100 | }
101 | private native void _prepareAsync() throws IllegalStateException;
102 |
103 | /**
104 | * setting reading packet buffer time
105 | * @param time
106 | */
107 | public void setBufferTime(float time){
108 | _setBufferTime(time);
109 | }
110 | private native void _setBufferTime(float time);
111 |
112 | /**
113 | * start play
114 | * @throws IllegalStateException
115 | */
116 | public void start() throws IllegalStateException {
117 | stayAwake(true);
118 | _start();
119 | }
120 | private native void _start() throws IllegalStateException;
121 |
122 | /**
123 | * setting playbackground(only play audio)
124 | * @param playBackground
125 | */
126 | public void setPlayBackground(boolean playBackground) {
127 | _setPlayBackground(playBackground);
128 | }
129 | private native void _setPlayBackground(boolean playBackground);
130 |
131 | /**
132 | * called in onPause of Activity
133 | */
134 | public void onPause() {
135 | _onPause();
136 | }
137 | private native void _onPause();
138 | public void onResume() {
139 | _onResume();
140 | }
141 | private native void _onResume();
142 |
143 | /**
144 | * stop play
145 | * @throws IllegalStateException
146 | */
147 | public void stop() throws IllegalStateException {
148 | stayAwake(false);
149 | _stop();
150 | }
151 | private native void _stop() throws IllegalStateException;
152 |
153 | /**
154 | * release res
155 | */
156 | public void release(){
157 | stayAwake(false);
158 | _release();
159 | }
160 | private native void _release();
161 |
162 | /**
163 | * setting render surface
164 | * @param holder
165 | */
166 | public void setSurface(SurfaceHolder holder){
167 | mSurfaceHolder = holder;
168 | _setVideoSurface(holder.getSurface());
169 | }
170 | /*
171 | * Update the SurfaceTexture. Call after setting a new
172 | * display surface.
173 | */
174 | private native void _setVideoSurface(Surface surface);
175 |
176 | /**
177 | * get current play time
178 | * @return
179 | */
180 | public float getCurrentTime(){
181 | return _getCurrentTime();
182 | }
183 | private native float _getCurrentTime();
184 |
185 | public void setWakeMode(Context context, int mode) {
186 | boolean washeld = false;
187 | if (mWakeLock != null) {
188 | if (mWakeLock.isHeld()) {
189 | washeld = true;
190 | mWakeLock.release();
191 | }
192 | mWakeLock = null;
193 | }
194 |
195 | PowerManager pm = (PowerManager) context
196 | .getSystemService(Context.POWER_SERVICE);
197 | mWakeLock = pm.newWakeLock(mode | PowerManager.ON_AFTER_RELEASE,
198 | OARPlayer.class.getName());
199 | mWakeLock.setReferenceCounted(false);
200 | if (washeld) {
201 | mWakeLock.acquire();
202 | }
203 | }
204 | public void setScreenOnWhilePlaying(boolean screenOn) {
205 | if (mScreenOnWhilePlaying != screenOn) {
206 | if (screenOn && mSurfaceHolder == null) {
207 | Log.w(TAG,
208 | "setScreenOnWhilePlaying(true) is ineffective without a SurfaceHolder");
209 | }
210 | mScreenOnWhilePlaying = screenOn;
211 | updateSurfaceScreenOn();
212 | }
213 | }
214 |
215 | private void stayAwake(boolean awake) {
216 | if (mWakeLock != null) {
217 | if (awake && !mWakeLock.isHeld()) {
218 | mWakeLock.acquire();
219 | } else if (!awake && mWakeLock.isHeld()) {
220 | mWakeLock.release();
221 | }
222 | }
223 | mStayAwake = awake;
224 | updateSurfaceScreenOn();
225 | }
226 |
227 | private void updateSurfaceScreenOn() {
228 | if (mSurfaceHolder != null) {
229 | mSurfaceHolder.setKeepScreenOn(mScreenOnWhilePlaying && mStayAwake);
230 | }
231 | }
232 |
233 | /**
234 | * callback by jni
235 | * @param status
236 | */
237 | void onPlayStatusChanged(int status) {
238 | if(isDebug) Log.i(TAG, "onPlayStatusChanged:" + status);
239 | }
240 |
241 | /**
242 | * native 调用的错误码回调
243 | *
244 | * @param error error code from native
245 | */
246 | void onPlayError(int error) {
247 | if(isDebug) Log.i(TAG, "onPlayError:" + error);
248 | }
249 | }
250 |
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_video_mediacodec_ctx.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | //
24 | // Created by qingkouwei on 2018/1/5.
25 | //
26 |
27 | #include
28 | #include
29 | #include
30 | #include "oar_video_mediacodec_ctx.h"
31 | oar_video_mediacodec_context *oar_create_video_mediacodec_context(
32 | oarplayer *oar) {
33 | oar_video_mediacodec_context *ctx = (oar_video_mediacodec_context *) malloc(sizeof(oar_video_mediacodec_context));
34 | ctx->width = oar->metadata->width;
35 | ctx->height = oar->metadata->height;
36 | ctx->codec_id = oar->metadata->video_codec;
37 | ctx->nal_size = 0;
38 | ctx->pix_format = PIX_FMT_NONE;
39 | return ctx;
40 | }
41 | /* Inspired by libavcodec/hevc.c */
42 | int convert_hevc_nal_units(const uint8_t *p_buf,size_t i_buf_size,
43 | uint8_t *p_out_buf,size_t i_out_buf_size,
44 | size_t *p_sps_pps_size,size_t *p_nal_size)
45 | {
46 | int i, num_arrays;
47 | const uint8_t *p_end = p_buf + i_buf_size;
48 | uint32_t i_sps_pps_size = 0;
49 |
50 | if( i_buf_size <= 3 || ( !p_buf[0] && !p_buf[1] && p_buf[2] <= 1 ) )
51 | return -1;
52 |
53 | if( p_end - p_buf < 23 )
54 | {
55 | //LOGE( "Input Metadata too small" );
56 | return -1;
57 | }
58 |
59 | p_buf += 21;
60 |
61 | if( p_nal_size )
62 | *p_nal_size = (size_t) ((*p_buf & 0x03) + 1);
63 | p_buf++;
64 |
65 | num_arrays = *p_buf++;
66 |
67 | for( i = 0; i < num_arrays; i++ )
68 | {
69 | int type, cnt, j;
70 |
71 | if( p_end - p_buf < 3 )
72 | {
73 | //LOGE( "Input Metadata too small" );
74 | return -1;
75 | }
76 | type = *(p_buf++) & 0x3f;
77 | (void)(type);
78 |
79 | cnt = p_buf[0] << 8 | p_buf[1];
80 | p_buf += 2;
81 |
82 | for( j = 0; j < cnt; j++ )
83 | {
84 | int i_nal_size;
85 |
86 | if( p_end - p_buf < 2 )
87 | {
88 | //LOGE( "Input Metadata too small" );
89 | return -1;
90 | }
91 |
92 | i_nal_size = p_buf[0] << 8 | p_buf[1];
93 | p_buf += 2;
94 |
95 | if( i_nal_size < 0 || p_end - p_buf < i_nal_size )
96 | {
97 | //LOGE( "NAL unit size does not match Input Metadata size" );
98 | return -1;
99 | }
100 |
101 | if( i_sps_pps_size + 4 + i_nal_size > i_out_buf_size )
102 | {
103 | //LOGE( "Output buffer too small" );
104 | return -1;
105 | }
106 |
107 | p_out_buf[i_sps_pps_size++] = 0;
108 | p_out_buf[i_sps_pps_size++] = 0;
109 | p_out_buf[i_sps_pps_size++] = 0;
110 | p_out_buf[i_sps_pps_size++] = 1;
111 |
112 | memcpy(p_out_buf + i_sps_pps_size, p_buf, (size_t) i_nal_size);
113 | p_buf += i_nal_size;
114 |
115 | i_sps_pps_size += i_nal_size;
116 | }
117 | }
118 |
119 | *p_sps_pps_size = i_sps_pps_size;
120 |
121 | return 0;
122 | }
123 | int convert_sps_pps2(const uint8_t *p_buf, size_t i_buf_size,
124 | uint8_t * out_sps_buf, size_t * out_sps_buf_size,
125 | uint8_t * out_pps_buf, size_t * out_pps_buf_size,
126 | // uint8_t *p_out_buf, size_t i_out_buf_size,
127 | // size_t *p_sps_pps_size,
128 | size_t *p_nal_size
129 | ) {
130 | // int i_profile;
131 | uint32_t i_data_size = (uint32_t) i_buf_size, i_nal_size ;
132 | unsigned int i_loop_end;
133 |
134 | /* */
135 | if (i_data_size < 7) {
136 | //LOGE("Input Metadata too small");
137 | return -1;
138 | }
139 |
140 | /* Read infos in first 6 bytes */
141 | // i_profile = (p_buf[1] << 16) | (p_buf[2] << 8) | p_buf[3];
142 | if (p_nal_size)
143 | *p_nal_size = (size_t) ((p_buf[4] & 0x03) + 1);
144 | p_buf += 5;
145 | i_data_size -= 5;
146 |
147 | for (unsigned int j = 0; j < 2; j++) {
148 | /* First time is SPS, Second is PPS */
149 | if (i_data_size < 1) {
150 | /*LOGE("PPS too small after processing SPS/PPS %u",
151 | i_data_size);*/
152 | return -1;
153 | }
154 | i_loop_end = (unsigned int) (p_buf[0] & (j == 0 ? 0x1f : 0xff));
155 | p_buf++;
156 | i_data_size--;
157 |
158 | for (unsigned int i = 0; i < i_loop_end; i++) {
159 | if (i_data_size < 2) {
160 | //LOGE("SPS is too small %u", i_data_size);
161 | return -1;
162 | }
163 |
164 | i_nal_size = (p_buf[0] << 8) | p_buf[1];
165 | p_buf += 2;
166 | i_data_size -= 2;
167 |
168 | if (i_data_size < i_nal_size) {
169 | //LOGE("SPS size does not match NAL specified size %u",
170 | // i_data_size);
171 | return -1;
172 | }
173 | // if (i_sps_pps_size + 4 + i_nal_size > i_out_buf_size) {
174 | // LOGE("Output SPS/PPS buffer too small");
175 | // return -1;
176 | // }
177 | //
178 | // p_out_buf[i_sps_pps_size++] = 0;
179 | // p_out_buf[i_sps_pps_size++] = 0;
180 | // p_out_buf[i_sps_pps_size++] = 0;
181 | // p_out_buf[i_sps_pps_size++] = 1;
182 | //
183 | // memcpy(p_out_buf + i_sps_pps_size, p_buf, i_nal_size);
184 | // i_sps_pps_size += i_nal_size;
185 | if(j == 0){
186 | out_sps_buf[0] = 0;
187 | out_sps_buf[1] = 0;
188 | out_sps_buf[2] = 0;
189 | out_sps_buf[3] = 1;
190 | memcpy(out_sps_buf + 4, p_buf, i_nal_size);
191 | * out_sps_buf_size = i_nal_size + 4;
192 | }else{
193 | out_pps_buf[0] = 0;
194 | out_pps_buf[1] = 0;
195 | out_pps_buf[2] = 0;
196 | out_pps_buf[3] = 1;
197 | memcpy(out_pps_buf + 4, p_buf, i_nal_size);
198 | * out_pps_buf_size = i_nal_size + 4;
199 | }
200 |
201 | p_buf += i_nal_size;
202 | i_data_size -= i_nal_size;
203 | }
204 | }
205 |
206 | // *p_sps_pps_size = i_sps_pps_size;
207 |
208 | return 0;
209 | }
210 |
211 | void convert_h264_to_annexb( uint8_t *p_buf, size_t i_len,
212 | size_t i_nal_size,
213 | H264ConvertState *state )
214 | {
215 | if( i_nal_size < 3 || i_nal_size > 4 )
216 | return;
217 |
218 | /* This only works for NAL sizes 3-4 */
219 | while( i_len > 0 )
220 | {
221 | if( state->nal_pos < i_nal_size ) {
222 | unsigned int i;
223 | for( i = 0; state->nal_pos < i_nal_size && i < i_len; i++, state->nal_pos++ ) {
224 | state->nal_len = (state->nal_len << 8) | p_buf[i];
225 | p_buf[i] = 0;
226 | }
227 | if( state->nal_pos < i_nal_size )
228 | return;
229 | p_buf[i - 1] = 1;
230 | p_buf += i;
231 | i_len -= i;
232 | }
233 | if( state->nal_len > INT_MAX )
234 | return;
235 | if( state->nal_len > i_len )
236 | {
237 | state->nal_len -= i_len;
238 | return;
239 | }
240 | else
241 | {
242 | p_buf += state->nal_len;
243 | i_len -= state->nal_len;
244 | state->nal_len = 0;
245 | state->nal_pos = 0;
246 | }
247 | }
248 | }
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_audio_mediacodec_java.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #define _JNILOG_TAG "audiomediacodec"
24 | #include "_android.h"
25 | #include
26 | #include
27 | #include "oar_audio_mediacodec_java.h"
28 | #include "util.h"
29 |
30 | #define isDebug 0
31 | #define _LOGD if(isDebug) LOGI
32 |
33 | void oar_audio_mediacodec_start(oarplayer *oar){
34 | _LOGD("oar_audio_mediacodec_start...");
35 | oar_audio_mediacodec_context *ctx = oar->audio_mediacodec_ctx;
36 | JNIEnv *jniEnv = ctx->jniEnv;
37 | oar_java_class * jc = oar->jc;
38 | jobject codecName = NULL, csd_0 = NULL;
39 |
40 | switch (ctx->codec_id) {
41 | case AUDIO_CODEC_AAC:
42 | codecName = (*jniEnv)->NewStringUTF(jniEnv, "audio/mp4a-latm");
43 | if (oar->metadata->audio_pps) {
44 | csd_0 = (*jniEnv)->NewDirectByteBuffer(jniEnv, oar->metadata->audio_pps, oar->metadata->audio_pps_size);
45 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwAudioDecodeBridge, jc->audio_codec_init,
46 | codecName, ctx->sample_rate, ctx->channel_count, csd_0);
47 | (*jniEnv)->DeleteLocalRef(jniEnv, csd_0);
48 | } else {
49 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwAudioDecodeBridge, jc->audio_codec_init,
50 | codecName, ctx->sample_rate, ctx->channel_count, NULL);
51 | }
52 | break;
53 | default:
54 | break;
55 | }
56 | if (codecName != NULL) {
57 | (*jniEnv)->DeleteLocalRef(jniEnv, codecName);
58 | }
59 | }
60 |
61 | void oar_audio_mediacodec_release_buffer(oarplayer *oar, int index) {
62 | JNIEnv *jniEnv = oar->audio_mediacodec_ctx->jniEnv;
63 | oar_java_class * jc = oar->jc;
64 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwAudioDecodeBridge, jc->audio_codec_releaseOutPutBuffer,
65 | index);
66 | }
67 |
68 | int oar_audio_mediacodec_receive_frame(oarplayer *oar, OARFrame **frame) {
69 | JNIEnv *jniEnv = oar->audio_mediacodec_ctx->jniEnv;
70 | oar_java_class * jc = oar->jc;
71 | oar_audio_mediacodec_context *ctx = oar->audio_mediacodec_ctx;
72 | int output_ret = 1;
73 | jobject deqret = (*jniEnv)->CallStaticObjectMethod(jniEnv, jc->HwAudioDecodeBridge,
74 | jc->audio_codec_dequeueOutputBufferIndex,
75 | (jlong) 0);
76 | uint8_t *retbuf = (*jniEnv)->GetDirectBufferAddress(jniEnv, deqret);
77 | int outbufidx = get_int(retbuf);
78 | int64_t pts = get_long(retbuf + 8);
79 | int size = get_int(retbuf + 16);
80 | (*jniEnv)->DeleteLocalRef(jniEnv, deqret);
81 | _LOGD("outbufidx:%d" , outbufidx);
82 | if (outbufidx >= 0) {
83 | *frame = malloc(sizeof(OARFrame) + size);
84 | jobject outputBuf = (*jniEnv)->CallStaticObjectMethod(jniEnv, jc->HwAudioDecodeBridge,
85 | jc->audio_codec_getOutputBuffer,
86 | outbufidx);
87 | uint8_t *buf = (*jniEnv)->GetDirectBufferAddress(jniEnv, outputBuf);
88 | if (buf != NULL){
89 | memcpy((*frame)->data, buf, size);
90 | }
91 | _LOGD("release outputbuffer index : %d", outbufidx);
92 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwAudioDecodeBridge,
93 | jc->audio_codec_releaseOutPutBuffer,
94 | outbufidx);
95 | (*jniEnv)->DeleteLocalRef(jniEnv, outputBuf);
96 | (*frame)->type = PktType_Audio;
97 | (*frame)->size = size;
98 | (*frame)->pts = pts;
99 | (*frame)->HW_BUFFER_ID = outbufidx;
100 | (*frame)->next=NULL;
101 | output_ret = 0;
102 | } else {
103 | switch (outbufidx) {
104 | // AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED
105 | case -2: {
106 | jobject newFormat = (*jniEnv)->CallStaticObjectMethod(jniEnv, jc->HwAudioDecodeBridge,
107 | jc->audio_codec_formatChange);
108 | uint8_t *fmtbuf = (*jniEnv)->GetDirectBufferAddress(jniEnv, newFormat);
109 | ctx->sample_rate = get_int(fmtbuf);
110 | ctx->channel_count = get_int(fmtbuf + 4);
111 | (*jniEnv)->DeleteLocalRef(jniEnv, newFormat);
112 | output_ret = -2;
113 | break;
114 | }
115 | // AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED
116 | case -3:
117 | _LOGD("output_ret: %d", -3);
118 | break;
119 | // AMEDIACODEC_INFO_TRY_AGAIN_LATER
120 | case -1:
121 | _LOGD("output_ret: %d", -1);
122 | break;
123 | default:
124 | _LOGD("output_ret: %d", outbufidx);
125 | break;
126 | }
127 |
128 | }
129 | return output_ret;
130 | }
131 |
132 | int oar_audio_mediacodec_send_packet(oarplayer *oar, OARPacket *packet) {
133 | JNIEnv *jniEnv = oar->audio_mediacodec_ctx->jniEnv;
134 | oar_java_class * jc = oar->jc;
135 | oar_audio_mediacodec_context *ctx = oar->audio_mediacodec_ctx;
136 | if (packet == NULL) { return -2; }
137 | int64_t time_stamp = packet->pts;
138 |
139 | int id = (*jniEnv)->CallStaticIntMethod(jniEnv, jc->HwAudioDecodeBridge,
140 | jc->audio_codec_dequeueInputBuffer, (jlong) 1000000);
141 | if (id >= 0) {
142 | _LOGD("start get inputbuffer...");
143 | jobject inputBuffer = (*jniEnv)->CallStaticObjectMethod(jniEnv, jc->HwAudioDecodeBridge,
144 | jc->audio_codec_getInputBuffer, id);
145 | uint8_t *buf = (*jniEnv)->GetDirectBufferAddress(jniEnv, inputBuffer);
146 | jlong size = (*jniEnv)->GetDirectBufferCapacity(jniEnv, inputBuffer);
147 | if (buf != NULL && size >= packet->size) {
148 | /*_LOGD("data:%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
149 | packet->data[0],packet->data[1],packet->data[2],packet->data[3],
150 | packet->data[4],packet->data[5],packet->data[6],packet->data[7],
151 | packet->data[8],packet->data[9],packet->data[10],packet->data[11],
152 | packet->data[12],packet->data[13],packet->data[14],packet->data[15]);*/
153 | memcpy(buf, packet->data, (size_t) packet->size);
154 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwAudioDecodeBridge,
155 | jc->audio_codec_queueInputBuffer,
156 | (jint) id, (jint) packet->size,
157 | (jlong) time_stamp, (jint) 0);
158 | }
159 | (*jniEnv)->DeleteLocalRef(jniEnv, inputBuffer);
160 | } else if (id == -1) {
161 | return -1;
162 | } else {
163 | LOGE("input buffer id < 0 value == %zd", id);
164 | }
165 | return 0;
166 | }
167 |
168 | void oar_audio_mediacodec_flush(oarplayer *oar) {
169 | JNIEnv *jniEnv = oar->audio_mediacodec_ctx->jniEnv;
170 | oar_java_class * jc = oar->jc;
171 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwAudioDecodeBridge, jc->audio_codec_flush);
172 | }
173 |
174 | void oar_audio_mediacodec_release_context(oarplayer *oar) {
175 | JNIEnv *jniEnv = oar->jniEnv;
176 | oar_java_class * jc = oar->jc;
177 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwAudioDecodeBridge, jc->audio_codec_release);
178 | oar_audio_mediacodec_context *ctx = oar->audio_mediacodec_ctx;
179 | free(ctx);
180 | oar->audio_mediacodec_ctx = NULL;
181 | }
182 |
183 | void oar_audio_mediacodec_stop(oarplayer *oar) {
184 | JNIEnv *jniEnv = oar->audio_mediacodec_ctx->jniEnv;
185 | oar_java_class * jc = oar->jc;
186 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwAudioDecodeBridge, jc->audio_codec_stop);
187 | }
188 |
--------------------------------------------------------------------------------
/nativemediacodec/src/main/cpp/oar_native_mediacodec.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | //
24 | // Created by qingkouwei on 2018/1/4.
25 | //
26 | #define _JNILOG_TAG "native_mediacodec"
27 | #include "_android.h"
28 | #include "oar_native_mediacodec.h"
29 | #include
30 | #include
31 |
32 | #define VIDEO_CODEC_AVC 7
33 | #define VIDEO_CODEC_H263 2
34 | #define AUDIO_CODEC_AAC 10
35 |
36 | int oar_native_mediacodec_send_packet(void * codec,
37 | int len,
38 | int type,
39 | int64_t dts,
40 | int64_t pts,
41 | int isKeyframe,
42 | uint8_t *data) {
43 | AMediaCodec *c = (AMediaCodec *)codec;
44 | if (data == NULL) { return -2; }
45 | uint32_t keyframe_flag = 0;
46 | int64_t time_stamp = pts;
47 | if (isKeyframe) {
48 | keyframe_flag |= 0x1;
49 | }
50 | ssize_t id = AMediaCodec_dequeueInputBuffer(c, 1000000);
51 | media_status_t media_status;
52 | size_t size;
53 | if (id >= 0) {
54 | uint8_t *buf = AMediaCodec_getInputBuffer(c, (size_t) id, &size);
55 | if (buf != NULL && size >= len) {
56 | memcpy(buf, data, (size_t)len);
57 | media_status = AMediaCodec_queueInputBuffer(c, (size_t) id, 0, (size_t) len,
58 | (uint64_t) time_stamp,
59 | keyframe_flag);
60 | if (media_status != AMEDIA_OK) {
61 | // LOGE("AMediaCodec_queueInputBuffer error. status ==> %d", media_status);
62 | return (int) media_status;
63 | }
64 | }
65 | }else if(id == AMEDIACODEC_INFO_TRY_AGAIN_LATER){
66 | return -1;
67 | }else{
68 | // LOGE("input buffer id < 0 value == %zd", id);
69 | }
70 | return 0;
71 | }
72 |
73 | void oar_native_mediacodec_release_buffer(void * codec, int bufferID, bool render) {
74 | AMediaCodec *c = (AMediaCodec *)codec;
75 | AMediaCodec_releaseOutputBuffer(c, (size_t) bufferID, render);
76 | }
77 |
78 | int oar_native_mediacodec_receive_frame(void * codec,
79 | void **frame,
80 | void *oar,
81 | int type,
82 | void *(frameGenerate)(void *,void **, void*, int, int64_t,ssize_t,int, int, int)) {
83 | AMediaCodec *c = (AMediaCodec *)codec;
84 | AMediaCodecBufferInfo info;
85 | int output_ret = 1;
86 | ssize_t outbufidx = AMediaCodec_dequeueOutputBuffer(c, &info, 0);
87 | if (outbufidx >= 0) {
88 | if(type == 0){//video
89 | frameGenerate(oar, frame, NULL, 0, info.presentationTimeUs, outbufidx, -1, -1, 2);
90 | }else{
91 | int size = 0;
92 | uint8_t *data = AMediaCodec_getOutputBuffer(c, outbufidx, &size);
93 | // LOGE("index : %d, size:%d, info.size : %d, offset: %d", outbufidx, size, info.size, info.offset);
94 | frameGenerate(oar, frame, data, info.size, info.presentationTimeUs, outbufidx, -1, -1, -1);
95 | AMediaCodec_releaseOutputBuffer(c,outbufidx, false);
96 | }
97 | output_ret = 0;
98 | } else {
99 | switch (outbufidx) {
100 | case AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED: {
101 | AMediaFormat *format = AMediaCodec_getOutputFormat(c);
102 | if(type == 0){
103 | int pix_format = -1;
104 | int width =0, height =0;
105 | AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &width);
106 | AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &height);
107 | AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT, &pix_format);
108 | frameGenerate(oar, frame, NULL, 0, 0, AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED, width, height, pix_format);
109 | }else{
110 | int sample_rate =0, channel_count =0;
111 | AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &sample_rate);
112 | AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &channel_count);
113 | frameGenerate(oar,frame, NULL, 0, 0, AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED, sample_rate, channel_count, -1);
114 | }
115 | output_ret = -2;
116 | break;
117 | }
118 | case AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED:
119 | break;
120 | case AMEDIACODEC_INFO_TRY_AGAIN_LATER:
121 | break;
122 | default:
123 | break;
124 | }
125 |
126 | }
127 | return output_ret;
128 | }
129 |
130 | void oar_native_mediacodec_flush(void * codec) {
131 | AMediaCodec *c = (AMediaCodec *)codec;
132 | AMediaCodec_flush(c);
133 | }
134 |
135 | void *oar_create_native_mediacodec(int codec_id,
136 | int width, int height,
137 | int sample_rate, int channelCount,
138 | uint8_t *sps, int sps_size,
139 | uint8_t *pps, int pps_size,
140 | void *ctx,
141 | void (*formatCreated(void*, void*))) {
142 | /*LOGE("codecid:%d, width:%d, height:%d, samplerate:%d, channelCount:%d, sps_size:%d", codec_id,
143 | width, height, sample_rate, channelCount, sps_size);*/
144 | AMediaCodec *codec = NULL;
145 | AMediaFormat *format = AMediaFormat_new();
146 | // "video/x-vnd.on2.vp8" - VP8 video (i.e. video in .webm)
147 | // "video/x-vnd.on2.vp9" - VP9 video (i.e. video in .webm)
148 | // "video/avc" - H.264/AVC video
149 | // "video/hevc" - H.265/HEVC video
150 | // "video/mp4v-es" - MPEG4 video
151 | // "video/3gpp" - H.263 video
152 | switch (codec_id) {
153 | case VIDEO_CODEC_AVC:
154 | codec = AMediaCodec_createDecoderByType("video/avc");
155 | AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "video/avc");
156 | AMediaFormat_setBuffer(format, "csd-0", sps, sps_size);
157 | AMediaFormat_setBuffer(format, "csd-1", pps, pps_size);
158 | // AMediaFormat_setInt32(ctx->format, "rotation-degrees", 90);
159 | AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, width);
160 | AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, height);
161 | break;
162 |
163 | case VIDEO_CODEC_H263:
164 | codec = AMediaCodec_createDecoderByType("video/3gpp");
165 | AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "video/3gpp");
166 | AMediaFormat_setBuffer(format, "csd-0", sps, sps_size);
167 | // AMediaFormat_setInt32(ctx->format, "rotation-degrees", 90);
168 | AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, width);
169 | AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, height);
170 | break;
171 | case AUDIO_CODEC_AAC:
172 | codec = AMediaCodec_createDecoderByType("audio/mp4a-latm");
173 | AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "audio/mp4a-latm");
174 | AMediaFormat_setBuffer(format, "csd-0", sps, sps_size);
175 | AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, channelCount);
176 | AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, sample_rate);
177 | break;
178 | default:
179 | break;
180 | }
181 |
182 | formatCreated(ctx, format);
183 | return codec;
184 | }
185 |
186 | int oar_native_mediacodec_start(void * codec, void *format, void *window){
187 | AMediaCodec *c = (AMediaCodec *)codec;
188 | AMediaFormat *f = (AMediaFormat *)format;
189 | ANativeWindow *texture_window = NULL;
190 | if(window != NULL){
191 | texture_window = (ANativeWindow *)window;
192 | }
193 | media_status_t ret = AMediaCodec_configure(c, f, texture_window, NULL, 0);
194 | if (ret != AMEDIA_OK) {
195 | return ret;
196 | }
197 | ret = AMediaCodec_start(c);
198 | /*if (ret != AMEDIA_OK) {
199 | return ret;
200 | }*/
201 | return ret;
202 | }
203 |
204 | void oar_native_mediacodec_stop(void * codec){
205 | AMediaCodec *c = (AMediaCodec *)codec;
206 | AMediaCodec_stop(c);
207 | }
208 |
209 | void oar_native_mediacodec_release_context(void * codec, void *format){
210 | AMediaCodec *c = (AMediaCodec *)codec;
211 | AMediaFormat *f = (AMediaFormat *)format;
212 | AMediaCodec_delete(c);
213 | AMediaFormat_delete(f);
214 | }
--------------------------------------------------------------------------------
/oarplayer/src/main/cpp/oar_video_mediacodec_java.c:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2017-2020 oarplayer(qingkouwei)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of
7 | this software and associated documentation files (the "Software"), to deal in
8 | the Software without restriction, including without limitation the rights to
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 | the Software, and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | #define _JNILOG_TAG "videomediacodec"
24 | #include "_android.h"
25 |
26 | #include
27 | #include
28 | #include "oar_video_mediacodec_java.h"
29 | #include "oarplayer_type_def.h"
30 | #include "util.h"
31 | #include "oar_video_mediacodec_ctx.h"
32 |
33 | #define _LOGD if(isDebug) LOGD
34 |
35 |
36 | void oar_video_mediacodec_start(oarplayer *oar){
37 | _LOGD("oar_video_mediacodec_start...");
38 | oar_video_mediacodec_context *ctx = oar->video_mediacodec_ctx;
39 | JNIEnv *jniEnv = ctx->jniEnv;
40 | oar_java_class * jc = oar->jc;
41 | jobject codecName = NULL, csd_0 = NULL, csd_1 = NULL;
42 | while(oar->video_render_ctx->texture_window == NULL){
43 | usleep(10000);
44 | }
45 | switch (ctx->codec_id) {
46 | case VIDEO_CODEC_AVC:
47 | codecName = (*jniEnv)->NewStringUTF(jniEnv, "video/avc");
48 | if (oar->metadata->video_extradata) {
49 | size_t sps_size, pps_size;
50 | uint8_t *sps_buf;
51 | uint8_t *pps_buf;
52 | sps_buf = (uint8_t *) malloc((size_t) oar->metadata->video_extradata_size + 20);
53 | pps_buf = (uint8_t *) malloc((size_t) oar->metadata->video_extradata_size + 20);
54 | if (0 != convert_sps_pps2(oar->metadata->video_extradata, (size_t) oar->metadata->video_extradata_size,
55 | sps_buf, &sps_size, pps_buf, &pps_size, &ctx->nal_size)) {
56 | LOGE("%s:convert_sps_pps: failed\n", __func__);
57 | }
58 | _LOGD("extradata_size = %d, sps_size = %d, pps_size = %d, nal_size = %d",
59 | (size_t) oar->metadata->video_extradata_size, sps_size, pps_size, ctx->nal_size);
60 |
61 | csd_0 = (*jniEnv)->NewDirectByteBuffer(jniEnv, sps_buf, sps_size);
62 | csd_1 = (*jniEnv)->NewDirectByteBuffer(jniEnv, pps_buf, pps_size);
63 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwDecodeBridge, jc->codec_init,
64 | codecName, ctx->width, ctx->height, csd_0, csd_1);
65 | (*jniEnv)->DeleteLocalRef(jniEnv, csd_0);
66 | (*jniEnv)->DeleteLocalRef(jniEnv, csd_1);
67 | } else {
68 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwDecodeBridge, jc->codec_init,
69 | codecName, ctx->width, ctx->height, NULL, NULL);
70 | }
71 | break;
72 |
73 | case VIDEO_CODEC_H263:
74 | codecName = (*jniEnv)->NewStringUTF(jniEnv, "video/3gpp");
75 | //TODO 解析h263格式
76 | /*csd_0 = (*jniEnv)->NewDirectByteBuffer(jniEnv, oar->metadata->video_sps, oar->metadata->video_sps_size);
77 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwDecodeBridge, jc->codec_init, codecName,
78 | ctx->width, ctx->height, csd_0, NULL);
79 | (*jniEnv)->DeleteLocalRef(jniEnv, csd_0);*/
80 | break;
81 | default:
82 | break;
83 | }
84 | if (codecName != NULL) {
85 | (*jniEnv)->DeleteLocalRef(jniEnv, codecName);
86 | }
87 | }
88 |
89 | void oar_video_mediacodec_release_buffer(oarplayer *oar, int index) {
90 | JNIEnv *jniEnv = oar->video_render_ctx->jniEnv;
91 | oar_java_class * jc = oar->jc;
92 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwDecodeBridge, jc->codec_releaseOutPutBuffer,
93 | index);
94 | }
95 |
96 | int oar_video_mediacodec_receive_frame(oarplayer *oar, OARFrame *frame) {
97 | JNIEnv *jniEnv = oar->video_mediacodec_ctx->jniEnv;
98 | oar_java_class * jc = oar->jc;
99 | oar_video_mediacodec_context *ctx = oar->video_mediacodec_ctx;
100 | int output_ret = 1;
101 | jobject deqret = (*jniEnv)->CallStaticObjectMethod(jniEnv, jc->HwDecodeBridge,
102 | jc->codec_dequeueOutputBufferIndex,
103 | (jlong) 0);
104 | uint8_t *retbuf = (*jniEnv)->GetDirectBufferAddress(jniEnv, deqret);
105 | int outbufidx = get_int(retbuf);
106 | int64_t pts = get_long(retbuf + 8);
107 | (*jniEnv)->DeleteLocalRef(jniEnv, deqret);
108 | _LOGD("oar_video_mediacodec_receive_frame outbufidx:%d" , outbufidx);
109 | if (outbufidx >= 0) {
110 | frame->type = PktType_Video;
111 | frame->pts = pts;
112 | frame->format = PIX_FMT_EGL_EXT;
113 | frame->width = oar->metadata->width;
114 | frame->height = oar->metadata->height;
115 | frame->HW_BUFFER_ID = outbufidx;
116 | frame->next=NULL;
117 | output_ret = 0;
118 | } else {
119 | switch (outbufidx) {
120 | // AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED
121 | case -2: {
122 | jobject newFormat = (*jniEnv)->CallStaticObjectMethod(jniEnv, jc->HwDecodeBridge,
123 | jc->codec_formatChange);
124 | uint8_t *fmtbuf = (*jniEnv)->GetDirectBufferAddress(jniEnv, newFormat);
125 | ctx->width = get_int(fmtbuf);
126 | ctx->height = get_int(fmtbuf + 4);
127 | int pix_format = get_int(fmtbuf + 8);
128 | (*jniEnv)->DeleteLocalRef(jniEnv, newFormat);
129 |
130 | //todo 仅支持了两种格式
131 | switch (pix_format) {
132 | case 19:
133 | ctx->pix_format = PIX_FMT_YUV420P;
134 | break;
135 | case 21:
136 | ctx->pix_format = PIX_FMT_NV12;
137 | break;
138 | default:
139 | break;
140 | }
141 | output_ret = -2;
142 | break;
143 | }
144 | // AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED
145 | case -3:
146 | break;
147 | // AMEDIACODEC_INFO_TRY_AGAIN_LATER
148 | case -1:
149 | break;
150 | default:
151 | break;
152 | }
153 |
154 | }
155 | return output_ret;
156 | }
157 |
158 | int oar_video_mediacodec_send_packet(oarplayer *oar, OARPacket *packet) {
159 | JNIEnv *jniEnv = oar->video_mediacodec_ctx->jniEnv;
160 | oar_java_class * jc = oar->jc;
161 | oar_video_mediacodec_context *ctx = oar->video_mediacodec_ctx;
162 | if (packet == NULL) { return -2; }
163 | int keyframe_flag = 0;
164 | int64_t time_stamp = packet->pts;
165 |
166 | if (ctx->codec_id == VIDEO_CODEC_AVC) {
167 | H264ConvertState convert_state = {0, 0};
168 | convert_h264_to_annexb(packet->data, packet->size, ctx->nal_size, &convert_state);
169 | }
170 | if (packet->isKeyframe) {
171 | keyframe_flag |= 0x1;
172 | }
173 | int id = (*jniEnv)->CallStaticIntMethod(jniEnv, jc->HwDecodeBridge,
174 | jc->codec_dequeueInputBuffer, (jlong) 1000000);
175 | if (id >= 0) {
176 | jobject inputBuffer = (*jniEnv)->CallStaticObjectMethod(jniEnv, jc->HwDecodeBridge,
177 | jc->codec_getInputBuffer, id);
178 | uint8_t *buf = (*jniEnv)->GetDirectBufferAddress(jniEnv, inputBuffer);
179 | jlong size = (*jniEnv)->GetDirectBufferCapacity(jniEnv, inputBuffer);
180 | if (buf != NULL && size >= packet->size) {
181 | memcpy(buf, packet->data, (size_t) packet->size);
182 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwDecodeBridge,
183 | jc->codec_queueInputBuffer,
184 | (jint) id, (jint) packet->size,
185 | (jlong) time_stamp, (jint) keyframe_flag);
186 | }
187 | (*jniEnv)->DeleteLocalRef(jniEnv, inputBuffer);
188 | } else if (id == -1) {
189 | _LOGD("dequeue inputbuffer is -1");
190 | return -1;
191 | } else {
192 | _LOGD("input buffer id < 0 value == %zd", id);
193 | }
194 | return 0;
195 | }
196 |
197 | void oar_video_mediacodec_flush(oarplayer *oar) {
198 | JNIEnv *jniEnv = oar->video_mediacodec_ctx->jniEnv;
199 | oar_java_class * jc = oar->jc;
200 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwDecodeBridge, jc->codec_flush);
201 | }
202 |
203 | void oar_video_mediacodec_release_context(oarplayer *oar) {
204 | JNIEnv *jniEnv = oar->jniEnv;
205 | oar_java_class * jc = oar->jc;
206 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwDecodeBridge, jc->codec_release);
207 | oar_video_mediacodec_context *ctx = oar->video_mediacodec_ctx;
208 | free(ctx);
209 | oar->video_mediacodec_ctx = NULL;
210 | }
211 |
212 | void oar_video_mediacodec_stop(oarplayer *oar) {
213 | JNIEnv *jniEnv = oar->video_mediacodec_ctx->jniEnv;
214 | oar_java_class * jc = oar->jc;
215 | (*jniEnv)->CallStaticVoidMethod(jniEnv, jc->HwDecodeBridge, jc->codec_stop);
216 | }
217 |
218 | //#endif
--------------------------------------------------------------------------------