From 9773f3da1389f4e52fecfc79686fe2c94b08d6bc Mon Sep 17 00:00:00 2001 From: Peng Li Date: Tue, 22 May 2018 14:48:47 +0800 Subject: [PATCH] Add NetworkMonitor --- app/src/main/AndroidManifest.xml | 1 + .../java/ai/suanzi/rtmpclient/FfmpegHelper.java | 9 +- .../java/ai/suanzi/rtmpclient/MainActivity.java | 116 ++++++++++----------- .../main/java/ai/suanzi/rtmpclient/MyService.java | 12 +-- .../java/ai/suanzi/rtmpclient/NetworkMonitor.java | 64 ++++++++++++ .../main/java/ai/suanzi/rtmpclient/UsbMonitor.java | 4 + .../java/ai/suanzi/rtmpclient/WifiReceiver.java | 47 +++++++++ app/src/main/jni/.vim-bookmarks | 3 - app/src/main/jni/Application.mk | 2 +- app/src/main/jni/FfmpegHelper.cpp | 74 ++++++++----- app/src/main/jni/FfmpegHelper.h | 6 +- .../main/jni/ai_suanzi_rtmpclient_FfmpegHelper.cpp | 4 +- .../main/jni/ai_suanzi_rtmpclient_FfmpegHelper.h | 4 +- 13 files changed, 240 insertions(+), 106 deletions(-) create mode 100644 app/src/main/java/ai/suanzi/rtmpclient/NetworkMonitor.java create mode 100644 app/src/main/java/ai/suanzi/rtmpclient/UsbMonitor.java create mode 100644 app/src/main/java/ai/suanzi/rtmpclient/WifiReceiver.java delete mode 100644 app/src/main/jni/.vim-bookmarks diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b255af6..6c2a7f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -36,6 +36,7 @@ + diff --git a/app/src/main/java/ai/suanzi/rtmpclient/FfmpegHelper.java b/app/src/main/java/ai/suanzi/rtmpclient/FfmpegHelper.java index 5863243..ad69bf9 100644 --- a/app/src/main/java/ai/suanzi/rtmpclient/FfmpegHelper.java +++ b/app/src/main/java/ai/suanzi/rtmpclient/FfmpegHelper.java @@ -23,12 +23,15 @@ public class FfmpegHelper { private static Logger gLogger = Logger.getLogger("FfmpegHelper"); // callback from native - public static void javaPrint(String string){ - gLogger.error(string); + public static void javaPrint(String string, int level){ + if(level == 1) + gLogger.error(string); + else + gLogger.info(string); } // native methods - public static native int initialEncoder(int width, int height, String url); + public static native int initEncoder(int width, int height, String url); public static native int processFrame(byte[] frame); public static native int close(); } diff --git a/app/src/main/java/ai/suanzi/rtmpclient/MainActivity.java b/app/src/main/java/ai/suanzi/rtmpclient/MainActivity.java index 4886501..320e2bb 100644 --- a/app/src/main/java/ai/suanzi/rtmpclient/MainActivity.java +++ b/app/src/main/java/ai/suanzi/rtmpclient/MainActivity.java @@ -47,6 +47,7 @@ import android.content.ComponentName; import ai.suanzi.rtmpclient.MyService.LocalBinder; import android.os.IBinder; +import android.net.ConnectivityManager; //"rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90_cameraid"; @@ -75,6 +76,7 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal private String mMacAddr = ""; //private CameraView mCameraView; private String mRtmpUrl; + private NetworkMonitor networkMonitor; boolean mBounded; MyService mServer; @@ -110,8 +112,6 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal mSufaceView = findViewById(R.id.surfaceView); mHolder = mSufaceView.getHolder(); mHolder.addCallback(this); - - //intent.setPackage(this.getPackageName()); // init service //intent.setAction("ai.suanzi.rtmpclient.service"); } @@ -136,10 +136,24 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal if(mServer.setRtmpUrl(UserInfo.getConfig().toUrl())){ mServer.startPreview(mHolder); } - } }; + private void doBindService(){ + if(!mBounded) { + gLogger.debug("doBindService"); + bindService(mIntent, mConnection, BIND_AUTO_CREATE); + } + } + + private void doUnbindService() { + if(mBounded){ + gLogger.debug("doUnbindService"); + unbindService(mConnection); + mBounded = false; + } + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -150,8 +164,12 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal //startService(intent); mIntent = new Intent(this, MyService.class); - bindService(mIntent, mConnection, BIND_AUTO_CREATE); - + if(NetworkMonitor.isNetworkAvailable(this)){ + gLogger.error("Current network is available"); + doBindService(); + } else { + gLogger.error("Current network is NOT available"); + } mBtnStart.setText("start"); mBtnStart.setOnClickListener(new View.OnClickListener(){ @@ -159,10 +177,39 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal public void onClick(View view){ gLogger.error("----------> onClick"); saveConfig(); - unbindService(mConnection); - bindService(mIntent, mConnection, BIND_AUTO_CREATE); + doUnbindService(); + } }); + + if ( networkMonitor == null) { + networkMonitor = new NetworkMonitor(new NetworkMonitor.NetworkListener() { + @Override + public void onWifiConnected() { + gLogger.error("onWifiConnected"); + doBindService(); + } + + @Override + public void onWifiDisconnected() { + gLogger.error("onWifiDisconnected"); + doUnbindService(); + } + + @Override + public void onWifiEnabled() { + gLogger.error("onWifiEnabled"); + } + + @Override + public void onWifiDisabled() { + gLogger.error("onWifiDisabled"); + } + }); + } + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + registerReceiver(networkMonitor, filter); } @Override @@ -192,6 +239,7 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal @Override protected void onDestroy(){ super.onDestroy(); + unregisterReceiver(networkMonitor); gLogger.debug("onDestroy --------->"); } @@ -201,9 +249,6 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal gLogger.debug("onRestart ---------->"); } - - - // SurfaceHolder.Callback implementation @Override public void surfaceCreated(final SurfaceHolder holder){ @@ -323,55 +368,4 @@ public class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal i.addCategory(Intent.CATEGORY_HOME); this.startActivity(i); } - -// -// // class StreamTask AsyncTask -// private class StreamTask extends AsyncTask{ -// private byte[] data; -// -// StreamTask(byte[] data){ -// this.data = data; -// } -// -// @Override -// protected Void doInBackground(Void... params) { -// -// if (this.data != null){ -// Log.e(TAG, "fps: " + mCamera.getParameters().getPreviewFrameRate()); -// ffmpeg.process(this.data); -// } -// return null; -// } -// } - - /*if (null != mStreamTask){ - switch (mStreamTask.getStatus()){ - case RUNNING: - Log.e(TAG, "onPreviewFrame Running"); - return; - case PENDING: - Log.e(TAG,"OnPreviewFrame Pending"); - mStreamTask.cancel(false); - break; - } - } - mStreamTask = new StreamTask(data); - mStreamTask.execute((Void)null); -*/ - -// ong endTime = System.currentTimeMillis(); -// mExecutor.execute(new Runnable() { -// @Override -// public void run() { -// //long encodeTime = System.currentTimeMillis(); -// ffmpeg.process(data); - //Log.e(TAG, "编码第:" + (encodeCount++) + "帧,耗时:" + (System.currentTimeMillis() - encodeTime)); -// } -// }); - //Log.e(TAG, "采集第:" + (++count) + "帧,距上一帧间隔时间:" -// + (endTime - previewTime) + " " + Thread.currentThread().getName()); -// previewTime = endTime;*/ - - - } diff --git a/app/src/main/java/ai/suanzi/rtmpclient/MyService.java b/app/src/main/java/ai/suanzi/rtmpclient/MyService.java index a9ef972..45aedcc 100644 --- a/app/src/main/java/ai/suanzi/rtmpclient/MyService.java +++ b/app/src/main/java/ai/suanzi/rtmpclient/MyService.java @@ -33,7 +33,6 @@ public class MyService extends Service implements Camera.PreviewCallback { private static String TAG = "MyService"; //private Ffmpeg ffmpeg = Ffmpeg.getInstance(); - private FfmpegHelper helper; private Boolean isRunning = false; private Camera mCamera = null; IBinder mBinder = new LocalBinder(); @@ -138,14 +137,13 @@ public class MyService extends Service implements Camera.PreviewCallback { mCamera.stopPreview(); mCamera.release(); } + FfmpegHelper.close(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { gLogger.error("onStartCommand"); - //nrunnable = new FfmpegRunnable("xxx", this); - //new Thread(runnable).start(); return START_STICKY; } @@ -162,7 +160,10 @@ public class MyService extends Service implements Camera.PreviewCallback { gLogger.error("onPreviewFrame"); } frameCount++; - //ffmpeg.process(data); + if(FfmpegHelper.processFrame(data) != 0){ + gLogger.error("FfmpegHelper.processFrame error. close"); + FfmpegHelper.close(); + } } public void startPreview (SurfaceHolder holder){ @@ -186,8 +187,7 @@ public class MyService extends Service implements Camera.PreviewCallback { int width = param.getPictureSize().width; int height = param.getPictureSize().height; gLogger.error("setRtmpUrl - size: " + width + "x" + height + ". url: " + url); - //int ret = ffmpeg.initnew(width, height, url); - int ret = FfmpegHelper.initialEncoder(width, height, url); + int ret = FfmpegHelper.initEncoder(width, height, url); return ret == 0 ? true : false; } diff --git a/app/src/main/java/ai/suanzi/rtmpclient/NetworkMonitor.java b/app/src/main/java/ai/suanzi/rtmpclient/NetworkMonitor.java new file mode 100644 index 0000000..7d51b62 --- /dev/null +++ b/app/src/main/java/ai/suanzi/rtmpclient/NetworkMonitor.java @@ -0,0 +1,64 @@ +package ai.suanzi.rtmpclient; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.NetworkInfo; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.util.Log; +import org.apache.log4j.Logger; +import android.net.ConnectivityManager; +import android.widget.Toast; + +import java.lang.ref.WeakReference; + +public class NetworkMonitor extends BroadcastReceiver { + + private Logger gLogger = Logger.getLogger("NetworkMonitor"); + private NetworkListener mListener; + + public NetworkMonitor(NetworkListener listener) { + mListener = listener; + } + + @Override + public void onReceive (Context context, Intent intent) { + + //获得ConnectivityManager对象 + ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + + NetworkInfo wifiNetworkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI); + + //NetworkInfo dataNetworkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); + if(wifiNetworkInfo.isConnected()){ + Toast.makeText(context, "Wifi Connected", Toast.LENGTH_SHORT).show(); + gLogger.error("Wifi Connected"); + mListener.onWifiConnected(); + } else { + Toast.makeText(context, "Wifi Disconnected", Toast.LENGTH_SHORT).show(); + gLogger.error("Wifi Disconnected"); + mListener.onWifiDisconnected(); + } + } + + public static boolean isNetworkAvailable(Context context){ + ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (connectivity != null) { + NetworkInfo info = connectivity.getActiveNetworkInfo(); + if (info != null && info.isConnected()) { + if (info.getState() == NetworkInfo.State.CONNECTED) { + return true; + } + } + } + return false; + } + + public interface NetworkListener { + void onWifiConnected(); + void onWifiDisconnected(); + void onWifiEnabled(); + void onWifiDisabled(); + } +} diff --git a/app/src/main/java/ai/suanzi/rtmpclient/UsbMonitor.java b/app/src/main/java/ai/suanzi/rtmpclient/UsbMonitor.java new file mode 100644 index 0000000..fc8bbdd --- /dev/null +++ b/app/src/main/java/ai/suanzi/rtmpclient/UsbMonitor.java @@ -0,0 +1,4 @@ +package ai.suanzi.rtmpclient; + +public class UsbMonitor { +} diff --git a/app/src/main/java/ai/suanzi/rtmpclient/WifiReceiver.java b/app/src/main/java/ai/suanzi/rtmpclient/WifiReceiver.java new file mode 100644 index 0000000..5a85509 --- /dev/null +++ b/app/src/main/java/ai/suanzi/rtmpclient/WifiReceiver.java @@ -0,0 +1,47 @@ +package ai.suanzi.rtmpclient; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.NetworkInfo; +import android.net.wifi.WifiManager; + +import org.apache.log4j.Logger; +import android.net.wifi.WifiInfo; +import android.util.Log; + +public class WifiReceiver extends BroadcastReceiver { + + private Logger gLogger = Logger.getLogger("WifiReceiver"); + @Override + public void onReceive(Context context, Intent intent) { + if(intent.getAction().equals(WifiManager.RSSI_CHANGED_ACTION)) { + gLogger.error("Wifi rssi changed"); + } + + if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){ + NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); + if(info.getState().equals(NetworkInfo.State.DISCONNECTED)){ + Log.e("WIFI", "wowowo"); + gLogger.error("Wifi Disconnected"); + } else if (info.getState().equals(NetworkInfo.State.CONNECTED)){ + gLogger.error("Wifi Connected"); + WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + WifiInfo wifiInfo = wifiManager.getConnectionInfo(); + //获取当前wifi名称 + gLogger.error("连接到网络 " + wifiInfo.getSSID()); + //TtsManager ttsManager = new TtsManager(); + //ttsManager.checkTtsJet(context.getApplicationContext()); + + } + } + if(intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { + int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED); + if(wifiState == WifiManager.WIFI_STATE_DISABLED){ + gLogger.error("Wifi Disabled"); + } else if (wifiState == WifiManager.WIFI_STATE_ENABLED) { + gLogger.error("Wifi Enabled"); + } + } + } +} diff --git a/app/src/main/jni/.vim-bookmarks b/app/src/main/jni/.vim-bookmarks deleted file mode 100644 index 8643ddf..0000000 --- a/app/src/main/jni/.vim-bookmarks +++ /dev/null @@ -1,3 +0,0 @@ -let l:bm_file_version = 1 -let l:bm_sessions = {'default': {'/Users/peng/project/yunzhi/RtmpClient/app/src/main/jni/FfmpegHelper.cpp': [{'sign_idx': 9500, 'line_nr': 109, 'content': ' //pCodecCtx->me_range = 16;'},],}} -let l:bm_current_session = 'default' diff --git a/app/src/main/jni/Application.mk b/app/src/main/jni/Application.mk index f0d9ca8..08f2103 100644 --- a/app/src/main/jni/Application.mk +++ b/app/src/main/jni/Application.mk @@ -1,2 +1,2 @@ -APP_ABI := armeabi-v7a x86 +APP_ABI := armeabi-v7a APP_STL := c++_shared \ No newline at end of file diff --git a/app/src/main/jni/FfmpegHelper.cpp b/app/src/main/jni/FfmpegHelper.cpp index 279341b..1df52e5 100644 --- a/app/src/main/jni/FfmpegHelper.cpp +++ b/app/src/main/jni/FfmpegHelper.cpp @@ -3,7 +3,7 @@ #include #define FLOGE(...) av_log(NULL, AV_LOG_ERROR, __VA_ARGS__) -#define FLOGD(...) av_log(NULL, AV_LOG_DEBUG, __VA_ARGS__) +#define FLOGD(...) av_log(NULL, AV_LOG_INFO, __VA_ARGS__) FfmpegHelper* FfmpegHelper::singleton = NULL; bool FfmpegHelper::isInit = false; @@ -37,22 +37,24 @@ void FfmpegHelper::av_log_cb (void *ptr, int level, const char* fmt, va_list vl) av_log_format_line(ptr, level, fmt, vl, line, sizeof(line), &print_prefix); if (level <= AV_LOG_WARNING){ - if (singleton) singleton->javaPrint(line); + if (singleton) singleton->javaPrint(line, 1); + } else if(level <= AV_LOG_INFO){ + if (singleton) singleton->javaPrint(line, 0); + // LOGE("%s", line); } else { - if (singleton) singleton->javaPrint(line); - //LOGE("%s", line); + } } -void FfmpegHelper::javaPrint(const char* str) +void FfmpegHelper::javaPrint(const char* str, int level) { JNIEnv* env = 0; if(this->jvm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK){ return; } - jmethodID mid = env->GetStaticMethodID(ai_suanzi_rtmpclient_FfmpegHelper, "javaPrint", "(Ljava/lang/String;)V"); + jmethodID mid = env->GetStaticMethodID(ai_suanzi_rtmpclient_FfmpegHelper, "javaPrint", "(Ljava/lang/String;I)V"); jstring jstr = env->NewStringUTF(str); - env->CallStaticVoidMethod(ai_suanzi_rtmpclient_FfmpegHelper, mid, jstr); + env->CallStaticVoidMethod(ai_suanzi_rtmpclient_FfmpegHelper, mid, jstr, level); env->DeleteLocalRef(jstr); } @@ -60,15 +62,15 @@ void FfmpegHelper::init() { av_log_set_callback(av_log_cb); av_log_set_level(AV_LOG_DEBUG); - FLOGE("########## Ffmpeg Init ##########"); + FLOGD("########## Ffmpeg Init ##########"); unsigned int v = avutil_version(); - FLOGE("libavutil - %d.%d.%d", AV_VERSION_MAJOR(v), AV_VERSION_MINOR(v), AV_VERSION_MICRO(v)); + FLOGD("libavutil - %d.%d.%d", AV_VERSION_MAJOR(v), AV_VERSION_MINOR(v), AV_VERSION_MICRO(v)); v = avcodec_version(); - FLOGE("libavcodec - %d.%d.%d", AV_VERSION_MAJOR(v), AV_VERSION_MINOR(v), AV_VERSION_MICRO(v)); + FLOGD("libavcodec - %d.%d.%d", AV_VERSION_MAJOR(v), AV_VERSION_MINOR(v), AV_VERSION_MICRO(v)); v = avformat_version(); - FLOGE("libavformat - %d.%d.%d", AV_VERSION_MAJOR(v), AV_VERSION_MINOR(v), AV_VERSION_MICRO(v)); + FLOGD("libavformat - %d.%d.%d", AV_VERSION_MAJOR(v), AV_VERSION_MINOR(v), AV_VERSION_MICRO(v)); v = avdevice_version(); - FLOGE("libavdevice - %d.%d.%d", AV_VERSION_MAJOR(v), AV_VERSION_MINOR(v), AV_VERSION_MICRO(v)); + FLOGD("libavdevice - %d.%d.%d", AV_VERSION_MAJOR(v), AV_VERSION_MINOR(v), AV_VERSION_MICRO(v)); av_register_all(); //avdevice_register_all(); @@ -82,7 +84,8 @@ void FfmpegHelper::init() int FfmpegHelper::initEncoder(int width, int height, const char* outpath) { if(!isInit) init(); - FLOGE("initEncoder - width=%d, height=%d, url=%s", width, height, outpath); + FLOGE("-----------> FfmpegHelper::initEncoder"); + FLOGD("initEncoder - width=%d, height=%d, url=%s", width, height, outpath); pWidth = width; pHeight = height; @@ -123,7 +126,6 @@ int FfmpegHelper::initEncoder(int width, int height, const char* outpath) } //Add a new stream to output,should be called by the user before avformat_write_header() for muxing - AVStream* vStream; if ((vStream = avformat_new_stream(formatCtx, codec)) == NULL){ FLOGE("avformat_new_stream - error"); return -1; @@ -143,22 +145,33 @@ int FfmpegHelper::initEncoder(int width, int height, const char* outpath) return -1; } startTime = av_gettime(); + frameCnt = 0; return 0; } + int FfmpegHelper::processFrame(uint8_t* data) { int ret = 0; - AVFrame *pFrame, *pFrameYUV; - pFrameYUV = av_frame_alloc(); int y_length = pWidth * pHeight; + pFrameYUV = av_frame_alloc(); uint8_t *outBuf = (uint8_t *)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P, codecCtx->width, codecCtx->height, 1)); - av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, outBuf, AV_PIX_FMT_YUV420P, codecCtx->width, codecCtx->height, 1); + if(outBuf == NULL) { + FLOGE("av_malloc, error"); + av_frame_free(&pFrameYUV); + return -1; + } + if((ret = av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, outBuf, AV_PIX_FMT_YUV420P, codecCtx->width, codecCtx->height, 1)) < 0){ + FLOGE("av_image_fill_arrays - error: %s(%d).", av_err2str(ret), ret); + av_frame_free(&pFrameYUV); + return -1; + } + // NV21 to YUV420P memcpy(pFrameYUV->data[0], data, y_length); for (int i = 0; i < y_length / 4; i++){ - *(pFrameYUV->data[2] + i) = *(data + y_length * 2); - *(pFrameYUV->data[1] + i) = *(data + y_length * 2 + 1); + *(pFrameYUV->data[2] + i) = *(data + y_length + i * 2); + *(pFrameYUV->data[1] + i) = *(data + y_length + i * 2 + 1); } pFrameYUV->format = AV_PIX_FMT_YUV420P; @@ -166,18 +179,21 @@ int FfmpegHelper::processFrame(uint8_t* data) pFrameYUV->height = pHeight; - AVPacket encPkt; encPkt.data = NULL; encPkt.size = 0; av_init_packet(&encPkt); int got_frame = 0; - avcodec_encode_video2(codecCtx, &encPkt, pFrameYUV, &got_frame); + if((ret = avcodec_encode_video2(codecCtx, &encPkt, pFrameYUV, &got_frame)) < 0){ + FLOGE("avcodec_encode_video2 - error: %s(%d).", av_err2str(ret), ret); + av_frame_free(&pFrameYUV); + return -1; + } av_frame_free(&pFrameYUV); if(got_frame == 1){ if (frameCnt % (15 * 60) == 0){ - FLOGE("Succeed to encode frame: %5d\tsize:%5d\n", frameCnt, encPkt.size); + FLOGD("Succeed to encode frame: %5d\tsize:%5d\n", frameCnt, encPkt.size); } frameCnt++; encPkt.stream_index = vStream->index; @@ -201,7 +217,10 @@ int FfmpegHelper::processFrame(uint8_t* data) if (pts_time > now_time) av_usleep(pts_time - now_time); - ret = av_interleaved_write_frame(formatCtx, &encPkt); + if((ret = av_interleaved_write_frame(formatCtx, &encPkt)) < 0){ + FLOGE("av_interleaved_write_frame - error: %s(%d)", av_err2str(ret), ret); + return -1; + } av_packet_unref(&encPkt); } av_free(outBuf); @@ -212,13 +231,16 @@ int FfmpegHelper::close() { if(vStream) avcodec_close(vStream->codec); - avio_close(formatCtx->pb); - avformat_free_context(formatCtx); + if (formatCtx){ + avio_close(formatCtx->pb); + avformat_free_context(formatCtx); + } + FLOGE("<----------- FfmpegHelper::close "); return 0; } -jint FfmpegHelper::nativeInitialEncoder(JNIEnv *env, jclass cls, jint width, jint height, jstring url) +jint FfmpegHelper::nativeInitEncoder(JNIEnv *env, jclass cls, jint width, jint height, jstring url) { const char* output = env->GetStringUTFChars(url, 0); int ret = 0; diff --git a/app/src/main/jni/FfmpegHelper.h b/app/src/main/jni/FfmpegHelper.h index aba871b..9c95cda 100644 --- a/app/src/main/jni/FfmpegHelper.h +++ b/app/src/main/jni/FfmpegHelper.h @@ -16,13 +16,13 @@ extern "C" { class FfmpegHelper { public: static jint nativeOnLoad(JavaVM * jvm, void* reserved); - static jint nativeInitialEncoder(JNIEnv *env, jclass cls, jint width, jint height, jstring url); + static jint nativeInitEncoder(JNIEnv *env, jclass cls, jint width, jint height, jstring url); static jint nativeProcessFrame(JNIEnv *env, jclass cls, jbyteArray data); static jint nativeClose(); private: static void av_log_cb (void *ptr, int level, const char* fmt, va_list vl); - void javaPrint(const char* str); + void javaPrint(const char* str, int level); static void init(); int processFrame(uint8_t *data); int initEncoder(int width, int height, const char* url); @@ -41,6 +41,8 @@ private: AVCodecContext* codecCtx; AVCodec* codec; AVStream* vStream; + AVPacket encPkt; + AVFrame *pFrameYUV; int pWidth; int pHeight; unsigned int frameCnt; diff --git a/app/src/main/jni/ai_suanzi_rtmpclient_FfmpegHelper.cpp b/app/src/main/jni/ai_suanzi_rtmpclient_FfmpegHelper.cpp index ee081c2..b87bb34 100644 --- a/app/src/main/jni/ai_suanzi_rtmpclient_FfmpegHelper.cpp +++ b/app/src/main/jni/ai_suanzi_rtmpclient_FfmpegHelper.cpp @@ -16,9 +16,9 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void* reserved) * Method: initialDecoder * Signature: ()I */ -JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_FfmpegHelper_initialEncoder (JNIEnv *env, jclass cls, jint width, jint height, jstring url) +JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_FfmpegHelper_initEncoder (JNIEnv *env, jclass cls, jint width, jint height, jstring url) { - return FfmpegHelper::nativeInitialEncoder(env, cls, width, height, url); + return FfmpegHelper::nativeInitEncoder(env, cls, width, height, url); } /* diff --git a/app/src/main/jni/ai_suanzi_rtmpclient_FfmpegHelper.h b/app/src/main/jni/ai_suanzi_rtmpclient_FfmpegHelper.h index bedc4a8..303ca28 100644 --- a/app/src/main/jni/ai_suanzi_rtmpclient_FfmpegHelper.h +++ b/app/src/main/jni/ai_suanzi_rtmpclient_FfmpegHelper.h @@ -9,10 +9,10 @@ extern "C" { #endif /* * Class: ai_suanzi_rtmpclient_FfmpegHelper - * Method: initialEncoder + * Method: initEncoder * Signature: (IILjava/lang/String;)I */ -JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_FfmpegHelper_initialEncoder +JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_FfmpegHelper_initEncoder (JNIEnv *, jclass, jint, jint, jstring); /* -- 2.11.0