├── .gitignore ├── AndroidMedia ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── frank │ └── androidmedia │ ├── controller │ ├── AudioEffectController.kt │ ├── AudioProcessController.kt │ ├── AudioRecordController.kt │ ├── AudioTrackController.kt │ ├── MediaDecodeController.kt │ ├── MediaMetadataController.kt │ ├── MediaMuxController.kt │ ├── MediaPlayController.kt │ ├── MediaProjectionController.kt │ └── MediaRecordController.kt │ ├── listener │ ├── AudioEffectCallback.kt │ ├── PlayerCallback.kt │ └── VideoEncodeCallback.kt │ ├── util │ ├── WavHeader.kt │ └── WavUtil.kt │ └── wrap │ └── AudioVisualizer.java ├── CameraFilter ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── frank │ │ └── camerafilter │ │ ├── camera │ │ └── CameraManager.java │ │ ├── factory │ │ ├── BeautyFilterFactory.java │ │ └── BeautyFilterType.java │ │ ├── filter │ │ ├── BaseFilter.java │ │ ├── BeautyCameraFilter.java │ │ └── advance │ │ │ ├── BreathCircleBeautyFilter.java │ │ │ ├── BrightnessBeautyFilter.java │ │ │ ├── ContrastBeautyFilter.java │ │ │ ├── GaussianBlurFilter.java │ │ │ ├── HueBeautyFilter.java │ │ │ ├── OverlayBeautyFilter.java │ │ │ ├── SaturationBeautyFilter.java │ │ │ ├── SharpenBeautyFilter.java │ │ │ ├── SketchBeautyFilter.java │ │ │ └── WhiteBalanceBeautyFilter.java │ │ ├── recorder │ │ ├── egl │ │ │ ├── EglCore.java │ │ │ └── EglSurfaceBase.java │ │ └── video │ │ │ ├── CameraVideoRecorder.java │ │ │ ├── VideoRecorderCore.java │ │ │ └── WindowEglSurface.java │ │ ├── util │ │ ├── OpenGLUtil.java │ │ ├── Rotation.java │ │ └── TextureRotateUtil.java │ │ └── widget │ │ ├── BeautyCameraView.java │ │ └── CameraRender.java │ └── res │ └── raw │ ├── breath_circle.glsl │ ├── brightness.glsl │ ├── contrast.glsl │ ├── default_fragment.glsl │ ├── default_vertex.glsl │ ├── frag_gaussian_blur.glsl │ ├── hue.glsl │ ├── overlay.glsl │ ├── saturation.glsl │ ├── sharpen_fragment.glsl │ ├── sharpen_vertex.glsl │ ├── sketch.glsl │ ├── vert_gaussian_blur.glsl │ └── whitebalance.glsl ├── Live ├── .gitignore ├── CMakeLists.txt ├── build.gradle ├── libs │ ├── arm64-v8a │ │ ├── libfaac.a │ │ └── libx264.a │ └── armeabi-v7a │ │ ├── libfaac.a │ │ └── libx264.a ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── cpp │ ├── AudioStream.cpp │ ├── AudioStream.h │ ├── PacketQueue.h │ ├── PushInterface.h │ ├── RtmpPusher.cpp │ ├── VideoStream.cpp │ ├── VideoStream.h │ ├── include │ │ ├── faac │ │ │ ├── faac.h │ │ │ └── faaccfg.h │ │ └── x264 │ │ │ ├── x264.h │ │ │ └── x264_config.h │ └── rtmp │ │ ├── CMakeLists.txt │ │ ├── amf.c │ │ ├── amf.h │ │ ├── bytes.h │ │ ├── dh.h │ │ ├── dhgroups.h │ │ ├── handshake.h │ │ ├── hashswf.c │ │ ├── http.h │ │ ├── log.c │ │ ├── log.h │ │ ├── parseurl.c │ │ ├── rtmp.c │ │ ├── rtmp.h │ │ └── rtmp_sys.h │ ├── java │ └── com │ │ └── frank │ │ └── live │ │ ├── LivePusherNew.java │ │ ├── camera │ │ ├── Camera2Helper.java │ │ ├── Camera2Listener.java │ │ ├── CameraHelper.java │ │ └── CameraType.java │ │ ├── listener │ │ ├── LiveStateChangeListener.java │ │ └── OnFrameDataCallback.java │ │ ├── param │ │ ├── AudioParam.java │ │ └── VideoParam.java │ │ ├── stream │ │ ├── AudioStream.java │ │ ├── VideoStream.java │ │ ├── VideoStreamBase.java │ │ └── VideoStreamNew.java │ │ └── util │ │ └── YUVUtil.java │ └── res │ ├── drawable │ └── ic_camera_switch.png │ ├── mipmap-hdpi │ ├── 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 │ ├── values-en │ └── strings.xml │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── arm64-v8a │ │ └── libffmpeg.so │ └── armeabi-v7a │ │ └── libffmpeg.so ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── cpp │ ├── CMakeLists.txt │ ├── audio_player_jni.cpp │ ├── common_media_jni.cpp │ ├── ff_audio_player.cpp │ ├── ff_audio_player.h │ ├── ff_audio_resample.cpp │ ├── ff_audio_resample.h │ ├── ff_rtmp_pusher.cpp │ ├── ff_rtmp_pusher.h │ ├── ffmpeg │ │ ├── cmdutils.c │ │ ├── cmdutils.h │ │ ├── config.h │ │ ├── ffmpeg.c │ │ ├── ffmpeg.h │ │ ├── ffmpeg_demux.c │ │ ├── ffmpeg_filter.c │ │ ├── ffmpeg_hw.c │ │ ├── ffmpeg_mux.c │ │ ├── ffmpeg_mux.h │ │ ├── ffmpeg_mux_init.c │ │ ├── ffmpeg_opt.c │ │ ├── ffprobe.c │ │ ├── ffprobe.h │ │ ├── fopen_utf8.h │ │ ├── objpool.c │ │ ├── objpool.h │ │ ├── opt_common.c │ │ ├── opt_common.h │ │ ├── sync_queue.c │ │ ├── sync_queue.h │ │ ├── thread_queue.c │ │ └── thread_queue.h │ ├── ffmpeg_cmd.c │ ├── ffmpeg_jni_define.h │ ├── ffmpeg_pusher_jni.cpp │ ├── ffprobe_cmd.cpp │ ├── include │ │ ├── arm64-v8a │ │ │ ├── libavcodec │ │ │ │ └── aarch64 │ │ │ │ │ └── mathops.h │ │ │ └── libavutil │ │ │ │ └── aarch64 │ │ │ │ └── timer.h │ │ ├── armeabi-v7a │ │ │ ├── libavcodec │ │ │ │ └── arm │ │ │ │ │ └── mathops.h │ │ │ └── libavutil │ │ │ │ └── arm │ │ │ │ └── timer.h │ │ ├── compat │ │ │ └── va_copy.h │ │ ├── lame │ │ │ └── lame.h │ │ ├── libavcodec │ │ │ ├── avcodec.h │ │ │ ├── bsf.h │ │ │ ├── codec.h │ │ │ ├── codec_desc.h │ │ │ ├── codec_id.h │ │ │ ├── codec_par.h │ │ │ ├── defs.h │ │ │ ├── jni.h │ │ │ ├── mathops.h │ │ │ ├── mediacodec.h │ │ │ ├── packet.h │ │ │ ├── version.h │ │ │ └── version_major.h │ │ ├── libavfilter │ │ │ ├── avfilter.h │ │ │ ├── buffersink.h │ │ │ ├── buffersrc.h │ │ │ ├── version.h │ │ │ └── version_major.h │ │ ├── libavformat │ │ │ ├── avformat.h │ │ │ ├── avio.h │ │ │ ├── network.h │ │ │ ├── os_support.h │ │ │ ├── url.h │ │ │ ├── version.h │ │ │ └── version_major.h │ │ ├── libavutil │ │ │ ├── ambient_viewing_environment.h │ │ │ ├── attributes.h │ │ │ ├── attributes_internal.h │ │ │ ├── audio_fifo.h │ │ │ ├── avassert.h │ │ │ ├── avconfig.h │ │ │ ├── avstring.h │ │ │ ├── avutil.h │ │ │ ├── bprint.h │ │ │ ├── bswap.h │ │ │ ├── buffer.h │ │ │ ├── channel_layout.h │ │ │ ├── common.h │ │ │ ├── cpu.h │ │ │ ├── dict.h │ │ │ ├── display.h │ │ │ ├── dovi_meta.h │ │ │ ├── error.h │ │ │ ├── eval.h │ │ │ ├── ffversion.h │ │ │ ├── fifo.h │ │ │ ├── frame.h │ │ │ ├── getenv_utf8.h │ │ │ ├── hash.h │ │ │ ├── hdr_dynamic_metadata.h │ │ │ ├── hdr_dynamic_vivid_metadata.h │ │ │ ├── hwcontext.h │ │ │ ├── hwcontext_mediacodec.h │ │ │ ├── imgutils.h │ │ │ ├── internal.h │ │ │ ├── intfloat.h │ │ │ ├── intreadwrite.h │ │ │ ├── libm.h │ │ │ ├── log.h │ │ │ ├── macros.h │ │ │ ├── mastering_display_metadata.h │ │ │ ├── mathematics.h │ │ │ ├── md5.h │ │ │ ├── mem.h │ │ │ ├── motion_vector.h │ │ │ ├── opt.h │ │ │ ├── parseutils.h │ │ │ ├── pixdesc.h │ │ │ ├── pixelutils.h │ │ │ ├── pixfmt.h │ │ │ ├── rational.h │ │ │ ├── reverse.h │ │ │ ├── samplefmt.h │ │ │ ├── spherical.h │ │ │ ├── stereo3d.h │ │ │ ├── thread.h │ │ │ ├── threadmessage.h │ │ │ ├── time.h │ │ │ ├── time_internal.h │ │ │ ├── timecode.h │ │ │ ├── timer.h │ │ │ ├── timestamp.h │ │ │ └── version.h │ │ ├── libswresample │ │ │ ├── swresample.h │ │ │ ├── version.h │ │ │ └── version_major.h │ │ └── libswscale │ │ │ ├── swscale.h │ │ │ ├── version.h │ │ │ └── version_major.h │ ├── media_transcode.cpp │ ├── metadata │ │ ├── Mutex.h │ │ ├── ffmpeg_media_retriever.c │ │ ├── ffmpeg_media_retriever.h │ │ ├── media_retriever.cpp │ │ ├── media_retriever.h │ │ ├── media_retriever_jni.cpp │ │ ├── metadata_util.c │ │ └── metadata_util.h │ ├── pcm │ │ └── pcm_process.cpp │ ├── video_cutting.cpp │ ├── video_cutting.h │ ├── video_filter.c │ ├── visualizer │ │ ├── fft.cpp │ │ ├── fft.h │ │ ├── fixed_fft.cpp │ │ ├── fixed_fft.h │ │ ├── frank_visualizer.cpp │ │ ├── frank_visualizer.h │ │ ├── frank_visualizer_jni.cpp │ │ ├── window.cpp │ │ └── window.h │ └── yuv │ │ ├── yuv_converter.cpp │ │ └── yuv_converter.h │ ├── java │ └── com │ │ └── frank │ │ └── ffmpeg │ │ ├── AudioPlayer.java │ │ ├── CommonMediaHelper.java │ │ ├── FFmpegApplication.java │ │ ├── FFmpegCmd.java │ │ ├── FFmpegPusher.java │ │ ├── VideoPlayer.java │ │ ├── activity │ │ ├── AudioEffectActivity.kt │ │ ├── AudioHandleActivity.kt │ │ ├── AudioPlayActivity.kt │ │ ├── BaseActivity.kt │ │ ├── CameraFilterActivity.kt │ │ ├── EqualizerActivity.kt │ │ ├── FilterActivity.kt │ │ ├── LiveActivity.kt │ │ ├── MainActivity.kt │ │ ├── MediaHandleActivity.kt │ │ ├── ProbeFormatActivity.kt │ │ ├── PushActivity.kt │ │ ├── VideoHandleActivity.kt │ │ └── VideoPreviewActivity.kt │ │ ├── adapter │ │ ├── EqualizerAdapter.kt │ │ ├── HorizontalAdapter.kt │ │ └── WaterfallAdapter.kt │ │ ├── effect │ │ └── FrankVisualizer.java │ │ ├── gif │ │ ├── BeautyGifEncoder.java │ │ └── HighQualityGif.kt │ │ ├── handler │ │ ├── ConnectionReceiver.kt │ │ ├── FFmpegHandler.java │ │ └── OrientationHandler.kt │ │ ├── listener │ │ ├── OnHandleListener.kt │ │ ├── OnItemClickListener.kt │ │ ├── OnLrcListener.kt │ │ ├── OnNetworkChangeListener.kt │ │ └── OnSeekBarListener.kt │ │ ├── metadata │ │ └── FFmpegMediaRetriever.java │ │ ├── model │ │ ├── AudioBean.kt │ │ ├── LrcInfo.kt │ │ ├── LrcLine.kt │ │ ├── MediaBean.kt │ │ ├── VideoBean.kt │ │ └── VideoLayout.kt │ │ ├── tool │ │ ├── JsonParseTool.kt │ │ ├── LrcLineTool.kt │ │ ├── LrcParser.kt │ │ └── UnicodeInputStream.kt │ │ ├── util │ │ ├── BitmapUtil.kt │ │ ├── ContentUtil.kt │ │ ├── FFmpegUtil.java │ │ ├── FileUtil.kt │ │ ├── FilterTypeUtil.kt │ │ ├── ImageConverter.java │ │ ├── MediaFormatIdentify.java │ │ ├── ScreenUtil.kt │ │ ├── ThreadPoolUtil.kt │ │ └── TimeUtil.kt │ │ └── view │ │ ├── LrcView.kt │ │ ├── VideoPreviewBar.kt │ │ └── VisualizerView.kt │ └── res │ ├── drawable-xhdpi │ ├── ic_camera_filter.png │ ├── ic_pause.png │ ├── ic_play.png │ └── ic_video_record.png │ ├── drawable │ ├── btn_circle.xml │ ├── btn_point.xml │ ├── btn_rect.xml │ ├── btn_rect_normal.xml │ ├── btn_rect_selected.xml │ └── white_background.xml │ ├── layout │ ├── activity_audio_effect.xml │ ├── activity_audio_handle.xml │ ├── activity_audio_play.xml │ ├── activity_camera_filter.xml │ ├── activity_equalizer.xml │ ├── activity_filter.xml │ ├── activity_live.xml │ ├── activity_main.xml │ ├── activity_media_handle.xml │ ├── activity_preview.xml │ ├── activity_probe.xml │ ├── activity_push.xml │ ├── activity_video_handle.xml │ ├── adapter_equalizer.xml │ ├── item_progress.xml │ ├── item_select.xml │ ├── item_waterfall.xml │ └── preview_video.xml │ ├── menu │ └── menu_setting.xml │ ├── mipmap-hdpi │ ├── 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 │ ├── values-en │ └── strings.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── doc ├── FFmpeg_command_line.md ├── FFmpeg_compile_shell.md ├── FFmpeg_sourcecode.md ├── JNI_develop_practice.md ├── NDK_compile_shell.md ├── multimedia_knowledge.md ├── multimedia_protocol.md ├── multimedia_work.md └── player_framework.md ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── libmp3 ├── .gitignore ├── CMakeLists.txt ├── build.gradle ├── libs │ ├── arm64-v8a │ │ └── libmp3lame.so │ └── armeabi-v7a │ │ └── libmp3lame.so ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── cpp │ ├── audio_lame.c │ └── lame.h │ ├── java │ └── com │ │ └── frank │ │ └── mp3 │ │ ├── Mp3Converter.kt │ │ ├── Mp3Lame.kt │ │ ├── Mp3LameBuilder.kt │ │ └── Mp3Lite.java │ └── res │ └── values │ └── strings.xml ├── media ├── travel.lrc └── travel.mp3 ├── picture ├── ffmpeg_group.png ├── ffmpeg_sequence.png ├── multimedia_baseline.png ├── multimedia_library.png ├── multimedia_main.png └── multimedia_work.png ├── settings.gradle └── shell ├── faac └── CMakeLists.txt ├── ffmpeg └── build_ffmpeg_one.sh ├── ios ├── build-ffmpeg-framework.sh ├── build-ffmpeg-ios.sh └── build-ffmpeg-tvos.sh ├── mp3lame └── Android.mk ├── openssl └── build_openssl.sh └── x264 └── build_x264.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | .DS_Store 5 | /build 6 | /captures 7 | /local.properties 8 | .externalNativeBuild 9 | .cxx 10 | -------------------------------------------------------------------------------- /AndroidMedia/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /AndroidMedia/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | apply plugin: 'com.android.library' 3 | //apply plugin: 'com.android.application' 4 | apply plugin: 'kotlin-android' 5 | apply plugin: 'kotlin-kapt' 6 | 7 | android { 8 | compileSdkVersion rootProject.ext.compileSdkVersion 9 | buildToolsVersion rootProject.ext.buildToolsVersion 10 | 11 | defaultConfig { 12 | minSdkVersion rootProject.ext.minSdkVersion 13 | targetSdkVersion rootProject.ext.targetSdkVersion 14 | versionCode rootProject.ext.versionCode 15 | versionName rootProject.ext.versionName 16 | // applicationId "com.frank.androidmedia" 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | compileOptions { 26 | sourceCompatibility JavaVersion.VERSION_1_8 27 | targetCompatibility JavaVersion.VERSION_1_8 28 | } 29 | } 30 | 31 | dependencies { 32 | 33 | implementation fileTree(include: ['*.jar'], dir: 'libs') 34 | implementation "androidx.appcompat:appcompat:$rootProject.appcompatVersion" 35 | implementation "androidx.recyclerview:recyclerview:$rootProject.recyclerviewVersion" 36 | implementation "androidx.core:core-ktx:$rootProject.core_ktx" 37 | implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.lifecycle_ktx" 38 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 39 | 40 | } -------------------------------------------------------------------------------- /AndroidMedia/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 -------------------------------------------------------------------------------- /AndroidMedia/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /AndroidMedia/src/main/java/com/frank/androidmedia/listener/AudioEffectCallback.kt: -------------------------------------------------------------------------------- 1 | package com.frank.androidmedia.listener 2 | 3 | import android.util.Pair 4 | import android.widget.SeekBar 5 | import java.util.ArrayList 6 | 7 | /** 8 | * The callback of AudioEffect 9 | * 10 | * @author frank 11 | * @date 2022/3/23 12 | */ 13 | interface AudioEffectCallback { 14 | 15 | fun getSeekBarList(): List? 16 | 17 | fun setEqualizerList(maxProgress: Int, equalizerList: ArrayList>) 18 | 19 | fun onFFTDataCallback(fft: ByteArray?) 20 | 21 | } -------------------------------------------------------------------------------- /AndroidMedia/src/main/java/com/frank/androidmedia/listener/PlayerCallback.kt: -------------------------------------------------------------------------------- 1 | package com.frank.androidmedia.listener 2 | 3 | /** 4 | * 5 | * @author frank 6 | * @date 2022/3/18 7 | */ 8 | interface PlayerCallback { 9 | 10 | fun onPrepare() 11 | 12 | fun onError(what :Int, extra :Int) :Boolean 13 | 14 | fun onRenderFirstFrame() 15 | 16 | fun onCompleteListener() 17 | 18 | } -------------------------------------------------------------------------------- /AndroidMedia/src/main/java/com/frank/androidmedia/listener/VideoEncodeCallback.kt: -------------------------------------------------------------------------------- 1 | package com.frank.androidmedia.listener 2 | 3 | /** 4 | * @author xufulong 5 | * @date 4/1/22 1:44 PM 6 | * @desc 7 | */ 8 | interface VideoEncodeCallback { 9 | 10 | fun onVideoEncodeData(data: ByteArray, size: Int, flag: Int, timestamp: Long) 11 | 12 | } -------------------------------------------------------------------------------- /AndroidMedia/src/main/java/com/frank/androidmedia/util/WavUtil.kt: -------------------------------------------------------------------------------- 1 | package com.frank.androidmedia.util 2 | 3 | import android.util.Log 4 | import java.io.* 5 | 6 | /** 7 | * Convert pcm to wav 8 | * 9 | * @author frank 10 | * @date 2022/3/22 11 | */ 12 | object WavUtil { 13 | 14 | fun makePCMToWAVFile(pcmPath: String?, wavPath: String?, deletePcmFile: Boolean): Boolean { 15 | val buffer: ByteArray 16 | val file = File(pcmPath) 17 | if (!file.exists()) { 18 | return false 19 | } 20 | val len = file.length().toInt() 21 | val header = WavHeader() 22 | header.riffSize = len + (44 - 8) 23 | header.formatSize = 16 24 | header.bitsPerSample = 16 25 | header.numChannels = 2 26 | header.formatTag = 0x0001 27 | header.sampleRate = 44100 28 | header.blockAlign = (header.numChannels * header.bitsPerSample / 8).toShort() 29 | header.avgBytesPerSec = header.blockAlign * header.sampleRate 30 | header.dataSize = len 31 | val h: ByteArray = try { 32 | header.header 33 | } catch (e1: IOException) { 34 | e1.message?.let { Log.e("WavUtil", it) } 35 | return false 36 | } 37 | if (h.size != 44) return false 38 | val dstFile = File(wavPath) 39 | if (dstFile.exists()) dstFile.delete() 40 | try { 41 | buffer = ByteArray(1024 * 4) 42 | val inStream: InputStream 43 | val ouStream: OutputStream 44 | ouStream = BufferedOutputStream(FileOutputStream(wavPath)) 45 | ouStream.write(h, 0, h.size) 46 | inStream = BufferedInputStream(FileInputStream(file)) 47 | var size = inStream.read(buffer) 48 | while (size != -1) { 49 | ouStream.write(buffer) 50 | size = inStream.read(buffer) 51 | } 52 | inStream.close() 53 | ouStream.close() 54 | } catch (e: IOException) { 55 | e.message?.let { Log.e("WavUtil", it) } 56 | return false 57 | } 58 | if (deletePcmFile) { 59 | file.delete() 60 | } 61 | Log.i("WavUtil", "makePCMToWAVFile success...") 62 | return true 63 | } 64 | } -------------------------------------------------------------------------------- /AndroidMedia/src/main/java/com/frank/androidmedia/wrap/AudioVisualizer.java: -------------------------------------------------------------------------------- 1 | package com.frank.androidmedia.wrap; 2 | 3 | import android.media.audiofx.Visualizer; 4 | import android.util.Log; 5 | 6 | /** 7 | * Visualizer of Audio frequency 8 | * Created by frank on 2020/10/20. 9 | */ 10 | public class AudioVisualizer { 11 | 12 | private Visualizer visualizer; 13 | 14 | public void initVisualizer(int audioSession, boolean waveform, boolean fft, Visualizer.OnDataCaptureListener dataCaptureListener) { 15 | try { 16 | visualizer = new Visualizer(audioSession); 17 | int captureSize = Visualizer.getCaptureSizeRange()[1]; 18 | int captureRate = Visualizer.getMaxCaptureRate() / 2; 19 | 20 | visualizer.setCaptureSize(captureSize); 21 | visualizer.setDataCaptureListener(dataCaptureListener, captureRate, waveform, fft); 22 | visualizer.setScalingMode(Visualizer.SCALING_MODE_NORMALIZED); 23 | visualizer.setEnabled(true); 24 | } catch (Exception e) { 25 | Log.e("AudioVisualizer", "initVisualizer error=" + e.toString()); 26 | releaseVisualizer(); 27 | } 28 | } 29 | 30 | public void releaseVisualizer() { 31 | if (visualizer != null) { 32 | int captureRate = Visualizer.getMaxCaptureRate() / 2; 33 | visualizer.setEnabled(false); 34 | visualizer.setDataCaptureListener(null, captureRate, false, false); 35 | visualizer.release(); 36 | visualizer = null; 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /CameraFilter/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /.cxx -------------------------------------------------------------------------------- /CameraFilter/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | } 4 | 5 | android { 6 | compileSdkVersion rootProject.ext.compileSdkVersion 7 | 8 | defaultConfig { 9 | minSdkVersion rootProject.ext.minSdkVersion 10 | targetSdkVersion rootProject.ext.targetSdkVersion 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | 20 | } 21 | 22 | dependencies { 23 | 24 | implementation "androidx.appcompat:appcompat:$rootProject.appcompatVersion" 25 | 26 | } -------------------------------------------------------------------------------- /CameraFilter/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 -------------------------------------------------------------------------------- /CameraFilter/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/factory/BeautyFilterFactory.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.factory; 2 | 3 | import android.content.Context; 4 | 5 | import com.frank.camerafilter.filter.advance.BreathCircleBeautyFilter; 6 | import com.frank.camerafilter.filter.advance.BrightnessBeautyFilter; 7 | import com.frank.camerafilter.filter.advance.ContrastBeautyFilter; 8 | import com.frank.camerafilter.filter.advance.GaussianBlurFilter; 9 | import com.frank.camerafilter.filter.advance.HueBeautyFilter; 10 | import com.frank.camerafilter.filter.advance.OverlayBeautyFilter; 11 | import com.frank.camerafilter.filter.advance.SharpenBeautyFilter; 12 | import com.frank.camerafilter.filter.advance.SketchBeautyFilter; 13 | import com.frank.camerafilter.filter.BaseFilter; 14 | import com.frank.camerafilter.filter.advance.WhiteBalanceBeautyFilter; 15 | import com.frank.camerafilter.filter.advance.SaturationBeautyFilter; 16 | 17 | public class BeautyFilterFactory { 18 | 19 | private static BeautyFilterType filterType = BeautyFilterType.NONE; 20 | 21 | public static BaseFilter getFilter(BeautyFilterType type, Context context) { 22 | filterType = type; 23 | switch (type) { 24 | case BRIGHTNESS: 25 | return new BrightnessBeautyFilter(context); 26 | case SATURATION: 27 | return new SaturationBeautyFilter(context); 28 | case CONTRAST: 29 | return new ContrastBeautyFilter(context); 30 | case SHARPEN: 31 | return new SharpenBeautyFilter(context); 32 | case SKETCH: 33 | return new SketchBeautyFilter(context); 34 | case BLUR: 35 | return new GaussianBlurFilter(context); 36 | case HUE: 37 | return new HueBeautyFilter(context); 38 | case WHITE_BALANCE: 39 | return new WhiteBalanceBeautyFilter(context); 40 | case OVERLAY: 41 | return new OverlayBeautyFilter(context); 42 | case BREATH_CIRCLE: 43 | return new BreathCircleBeautyFilter(context); 44 | default: 45 | return null; 46 | } 47 | } 48 | 49 | public static BeautyFilterType getFilterType() { 50 | return filterType; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/factory/BeautyFilterType.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.factory; 2 | 3 | public enum BeautyFilterType { 4 | NONE, 5 | BRIGHTNESS, 6 | SATURATION, 7 | CONTRAST, 8 | SHARPEN, 9 | BLUR, 10 | HUE, 11 | WHITE_BALANCE, 12 | SKETCH, 13 | OVERLAY, 14 | BREATH_CIRCLE 15 | } 16 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/BreathCircleBeautyFilter.java: -------------------------------------------------------------------------------- 1 | 2 | package com.frank.camerafilter.filter.advance; 3 | 4 | import android.content.Context; 5 | import android.opengl.GLES30; 6 | 7 | import com.frank.camerafilter.R; 8 | import com.frank.camerafilter.filter.BaseFilter; 9 | import com.frank.camerafilter.util.OpenGLUtil; 10 | 11 | public class BreathCircleBeautyFilter extends BaseFilter { 12 | 13 | private static final float BREATH_PERIOD = 3_000_000f; 14 | 15 | private static final float centerX = 0.5f; 16 | private static final float centerY = 0.5f; 17 | private static final float minInnerRadius = 0.0f; 18 | private static final float maxInnerRadius = 0.8f; 19 | private static final float outerRadius = 0.8f; 20 | 21 | private int uInnerRadius; 22 | private long startTime; 23 | 24 | private final float deltaInnerRadius; 25 | 26 | public BreathCircleBeautyFilter(Context context) { 27 | super(NORMAL_VERTEX_SHADER, OpenGLUtil.readShaderFromSource(context, R.raw.breath_circle)); 28 | 29 | this.deltaInnerRadius = maxInnerRadius - minInnerRadius; 30 | } 31 | 32 | @Override 33 | protected void onInit() { 34 | super.onInit(); 35 | 36 | startTime = System.currentTimeMillis(); 37 | 38 | int uCenter = GLES30.glGetUniformLocation(getProgramId(), "uCenter"); 39 | uInnerRadius = GLES30.glGetUniformLocation(getProgramId(), "uInnerRadius"); 40 | int uOuterRadius = GLES30.glGetUniformLocation(getProgramId(), "uOuterRadius"); 41 | 42 | setFloat(uOuterRadius, outerRadius); 43 | setFloatVec2(uCenter, new float[] {centerX, centerY}); 44 | } 45 | 46 | @Override 47 | protected void onDrawArrayBefore() { 48 | super.onDrawArrayBefore(); 49 | long currentTimeUs = (System.currentTimeMillis() - startTime) * 1000; 50 | double theta = currentTimeUs * 2 * Math.PI / BREATH_PERIOD; 51 | float innerRadius = minInnerRadius + deltaInnerRadius * (0.5f - 0.5f * (float) Math.cos(theta)); 52 | setFloat(uInnerRadius, innerRadius); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/BrightnessBeautyFilter.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.filter.advance; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES30; 5 | 6 | import com.frank.camerafilter.R; 7 | import com.frank.camerafilter.filter.BaseFilter; 8 | import com.frank.camerafilter.util.OpenGLUtil; 9 | 10 | public class BrightnessBeautyFilter extends BaseFilter { 11 | 12 | private int brightness; 13 | 14 | public BrightnessBeautyFilter(Context context) { 15 | super(NORMAL_VERTEX_SHADER, OpenGLUtil.readShaderFromSource(context, R.raw.brightness)); 16 | } 17 | 18 | protected void onInit() { 19 | super.onInit(); 20 | brightness = GLES30.glGetUniformLocation(getProgramId(), "brightness"); 21 | } 22 | 23 | protected void onInitialized() { 24 | super.onInitialized(); 25 | setFloat(brightness, 0.3f); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/ContrastBeautyFilter.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.filter.advance; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES30; 5 | 6 | import com.frank.camerafilter.R; 7 | import com.frank.camerafilter.filter.BaseFilter; 8 | import com.frank.camerafilter.util.OpenGLUtil; 9 | 10 | public class ContrastBeautyFilter extends BaseFilter { 11 | 12 | private int contrast; 13 | 14 | public ContrastBeautyFilter(Context context) { 15 | super(NORMAL_VERTEX_SHADER, OpenGLUtil.readShaderFromSource(context, R.raw.contrast)); 16 | } 17 | 18 | protected void onInit() { 19 | super.onInit(); 20 | contrast = GLES30.glGetUniformLocation(getProgramId(), "contrast"); 21 | } 22 | 23 | protected void onInitialized() { 24 | super.onInitialized(); 25 | setFloat(contrast, 1.5f); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/GaussianBlurFilter.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.filter.advance; 2 | 3 | 4 | import android.content.Context; 5 | import android.opengl.GLES30; 6 | 7 | import com.frank.camerafilter.R; 8 | import com.frank.camerafilter.filter.BaseFilter; 9 | import com.frank.camerafilter.util.OpenGLUtil; 10 | 11 | /** 12 | * @author xufulong 13 | * @date 2023/7/9 9:06 PM 14 | */ 15 | 16 | public class GaussianBlurFilter extends BaseFilter { 17 | 18 | private float blurSize = 1.5f; 19 | 20 | private int blurRadius; 21 | private int blurCenter; 22 | private int aspectRatio; 23 | 24 | private int textureWidthOffset; 25 | 26 | private int textureHeightOffset; 27 | 28 | public GaussianBlurFilter(Context context) { 29 | super(OpenGLUtil.readShaderFromSource(context, R.raw.vert_gaussian_blur), 30 | OpenGLUtil.readShaderFromSource(context, R.raw.frag_gaussian_blur)); 31 | } 32 | 33 | protected void onInit() { 34 | super.onInit(); 35 | blurRadius = GLES30.glGetUniformLocation(getProgramId(), "blurRadius"); 36 | blurCenter = GLES30.glGetUniformLocation(getProgramId(), "blurCenter"); 37 | aspectRatio = GLES30.glGetUniformLocation(getProgramId(), "aspectRatio"); 38 | textureWidthOffset = GLES30.glGetUniformLocation(getProgramId(), "textureWidthOffset"); 39 | textureHeightOffset = GLES30.glGetUniformLocation(getProgramId(), "textureHeightOffset"); 40 | } 41 | 42 | protected void onInitialized() { 43 | super.onInitialized(); 44 | setFloat(blurRadius, 1.0f); 45 | setFloatVec2(blurCenter, new float[]{0.5f, 0.5f}); 46 | } 47 | 48 | @Override 49 | public void onInputSizeChanged(int width, int height) { 50 | super.onInputSizeChanged(width, height); 51 | float ratio = (float) (height / width); 52 | setFloat(aspectRatio, ratio); 53 | setFloat(textureWidthOffset, blurSize / width); 54 | setFloat(textureHeightOffset, blurSize / height); 55 | } 56 | 57 | public void setBlurSize(float blurSize) { 58 | this.blurSize = blurSize; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/HueBeautyFilter.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.filter.advance; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES30; 5 | 6 | import com.frank.camerafilter.R; 7 | import com.frank.camerafilter.filter.BaseFilter; 8 | import com.frank.camerafilter.util.OpenGLUtil; 9 | 10 | public class HueBeautyFilter extends BaseFilter { 11 | 12 | private int hueAdjust; 13 | 14 | public HueBeautyFilter(Context context) { 15 | super(NORMAL_VERTEX_SHADER, OpenGLUtil.readShaderFromSource(context, R.raw.hue)); 16 | } 17 | 18 | protected void onInit() { 19 | super.onInit(); 20 | hueAdjust = GLES30.glGetUniformLocation(getProgramId(), "hueAdjust"); 21 | } 22 | 23 | protected void onInitialized() { 24 | super.onInitialized(); 25 | setFloat(hueAdjust, 3.0f); 26 | } 27 | 28 | @Override 29 | public void onInputSizeChanged(int width, int height) { 30 | super.onInputSizeChanged(width, height); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/SaturationBeautyFilter.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.filter.advance; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES30; 5 | 6 | import com.frank.camerafilter.R; 7 | import com.frank.camerafilter.filter.BaseFilter; 8 | import com.frank.camerafilter.util.OpenGLUtil; 9 | 10 | public class SaturationBeautyFilter extends BaseFilter { 11 | 12 | private int saturation; 13 | 14 | public SaturationBeautyFilter(Context context) { 15 | super(NORMAL_VERTEX_SHADER, OpenGLUtil.readShaderFromSource(context, R.raw.saturation)); 16 | } 17 | 18 | protected void onInit() { 19 | super.onInit(); 20 | saturation = GLES30.glGetUniformLocation(getProgramId(), "saturation"); 21 | } 22 | 23 | protected void onInitialized() { 24 | super.onInitialized(); 25 | setFloat(saturation, 1.8f); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/SharpenBeautyFilter.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.filter.advance; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES30; 5 | 6 | import com.frank.camerafilter.R; 7 | import com.frank.camerafilter.filter.BaseFilter; 8 | import com.frank.camerafilter.util.OpenGLUtil; 9 | 10 | public class SharpenBeautyFilter extends BaseFilter { 11 | // -4.0-4.0 12 | private static final float mSharpness = 2.8f; 13 | private int mSharpenLocation; 14 | private int mImageWidthLocation; 15 | private int mImageHeightLocation; 16 | 17 | public SharpenBeautyFilter(Context context) { 18 | super(OpenGLUtil.readShaderFromSource(context, R.raw.sharpen_vertex), 19 | OpenGLUtil.readShaderFromSource(context, R.raw.sharpen_fragment)); 20 | } 21 | 22 | protected void onInit() { 23 | super.onInit(); 24 | mSharpenLocation = GLES30.glGetUniformLocation(getProgramId(), "sharpen"); 25 | mImageWidthLocation = GLES30.glGetUniformLocation(getProgramId(), "imageWidthFactor"); 26 | mImageHeightLocation = GLES30.glGetUniformLocation(getProgramId(), "imageHeightFactor"); 27 | } 28 | 29 | protected void onInitialized() { 30 | super.onInitialized(); 31 | setFloat(mSharpenLocation, mSharpness); 32 | } 33 | 34 | @Override 35 | public void onInputSizeChanged(int width, int height) { 36 | super.onInputSizeChanged(width, height); 37 | setFloat(mImageWidthLocation, 1.0f / width); 38 | setFloat(mImageHeightLocation, 1.0f / height); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/SketchBeautyFilter.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.filter.advance; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES30; 5 | 6 | import com.frank.camerafilter.R; 7 | import com.frank.camerafilter.filter.BaseFilter; 8 | import com.frank.camerafilter.util.OpenGLUtil; 9 | 10 | public class SketchBeautyFilter extends BaseFilter { 11 | 12 | private int strengthLocation; 13 | private int stepOffsetLocation; 14 | 15 | public SketchBeautyFilter(Context context) { 16 | super(NORMAL_VERTEX_SHADER, OpenGLUtil.readShaderFromSource(context, R.raw.sketch)); 17 | } 18 | 19 | protected void onInit() { 20 | super.onInit(); 21 | strengthLocation = GLES30.glGetUniformLocation(getProgramId(), "strength"); 22 | stepOffsetLocation = GLES30.glGetUniformLocation(getProgramId(), "singleStepOffset"); 23 | } 24 | 25 | @Override 26 | protected void onInitialized() { 27 | super.onInitialized(); 28 | setFloat(strengthLocation, 0.5f); 29 | } 30 | 31 | @Override 32 | public void onInputSizeChanged(int width, int height) { 33 | super.onInputSizeChanged(width, height); 34 | setFloatVec2(stepOffsetLocation, new float[] {1.0f / width, 1.0f / height}); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/WhiteBalanceBeautyFilter.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.filter.advance; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES30; 5 | 6 | import com.frank.camerafilter.R; 7 | import com.frank.camerafilter.filter.BaseFilter; 8 | import com.frank.camerafilter.util.OpenGLUtil; 9 | 10 | public class WhiteBalanceBeautyFilter extends BaseFilter { 11 | 12 | private int tint; 13 | private int temperature; 14 | 15 | public WhiteBalanceBeautyFilter(Context context) { 16 | super(NORMAL_VERTEX_SHADER, OpenGLUtil.readShaderFromSource(context, R.raw.whitebalance)); 17 | } 18 | 19 | protected void onInit() { 20 | super.onInit(); 21 | tint = GLES30.glGetUniformLocation(getProgramId(), "tint"); 22 | temperature = GLES30.glGetUniformLocation(getProgramId(), "temperature"); 23 | } 24 | 25 | protected void onInitialized() { 26 | super.onInitialized(); 27 | setFloat(tint, 0.5f); 28 | setFloat(temperature, 0.3f); 29 | } 30 | 31 | @Override 32 | public void onInputSizeChanged(int width, int height) { 33 | super.onInputSizeChanged(width, height); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/recorder/video/WindowEglSurface.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.recorder.video; 2 | 3 | import android.view.Surface; 4 | 5 | import com.frank.camerafilter.recorder.egl.EglCore; 6 | import com.frank.camerafilter.recorder.egl.EglSurfaceBase; 7 | 8 | /** 9 | * @author xufulong 10 | * @date 2022/6/23 9:15 上午 11 | * @desc 12 | */ 13 | public class WindowEglSurface extends EglSurfaceBase { 14 | 15 | private Surface mSurface; 16 | private boolean mReleaseSurface; 17 | 18 | public WindowEglSurface(EglCore eglCore, Surface surface) { 19 | this(eglCore, surface, false); 20 | } 21 | 22 | public WindowEglSurface(EglCore eglCore, Surface surface, boolean releaseSurface) { 23 | super(eglCore); 24 | createWindowSurface(surface); 25 | mSurface = surface; 26 | mReleaseSurface = releaseSurface; 27 | } 28 | 29 | public void release() { 30 | releaseEglSurface(); 31 | if (mSurface != null && mReleaseSurface) { 32 | mSurface.release(); 33 | } 34 | mSurface = null; 35 | } 36 | 37 | public void recreate(EglCore newEglCore) { 38 | if (mSurface == null) { 39 | throw new RuntimeException("Surface is null"); 40 | } 41 | mEglCore = newEglCore; 42 | createWindowSurface(mSurface); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/util/Rotation.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.util; 2 | 3 | public enum Rotation { 4 | 5 | NORMAL, ROTATION_90, ROTATION_180, ROTATION_270; 6 | 7 | public int toInt() { 8 | switch (this) { 9 | case NORMAL: 10 | return 0; 11 | case ROTATION_90: 12 | return 90; 13 | case ROTATION_180: 14 | return 180; 15 | case ROTATION_270: 16 | return 270; 17 | default: 18 | throw new IllegalStateException("unknown rotation value..."); 19 | } 20 | } 21 | 22 | public static Rotation fromInt(int rotation) { 23 | switch (rotation) { 24 | case 0: 25 | return NORMAL; 26 | case 90: 27 | return ROTATION_90; 28 | case 180: 29 | return ROTATION_180; 30 | case 270: 31 | return ROTATION_270; 32 | default: 33 | throw new IllegalStateException("unknown rotation=" +rotation); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /CameraFilter/src/main/java/com/frank/camerafilter/widget/BeautyCameraView.java: -------------------------------------------------------------------------------- 1 | package com.frank.camerafilter.widget; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLSurfaceView; 5 | import android.util.AttributeSet; 6 | import android.view.SurfaceHolder; 7 | 8 | import com.frank.camerafilter.factory.BeautyFilterType; 9 | 10 | public class BeautyCameraView extends GLSurfaceView { 11 | 12 | private final CameraRender mCameraRender; 13 | 14 | public BeautyCameraView(Context context) { 15 | this(context, null); 16 | } 17 | 18 | public BeautyCameraView(Context context, AttributeSet attrs) { 19 | super(context, attrs); 20 | getHolder().addCallback(this); 21 | 22 | mCameraRender = new CameraRender(this); 23 | setEGLContextClientVersion(3); 24 | setRenderer(mCameraRender); 25 | setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); 26 | } 27 | 28 | @Override 29 | public void surfaceDestroyed(SurfaceHolder holder) { 30 | super.surfaceDestroyed(holder); 31 | if (mCameraRender != null) { 32 | mCameraRender.releaseCamera(); 33 | } 34 | } 35 | 36 | public void switchCamera() { 37 | if (mCameraRender != null) { 38 | mCameraRender.switchCamera(); 39 | } 40 | } 41 | 42 | public void setFilter(BeautyFilterType type) { 43 | if (mCameraRender == null) 44 | return; 45 | mCameraRender.setFilter(type); 46 | } 47 | 48 | public void setRecording(boolean isRecording) { 49 | if (mCameraRender == null) 50 | return; 51 | mCameraRender.setRecording(isRecording); 52 | } 53 | 54 | public boolean isRecording() { 55 | if (mCameraRender == null) 56 | return false; 57 | return mCameraRender.isRecording(); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/breath_circle.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | varying highp vec2 textureCoordinate; 4 | 5 | uniform sampler2D inputImageTexture; 6 | uniform vec2 uCenter; 7 | uniform float uInnerRadius; 8 | uniform float uOuterRadius; 9 | 10 | void main() { 11 | vec3 textureColor = texture2D(inputImageTexture, textureCoordinate).rgb; 12 | 13 | float dist = distance(textureCoordinate, uCenter); 14 | float scale = clamp(1.0 - (dist - uInnerRadius) / (uOuterRadius - uInnerRadius), 0.0, 1.0); 15 | 16 | gl_FragColor = vec4(textureColor.r * scale, textureColor.g * scale, textureColor.b * scale, 1.0); 17 | } -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/brightness.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | varying vec2 textureCoordinate; 4 | 5 | uniform sampler2D inputImageTexture; 6 | uniform float brightness; 7 | 8 | void main() { 9 | vec3 textureColor = texture2D(inputImageTexture, textureCoordinate).rgb; 10 | 11 | gl_FragColor = vec4(textureColor.rgb + vec3(brightness), 1.0); 12 | } -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/contrast.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | varying vec2 textureCoordinate; 4 | 5 | uniform sampler2D inputImageTexture; 6 | uniform float contrast; 7 | 8 | const vec3 halfColor = vec3(0.5); 9 | 10 | void main() { 11 | vec3 textureColor = texture2D(inputImageTexture, textureCoordinate).rgb; 12 | vec3 outputColor = (textureColor - halfColor) * contrast + halfColor; 13 | gl_FragColor = vec4(outputColor, 1.0); 14 | } -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/default_fragment.glsl: -------------------------------------------------------------------------------- 1 | #extension GL_OES_EGL_image_external : require 2 | 3 | precision mediump float; 4 | 5 | varying mediump vec2 textureCoordinate; 6 | 7 | uniform samplerExternalOES inputImageTexture; 8 | 9 | void main(){ 10 | vec2 xy = textureCoordinate.xy; 11 | // two screen(0.25~0.75) 12 | // if (xy.x <= 0.5) { 13 | // xy.x += 0.25; 14 | // } else { 15 | // xy.x -= 0.25; 16 | // } 17 | // four screen 18 | // if (xy.x <= 0.5) { 19 | // xy.x = xy.x * 2.0; 20 | // } else { 21 | // xy.x = (xy.x - 0.5) * 2.0; 22 | // } 23 | // if (xy.y <= 0.5) { 24 | // xy.y = xy.y * 2.0; 25 | // } else { 26 | // xy.y = (xy.y - 0.5) * 2.0; 27 | // } 28 | // white black 29 | // const vec3 weight = vec3(0.3, 0.59, 0.11); 30 | // float gray = dot(textureColor.rgb, weight); 31 | // invert 32 | // 1.0 - textureColor.rgb 33 | // mirror 34 | // if (xy.x <= 0.5) { 35 | // xy.x += 0.25; 36 | // } else { 37 | // xy.x -= 0.25; 38 | // xy.x = 1.0 - xy.x; 39 | // } 40 | 41 | vec3 textureColor = texture2D(inputImageTexture, xy).rgb; 42 | gl_FragColor = vec4(textureColor.rgb,1.0); 43 | } -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/default_vertex.glsl: -------------------------------------------------------------------------------- 1 | attribute vec4 position; 2 | attribute vec4 inputTextureCoordinate; 3 | 4 | uniform mat4 textureTransform; 5 | varying vec2 textureCoordinate; 6 | 7 | void main() 8 | { 9 | textureCoordinate = (textureTransform * inputTextureCoordinate).xy; 10 | gl_Position = position; 11 | } 12 | -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/frag_gaussian_blur.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | const int GAUSSIAN_SAMPLES = 9; 4 | 5 | varying vec2 textureCoordinate; 6 | varying vec2 blurCoordinates[GAUSSIAN_SAMPLES]; 7 | 8 | uniform vec2 blurCenter; 9 | uniform float blurRadius; 10 | uniform float aspectRatio; 11 | uniform sampler2D inputImageTexture; 12 | 13 | void main() { 14 | vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); 15 | float dist = distance(blurCenter, textureCoordinateToUse); 16 | 17 | if (dist < blurRadius) { 18 | vec4 sum = vec4(0.0); 19 | 20 | sum += texture2D(inputImageTexture, blurCoordinates[0]) * 0.05; 21 | sum += texture2D(inputImageTexture, blurCoordinates[1]) * 0.09; 22 | sum += texture2D(inputImageTexture, blurCoordinates[2]) * 0.12; 23 | sum += texture2D(inputImageTexture, blurCoordinates[3]) * 0.15; 24 | sum += texture2D(inputImageTexture, blurCoordinates[4]) * 0.18; 25 | sum += texture2D(inputImageTexture, blurCoordinates[5]) * 0.15; 26 | sum += texture2D(inputImageTexture, blurCoordinates[6]) * 0.12; 27 | sum += texture2D(inputImageTexture, blurCoordinates[7]) * 0.09; 28 | sum += texture2D(inputImageTexture, blurCoordinates[8]) * 0.05; 29 | 30 | gl_FragColor = sum; 31 | } else { 32 | gl_FragColor = texture2D(inputImageTexture, textureCoordinate); 33 | } 34 | } -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/hue.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | varying highp vec2 textureCoordinate; 3 | 4 | uniform sampler2D inputImageTexture; 5 | uniform mediump float hueAdjust; 6 | const highp vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0); 7 | const highp vec4 kRGBToI = vec4 (0.595716, -0.274453, -0.321263, 0.0); 8 | const highp vec4 kRGBToQ = vec4 (0.211456, -0.522591, 0.31135, 0.0); 9 | 10 | const highp vec4 kYIQToR = vec4 (1.0, 0.9563, 0.6210, 0.0); 11 | const highp vec4 kYIQToG = vec4 (1.0, -0.2721, -0.6474, 0.0); 12 | const highp vec4 kYIQToB = vec4 (1.0, -1.1070, 1.7046, 0.0); 13 | 14 | void main () 15 | { 16 | // Sample the input pixel 17 | highp vec4 color = texture2D(inputImageTexture, textureCoordinate); 18 | 19 | // Convert to YIQ 20 | highp float YPrime = dot (color, kRGBToYPrime); 21 | highp float I = dot (color, kRGBToI); 22 | highp float Q = dot (color, kRGBToQ); 23 | 24 | // Calculate the hue and chroma 25 | highp float hue = atan (Q, I); 26 | highp float chroma = sqrt (I * I + Q * Q); 27 | 28 | // Make the user's adjustments 29 | hue += (-hueAdjust); //why negative rotation? 30 | 31 | // Convert back to YIQ 32 | Q = chroma * sin (hue); 33 | I = chroma * cos (hue); 34 | 35 | // Convert back to RGB 36 | highp vec4 yIQ = vec4 (YPrime, I, Q, 0.0); 37 | color.r = dot (yIQ, kYIQToR); 38 | color.g = dot (yIQ, kYIQToG); 39 | color.b = dot (yIQ, kYIQToB); 40 | 41 | // Save the result 42 | gl_FragColor = color; 43 | } -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/overlay.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | varying highp vec2 textureCoordinate; 4 | 5 | uniform sampler2D inputImageTexture; 6 | uniform sampler2D overlayTexture; 7 | 8 | void main() 9 | { 10 | vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); 11 | vec4 overlayColor = texture2D(overlayTexture, textureCoordinate); 12 | 13 | gl_FragColor = mix(textureColor, overlayColor, overlayColor.a); 14 | } -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/saturation.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | varying vec2 textureCoordinate; 4 | 5 | uniform sampler2D inputImageTexture; 6 | uniform float saturation; 7 | 8 | const vec3 lumaWeight = vec3(0.2125, 0.7154, 0.0721); 9 | 10 | void main() { 11 | vec3 textureColor = texture2D(inputImageTexture, textureCoordinate).rgb; 12 | float luma = dot(textureColor, lumaWeight); 13 | vec3 lumaColor = vec3(luma); 14 | vec3 outputColor = mix(lumaColor, textureColor, saturation); 15 | gl_FragColor = vec4(outputColor, 1.0); 16 | } -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/sharpen_fragment.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | varying vec2 textureCoordinate; 4 | varying vec2 leftTextureCoordinate; 5 | varying vec2 rightTextureCoordinate; 6 | varying vec2 topTextureCoordinate; 7 | varying vec2 bottomTextureCoordinate; 8 | varying float centerMultiplier; 9 | varying float edgeMultiplier; 10 | 11 | uniform sampler2D inputImageTexture; 12 | 13 | void main() { 14 | vec3 textureColor = texture2D(inputImageTexture, textureCoordinate).rgb; 15 | vec3 leftTextureColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb; 16 | vec3 rightTextureColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb; 17 | vec3 topTextureColor = texture2D(inputImageTexture, topTextureCoordinate).rgb; 18 | vec3 bottomTextureColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb; 19 | 20 | gl_FragColor = vec4((textureColor * centerMultiplier - 21 | ((leftTextureColor+rightTextureColor+topTextureColor+bottomTextureColor)* edgeMultiplier)), 22 | texture2D(inputImageTexture, bottomTextureCoordinate).w); 23 | } -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/sharpen_vertex.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | attribute vec4 position; 4 | attribute vec4 inputTextureCoordinate; 5 | 6 | varying vec2 textureCoordinate; 7 | varying vec2 leftTextureCoordinate; 8 | varying vec2 rightTextureCoordinate; 9 | varying vec2 topTextureCoordinate; 10 | varying vec2 bottomTextureCoordinate; 11 | 12 | varying float centerMultiplier; 13 | varying float edgeMultiplier; 14 | uniform float imageWidthFactor; 15 | uniform float imageHeightFactor; 16 | uniform float sharpness; 17 | 18 | void main() { 19 | gl_Position = position; 20 | vec2 width = vec2(imageWidthFactor, 0.0); 21 | vec2 height = vec2(0.0, imageHeightFactor); 22 | 23 | textureCoordinate = inputTextureCoordinate.xy; 24 | leftTextureCoordinate = inputTextureCoordinate.xy - width; 25 | rightTextureCoordinate = inputTextureCoordinate.xy + width; 26 | topTextureCoordinate = inputTextureCoordinate.xy + height; 27 | bottomTextureCoordinate = inputTextureCoordinate.xy - height; 28 | 29 | centerMultiplier = 1.0 + 4.0 * sharpness; 30 | edgeMultiplier = sharpness; 31 | } -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/sketch.glsl: -------------------------------------------------------------------------------- 1 | varying highp vec2 textureCoordinate; 2 | precision mediump float; 3 | 4 | uniform sampler2D inputImageTexture; 5 | uniform vec2 singleStepOffset; 6 | uniform float strength; 7 | 8 | const highp vec3 W = vec3(0.299, 0.587, 0.114); 9 | 10 | 11 | void main() 12 | { 13 | float threshold = 0.0; 14 | //pic1 15 | vec4 oralColor = texture2D(inputImageTexture, textureCoordinate); 16 | //pic2 17 | vec3 maxValue = vec3(0., 0., 0.); 18 | 19 | for (int i = -2; i<=2; i++) 20 | { 21 | for (int j = -2; j<=2; j++) 22 | { 23 | vec4 tempColor = texture2D(inputImageTexture, textureCoordinate+singleStepOffset*vec2(i, j)); 24 | maxValue.r = max(maxValue.r, tempColor.r); 25 | maxValue.g = max(maxValue.g, tempColor.g); 26 | maxValue.b = max(maxValue.b, tempColor.b); 27 | threshold += dot(tempColor.rgb, W); 28 | } 29 | } 30 | //pic3 31 | float gray1 = dot(oralColor.rgb, W); 32 | //pic4 33 | float gray2 = dot(maxValue, W); 34 | //pic5 35 | float contour = gray1 / gray2; 36 | 37 | threshold = threshold / 25.; 38 | float alpha = max(1.0, gray1>threshold?1.0:(gray1/threshold)); 39 | 40 | float result = contour * alpha + (1.0-alpha)*gray1; 41 | 42 | gl_FragColor = vec4(vec3(result, result, result), oralColor.w); 43 | } -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/vert_gaussian_blur.glsl: -------------------------------------------------------------------------------- 1 | attribute vec4 position; 2 | attribute vec4 inputTextureCoordinate; 3 | 4 | const int GAUSSIAN_SAMPLES = 9; 5 | 6 | varying vec2 textureCoordinate; 7 | varying vec2 blurCoordinates[GAUSSIAN_SAMPLES]; 8 | 9 | uniform float textureWidthOffset; 10 | uniform float textureHeightOffset; 11 | 12 | void main() { 13 | gl_Position = position; 14 | textureCoordinate = inputTextureCoordinate.xy; 15 | 16 | // Calculate the position of blur 17 | vec2 blurStep; 18 | int multiplier = 0; 19 | vec2 singleStepOffset = vec2(textureWidthOffset, textureHeightOffset); 20 | 21 | for (int i = 0; i < GAUSSIAN_SAMPLES; i++) { 22 | multiplier = (i - ((GAUSSIAN_SAMPLES - 1) / 2)); 23 | // Blur in x (horizontal) 24 | blurStep = float(multiplier) * singleStepOffset; 25 | blurCoordinates[i] = inputTextureCoordinate.xy + blurStep; 26 | } 27 | } -------------------------------------------------------------------------------- /CameraFilter/src/main/res/raw/whitebalance.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D inputImageTexture; 2 | varying highp vec2 textureCoordinate; 3 | 4 | uniform lowp float temperature; 5 | uniform lowp float tint; 6 | 7 | const lowp vec3 warmFilter = vec3(0.93, 0.54, 0.0); 8 | 9 | const mediump mat3 RGBtoYIQ = mat3(0.299, 0.587, 0.114, 0.596, -0.274, -0.322, 0.212, -0.523, 0.311); 10 | const mediump mat3 YIQtoRGB = mat3(1.0, 0.956, 0.621, 1.0, -0.272, -0.647, 1.0, -1.105, 1.702); 11 | 12 | void main() 13 | { 14 | lowp vec4 source = texture2D(inputImageTexture, textureCoordinate); 15 | 16 | mediump vec3 yiq = RGBtoYIQ * source.rgb; //adjusting tint 17 | yiq.b = clamp(yiq.b + tint*0.5226*0.1, -0.5226, 0.5226); 18 | lowp vec3 rgb = YIQtoRGB * yiq; 19 | 20 | lowp vec3 processed = vec3( 21 | (rgb.r < 0.5 ? (2.0 * rgb.r * warmFilter.r) : (1.0 - 2.0 * (1.0 - rgb.r) * (1.0 - warmFilter.r))), //adjusting temperature 22 | (rgb.g < 0.5 ? (2.0 * rgb.g * warmFilter.g) : (1.0 - 2.0 * (1.0 - rgb.g) * (1.0 - warmFilter.g))), 23 | (rgb.b < 0.5 ? (2.0 * rgb.b * warmFilter.b) : (1.0 - 2.0 * (1.0 - rgb.b) * (1.0 - warmFilter.b)))); 24 | 25 | gl_FragColor = vec4(mix(rgb, processed, temperature), source.a); 26 | } -------------------------------------------------------------------------------- /Live/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Live/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 | set(distribution_DIR ${CMAKE_SOURCE_DIR}/../../../../libs) 8 | 9 | add_library(faac 10 | STATIC 11 | IMPORTED) 12 | set_target_properties(faac 13 | PROPERTIES IMPORTED_LOCATION 14 | ../../../../libs/${CMAKE_ANDROID_ARCH_ABI}/libfaac.a) 15 | 16 | add_subdirectory(src/main/cpp/rtmp) 17 | #add_library(rtmp 18 | # STATIC 19 | # IMPORTED) 20 | #set_target_properties(rtmp 21 | # PROPERTIES IMPORTED_LOCATION 22 | # ../../../../libs/${CMAKE_ANDROID_ARCH_ABI}/librtmp.a) 23 | 24 | add_library(x264 25 | STATIC 26 | IMPORTED) 27 | set_target_properties(x264 28 | PROPERTIES IMPORTED_LOCATION 29 | ../../../../libs/${CMAKE_ANDROID_ARCH_ABI}/libx264.a) 30 | 31 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") 32 | 33 | include_directories(src/main/cpp/include) 34 | 35 | add_library(live 36 | SHARED 37 | src/main/cpp/AudioStream.cpp 38 | src/main/cpp/VideoStream.cpp 39 | src/main/cpp/RtmpPusher.cpp) 40 | 41 | find_library( log-lib 42 | log ) 43 | 44 | target_link_libraries(live x264 faac rtmp 45 | -landroid 46 | -ljnigraphics 47 | ${log-lib} ) -------------------------------------------------------------------------------- /Live/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.compileSdkVersion 5 | buildToolsVersion rootProject.ext.buildToolsVersion 6 | defaultConfig { 7 | minSdkVersion rootProject.ext.minSdkVersion 8 | targetSdkVersion rootProject.ext.targetSdkVersion 9 | versionCode rootProject.ext.versionCode 10 | versionName rootProject.ext.versionName 11 | externalNativeBuild { 12 | cmake { 13 | cppFlags "" 14 | } 15 | } 16 | ndk{ 17 | abiFilters /*"armeabi-v7a",*/ "arm64-v8a" 18 | } 19 | } 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | externalNativeBuild { 27 | cmake { 28 | path "CMakeLists.txt" 29 | } 30 | } 31 | } 32 | 33 | dependencies { 34 | implementation fileTree(dir: 'libs', include: ['*.jar']) 35 | implementation "androidx.appcompat:appcompat:$rootProject.appcompatVersion" 36 | } 37 | -------------------------------------------------------------------------------- /Live/libs/arm64-v8a/libfaac.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/Live/libs/arm64-v8a/libfaac.a -------------------------------------------------------------------------------- /Live/libs/arm64-v8a/libx264.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/Live/libs/arm64-v8a/libx264.a -------------------------------------------------------------------------------- /Live/libs/armeabi-v7a/libfaac.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/Live/libs/armeabi-v7a/libfaac.a -------------------------------------------------------------------------------- /Live/libs/armeabi-v7a/libx264.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/Live/libs/armeabi-v7a/libx264.a -------------------------------------------------------------------------------- /Live/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 C:\Users\frank\AppData\Local\Android\Sdk/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 | -keepclasseswithmembernames class * { 27 | native ; 28 | } 29 | 30 | -keep public class com.frank.live.LivePusherNew { 31 | } -------------------------------------------------------------------------------- /Live/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Live/src/main/cpp/AudioStream.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef AUDIOSTREAM_H 3 | #define AUDIOSTREAM_H 4 | 5 | #include "rtmp/rtmp.h" 6 | #include "faac/faac.h" 7 | #include 8 | 9 | class AudioStream { 10 | typedef void (*AudioCallback)(RTMPPacket *packet); 11 | 12 | private: 13 | AudioCallback audioCallback; 14 | int m_channels; 15 | faacEncHandle m_audioCodec = 0; 16 | u_long m_inputSamples; 17 | u_long m_maxOutputBytes; 18 | u_char *m_buffer = 0; 19 | 20 | public: 21 | AudioStream(); 22 | 23 | ~AudioStream(); 24 | 25 | int setAudioEncInfo(int samplesInHZ, int channels); 26 | 27 | void setAudioCallback(AudioCallback audioCallback); 28 | 29 | int getInputSamples() const; 30 | 31 | void encodeData(int8_t *data); 32 | 33 | RTMPPacket *getAudioTag(); 34 | 35 | }; 36 | 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Live/src/main/cpp/PacketQueue.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PACKET_QUEUE_H 3 | #define PACKET_QUEUE_H 4 | 5 | #include 6 | #include 7 | 8 | template 9 | class PacketQueue { 10 | typedef void (*ReleaseCallback)(T &); 11 | 12 | private: 13 | std::mutex m_mutex; 14 | std::condition_variable m_cond; 15 | std::queue m_queue; 16 | bool m_running; 17 | 18 | ReleaseCallback releaseCallback; 19 | 20 | public: 21 | 22 | void push(T new_value) { 23 | std::lock_guard lock(m_mutex); 24 | if (m_running) { 25 | m_queue.push(new_value); 26 | m_cond.notify_one(); 27 | } 28 | } 29 | 30 | int pop(T &value) { 31 | int ret = 0; 32 | std::unique_lock lock(m_mutex); 33 | if (!m_running) { 34 | return ret; 35 | } 36 | if (!m_queue.empty()) { 37 | value = m_queue.front(); 38 | m_queue.pop(); 39 | ret = 1; 40 | } 41 | return ret; 42 | } 43 | 44 | void clear() { 45 | std::lock_guard lock(m_mutex); 46 | int size = m_queue.size(); 47 | for (int i = 0; i < size; ++i) { 48 | T value = m_queue.front(); 49 | releaseCallback(value); 50 | m_queue.pop(); 51 | } 52 | } 53 | 54 | void setRunning(bool run) { 55 | std::lock_guard lock(m_mutex); 56 | m_running = run; 57 | } 58 | 59 | bool empty() { 60 | std::lock_guard lock(m_mutex); 61 | return m_queue.empty(); 62 | } 63 | 64 | int size() { 65 | std::lock_guard lock(m_mutex); 66 | return static_cast(m_queue.size()); 67 | } 68 | 69 | void setReleaseCallback(ReleaseCallback callback) { 70 | releaseCallback = callback; 71 | } 72 | 73 | }; 74 | 75 | #endif // PACKET_QUEUE_H 76 | -------------------------------------------------------------------------------- /Live/src/main/cpp/PushInterface.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PUSHINTERFACE_H 3 | #define PUSHINTERFACE_H 4 | 5 | #include 6 | 7 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,"FrankLive",__VA_ARGS__) 8 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,"FrankLive",__VA_ARGS__) 9 | 10 | /***************relative to Java**************/ 11 | //error code for opening video encoder 12 | const int ERROR_VIDEO_ENCODER_OPEN = 0x01; 13 | //error code for video encoding 14 | const int ERROR_VIDEO_ENCODE = 0x02; 15 | //error code for opening audio encoder 16 | const int ERROR_AUDIO_ENCODER_OPEN = 0x03; 17 | //error code for audio encoding 18 | const int ERROR_AUDIO_ENCODE = 0x04; 19 | //error code for RTMP connecting 20 | const int ERROR_RTMP_CONNECT = 0x05; 21 | //error code for connecting stream 22 | const int ERROR_RTMP_CONNECT_STREAM = 0x06; 23 | //error code for sending packet 24 | const int ERROR_RTMP_SEND_PACKET = 0x07; 25 | 26 | /***************relative to Java**************/ 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /Live/src/main/cpp/VideoStream.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef VIDEOSTREAM_H 3 | #define VIDEOSTREAM_H 4 | 5 | #include 6 | #include 7 | #include "rtmp/rtmp.h" 8 | #include "x264/x264.h" 9 | 10 | class VideoStream { 11 | typedef void (*VideoCallback)(RTMPPacket *packet); 12 | 13 | private: 14 | std::mutex m_mutex; 15 | 16 | int m_frameLen; 17 | x264_t *videoCodec = 0; 18 | x264_picture_t *pic_in = 0; 19 | 20 | VideoCallback videoCallback; 21 | 22 | void sendSpsPps(uint8_t *sps, uint8_t *pps, int sps_len, int pps_len); 23 | 24 | void sendFrame(int type, uint8_t *payload, int i_payload); 25 | 26 | public: 27 | VideoStream(); 28 | 29 | ~VideoStream(); 30 | 31 | int setVideoEncInfo(int width, int height, int fps, int bitrate); 32 | 33 | void encodeVideo(int8_t *data, int camera_type); 34 | 35 | void setVideoCallback(VideoCallback videoCallback); 36 | 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /Live/src/main/cpp/include/x264/x264_config.h: -------------------------------------------------------------------------------- 1 | #define X264_GPL 1 2 | #define X264_INTERLACED 1 3 | #define X264_BIT_DEPTH 0 4 | #define X264_CHROMA_FORMAT 0 5 | #define X264_VERSION "" 6 | #define X264_POINTVER "0.159.x" 7 | -------------------------------------------------------------------------------- /Live/src/main/cpp/rtmp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | cmake_minimum_required(VERSION 3.4.1) 4 | 5 | 6 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNO_CRYPTO") 7 | 8 | add_library(rtmp 9 | 10 | STATIC 11 | 12 | amf.c 13 | hashswf.c 14 | log.c 15 | parseurl.c 16 | rtmp.c) -------------------------------------------------------------------------------- /Live/src/main/cpp/rtmp/http.h: -------------------------------------------------------------------------------- 1 | #ifndef __RTMP_HTTP_H__ 2 | #define __RTMP_HTTP_H__ 3 | /* 4 | * Copyright (C) 2010 Howard Chu 5 | * Copyright (C) 2010 Antti Ajanki 6 | * 7 | * This file is part of librtmp. 8 | * 9 | * librtmp is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU Lesser General Public License as 11 | * published by the Free Software Foundation; either version 2.1, 12 | * or (at your option) any later version. 13 | * 14 | * librtmp is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public License 20 | * along with librtmp see the file COPYING. If not, write to 21 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 | * Boston, MA 02110-1301, USA. 23 | * http://www.gnu.org/copyleft/lgpl.html 24 | */ 25 | 26 | typedef enum { 27 | HTTPRES_OK, /* result OK */ 28 | HTTPRES_OK_NOT_MODIFIED, /* not modified since last request */ 29 | HTTPRES_NOT_FOUND, /* not found */ 30 | HTTPRES_BAD_REQUEST, /* client error */ 31 | HTTPRES_SERVER_ERROR, /* server reported an error */ 32 | HTTPRES_REDIRECTED, /* resource has been moved */ 33 | HTTPRES_LOST_CONNECTION /* connection lost while waiting for data */ 34 | } HTTPResult; 35 | 36 | struct HTTP_ctx { 37 | char *date; 38 | int size; 39 | int status; 40 | void *data; 41 | }; 42 | 43 | typedef size_t (HTTP_read_callback)(void *ptr, size_t size, size_t nmemb, void *stream); 44 | 45 | HTTPResult HTTP_get(struct HTTP_ctx *http, const char *url, HTTP_read_callback *cb); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /Live/src/main/cpp/rtmp/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008-2009 Andrej Stepanchuk 3 | * Copyright (C) 2009-2010 Howard Chu 4 | * 5 | * This file is part of librtmp. 6 | * 7 | * librtmp is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as 9 | * published by the Free Software Foundation; either version 2.1, 10 | * or (at your option) any later version. 11 | * 12 | * librtmp is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with librtmp see the file COPYING. If not, write to 19 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 | * Boston, MA 02110-1301, USA. 21 | * http://www.gnu.org/copyleft/lgpl.html 22 | */ 23 | 24 | #ifndef __RTMP_LOG_H__ 25 | #define __RTMP_LOG_H__ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | /* Enable this to get full debugging output */ 35 | /* #define _DEBUG */ 36 | 37 | #ifdef _DEBUG 38 | #undef NODEBUG 39 | #endif 40 | 41 | typedef enum 42 | { RTMP_LOGCRIT=0, RTMP_LOGERROR, RTMP_LOGWARNING, RTMP_LOGINFO, 43 | RTMP_LOGDEBUG, RTMP_LOGDEBUG2, RTMP_LOGALL 44 | } RTMP_LogLevel; 45 | 46 | extern RTMP_LogLevel RTMP_debuglevel; 47 | 48 | typedef void (RTMP_LogCallback)(int level, const char *fmt, va_list); 49 | void RTMP_LogSetCallback(RTMP_LogCallback *cb); 50 | void RTMP_LogSetOutput(FILE *file); 51 | void RTMP_LogPrintf(const char *format, ...); 52 | void RTMP_LogStatus(const char *format, ...); 53 | void RTMP_Log(int level, const char *format, ...); 54 | void RTMP_LogHex(int level, const uint8_t *data, unsigned long len); 55 | void RTMP_LogHexString(int level, const uint8_t *data, unsigned long len); 56 | void RTMP_LogSetLevel(RTMP_LogLevel lvl); 57 | RTMP_LogLevel RTMP_LogGetLevel(void); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /Live/src/main/java/com/frank/live/camera/Camera2Listener.java: -------------------------------------------------------------------------------- 1 | package com.frank.live.camera; 2 | 3 | 4 | import android.util.Size; 5 | 6 | public interface Camera2Listener { 7 | 8 | void onCameraOpened(Size previewSize, int displayOrientation); 9 | 10 | void onPreviewFrame(byte[] yuvData); 11 | 12 | void onCameraClosed(); 13 | 14 | void onCameraError(Exception e); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Live/src/main/java/com/frank/live/camera/CameraType.java: -------------------------------------------------------------------------------- 1 | package com.frank.live.camera; 2 | 3 | public enum CameraType { 4 | CAMERA1, 5 | CAMERA2 6 | } 7 | -------------------------------------------------------------------------------- /Live/src/main/java/com/frank/live/listener/LiveStateChangeListener.java: -------------------------------------------------------------------------------- 1 | package com.frank.live.listener; 2 | 3 | /** 4 | * Listener of living state 5 | * Created by frank on 2018/1/29. 6 | */ 7 | 8 | public interface LiveStateChangeListener { 9 | void onError(String msg); 10 | } 11 | -------------------------------------------------------------------------------- /Live/src/main/java/com/frank/live/listener/OnFrameDataCallback.java: -------------------------------------------------------------------------------- 1 | package com.frank.live.listener; 2 | 3 | /** 4 | * Video/Audio frame callback 5 | * Created by frank on 2022/01/25. 6 | */ 7 | 8 | public interface OnFrameDataCallback { 9 | 10 | int getInputSamples(); 11 | 12 | void onAudioFrame(byte[] pcm); 13 | 14 | void onAudioCodecInfo(int sampleRate, int channelCount); 15 | 16 | void onVideoFrame(byte[] yuv, int cameraType); 17 | 18 | void onVideoCodecInfo(int width, int height, int frameRate, int bitrate); 19 | } 20 | -------------------------------------------------------------------------------- /Live/src/main/java/com/frank/live/param/AudioParam.java: -------------------------------------------------------------------------------- 1 | package com.frank.live.param; 2 | 3 | 4 | /** 5 | * Audio param Entity 6 | * Created by frank on 2018/1/28. 7 | */ 8 | 9 | public class AudioParam { 10 | private int channelConfig; 11 | private int sampleRate; 12 | private int audioFormat; 13 | private int numChannels; 14 | 15 | public AudioParam(int sampleRate, int channelConfig, int audioFormat, int numChannels) { 16 | this.sampleRate = sampleRate; 17 | this.channelConfig = channelConfig; 18 | this.audioFormat = audioFormat; 19 | this.numChannels = numChannels; 20 | } 21 | 22 | public int getChannelConfig() { 23 | return channelConfig; 24 | } 25 | 26 | public void setChannelConfig(int channelConfig) { 27 | this.channelConfig = channelConfig; 28 | } 29 | 30 | public int getSampleRate() { 31 | return sampleRate; 32 | } 33 | 34 | public void setSampleRate(int sampleRate) { 35 | this.sampleRate = sampleRate; 36 | } 37 | 38 | public int getAudioFormat() { 39 | return audioFormat; 40 | } 41 | 42 | public void setAudioFormat(int audioFormat) { 43 | this.audioFormat = audioFormat; 44 | } 45 | 46 | public int getNumChannels() { 47 | return numChannels; 48 | } 49 | 50 | public void setNumChannels(int numChannels) { 51 | this.numChannels = numChannels; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Live/src/main/java/com/frank/live/param/VideoParam.java: -------------------------------------------------------------------------------- 1 | package com.frank.live.param; 2 | 3 | /** 4 | * Video param Entity 5 | * Created by frank on 2018/1/28. 6 | */ 7 | 8 | public class VideoParam { 9 | private int width; 10 | private int height; 11 | private int cameraId; 12 | private int bitRate; 13 | private int frameRate; 14 | 15 | public VideoParam(int width, int height, int cameraId, int bitRate, int frameRate) { 16 | this.width = width; 17 | this.height = height; 18 | this.cameraId = cameraId; 19 | this.bitRate = bitRate; 20 | this.frameRate = frameRate; 21 | } 22 | 23 | public int getWidth() { 24 | return width; 25 | } 26 | 27 | public void setWidth(int width) { 28 | this.width = width; 29 | } 30 | 31 | public int getHeight() { 32 | return height; 33 | } 34 | 35 | public void setHeight(int height) { 36 | this.height = height; 37 | } 38 | 39 | public int getCameraId() { 40 | return cameraId; 41 | } 42 | 43 | public void setCameraId(int cameraId) { 44 | this.cameraId = cameraId; 45 | } 46 | 47 | public int getBitRate() { 48 | return bitRate; 49 | } 50 | 51 | public void setBitRate(int bitRate) { 52 | this.bitRate = bitRate; 53 | } 54 | 55 | public int getFrameRate() { 56 | return frameRate; 57 | } 58 | 59 | public void setFrameRate(int frameRate) { 60 | this.frameRate = frameRate; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Live/src/main/java/com/frank/live/stream/VideoStreamBase.java: -------------------------------------------------------------------------------- 1 | package com.frank.live.stream; 2 | 3 | import android.view.SurfaceHolder; 4 | 5 | /** 6 | * Base of VideoStream 7 | * Created by frank on 2022/01/27. 8 | */ 9 | 10 | public abstract class VideoStreamBase { 11 | 12 | public abstract void startLive(); 13 | 14 | public abstract void setPreviewDisplay(SurfaceHolder surfaceHolder); 15 | 16 | public abstract void switchCamera(); 17 | 18 | public abstract void stopLive(); 19 | 20 | public abstract void release(); 21 | 22 | public abstract void onPreviewDegreeChanged(int degree); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Live/src/main/res/drawable/ic_camera_switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/Live/src/main/res/drawable/ic_camera_switch.png -------------------------------------------------------------------------------- /Live/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/Live/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Live/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/Live/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Live/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/Live/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Live/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/Live/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Live/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/Live/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Live/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/Live/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Live/src/main/res/values-en/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | live 3 | swap 4 | start 5 | stop 6 | mute 7 | voice 8 | photo 9 | 10 | beauty 11 | cool 12 | sunrise 13 | sketch 14 | white 15 | romantic 16 | raw 17 | 18 | error of opening video encoder 19 | error of video encoding 20 | error of opening audio encoder 21 | error of audio encoding 22 | error of RTMP connecting server 23 | error of RTMP connecting stream 24 | error of RTMP sending packet 25 | 26 | -------------------------------------------------------------------------------- /Live/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /Live/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | live 3 | 切换 4 | 开始 5 | 停止 6 | 静音 7 | 取消静音 8 | 拍照 9 | 10 | 美颜 11 | 冷酷 12 | 日出 13 | 素描 14 | 纯白 15 | 浪漫 16 | 原图 17 | 18 | 打开视频编码器失败 19 | 视频编码失败 20 | 打开音频编码器失败 21 | 音频编码失败 22 | RTMP连接服务器失败 23 | RTMP连接流失败 24 | RTMP发送数据包失败 25 | 26 | -------------------------------------------------------------------------------- /Live/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FFmpegAndroid 2 | 3 | ### [FFmpeg官方文档](https://ffmpeg.org/) 4 | ### [FFmpeg编译流程](https://github.com/xufuji456/FFmpegAndroid/blob/master/doc/FFmpeg_compile_shell.md) 5 | ### [FFmpeg常用命令行](https://github.com/xufuji456/FFmpegAndroid/blob/master/doc/FFmpeg_command_line.md) 6 | ### [FFmpeg源码分析](https://github.com/xufuji456/FFmpegAndroid/blob/master/doc/FFmpeg_sourcecode.md) 7 | ### [JNI与NDK开发](https://github.com/xufuji456/FFmpegAndroid/blob/master/doc/JNI_develop_practice.md) 8 | ### [音视频知识汇总](https://github.com/xufuji456/FFmpegAndroid/blob/master/doc/multimedia_knowledge.md) 9 | ### [ijkplayer播放器架构](https://github.com/xufuji456/FFmpegAndroid/blob/master/doc/player_framework.md) 10 | 11 | ---------------------------------------------------------------------------------------------------- 12 | 13 | 常见的流媒体传输协议包括:RTP、RTMP、RTCP、RTSP,流媒体应用协议有HLS、DASH,
14 | WebRTC设计传输协议有SDP、ICE、NAT、STUN等,常用视频编码协议有H264、HEVC、VVC,
15 | 常用的视频封装格式有mp4,关于C/C++语言标准有C11、C20++等,书籍包括音视频编解码等。
16 | 详细列表可以查阅:[多媒体协议与书籍](https://github.com/xufuji456/FFmpegAndroid/blob/master/doc/multimedia_protocol.md) 17 | 18 | 音视频工作方向包括:直播、短视频、流媒体传输、视频播放器、音乐播放器、音视频算法、
19 | 流媒体后端、音视频编辑、图像处理(个人概括,具体方向不限于此)。
20 | 详情可查阅:[音视频工作方向](https://github.com/xufuji456/FFmpegAndroid/blob/master/doc/multimedia_work.md) 21 | 22 | ### 音视频基础知识: 23 | ![preview](https://github.com/xufuji456/FFmpegAndroid/blob/master/picture/multimedia_baseline.png) 24 | 25 | ### 音视频进阶成长: 26 | ![preview](https://github.com/xufuji456/FFmpegAndroid/blob/master/picture/multimedia_main.png) 27 | 28 | ### 音视频开源库: 29 | ![preview](https://github.com/xufuji456/FFmpegAndroid/blob/master/picture/multimedia_library.png) 30 | 31 | ### Joining the group to learn FFmpeg: 32 | ![preview](https://github.com/xufuji456/FFmpegAndroid/blob/master/picture/ffmpeg_group.png) 33 | 34 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/libs/arm64-v8a/libffmpeg.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/app/libs/arm64-v8a/libffmpeg.so -------------------------------------------------------------------------------- /app/libs/armeabi-v7a/libffmpeg.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/app/libs/armeabi-v7a/libffmpeg.so -------------------------------------------------------------------------------- /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 D:\adt-bundle-windows-x86_64-20131030\sdk/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 | -keepclasseswithmembernames class * { 27 | native ; 28 | } 29 | 30 | -keep public class com.frank.ffmpeg.AudioPlayer { 31 | } 32 | 33 | -keep public class com.frank.ffmpeg.FFmpegCmd { 34 | } 35 | 36 | -keep public class com.frank.ffmpeg.FFmpegPusher { 37 | } 38 | 39 | -keep public class com.frank.ffmpeg.VideoPlayer { 40 | } -------------------------------------------------------------------------------- /app/src/main/cpp/common_media_jni.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by xu fulong on 2022/9/7. 3 | // 4 | 5 | #include 6 | 7 | #include "ff_audio_resample.h" 8 | 9 | COMMON_MEDIA_FUNC(int, audioResample, jstring srcFile, jstring dstFile, int sampleRate) { 10 | const char *src_file = env->GetStringUTFChars(srcFile, JNI_FALSE); 11 | const char *dst_file = env->GetStringUTFChars(dstFile, JNI_FALSE); 12 | 13 | auto *audioResample = new FFAudioResample(); 14 | int ret = audioResample->resampling(src_file, dst_file, sampleRate); 15 | 16 | delete audioResample; 17 | env->ReleaseStringUTFChars(dstFile, dst_file); 18 | env->ReleaseStringUTFChars(srcFile, src_file); 19 | return ret; 20 | } -------------------------------------------------------------------------------- /app/src/main/cpp/ff_audio_player.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by xu fulong on 2022/9/4. 3 | // 4 | 5 | #ifndef FF_AUDIO_PLAYER_H 6 | #define FF_AUDIO_PLAYER_H 7 | 8 | #include 9 | #include "ffmpeg_jni_define.h" 10 | #include "visualizer/frank_visualizer.h" 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | #include "libavformat/avformat.h" 16 | #include "libavcodec/avcodec.h" 17 | #include "libswresample/swresample.h" 18 | 19 | #include "libavfilter/buffersink.h" 20 | #include "libavfilter/buffersrc.h" 21 | #include "libavfilter/avfilter.h" 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | 26 | struct AudioPlayerState { 27 | int out_channel; 28 | int out_ch_layout; 29 | int out_sample_rate; 30 | enum AVSampleFormat out_sample_fmt; 31 | int64_t m_position; 32 | 33 | AVPacket *packet; 34 | AVFrame *inputFrame; 35 | AVFrame *filterFrame; 36 | int audioIndex = -1; 37 | uint8_t *outBuffer; 38 | SwrContext *swrContext; 39 | 40 | AVFormatContext *formatContext; 41 | AVCodecContext *codecContext; 42 | 43 | const char *filterDesc; 44 | std::atomic filterAgain; 45 | bool exitPlaying; 46 | std::mutex m_playMutex; 47 | 48 | AVFilterGraph *audioFilterGraph; 49 | AVFilterContext *audioSrcContext; 50 | AVFilterContext *audioSinkContext; 51 | }; 52 | 53 | class FFAudioPlayer { 54 | private: 55 | 56 | AudioPlayerState *m_state; 57 | 58 | public: 59 | 60 | FFAudioPlayer(); 61 | 62 | ~FFAudioPlayer(); 63 | 64 | int open(const char* path); 65 | 66 | int getSampleRate() const; 67 | 68 | int getChannel() const; 69 | 70 | int decodeAudio(); 71 | 72 | uint8_t *getDecodeFrame() const; 73 | 74 | void setFilterAgain(bool again); 75 | 76 | void setFilterDesc(const char *filterDescription); 77 | 78 | void setExit(bool exit); 79 | 80 | int64_t getCurrentPosition(); 81 | 82 | int64_t getDuration(); 83 | 84 | void close(); 85 | }; 86 | #endif //FF_AUDIO_PLAYER_H 87 | -------------------------------------------------------------------------------- /app/src/main/cpp/ff_audio_resample.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by xu fulong on 2022/9/7. 3 | // 4 | 5 | #ifndef FFMPEGANDROID_FF_AUDIO_RESAMPLE_H 6 | #define FFMPEGANDROID_FF_AUDIO_RESAMPLE_H 7 | 8 | #include "ffmpeg_jni_define.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | #include "libavformat/avformat.h" 14 | #include "libavformat/avio.h" 15 | 16 | #include "libavcodec/avcodec.h" 17 | 18 | #include "libavutil/audio_fifo.h" 19 | #include "libavutil/avassert.h" 20 | #include "libavutil/avstring.h" 21 | #include "libavutil/frame.h" 22 | #include "libavutil/opt.h" 23 | 24 | #include "libswresample/swresample.h" 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | struct AudioResample { 30 | int64_t pts = 0; 31 | 32 | AVPacket inPacket; 33 | AVPacket outPacket; 34 | AVFrame *inFrame; 35 | AVFrame *outFrame; 36 | 37 | SwrContext *resampleCtx; 38 | AVAudioFifo *fifo = nullptr; 39 | 40 | AVFormatContext *inFormatCtx; 41 | AVCodecContext *inCodecCtx; 42 | AVFormatContext *outFormatCtx; 43 | AVCodecContext *outCodecCtx; 44 | }; 45 | 46 | class FFAudioResample { 47 | private: 48 | 49 | AudioResample *resample; 50 | 51 | int openInputFile(const char *filename); 52 | 53 | int openOutputFile(const char *filename, int sample_rate); 54 | 55 | int decodeAudioFrame(AVFrame *frame, int *data_present, int *finished); 56 | 57 | int decodeAndConvert(int *finished); 58 | 59 | int encodeAudioFrame(AVFrame *frame, int *data_present); 60 | 61 | int encodeAndWrite(); 62 | public: 63 | 64 | FFAudioResample(); 65 | 66 | ~FFAudioResample(); 67 | 68 | int resampling(const char *src_file, const char *dst_file, int sampleRate); 69 | 70 | }; 71 | #endif //FFMPEGANDROID_FF_AUDIO_RESAMPLE_H 72 | -------------------------------------------------------------------------------- /app/src/main/cpp/ff_rtmp_pusher.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by xu fulong on 2022/9/9. 3 | // 4 | 5 | #ifndef FF_RTMP_PUSHER_H 6 | #define FF_RTMP_PUSHER_H 7 | 8 | #include "ffmpeg_jni_define.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | #include "libavformat/avformat.h" 14 | #include "libavcodec/avcodec.h" 15 | #include "libavutil/time.h" 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | class FFRtmpPusher { 21 | private: 22 | AVFormatContext *inFormatCtx; 23 | AVFormatContext *outFormatCtx; 24 | 25 | AVPacket packet; 26 | int video_index = -1; 27 | int audio_index = -1; 28 | 29 | public: 30 | 31 | int open(const char *inputPath, const char *outputPath); 32 | 33 | int push(); 34 | 35 | void close(); 36 | 37 | }; 38 | 39 | #endif //FF_RTMP_PUSHER_H 40 | -------------------------------------------------------------------------------- /app/src/main/cpp/ffmpeg/ffprobe.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by frank on 2020-01-06. 3 | // 4 | 5 | #ifndef FFMPEGANDROID_FFPROBE_H 6 | #define FFMPEGANDROID_FFPROBE_H 7 | 8 | char* ffprobe_run(int argc, char **argv); 9 | 10 | void frank_printf_json(char *fmt, ...); 11 | 12 | #endif //FFMPEGANDROID_FFPROBE_H 13 | -------------------------------------------------------------------------------- /app/src/main/cpp/ffmpeg/fopen_utf8.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of FFmpeg. 3 | * 4 | * FFmpeg is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * FFmpeg is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with FFmpeg; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef FFTOOLS_FOPEN_UTF8_H 20 | #define FFTOOLS_FOPEN_UTF8_H 21 | 22 | #include 23 | 24 | /* The fopen_utf8 function here is essentially equivalent to avpriv_fopen_utf8, 25 | * except that it doesn't set O_CLOEXEC, and that it isn't exported 26 | * from a different library. (On Windows, each DLL might use a different 27 | * CRT, and FILE* handles can't be shared across them.) */ 28 | 29 | #ifdef _WIN32 30 | #include "libavutil/wchar_filename.h" 31 | 32 | static inline FILE *fopen_utf8(const char *path_utf8, const char *mode) 33 | { 34 | wchar_t *path_w, *mode_w; 35 | FILE *f; 36 | 37 | /* convert UTF-8 to wide chars */ 38 | if (get_extended_win32_path(path_utf8, &path_w)) /* This sets errno on error. */ 39 | return NULL; 40 | if (!path_w) 41 | goto fallback; 42 | 43 | if (utf8towchar(mode, &mode_w)) 44 | return NULL; 45 | if (!mode_w) { 46 | /* If failing to interpret the mode string as utf8, it is an invalid 47 | * parameter. */ 48 | av_freep(&path_w); 49 | errno = EINVAL; 50 | return NULL; 51 | } 52 | 53 | f = _wfopen(path_w, mode_w); 54 | av_freep(&path_w); 55 | av_freep(&mode_w); 56 | 57 | return f; 58 | fallback: 59 | /* path may be in CP_ACP */ 60 | return fopen(path_utf8, mode); 61 | } 62 | 63 | #else 64 | 65 | static inline FILE *fopen_utf8(const char *path, const char *mode) 66 | { 67 | return fopen(path, mode); 68 | } 69 | #endif 70 | 71 | #endif /* FFTOOLS_FOPEN_UTF8_H */ 72 | -------------------------------------------------------------------------------- /app/src/main/cpp/ffmpeg/objpool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of FFmpeg. 3 | * 4 | * FFmpeg is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * FFmpeg is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with FFmpeg; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef FFTOOLS_OBJPOOL_H 20 | #define FFTOOLS_OBJPOOL_H 21 | 22 | typedef struct ObjPool ObjPool; 23 | 24 | typedef void* (*ObjPoolCBAlloc)(void); 25 | typedef void (*ObjPoolCBReset)(void *); 26 | typedef void (*ObjPoolCBFree)(void **); 27 | 28 | void objpool_free(ObjPool **op); 29 | ObjPool *objpool_alloc(ObjPoolCBAlloc cb_alloc, ObjPoolCBReset cb_reset, 30 | ObjPoolCBFree cb_free); 31 | ObjPool *objpool_alloc_packets(void); 32 | ObjPool *objpool_alloc_frames(void); 33 | 34 | int objpool_get(ObjPool *op, void **obj); 35 | void objpool_release(ObjPool *op, void **obj); 36 | 37 | #endif // FFTOOLS_OBJPOOL_H 38 | -------------------------------------------------------------------------------- /app/src/main/cpp/ffmpeg_pusher_jni.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by xu fulong on 2022/9/9. 3 | // 4 | 5 | #include 6 | #include "ff_rtmp_pusher.h" 7 | 8 | PUSHER_FUNC(int, pushStream, jstring inputPath, jstring outputPath) { 9 | int ret; 10 | const char *input_path = env->GetStringUTFChars(inputPath, JNI_FALSE); 11 | const char *output_path = env->GetStringUTFChars(outputPath, JNI_FALSE); 12 | auto *rtmpPusher = new FFRtmpPusher(); 13 | ret = rtmpPusher->open(input_path, output_path); 14 | if (ret < 0) { 15 | LOGE("ffmpeg_pusher_jni", "open error=%d", ret); 16 | return ret; 17 | } 18 | ret = rtmpPusher->push(); 19 | 20 | rtmpPusher->close(); 21 | env->ReleaseStringUTFChars(inputPath, input_path); 22 | env->ReleaseStringUTFChars(outputPath, output_path); 23 | 24 | return ret; 25 | } -------------------------------------------------------------------------------- /app/src/main/cpp/ffprobe_cmd.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by frank on 2020-01-06. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include "ffmpeg_jni_define.h" 14 | #include "ffmpeg/ffprobe.h" 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | FFPROBE_FUNC(jstring, handleProbe, jobjectArray commands) { 21 | int argc = env->GetArrayLength(commands); 22 | char **argv = (char **) malloc(argc * sizeof(char *)); 23 | int i; 24 | for (i = 0; i < argc; i++) { 25 | jstring jstr = (jstring) env->GetObjectArrayElement( commands, i); 26 | char *temp = (char *) env->GetStringUTFChars(jstr, 0); 27 | argv[i] = static_cast(malloc(1024)); 28 | strcpy(argv[i], temp); 29 | env->ReleaseStringUTFChars(jstr, temp); 30 | } 31 | //execute ffprobe command 32 | char *result = ffprobe_run(argc, argv); 33 | //release memory 34 | for (i = 0; i < argc; i++) { 35 | free(argv[i]); 36 | } 37 | free(argv); 38 | 39 | return env->NewStringUTF(result); 40 | } 41 | 42 | 43 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/arm64-v8a/libavcodec/aarch64/mathops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * simple math operations 3 | * Copyright (c) 2006 Michael Niedermayer et al 4 | * 5 | * This file is part of FFmpeg. 6 | * 7 | * FFmpeg is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * FFmpeg is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with FFmpeg; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef AVCODEC_ARM_MATHOPS_H 23 | #define AVCODEC_ARM_MATHOPS_H 24 | 25 | 26 | #endif /* AVCODEC_ARM_MATHOPS_H */ 27 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/arm64-v8a/libavutil/aarch64/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Janne Grunau 3 | * 4 | * This file is part of FFmpeg. 5 | * 6 | * FFmpeg is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * FFmpeg is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with FFmpeg; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef AVUTIL_AARCH64_TIMER_H 22 | #define AVUTIL_AARCH64_TIMER_H 23 | 24 | #include 25 | #include "ffmpeg/config.h" 26 | 27 | #if defined(__APPLE__) 28 | 29 | #include 30 | 31 | #define AV_READ_TIME mach_absolute_time 32 | 33 | #elif HAVE_INLINE_ASM 34 | 35 | #define AV_READ_TIME read_time 36 | 37 | static inline uint64_t read_time(void) 38 | { 39 | uint64_t cycle_counter; 40 | __asm__ volatile( 41 | "isb \t\n" 42 | "mrs %0, pmccntr_el0 " 43 | : "=r"(cycle_counter) :: "memory" ); 44 | 45 | return cycle_counter; 46 | } 47 | 48 | #endif /* HAVE_INLINE_ASM */ 49 | 50 | #endif /* AVUTIL_AARCH64_TIMER_H */ 51 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/armeabi-v7a/libavutil/arm/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009 Mans Rullgard 3 | * 4 | * This file is part of FFmpeg. 5 | * 6 | * FFmpeg is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * FFmpeg is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with FFmpeg; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef AVUTIL_ARM_TIMER_H 22 | #define AVUTIL_ARM_TIMER_H 23 | 24 | #include 25 | #include "ffmpeg/config.h" 26 | 27 | #if defined(__APPLE__) 28 | 29 | #include 30 | 31 | #define AV_READ_TIME mach_absolute_time 32 | 33 | #elif HAVE_INLINE_ASM && defined(__ARM_ARCH_7A__) 34 | 35 | #define AV_READ_TIME read_time 36 | 37 | static inline uint64_t read_time(void) 38 | { 39 | unsigned cc; 40 | __asm__ volatile ("mrc p15, 0, %0, c9, c13, 0" : "=r"(cc)); 41 | return cc; 42 | } 43 | 44 | #endif /* HAVE_INLINE_ASM && __ARM_ARCH_7A__ */ 45 | 46 | #endif /* AVUTIL_ARM_TIMER_H */ 47 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/compat/va_copy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MSVC Compatible va_copy macro 3 | * Copyright (c) 2012 Derek Buitenhuis 4 | * 5 | * This file is part of FFmpeg. 6 | * 7 | * FFmpeg is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * FFmpeg is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with FFmpeg; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef COMPAT_VA_COPY_H 23 | #define COMPAT_VA_COPY_H 24 | 25 | #include 26 | 27 | #if !defined(va_copy) && defined(_MSC_VER) 28 | #define va_copy(dst, src) ((dst) = (src)) 29 | #endif 30 | #if !defined(va_copy) && defined(__GNUC__) && __GNUC__ < 3 31 | #define va_copy(dst, src) __va_copy(dst, src) 32 | #endif 33 | 34 | #endif /* COMPAT_VA_COPY_H */ 35 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavcodec/jni.h: -------------------------------------------------------------------------------- 1 | /* 2 | * JNI public API functions 3 | * 4 | * Copyright (c) 2015-2016 Matthieu Bouron 5 | * 6 | * This file is part of FFmpeg. 7 | * 8 | * FFmpeg is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2.1 of the License, or (at your option) any later version. 12 | * 13 | * FFmpeg is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with FFmpeg; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | 23 | #ifndef AVCODEC_JNI_H 24 | #define AVCODEC_JNI_H 25 | 26 | /* 27 | * Manually set a Java virtual machine which will be used to retrieve the JNI 28 | * environment. Once a Java VM is set it cannot be changed afterwards, meaning 29 | * you can call multiple times av_jni_set_java_vm with the same Java VM pointer 30 | * however it will error out if you try to set a different Java VM. 31 | * 32 | * @param vm Java virtual machine 33 | * @param log_ctx context used for logging, can be NULL 34 | * @return 0 on success, < 0 otherwise 35 | */ 36 | int av_jni_set_java_vm(void *vm, void *log_ctx); 37 | 38 | /* 39 | * Get the Java virtual machine which has been set with av_jni_set_java_vm. 40 | * 41 | * @param vm Java virtual machine 42 | * @return a pointer to the Java virtual machine 43 | */ 44 | void *av_jni_get_java_vm(void *log_ctx); 45 | 46 | #endif /* AVCODEC_JNI_H */ 47 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavcodec/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of FFmpeg. 3 | * 4 | * FFmpeg is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * FFmpeg is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with FFmpeg; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef AVCODEC_VERSION_H 20 | #define AVCODEC_VERSION_H 21 | 22 | /** 23 | * @file 24 | * @ingroup libavc 25 | * Libavcodec version macros. 26 | */ 27 | 28 | #include "libavutil/version.h" 29 | 30 | #include "version_major.h" 31 | 32 | #define LIBAVCODEC_VERSION_MINOR 3 33 | #define LIBAVCODEC_VERSION_MICRO 100 34 | 35 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ 36 | LIBAVCODEC_VERSION_MINOR, \ 37 | LIBAVCODEC_VERSION_MICRO) 38 | #define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \ 39 | LIBAVCODEC_VERSION_MINOR, \ 40 | LIBAVCODEC_VERSION_MICRO) 41 | #define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT 42 | 43 | #define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) 44 | 45 | #endif /* AVCODEC_VERSION_H */ 46 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavcodec/version_major.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of FFmpeg. 3 | * 4 | * FFmpeg is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * FFmpeg is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with FFmpeg; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef AVCODEC_VERSION_MAJOR_H 20 | #define AVCODEC_VERSION_MAJOR_H 21 | 22 | /** 23 | * @file 24 | * @ingroup libavc 25 | * Libavcodec version macros. 26 | */ 27 | 28 | #define LIBAVCODEC_VERSION_MAJOR 60 29 | 30 | /** 31 | * FF_API_* defines may be placed below to indicate public API that will be 32 | * dropped at a future version bump. The defines themselves are not part of 33 | * the public API and may change, break or disappear at any time. 34 | * 35 | * @note, when bumping the major version it is recommended to manually 36 | * disable each FF_API_* in its own commit instead of disabling them all 37 | * at once through the bump. This improves the git bisect-ability of the change. 38 | */ 39 | 40 | #define FF_API_INIT_PACKET (LIBAVCODEC_VERSION_MAJOR < 61) 41 | #define FF_API_IDCT_NONE (LIBAVCODEC_VERSION_MAJOR < 61) 42 | #define FF_API_SVTAV1_OPTS (LIBAVCODEC_VERSION_MAJOR < 61) 43 | #define FF_API_AYUV_CODECID (LIBAVCODEC_VERSION_MAJOR < 61) 44 | #define FF_API_VT_OUTPUT_CALLBACK (LIBAVCODEC_VERSION_MAJOR < 61) 45 | #define FF_API_AVCODEC_CHROMA_POS (LIBAVCODEC_VERSION_MAJOR < 61) 46 | #define FF_API_VT_HWACCEL_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 61) 47 | #define FF_API_AVCTX_FRAME_NUMBER (LIBAVCODEC_VERSION_MAJOR < 61) 48 | 49 | // reminder to remove CrystalHD decoders on next major bump 50 | #define FF_CODEC_CRYSTAL_HD (LIBAVCODEC_VERSION_MAJOR < 61) 51 | 52 | #endif /* AVCODEC_VERSION_MAJOR_H */ 53 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavfilter/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Version macros. 3 | * 4 | * This file is part of FFmpeg. 5 | * 6 | * FFmpeg is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * FFmpeg is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with FFmpeg; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef AVFILTER_VERSION_H 22 | #define AVFILTER_VERSION_H 23 | 24 | /** 25 | * @file 26 | * @ingroup lavfi 27 | * Libavfilter version macros 28 | */ 29 | 30 | #include "libavutil/version.h" 31 | 32 | #include "version_major.h" 33 | 34 | #define LIBAVFILTER_VERSION_MINOR 3 35 | #define LIBAVFILTER_VERSION_MICRO 100 36 | 37 | 38 | #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ 39 | LIBAVFILTER_VERSION_MINOR, \ 40 | LIBAVFILTER_VERSION_MICRO) 41 | #define LIBAVFILTER_VERSION AV_VERSION(LIBAVFILTER_VERSION_MAJOR, \ 42 | LIBAVFILTER_VERSION_MINOR, \ 43 | LIBAVFILTER_VERSION_MICRO) 44 | #define LIBAVFILTER_BUILD LIBAVFILTER_VERSION_INT 45 | 46 | #define LIBAVFILTER_IDENT "Lavfi" AV_STRINGIFY(LIBAVFILTER_VERSION) 47 | 48 | #endif /* AVFILTER_VERSION_H */ 49 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavfilter/version_major.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Version macros. 3 | * 4 | * This file is part of FFmpeg. 5 | * 6 | * FFmpeg is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * FFmpeg is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with FFmpeg; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef AVFILTER_VERSION_MAJOR_H 22 | #define AVFILTER_VERSION_MAJOR_H 23 | 24 | /** 25 | * @file 26 | * @ingroup lavfi 27 | * Libavfilter version macros 28 | */ 29 | 30 | #define LIBAVFILTER_VERSION_MAJOR 9 31 | 32 | /** 33 | * FF_API_* defines may be placed below to indicate public API that will be 34 | * dropped at a future version bump. The defines themselves are not part of 35 | * the public API and may change, break or disappear at any time. 36 | */ 37 | 38 | #endif /* AVFILTER_VERSION_MAJOR_H */ 39 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavformat/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Version macros. 3 | * 4 | * This file is part of FFmpeg. 5 | * 6 | * FFmpeg is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * FFmpeg is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with FFmpeg; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef AVFORMAT_VERSION_H 22 | #define AVFORMAT_VERSION_H 23 | 24 | /** 25 | * @file 26 | * @ingroup libavf 27 | * Libavformat version macros 28 | */ 29 | 30 | #include "libavutil/version.h" 31 | 32 | #include "version_major.h" 33 | 34 | #define LIBAVFORMAT_VERSION_MINOR 3 35 | #define LIBAVFORMAT_VERSION_MICRO 100 36 | 37 | #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ 38 | LIBAVFORMAT_VERSION_MINOR, \ 39 | LIBAVFORMAT_VERSION_MICRO) 40 | #define LIBAVFORMAT_VERSION AV_VERSION(LIBAVFORMAT_VERSION_MAJOR, \ 41 | LIBAVFORMAT_VERSION_MINOR, \ 42 | LIBAVFORMAT_VERSION_MICRO) 43 | #define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT 44 | 45 | #define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION) 46 | 47 | #endif /* AVFORMAT_VERSION_H */ 48 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavformat/version_major.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Version macros. 3 | * 4 | * This file is part of FFmpeg. 5 | * 6 | * FFmpeg is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * FFmpeg is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with FFmpeg; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef AVFORMAT_VERSION_MAJOR_H 22 | #define AVFORMAT_VERSION_MAJOR_H 23 | 24 | /** 25 | * @file 26 | * @ingroup libavf 27 | * Libavformat version macros 28 | */ 29 | 30 | // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) 31 | // Also please add any ticket numbers that you believe might be affected here 32 | #define LIBAVFORMAT_VERSION_MAJOR 60 33 | 34 | /** 35 | * FF_API_* defines may be placed below to indicate public API that will be 36 | * dropped at a future version bump. The defines themselves are not part of 37 | * the public API and may change, break or disappear at any time. 38 | * 39 | * @note, when bumping the major version it is recommended to manually 40 | * disable each FF_API_* in its own commit instead of disabling them all 41 | * at once through the bump. This improves the git bisect-ability of the change. 42 | * 43 | */ 44 | #define FF_API_COMPUTE_PKT_FIELDS2 (LIBAVFORMAT_VERSION_MAJOR < 61) 45 | #define FF_API_GET_END_PTS (LIBAVFORMAT_VERSION_MAJOR < 61) 46 | #define FF_API_AVIODIRCONTEXT (LIBAVFORMAT_VERSION_MAJOR < 61) 47 | #define FF_API_AVFORMAT_IO_CLOSE (LIBAVFORMAT_VERSION_MAJOR < 61) 48 | 49 | 50 | #define FF_API_R_FRAME_RATE 1 51 | 52 | #endif /* AVFORMAT_VERSION_MAJOR_H */ 53 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavutil/attributes_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of FFmpeg. 3 | * 4 | * FFmpeg is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * FFmpeg is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with FFmpeg; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef AVUTIL_ATTRIBUTES_INTERNAL_H 20 | #define AVUTIL_ATTRIBUTES_INTERNAL_H 21 | 22 | #include "attributes.h" 23 | 24 | #if (AV_GCC_VERSION_AT_LEAST(4,0) || defined(__clang__)) && (defined(__ELF__) || defined(__MACH__)) 25 | # define attribute_visibility_hidden __attribute__((visibility("hidden"))) 26 | # define FF_VISIBILITY_PUSH_HIDDEN _Pragma("GCC visibility push(hidden)") 27 | # define FF_VISIBILITY_POP_HIDDEN _Pragma("GCC visibility pop") 28 | #else 29 | # define attribute_visibility_hidden 30 | # define FF_VISIBILITY_PUSH_HIDDEN 31 | # define FF_VISIBILITY_POP_HIDDEN 32 | #endif 33 | 34 | #endif /* AVUTIL_ATTRIBUTES_INTERNAL_H */ 35 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavutil/avconfig.h: -------------------------------------------------------------------------------- 1 | /* Generated by ffmpeg configure */ 2 | #ifndef AVUTIL_AVCONFIG_H 3 | #define AVUTIL_AVCONFIG_H 4 | #define AV_HAVE_BIGENDIAN 0 5 | #define AV_HAVE_FAST_UNALIGNED 1 6 | #endif /* AVUTIL_AVCONFIG_H */ 7 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavutil/ffversion.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated by version.sh, do not manually edit! */ 2 | #ifndef AVUTIL_FFVERSION_H 3 | #define AVUTIL_FFVERSION_H 4 | #define FFMPEG_VERSION "6.0" 5 | #endif /* AVUTIL_FFVERSION_H */ 6 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavutil/getenv_utf8.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of FFmpeg. 3 | * 4 | * FFmpeg is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * FFmpeg is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with FFmpeg; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef AVUTIL_GETENV_UTF8_H 20 | #define AVUTIL_GETENV_UTF8_H 21 | 22 | #include 23 | 24 | #include "ffmpeg/config.h" 25 | #include "mem.h" 26 | 27 | #if HAVE_GETENV && defined(_WIN32) 28 | 29 | #include "libavutil/wchar_filename.h" 30 | 31 | static inline char *getenv_utf8(const char *varname) 32 | { 33 | wchar_t *varname_w, *var_w; 34 | char *var; 35 | 36 | if (utf8towchar(varname, &varname_w)) 37 | return NULL; 38 | if (!varname_w) 39 | return NULL; 40 | 41 | var_w = _wgetenv(varname_w); 42 | av_free(varname_w); 43 | 44 | if (!var_w) 45 | return NULL; 46 | if (wchartoutf8(var_w, &var)) 47 | return NULL; 48 | 49 | return var; 50 | 51 | // No CP_ACP fallback compared to other *_utf8() functions: 52 | // non UTF-8 strings must not be returned. 53 | } 54 | 55 | static inline void freeenv_utf8(char *var) 56 | { 57 | av_free(var); 58 | } 59 | 60 | static inline char *getenv_dup(const char *varname) 61 | { 62 | return getenv_utf8(varname); 63 | } 64 | 65 | #else 66 | 67 | static inline char *getenv_utf8(const char *varname) 68 | { 69 | return getenv(varname); 70 | } 71 | 72 | static inline void freeenv_utf8(char *var) 73 | { 74 | } 75 | 76 | static inline char *getenv_dup(const char *varname) 77 | { 78 | char *var = getenv(varname); 79 | if (!var) 80 | return NULL; 81 | return av_strdup(var); 82 | } 83 | 84 | #endif // HAVE_GETENV && defined(_WIN32) 85 | 86 | #endif // AVUTIL_GETENV_UTF8_H 87 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavutil/hwcontext_mediacodec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of FFmpeg. 3 | * 4 | * FFmpeg is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * FFmpeg is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with FFmpeg; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef AVUTIL_HWCONTEXT_MEDIACODEC_H 20 | #define AVUTIL_HWCONTEXT_MEDIACODEC_H 21 | 22 | /** 23 | * MediaCodec details. 24 | * 25 | * Allocated as AVHWDeviceContext.hwctx 26 | */ 27 | typedef struct AVMediaCodecDeviceContext { 28 | /** 29 | * android/view/Surface handle, to be filled by the user. 30 | * 31 | * This is the default surface used by decoders on this device. 32 | */ 33 | void *surface; 34 | 35 | /** 36 | * Pointer to ANativeWindow. 37 | * 38 | * It both surface and native_window is NULL, try to create it 39 | * automatically if create_window is true and OS support 40 | * createPersistentInputSurface. 41 | * 42 | * It can be used as output surface for decoder and input surface for 43 | * encoder. 44 | */ 45 | void *native_window; 46 | 47 | /** 48 | * Enable createPersistentInputSurface automatically. 49 | * 50 | * Disabled by default. 51 | * 52 | * It can be enabled by setting this flag directly, or by setting 53 | * AVDictionary of av_hwdevice_ctx_create(), with "create_window" as key. 54 | * The second method is useful for ffmpeg cmdline, e.g., we can enable it 55 | * via: 56 | * -init_hw_device mediacodec=mediacodec,create_window=1 57 | */ 58 | int create_window; 59 | } AVMediaCodecDeviceContext; 60 | 61 | #endif /* AVUTIL_HWCONTEXT_MEDIACODEC_H */ 62 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavutil/intfloat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 Mans Rullgard 3 | * 4 | * This file is part of FFmpeg. 5 | * 6 | * FFmpeg is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * FFmpeg is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with FFmpeg; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef AVUTIL_INTFLOAT_H 22 | #define AVUTIL_INTFLOAT_H 23 | 24 | #include 25 | #include "attributes.h" 26 | 27 | union av_intfloat32 { 28 | uint32_t i; 29 | float f; 30 | }; 31 | 32 | union av_intfloat64 { 33 | uint64_t i; 34 | double f; 35 | }; 36 | 37 | /** 38 | * Reinterpret a 32-bit integer as a float. 39 | */ 40 | static av_always_inline float av_int2float(uint32_t i) 41 | { 42 | union av_intfloat32 v; 43 | v.i = i; 44 | return v.f; 45 | } 46 | 47 | /** 48 | * Reinterpret a float as a 32-bit integer. 49 | */ 50 | static av_always_inline uint32_t av_float2int(float f) 51 | { 52 | union av_intfloat32 v; 53 | v.f = f; 54 | return v.i; 55 | } 56 | 57 | /** 58 | * Reinterpret a 64-bit integer as a double. 59 | */ 60 | static av_always_inline double av_int2double(uint64_t i) 61 | { 62 | union av_intfloat64 v; 63 | v.i = i; 64 | return v.f; 65 | } 66 | 67 | /** 68 | * Reinterpret a double as a 64-bit integer. 69 | */ 70 | static av_always_inline uint64_t av_double2int(double f) 71 | { 72 | union av_intfloat64 v; 73 | v.f = f; 74 | return v.i; 75 | } 76 | 77 | #endif /* AVUTIL_INTFLOAT_H */ 78 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavutil/motion_vector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of FFmpeg. 3 | * 4 | * FFmpeg is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * FFmpeg is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with FFmpeg; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef AVUTIL_MOTION_VECTOR_H 20 | #define AVUTIL_MOTION_VECTOR_H 21 | 22 | #include 23 | 24 | typedef struct AVMotionVector { 25 | /** 26 | * Where the current macroblock comes from; negative value when it comes 27 | * from the past, positive value when it comes from the future. 28 | * XXX: set exact relative ref frame reference instead of a +/- 1 "direction". 29 | */ 30 | int32_t source; 31 | /** 32 | * Width and height of the block. 33 | */ 34 | uint8_t w, h; 35 | /** 36 | * Absolute source position. Can be outside the frame area. 37 | */ 38 | int16_t src_x, src_y; 39 | /** 40 | * Absolute destination position. Can be outside the frame area. 41 | */ 42 | int16_t dst_x, dst_y; 43 | /** 44 | * Extra flag information. 45 | * Currently unused. 46 | */ 47 | uint64_t flags; 48 | /** 49 | * Motion vector 50 | * src_x = dst_x + motion_x / motion_scale 51 | * src_y = dst_y + motion_y / motion_scale 52 | */ 53 | int32_t motion_x, motion_y; 54 | uint16_t motion_scale; 55 | } AVMotionVector; 56 | 57 | #endif /* AVUTIL_MOTION_VECTOR_H */ 58 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavutil/pixelutils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of FFmpeg. 3 | * 4 | * FFmpeg is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * FFmpeg is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with FFmpeg; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef AVUTIL_PIXELUTILS_H 20 | #define AVUTIL_PIXELUTILS_H 21 | 22 | #include 23 | #include 24 | 25 | /** 26 | * Sum of abs(src1[x] - src2[x]) 27 | */ 28 | typedef int (*av_pixelutils_sad_fn)(const uint8_t *src1, ptrdiff_t stride1, 29 | const uint8_t *src2, ptrdiff_t stride2); 30 | 31 | /** 32 | * Get a potentially optimized pointer to a Sum-of-absolute-differences 33 | * function (see the av_pixelutils_sad_fn prototype). 34 | * 35 | * @param w_bits 1< 3 | * 4 | * This file is part of FFmpeg. 5 | * 6 | * FFmpeg is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * FFmpeg is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with FFmpeg; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef AVUTIL_REVERSE_H 22 | #define AVUTIL_REVERSE_H 23 | 24 | #include 25 | 26 | extern const uint8_t ff_reverse[256]; 27 | 28 | #endif /* AVUTIL_REVERSE_H */ 29 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavutil/time.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2003 Fabrice Bellard 3 | * 4 | * This file is part of FFmpeg. 5 | * 6 | * FFmpeg is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * FFmpeg is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with FFmpeg; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef AVUTIL_TIME_H 22 | #define AVUTIL_TIME_H 23 | 24 | #include 25 | 26 | /** 27 | * Get the current time in microseconds. 28 | */ 29 | int64_t av_gettime(void); 30 | 31 | /** 32 | * Get the current time in microseconds since some unspecified starting point. 33 | * On platforms that support it, the time comes from a monotonic clock 34 | * This property makes this time source ideal for measuring relative time. 35 | * The returned values may not be monotonic on platforms where a monotonic 36 | * clock is not available. 37 | */ 38 | int64_t av_gettime_relative(void); 39 | 40 | /** 41 | * Indicates with a boolean result if the av_gettime_relative() time source 42 | * is monotonic. 43 | */ 44 | int av_gettime_relative_is_monotonic(void); 45 | 46 | /** 47 | * Sleep for a period of time. Although the duration is expressed in 48 | * microseconds, the actual delay may be rounded to the precision of the 49 | * system timer. 50 | * 51 | * @param usec Number of microseconds to sleep. 52 | * @return zero on success or (negative) error code. 53 | */ 54 | int av_usleep(unsigned usec); 55 | 56 | #endif /* AVUTIL_TIME_H */ 57 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libavutil/time_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of FFmpeg. 3 | * 4 | * FFmpeg is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * FFmpeg is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with FFmpeg; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef AVUTIL_TIME_INTERNAL_H 20 | #define AVUTIL_TIME_INTERNAL_H 21 | 22 | #include 23 | #include "config.h" 24 | 25 | #if !HAVE_GMTIME_R && !defined(gmtime_r) 26 | static inline struct tm *ff_gmtime_r(const time_t* clock, struct tm *result) 27 | { 28 | struct tm *ptr = gmtime(clock); 29 | if (!ptr) 30 | return NULL; 31 | *result = *ptr; 32 | return result; 33 | } 34 | #define gmtime_r ff_gmtime_r 35 | #endif 36 | 37 | #if !HAVE_LOCALTIME_R && !defined(localtime_r) 38 | static inline struct tm *ff_localtime_r(const time_t* clock, struct tm *result) 39 | { 40 | struct tm *ptr = localtime(clock); 41 | if (!ptr) 42 | return NULL; 43 | *result = *ptr; 44 | return result; 45 | } 46 | #define localtime_r ff_localtime_r 47 | #endif 48 | 49 | #endif /* AVUTIL_TIME_INTERNAL_H */ 50 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libswresample/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Version macros. 3 | * 4 | * This file is part of libswresample 5 | * 6 | * libswresample is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * libswresample is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with libswresample; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef SWRESAMPLE_VERSION_H 22 | #define SWRESAMPLE_VERSION_H 23 | 24 | /** 25 | * @file 26 | * Libswresample version macros 27 | */ 28 | 29 | #include "libavutil/version.h" 30 | 31 | #include "version_major.h" 32 | 33 | #define LIBSWRESAMPLE_VERSION_MINOR 10 34 | #define LIBSWRESAMPLE_VERSION_MICRO 100 35 | 36 | #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ 37 | LIBSWRESAMPLE_VERSION_MINOR, \ 38 | LIBSWRESAMPLE_VERSION_MICRO) 39 | #define LIBSWRESAMPLE_VERSION AV_VERSION(LIBSWRESAMPLE_VERSION_MAJOR, \ 40 | LIBSWRESAMPLE_VERSION_MINOR, \ 41 | LIBSWRESAMPLE_VERSION_MICRO) 42 | #define LIBSWRESAMPLE_BUILD LIBSWRESAMPLE_VERSION_INT 43 | 44 | #define LIBSWRESAMPLE_IDENT "SwR" AV_STRINGIFY(LIBSWRESAMPLE_VERSION) 45 | 46 | #endif /* SWRESAMPLE_VERSION_H */ 47 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libswresample/version_major.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Version macros. 3 | * 4 | * This file is part of libswresample 5 | * 6 | * libswresample is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * libswresample is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with libswresample; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef SWRESAMPLE_VERSION_MAJOR_H 22 | #define SWRESAMPLE_VERSION_MAJOR_H 23 | 24 | /** 25 | * @file 26 | * Libswresample version macros 27 | */ 28 | 29 | #define LIBSWRESAMPLE_VERSION_MAJOR 4 30 | 31 | #endif /* SWRESAMPLE_VERSION_MAJOR_H */ 32 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libswscale/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of FFmpeg. 3 | * 4 | * FFmpeg is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * FFmpeg is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with FFmpeg; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef SWSCALE_VERSION_H 20 | #define SWSCALE_VERSION_H 21 | 22 | /** 23 | * @file 24 | * swscale version macros 25 | */ 26 | 27 | #include "libavutil/version.h" 28 | 29 | #include "version_major.h" 30 | 31 | #define LIBSWSCALE_VERSION_MINOR 1 32 | #define LIBSWSCALE_VERSION_MICRO 100 33 | 34 | #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ 35 | LIBSWSCALE_VERSION_MINOR, \ 36 | LIBSWSCALE_VERSION_MICRO) 37 | #define LIBSWSCALE_VERSION AV_VERSION(LIBSWSCALE_VERSION_MAJOR, \ 38 | LIBSWSCALE_VERSION_MINOR, \ 39 | LIBSWSCALE_VERSION_MICRO) 40 | #define LIBSWSCALE_BUILD LIBSWSCALE_VERSION_INT 41 | 42 | #define LIBSWSCALE_IDENT "SwS" AV_STRINGIFY(LIBSWSCALE_VERSION) 43 | 44 | #endif /* SWSCALE_VERSION_H */ 45 | -------------------------------------------------------------------------------- /app/src/main/cpp/include/libswscale/version_major.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of FFmpeg. 3 | * 4 | * FFmpeg is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * FFmpeg is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with FFmpeg; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef SWSCALE_VERSION_MAJOR_H 20 | #define SWSCALE_VERSION_MAJOR_H 21 | 22 | /** 23 | * @file 24 | * swscale version macros 25 | */ 26 | 27 | #define LIBSWSCALE_VERSION_MAJOR 7 28 | 29 | /** 30 | * FF_API_* defines may be placed below to indicate public API that will be 31 | * dropped at a future version bump. The defines themselves are not part of 32 | * the public API and may change, break or disappear at any time. 33 | */ 34 | 35 | #endif /* SWSCALE_VERSION_MAJOR_H */ 36 | -------------------------------------------------------------------------------- /app/src/main/cpp/metadata/Mutex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 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 | #ifndef MUTEX_H 18 | #define MUTEX_H 19 | 20 | #include 21 | #include 22 | #include 23 | # include 24 | 25 | 26 | class Mutex { 27 | public: 28 | Mutex(); 29 | ~Mutex(); 30 | 31 | int32_t lock(); 32 | void unlock(); 33 | 34 | class Autolock { 35 | public: 36 | inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } 37 | inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } 38 | inline ~Autolock() { mLock.unlock(); } 39 | private: 40 | Mutex& mLock; 41 | }; 42 | 43 | private: 44 | Mutex(const Mutex&); 45 | Mutex& operator = (const Mutex&); 46 | 47 | pthread_mutex_t mMutex; 48 | }; 49 | 50 | inline Mutex::Mutex() { 51 | pthread_mutex_init(&mMutex, NULL); 52 | } 53 | 54 | inline Mutex::~Mutex() { 55 | pthread_mutex_destroy(&mMutex); 56 | } 57 | 58 | inline int32_t Mutex::lock() { 59 | return -pthread_mutex_lock(&mMutex); 60 | } 61 | 62 | inline void Mutex::unlock() { 63 | pthread_mutex_unlock(&mMutex); 64 | } 65 | 66 | #endif // MUTEX_H 67 | -------------------------------------------------------------------------------- /app/src/main/cpp/metadata/ffmpeg_media_retriever.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by frank on 2022/2/23 3 | * 4 | * part of code from William Seemann 5 | */ 6 | 7 | #ifndef FFMPEG_MEDIA_RETRIEVER_H_ 8 | #define FFMPEG_MEDIA_RETRIEVER_H_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | typedef enum { 20 | OPTION_PREVIOUS_SYNC = 0, 21 | OPTION_NEXT_SYNC = 1, 22 | OPTION_CLOSEST_SYNC = 2, 23 | OPTION_CLOSEST = 3, 24 | } Options; 25 | 26 | typedef struct State { 27 | AVFormatContext *pFormatCtx; 28 | int audio_stream; 29 | int video_stream; 30 | AVStream *audio_st; 31 | AVStream *video_st; 32 | AVCodecContext *audio_codec; 33 | AVCodecContext *video_codec; 34 | int fd; 35 | int64_t offset; 36 | const char *headers; 37 | AVCodecContext *codecCtx; 38 | AVCodecContext *scaled_codecCtx; 39 | ANativeWindow *native_window; 40 | 41 | AVFilterContext *buffersink_ctx; 42 | AVFilterContext *buffersrc_ctx; 43 | AVFilterGraph *filter_graph; 44 | 45 | struct SwsContext *sws_ctx; 46 | struct SwsContext *scaled_sws_ctx; 47 | } State; 48 | 49 | struct AVDictionary { 50 | int count; 51 | AVDictionaryEntry *elems; 52 | }; 53 | 54 | int set_data_source(State **ps, const char* path); 55 | int set_data_source_fd(State **ps, int fd, int64_t offset, int64_t length); 56 | const char* extract_metadata(State **ps, const char* key); 57 | int get_frame_at_time(State **ps, int64_t timeUs, int option, AVPacket *pkt); 58 | int get_scaled_frame_at_time(State **ps, int64_t timeUs, int option, AVPacket *pkt, int width, int height); 59 | int get_audio_thumbnail(State **state_ptr, AVPacket *pkt); 60 | int set_native_window(State **ps, ANativeWindow* native_window); 61 | void release_retriever(State **ps); 62 | 63 | #endif /*FFMPEG_MEDIA_RETRIEVER_H_*/ 64 | -------------------------------------------------------------------------------- /app/src/main/cpp/metadata/media_retriever.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by frank on 2022/2/23 3 | * 4 | * part of code from William Seemann 5 | */ 6 | 7 | #include 8 | 9 | MediaRetriever::MediaRetriever() 10 | { 11 | state = nullptr; 12 | } 13 | 14 | MediaRetriever::~MediaRetriever() 15 | { 16 | Mutex::Autolock lock(mLock); 17 | ::release_retriever(&state); 18 | } 19 | 20 | int MediaRetriever::setDataSource(const char *srcUrl) 21 | { 22 | Mutex::Autolock lock(mLock); 23 | return ::set_data_source(&state, srcUrl); 24 | } 25 | 26 | int MediaRetriever::setDataSource(int fd, int64_t offset, int64_t length) 27 | { 28 | Mutex::Autolock lock(mLock); 29 | return ::set_data_source_fd(&state, fd, offset, length); 30 | } 31 | 32 | const char* MediaRetriever::extractMetadata(const char *key) 33 | { 34 | Mutex::Autolock lock(mLock); 35 | return ::extract_metadata(&state, key); 36 | } 37 | 38 | int MediaRetriever::getFrameAtTime(int64_t timeUs, int option, AVPacket *pkt) 39 | { 40 | Mutex::Autolock lock(mLock); 41 | return ::get_frame_at_time(&state, timeUs, option, pkt); 42 | } 43 | 44 | int MediaRetriever::getScaledFrameAtTime(int64_t timeUs, int option, AVPacket *pkt, int width, int height) 45 | { 46 | Mutex::Autolock lock(mLock); 47 | return ::get_scaled_frame_at_time(&state, timeUs, option, pkt, width, height); 48 | } 49 | 50 | int MediaRetriever::getAudioThumbnail(AVPacket *pkt) 51 | { 52 | Mutex::Autolock lock(mLock); 53 | return ::get_audio_thumbnail(&state, pkt); 54 | } 55 | 56 | int MediaRetriever::setNativeWindow(ANativeWindow* native_window) 57 | { 58 | Mutex::Autolock lock(mLock); 59 | return ::set_native_window(&state, native_window); 60 | } -------------------------------------------------------------------------------- /app/src/main/cpp/metadata/media_retriever.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by frank on 2022/2/23 3 | * 4 | * part of code from William Seemann 5 | */ 6 | 7 | #ifndef MEDIA_RETRIEVER_H 8 | #define MEDIA_RETRIEVER_H 9 | 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | #include "ffmpeg_media_retriever.h" 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | 22 | class MediaRetriever 23 | { 24 | State* state; 25 | public: 26 | MediaRetriever(); 27 | ~MediaRetriever(); 28 | int setDataSource(const char* dataSourceUrl); 29 | int setDataSource(int fd, int64_t offset, int64_t length); 30 | const char* extractMetadata(const char* key); 31 | int getFrameAtTime(int64_t timeUs, int option, AVPacket *pkt); 32 | int getScaledFrameAtTime(int64_t timeUs, int option, AVPacket *pkt, int width, int height); 33 | int getAudioThumbnail(AVPacket *pkt); 34 | int setNativeWindow(ANativeWindow* native_window); 35 | 36 | private: 37 | Mutex mLock; 38 | }; 39 | 40 | #endif // MEDIA_RETRIEVER_H 41 | -------------------------------------------------------------------------------- /app/src/main/cpp/metadata/metadata_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by frank on 2022/2/23 3 | * 4 | * part of code from William Seemann 5 | */ 6 | 7 | #ifndef METADATA_UTIL_H_ 8 | #define METADATA_UTIL_H_ 9 | 10 | #include "libavutil/opt.h" 11 | #include "libavcodec/avcodec.h" 12 | #include "libavformat/avformat.h" 13 | 14 | static const char *DURATION = "duration"; 15 | static const char *AUDIO_CODEC = "audio_codec"; 16 | static const char *VIDEO_CODEC = "video_codec"; 17 | static const char *ROTATE = "rotate"; 18 | static const char *FRAME_RATE = "frame_rate"; 19 | static const char *FILE_SIZE = "file_size"; 20 | static const char *VIDEO_WIDTH = "video_width"; 21 | static const char *VIDEO_HEIGHT = "video_height"; 22 | static const char *MIME_TYPE = "mime_type"; 23 | static const char *SAMPLE_RATE = "sample_rate"; 24 | static const char *CHANNEL_COUNT = "channel_count"; 25 | static const char *CHANNEL_LAYOUT = "channel_layout"; 26 | static const char *PIXEL_FORMAT = "pixel_format"; 27 | 28 | static const int SUCCESS = 0; 29 | static const int FAILURE = -1; 30 | 31 | void set_duration(AVFormatContext *ic); 32 | void set_file_size(AVFormatContext *ic); 33 | void set_mimetype(AVFormatContext *ic); 34 | void set_codec(AVFormatContext *ic, int i); 35 | void set_sample_rate(AVFormatContext *ic, AVStream *stream); 36 | void set_channel_count(AVFormatContext *ic, AVStream *stream); 37 | void set_channel_layout(AVFormatContext *ic, AVStream *stream); 38 | void set_pixel_format(AVFormatContext *ic, AVStream *stream); 39 | void set_video_resolution(AVFormatContext *ic, AVStream *video_st); 40 | void set_rotation(AVFormatContext *ic, AVStream *audio_st, AVStream *video_st); 41 | void set_frame_rate(AVFormatContext *ic, AVStream *video_st); 42 | const char* extract_metadata_internal(AVFormatContext *ic, AVStream *audio_st, AVStream *video_st, const char* key); 43 | 44 | #endif /*METADATA_UTIL_H_*/ 45 | -------------------------------------------------------------------------------- /app/src/main/cpp/video_cutting.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by xu fulong on 2022/5/13. 3 | // 4 | 5 | #ifndef CUT_VIDEO_H 6 | #define CUT_VIDEO_H 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | #include "libavformat/avformat.h" 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | class CutVideo { 17 | private: 18 | 19 | int64_t m_startTime = 15; 20 | int64_t m_duration = 10; 21 | 22 | int64_t *dts_start_offset; 23 | int64_t *pts_start_offset; 24 | 25 | AVFormatContext *ofmt_ctx = nullptr; 26 | 27 | AVPacket* copy_packet(AVFormatContext *ifmt_ctx, AVPacket *packet); 28 | 29 | int write_internal(AVFormatContext *ifmt_ctx, AVPacket *packet); 30 | 31 | public: 32 | 33 | int open_output_file(AVFormatContext *ifmt_ctx, const char *filename); 34 | 35 | void setParam(int64_t start_time, int64_t duration); 36 | 37 | void write_output_file(AVFormatContext *ifmt_ctx, AVPacket *packet); 38 | 39 | void close_output_file(); 40 | }; 41 | 42 | #endif //CUT_VIDEO_H 43 | -------------------------------------------------------------------------------- /app/src/main/cpp/visualizer/fft.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * fft.h: Headers for iterative implementation of a FFT 3 | ***************************************************************************** 4 | * 5 | * Mainly taken from XMMS's code 6 | * 7 | * Authors: Richard Boulton 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 22 | *****************************************************************************/ 23 | 24 | #ifndef VLC_VISUAL_FFT_H_ 25 | #define VLC_VISUAL_FFT_H_ 26 | 27 | #define FFT_BUFFER_SIZE_LOG 8 28 | 29 | #define FFT_BUFFER_SIZE (1 << FFT_BUFFER_SIZE_LOG) 30 | 31 | /* sound sample - should be an signed 16 bit value */ 32 | typedef short int sound_sample; 33 | 34 | struct _struct_fft_state { 35 | /* Temporary data stores to perform FFT in. */ 36 | float real[FFT_BUFFER_SIZE]; 37 | float imag[FFT_BUFFER_SIZE]; 38 | 39 | /* */ 40 | unsigned int bitReverse[FFT_BUFFER_SIZE]; 41 | 42 | /* The next two tables could be made to use less space in memory, since they 43 | * overlap hugely, but hey. */ 44 | float sintable[FFT_BUFFER_SIZE / 2]; 45 | float costable[FFT_BUFFER_SIZE / 2]; 46 | }; 47 | 48 | /* FFT prototypes */ 49 | typedef struct _struct_fft_state fft_state; 50 | fft_state *visual_fft_init (void); 51 | void fft_perform (const sound_sample *input, float *output, fft_state *state); 52 | void fft_close (fft_state *state); 53 | 54 | 55 | #endif /* include-guard */ 56 | -------------------------------------------------------------------------------- /app/src/main/cpp/visualizer/fixed_fft.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FIXED_FFT_H 3 | #define FIXED_FFT_H 4 | 5 | #include 6 | 7 | 8 | extern void fixed_fft_real(int n, int32_t *v); 9 | 10 | 11 | #endif // FIXED_FFT_H -------------------------------------------------------------------------------- /app/src/main/cpp/visualizer/frank_visualizer.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by frank on 2021/8/16. 3 | // 4 | 5 | #ifndef FRANK_VISUALIZER_H 6 | #define FRANK_VISUALIZER_H 7 | 8 | #include 9 | #include 10 | 11 | #include "fft.h" 12 | #include "window.h" 13 | #include "fixed_fft.h" 14 | 15 | #define MIN_FFT_SIZE 128 16 | #define MAX_FFT_SIZE 1024 17 | 18 | #define FIXED_FFT 1 19 | 20 | typedef struct 21 | { 22 | bool convert_to_float; 23 | int i_channels; 24 | int i_prev_nb_samples; 25 | int16_t *p_prev_s16_buff; 26 | 27 | window_param *wind_param; 28 | 29 | uint8_t *data; 30 | int data_size; 31 | int nb_samples; 32 | int8_t *output; 33 | int out_samples; 34 | } filter_sys_t; 35 | 36 | 37 | class FrankVisualizer { 38 | 39 | private: 40 | std::mutex mFftLock; 41 | 42 | filter_sys_t *fft_context = nullptr; 43 | 44 | public: 45 | FrankVisualizer(); 46 | ~FrankVisualizer(); 47 | 48 | int getOutputSample(); 49 | 50 | int8_t* getFFTData(); 51 | 52 | int8_t* fft_run(uint8_t *input_buffer, int nb_samples); 53 | 54 | int init_visualizer(); 55 | 56 | void release_visualizer(); 57 | }; 58 | 59 | #endif //FRANK_VISUALIZER_H 60 | -------------------------------------------------------------------------------- /app/src/main/cpp/yuv/yuv_converter.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by xu fulong on 2022/7/9. 3 | // 4 | 5 | #ifndef FFMPEGANDROID_YUV_CONVERTER_H 6 | #define FFMPEGANDROID_YUV_CONVERTER_H 7 | 8 | #include 9 | 10 | static void rgba_to_yuv420p(const int *argb, int8_t *yuv, int width, int height); 11 | 12 | static void yuv420p_to_argb(const int8_t *yuv, int *argb, int width, int height); 13 | 14 | static void yuv420p_rotate(int8_t *dst, int8_t *src, int width, int height, int degree); 15 | 16 | /** 17 | * convert NV21 to YUV420P 18 | * @param dst data of yuv420p 19 | * @param src data of nv21 20 | * @param len width*height 21 | */ 22 | static void nv21_to_yuv420p(int8_t *dst, int8_t *src, int len); 23 | 24 | /** 25 | * convert NV12 to YUV420P 26 | * @param dst data of yuv420p 27 | * @param src data of nv12 28 | * @param len width*height 29 | */ 30 | static void nv12_to_yuv420p(int8_t *dst, int8_t *src, int len); 31 | 32 | #endif //FFMPEGANDROID_YUV_CONVERTER_H 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/CommonMediaHelper.java: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg; 2 | 3 | /** 4 | * @author xufulong 5 | * @date 2022/9/7 10:16 上午 6 | * @desc 7 | */ 8 | public class CommonMediaHelper { 9 | 10 | static { 11 | System.loadLibrary("media-handle"); 12 | } 13 | 14 | public native int audioResample(String inputFile, String outputFile, int sampleRate); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/FFmpegApplication.java: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg; 2 | 3 | import android.app.Application; 4 | 5 | public class FFmpegApplication extends Application { 6 | 7 | private static FFmpegApplication context; 8 | 9 | @Override 10 | public void onCreate() { 11 | super.onCreate(); 12 | context = this; 13 | } 14 | 15 | public static FFmpegApplication getInstance() { 16 | return context; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/FFmpegPusher.java: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg; 2 | 3 | /** 4 | * Using FFmpeg to push FLV stream 5 | * Created by frank on 2018/2/2. 6 | */ 7 | 8 | public class FFmpegPusher { 9 | static { 10 | System.loadLibrary("media-handle"); 11 | } 12 | 13 | /** 14 | * JNI interface: select file and push to rtmp server 15 | * 16 | * @param filePath liveUrl 17 | * @param liveUrl the url of rtmp server 18 | * @return the result of pushing stream 19 | */ 20 | public native int pushStream(String filePath, String liveUrl); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/VideoPlayer.java: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg; 2 | 3 | import android.media.AudioFormat; 4 | import android.media.AudioManager; 5 | import android.media.AudioTrack; 6 | 7 | /** 8 | * VideoPlayer: using FFmpeg filter 9 | * Created by frank on 2018/2/1 10 | */ 11 | public class VideoPlayer { 12 | 13 | static { 14 | System.loadLibrary("media-handle"); 15 | } 16 | 17 | public native int filter(String filePath, Object surface, int position); 18 | 19 | public native void again(int position); 20 | 21 | public native void release(); 22 | 23 | public native void playAudio(boolean play); 24 | 25 | public native int executeTranscode(String inputFile, String outputFile); 26 | 27 | /** 28 | * Create an AudioTrack instance for JNI calling 29 | * 30 | * @param sampleRate sampleRate 31 | * @param channels channel layout 32 | * @return AudioTrack 33 | */ 34 | public AudioTrack createAudioTrack(int sampleRate, int channels) { 35 | int audioFormat = AudioFormat.ENCODING_PCM_16BIT; 36 | int channelConfig; 37 | if (channels == 1) { 38 | channelConfig = AudioFormat.CHANNEL_OUT_MONO; 39 | } else if (channels == 2) { 40 | channelConfig = AudioFormat.CHANNEL_OUT_STEREO; 41 | } else { 42 | channelConfig = AudioFormat.CHANNEL_OUT_STEREO; 43 | } 44 | 45 | int bufferSizeInBytes = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat); 46 | 47 | return new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, channelConfig, audioFormat, 48 | bufferSizeInBytes, AudioTrack.MODE_STREAM); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/activity/CameraFilterActivity.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.activity 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import com.frank.camerafilter.factory.BeautyFilterType 6 | import com.frank.camerafilter.widget.BeautyCameraView 7 | import com.frank.ffmpeg.R 8 | import com.frank.ffmpeg.util.FilterTypeUtil 9 | 10 | class CameraFilterActivity : BaseActivity() { 11 | 12 | private var cameraView: BeautyCameraView ?= null 13 | 14 | private var index: Int = 0 15 | 16 | private val filterType: Array = arrayOf( 17 | BeautyFilterType.NONE, 18 | BeautyFilterType.SATURATION, 19 | BeautyFilterType.CONTRAST, 20 | BeautyFilterType.BRIGHTNESS, 21 | BeautyFilterType.SHARPEN, 22 | BeautyFilterType.BLUR, 23 | BeautyFilterType.HUE, 24 | BeautyFilterType.WHITE_BALANCE, 25 | BeautyFilterType.SKETCH, 26 | BeautyFilterType.OVERLAY, 27 | BeautyFilterType.BREATH_CIRCLE 28 | ) 29 | 30 | override val layoutId: Int 31 | get() = R.layout.activity_camera_filter 32 | 33 | override fun onCreate(savedInstanceState: Bundle?) { 34 | super.onCreate(savedInstanceState) 35 | 36 | initView() 37 | } 38 | 39 | fun initView() { 40 | cameraView = getView(R.id.surface_camera_filter) 41 | initViewsWithClick(R.id.btn_video_recorder) 42 | initViewsWithClick(R.id.btn_camera_filter) 43 | } 44 | 45 | override fun onViewClick(view: View) { 46 | if (view.id == R.id.btn_video_recorder) { 47 | val isRecording = cameraView!!.isRecording 48 | cameraView!!.isRecording = !isRecording 49 | if (!isRecording) { 50 | showToast("start recording...") 51 | } else { 52 | showToast("stop recording...") 53 | } 54 | } else if (view.id == R.id.btn_camera_filter) { 55 | index++ 56 | if (index >= filterType.size) 57 | index = 0 58 | cameraView!!.setFilter(filterType[index]) 59 | showToast(getString(FilterTypeUtil.filterTypeToNameId(filterType[index]))) 60 | } 61 | } 62 | 63 | override fun onSelectedFile(filePath: String) { 64 | 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/activity/PushActivity.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.activity 2 | 3 | import android.os.Bundle 4 | import android.text.TextUtils 5 | import android.util.Log 6 | import android.view.View 7 | import android.widget.EditText 8 | 9 | import com.frank.ffmpeg.FFmpegPusher 10 | import com.frank.ffmpeg.R 11 | 12 | import java.io.File 13 | 14 | /** 15 | * Using FFmpeg to push rtmp stream, 16 | * with SRS media server convert to http-flv stream 17 | * Created by frank on 2018/2/2. 18 | */ 19 | class PushActivity : BaseActivity() { 20 | 21 | private var editInputPath: EditText? = null 22 | 23 | private var editLiveURL: EditText? = null 24 | 25 | override val layoutId: Int 26 | get() = R.layout.activity_push 27 | 28 | override fun onCreate(savedInstanceState: Bundle?) { 29 | super.onCreate(savedInstanceState) 30 | 31 | hideActionBar() 32 | initView() 33 | } 34 | 35 | private fun initView() { 36 | editInputPath = getView(R.id.edit_file_path) 37 | editLiveURL = getView(R.id.edit_live_url) 38 | editInputPath!!.setText(INPUT_PATH) 39 | editLiveURL!!.setText(LIVE_URL) 40 | 41 | initViewsWithClick(R.id.btn_push_stream) 42 | } 43 | 44 | private fun startPushStreaming() { 45 | val filePath = editInputPath!!.text.toString() 46 | val liveUrl = editLiveURL!!.text.toString() 47 | 48 | if (!TextUtils.isEmpty(filePath) && !TextUtils.isEmpty(filePath)) { 49 | Thread(Runnable { 50 | FFmpegPusher().pushStream(filePath, liveUrl) 51 | }).start() 52 | } 53 | } 54 | 55 | override fun onViewClick(view: View) { 56 | if (view.id == R.id.btn_push_stream) { 57 | startPushStreaming() 58 | } 59 | } 60 | 61 | override fun onSelectedFile(filePath: String) { 62 | 63 | } 64 | 65 | companion object { 66 | 67 | // storage/emulated/0/beyond.mp4 68 | private const val INPUT_PATH = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" 69 | private const val LIVE_URL = "rtmp://192.168.17.168/live/stream" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/adapter/HorizontalAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.adapter 2 | 3 | import android.graphics.Color 4 | import androidx.recyclerview.widget.RecyclerView 5 | 6 | import android.view.LayoutInflater 7 | import android.view.View 8 | import android.view.ViewGroup 9 | import android.widget.Button 10 | 11 | import com.frank.ffmpeg.R 12 | import com.frank.ffmpeg.listener.OnItemClickListener 13 | 14 | /** 15 | * the horizontal adapter of RecyclerView 16 | * Created by frank on 2018/6/6. 17 | */ 18 | 19 | class HorizontalAdapter(private val itemList: List?) : RecyclerView.Adapter() { 20 | private var onItemClickListener: OnItemClickListener? = null 21 | private var lastClickPosition: Int = 0 22 | 23 | fun setOnItemClickListener(onItemClickListener: OnItemClickListener) { 24 | this.onItemClickListener = onItemClickListener 25 | } 26 | 27 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { 28 | return OkViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_select, parent, false)) 29 | } 30 | 31 | override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { 32 | val okViewHolder = holder as OkViewHolder 33 | okViewHolder.btnSelect.text = itemList!![position] 34 | okViewHolder.btnSelect.setTextColor(Color.DKGRAY) 35 | if (onItemClickListener != null) { 36 | okViewHolder.btnSelect.setOnClickListener { 37 | notifyItemChanged(lastClickPosition) 38 | //select the current color 39 | okViewHolder.btnSelect.setTextColor(Color.BLUE) 40 | onItemClickListener!!.onItemClick(okViewHolder.absoluteAdapterPosition) 41 | lastClickPosition = okViewHolder.absoluteAdapterPosition 42 | } 43 | } 44 | } 45 | 46 | override fun getItemCount(): Int { 47 | return itemList?.size ?: 0 48 | } 49 | 50 | private inner class OkViewHolder internal constructor(itemView: View) : RecyclerView.ViewHolder(itemView) { 51 | internal var btnSelect: Button = itemView.findViewById(R.id.btn_select) 52 | 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/effect/FrankVisualizer.java: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.effect; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | /** 6 | * @author frank 7 | * @date 2021/10/1 11:25 8 | * @desc custom audio visualizer 9 | */ 10 | public class FrankVisualizer { 11 | 12 | private long mNativeVisualizer; 13 | 14 | private static OnFftDataListener mOnFftDataListener; 15 | 16 | public FrankVisualizer() {} 17 | 18 | public void setOnFftDataListener(OnFftDataListener onFftDataListener) { 19 | mOnFftDataListener = onFftDataListener; 20 | } 21 | 22 | public int initVisualizer() { 23 | return nativeInitVisualizer(); 24 | } 25 | 26 | public void captureData(ByteBuffer data, int size) { 27 | if (data == null || size <= 0) { 28 | nativeCaptureData(data, size); 29 | } 30 | } 31 | 32 | public void releaseVisualizer() { 33 | mOnFftDataListener = null; 34 | nativeReleaseVisualizer(); 35 | } 36 | 37 | public interface OnFftDataListener { 38 | void onFftData(byte[] data); 39 | } 40 | 41 | public static void onFftCallback(byte[] data) { 42 | if (mOnFftDataListener != null) { 43 | mOnFftDataListener.onFftData(data); 44 | } 45 | } 46 | 47 | private native int nativeInitVisualizer(); 48 | 49 | private native int nativeCaptureData(ByteBuffer buffer, int size); 50 | 51 | private native void nativeReleaseVisualizer(); 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/handler/ConnectionReceiver.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.handler 2 | 3 | import android.content.BroadcastReceiver 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.net.ConnectivityManager 7 | import com.frank.ffmpeg.listener.OnNetworkChangeListener 8 | 9 | class ConnectionReceiver(networkChangeListener: OnNetworkChangeListener) : BroadcastReceiver() { 10 | 11 | var networkChangeListener :OnNetworkChangeListener ?= networkChangeListener 12 | 13 | override fun onReceive(context: Context?, intent: Intent?) { 14 | 15 | if (ConnectivityManager.CONNECTIVITY_ACTION == intent?.action) { 16 | val connectivityManager : ConnectivityManager = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager 17 | val activeNetworkInfo = connectivityManager.activeNetworkInfo 18 | if (activeNetworkInfo == null || !activeNetworkInfo.isAvailable) { 19 | networkChangeListener?.onNetworkChange() 20 | } 21 | 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/listener/OnHandleListener.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.listener 2 | 3 | /** 4 | * listener of FFmpeg processing 5 | * Created by frank on 2019/11/11. 6 | */ 7 | interface OnHandleListener { 8 | fun onBegin() 9 | fun onMsg(msg: String) 10 | fun onProgress(progress: Int, duration: Int) 11 | fun onEnd(resultCode: Int, resultMsg: String) 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/listener/OnItemClickListener.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.listener 2 | 3 | /** 4 | * listener of RecyclerView item clicking 5 | * Created by frank on 2018/6/6. 6 | */ 7 | 8 | interface OnItemClickListener { 9 | 10 | fun onItemClick(position: Int) 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/listener/OnLrcListener.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.listener 2 | 3 | import com.frank.ffmpeg.model.LrcLine 4 | 5 | interface OnLrcListener { 6 | 7 | fun onLrcSeek(position: Int, lrcLine: LrcLine) 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/listener/OnNetworkChangeListener.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.listener 2 | 3 | interface OnNetworkChangeListener { 4 | 5 | fun onNetworkChange() 6 | 7 | } -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/listener/OnSeekBarListener.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.listener 2 | 3 | interface OnSeekBarListener { 4 | fun onProgress(index: Int, progress: Int) 5 | } -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/model/AudioBean.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.model 2 | 3 | /** 4 | * the model of audio data 5 | * Created by frank on 2020/1/7. 6 | */ 7 | class AudioBean { 8 | 9 | //"codec_tag_string": "mp4a" 10 | var audioCodec: String? = null 11 | get() = if ("[0][0][0][0]" == field) { 12 | null 13 | } else field 14 | 15 | //"sample_rate": "44100" 16 | var sampleRate: Int = 0 17 | 18 | //"channels": 2 19 | var channels: Int = 0 20 | 21 | //"channel_layout": "stereo" 22 | var channelLayout: String? = null 23 | 24 | var title: String? = null 25 | 26 | var artist: String? = null 27 | 28 | var album: String? = null 29 | 30 | var albumArtist: String? = null 31 | 32 | var composer: String? = null 33 | 34 | var genre: String? = null 35 | 36 | var lyrics: List? = null 37 | 38 | var lrcLineList: List? = null 39 | 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/model/LrcInfo.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.model 2 | 3 | class LrcInfo { 4 | 5 | var title: String? = null 6 | var album: String? = null 7 | var artist: String? = null 8 | var author: String? = null 9 | var creator: String? = null 10 | var encoder: String? = null 11 | var version: String? = null 12 | var offset: Int = 0 13 | 14 | var lrcLineList: List? = null 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/model/LrcLine.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.model 2 | 3 | 4 | class LrcLine : Comparable { 5 | 6 | var timeString: String? = null 7 | 8 | var startTime: Long = 0 9 | 10 | var endTime: Long = 0 11 | 12 | var content: String? = null 13 | 14 | override fun compareTo(another: LrcLine): Int { 15 | return (this.startTime - another.startTime).toInt() 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/model/MediaBean.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.model 2 | 3 | /** 4 | * the model of media data 5 | * Created by frank on 2020/1/7. 6 | */ 7 | class MediaBean { 8 | 9 | var videoBean: VideoBean? = null 10 | 11 | var audioBean: AudioBean? = null 12 | 13 | // "duration": "313.330000" 14 | var duration: Long = 0 15 | 16 | // "size": "22160429" 17 | var size: Long = 0 18 | 19 | // "bit_rate": "565804" 20 | var bitRate: Int = 0 21 | 22 | // "format_name": "mov,mp4,m4a,3gp,3g2,mj2" 23 | var formatName: String? = null 24 | 25 | // "nb_streams": 2 26 | var streamNum: Int = 0 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/model/VideoBean.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.model 2 | 3 | /** 4 | * the model of video data 5 | * Created by frank on 2020/1/7. 6 | */ 7 | class VideoBean { 8 | 9 | //"codec_tag_string": "avc1" 10 | var videoCodec: String? = null 11 | get() = if ("[0][0][0][0]" == field) { 12 | null 13 | } else field 14 | 15 | //"width": 640 16 | var width: Int = 0 17 | 18 | //"height": 360 19 | var height: Int = 0 20 | 21 | //"display_aspect_ratio": "16:9" 22 | var displayAspectRatio: String? = null 23 | 24 | //"pix_fmt": "yuv420p" 25 | var pixelFormat: String? = null 26 | 27 | //"profile": "578" 28 | var profile: String? = null 29 | 30 | //"level": 30 31 | var level: Int = 0 32 | 33 | //"r_frame_rate": "24000/1001" 34 | var frameRate: Int = 0 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/model/VideoLayout.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.model 2 | 3 | /** 4 | * layout of video 5 | * Created by frank on 2018/6/18. 6 | */ 7 | 8 | object VideoLayout { 9 | 10 | //horizontal join 11 | const val LAYOUT_HORIZONTAL = 1 12 | //vertical join 13 | const val LAYOUT_VERTICAL = 2 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/util/FilterTypeUtil.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.util 2 | 3 | import com.frank.camerafilter.factory.BeautyFilterType 4 | import com.frank.ffmpeg.R 5 | 6 | /** 7 | * @author xufulong 8 | * @date 2022/10/17 5:39 下午 9 | * @desc 10 | */ 11 | object FilterTypeUtil { 12 | 13 | fun filterTypeToNameId(type: BeautyFilterType): Int { 14 | return when (type) { 15 | BeautyFilterType.NONE -> R.string.camera_filter_none 16 | BeautyFilterType.BRIGHTNESS -> R.string.camera_filter_brightness 17 | BeautyFilterType.SATURATION -> R.string.camera_filter_saturation 18 | BeautyFilterType.CONTRAST -> R.string.camera_filter_contrast 19 | BeautyFilterType.SHARPEN -> R.string.camera_filter_sharpen 20 | BeautyFilterType.BLUR -> R.string.camera_filter_blur 21 | BeautyFilterType.HUE -> R.string.camera_filter_hue 22 | BeautyFilterType.WHITE_BALANCE -> R.string.camera_filter_balance 23 | BeautyFilterType.SKETCH -> R.string.camera_filter_sketch 24 | BeautyFilterType.OVERLAY -> R.string.camera_filter_overlay 25 | BeautyFilterType.BREATH_CIRCLE -> R.string.camera_filter_circle 26 | else -> R.string.camera_filter_none 27 | } 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/util/ScreenUtil.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.util 2 | 3 | import android.content.Context 4 | import android.util.DisplayMetrics 5 | import android.view.WindowManager 6 | 7 | object ScreenUtil { 8 | 9 | private fun getDisplayMetrics(context: Context): DisplayMetrics? { 10 | val windowManager = context.applicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager 11 | val displayMetrics = DisplayMetrics() 12 | windowManager.defaultDisplay.getMetrics(displayMetrics) 13 | return displayMetrics 14 | } 15 | 16 | fun getScreenWidth(context: Context?): Int { 17 | if (context == null) { 18 | return 0 19 | } 20 | val displayMetrics = getDisplayMetrics(context) 21 | return displayMetrics?.widthPixels ?: 0 22 | } 23 | 24 | fun getScreenHeight(context: Context?): Int { 25 | if (context == null) { 26 | return 0 27 | } 28 | val displayMetrics = getDisplayMetrics(context) 29 | return displayMetrics?.heightPixels ?: 0 30 | } 31 | 32 | fun dp2px(context: Context?, dpValue: Int): Int { 33 | if (context == null) { 34 | return 0 35 | } 36 | val displayMetrics = getDisplayMetrics(context) 37 | val density: Float = displayMetrics?.density ?: 0F 38 | return (dpValue * density + 0.5f).toInt() 39 | } 40 | 41 | fun px2dp(context: Context?, pxValue: Int): Int { 42 | if (context == null) { 43 | return 0 44 | } 45 | val displayMetrics = getDisplayMetrics(context) 46 | val density: Float = displayMetrics?.density ?: 0F 47 | return (pxValue / density + 0.5f).toInt() 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/frank/ffmpeg/util/ThreadPoolUtil.kt: -------------------------------------------------------------------------------- 1 | package com.frank.ffmpeg.util 2 | 3 | import java.util.concurrent.ExecutorService 4 | import java.util.concurrent.Executors 5 | 6 | object ThreadPoolUtil { 7 | 8 | private val executor = Executors.newSingleThreadExecutor() 9 | 10 | fun executeSingleThreadPool(runnable: Runnable): ExecutorService { 11 | executor.submit(runnable) 12 | return executor 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_camera_filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/app/src/main/res/drawable-xhdpi/ic_camera_filter.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/app/src/main/res/drawable-xhdpi/ic_pause.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/app/src/main/res/drawable-xhdpi/ic_play.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_video_record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xufuji456/FFmpegAndroid/9c7668067b10ac7538a976cb8e7beb70b4aa845f/app/src/main/res/drawable-xhdpi/ic_video_record.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_point.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_rect_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_rect_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/white_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_camera_filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 23 | 24 | 30 | 31 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 16 | 17 | 25 | 26 |