Bug 863290 - Correctly detect failure to initialize Android capture objects. Fix crashers. r=jesup

This commit is contained in:
Gian-Carlo Pascutto 2013-05-15 18:50:42 +02:00
parent 684d37b3df
commit 9cc5fa74c8
6 changed files with 75 additions and 41 deletions

View File

@ -97,7 +97,10 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
JNIEnv *env;
jint res = jvm->AttachCurrentThread(&env, NULL);
webrtc::VideoEngine::SetAndroidObjects(jvm, (void*)context);
if (webrtc::VideoEngine::SetAndroidObjects(jvm, (void*)context) != 0) {
LOG(("VieCapture:SetAndroidObjects Failed"));
return;
}
env->DeleteGlobalRef(context);
#endif
@ -230,7 +233,10 @@ MediaEngineWebRTC::EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSourc
JNIEnv *env;
jvm->AttachCurrentThread(&env, NULL);
webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context);
if (webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context) != 0) {
LOG(("VoiceEngine:SetAndroidObjects Failed"));
return;
}
env->DeleteGlobalRef(context);
#endif

View File

@ -147,12 +147,15 @@ MediaConduitErrorCode WebrtcAudioConduit::Init(WebrtcAudioConduit *other)
JNIEnv* env;
if (jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
CSFLogError(logTag, "%s: could not get Java environment", __FUNCTION__);
return kMediaConduitSessionNotInited;
CSFLogError(logTag, "%s: could not get Java environment", __FUNCTION__);
return kMediaConduitSessionNotInited;
}
jvm->AttachCurrentThread(&env, NULL);
webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context);
if (webrtc::VoiceEngine::SetAndroidObjects(jvm, (void*)context) != 0) {
CSFLogError(logTag, "%s Unable to set Android objects", __FUNCTION__);
return kMediaConduitSessionNotInited;
}
env->DeleteGlobalRef(context);
#endif

View File

@ -117,7 +117,10 @@ MediaConduitErrorCode WebrtcVideoConduit::Init()
}
jvm->AttachCurrentThread(&env, nullptr);
webrtc::VideoEngine::SetAndroidObjects(jvm, (void*)context);
if (webrtc::VideoEngine::SetAndroidObjects(jvm, (void*)context) != 0) {
CSFLogError(logTag, "%s: could not set Android objects", __FUNCTION__);
return kMediaConduitSessionNotInited;
}
env->DeleteGlobalRef(context);
#endif

View File

@ -146,15 +146,21 @@ public:
WebrtcVideoConduit():
mVideoEngine(NULL),
mTransport(NULL),
mRenderer(NULL),
mVideoEngine(nullptr),
mTransport(nullptr),
mRenderer(nullptr),
mEngineTransmitting(false),
mEngineReceiving(false),
mChannel(-1),
mCapId(-1),
mCurSendCodecConfig(NULL)
mCurSendCodecConfig(nullptr),
mPtrViEBase(nullptr),
mPtrViECapture(nullptr),
mPtrViECodec(nullptr),
mPtrViENetwork(nullptr),
mPtrViERender(nullptr),
mPtrExtCapture(nullptr),
mPtrRTP(nullptr)
{
}

View File

@ -118,11 +118,23 @@ public class VideoCaptureDeviceInfoAndroid {
camera = null;
deviceList.add(newDevice);
}
} else {
camera = Camera.open();
Camera.Parameters parameters = camera.getParameters();
AndroidVideoCaptureDevice newDevice = new AndroidVideoCaptureDevice();
AddDeviceInfo(newDevice, parameters);
newDevice.deviceUniqueName = "Camera";
camera.release();
camera = null;
deviceList.add(newDevice);
}
}
catch (Exception ex) {
Log.e(TAG, "Failed to init VideoCaptureDeviceInfo ex" +
ex.getLocalizedMessage());
Log.e(TAG, "Failed to init VideoCaptureDeviceInfo exception: " +
ex.getMessage());
if (camera != null) {
camera.release();
}
return -1;
}
VerifyCapabilities();
@ -136,9 +148,11 @@ public class VideoCaptureDeviceInfoAndroid {
List<Size> sizes = parameters.getSupportedPreviewSizes();
List<Integer> frameRates = parameters.getSupportedPreviewFrameRates();
int maxFPS = 0;
for(Integer frameRate:frameRates) {
if(frameRate > maxFPS) {
maxFPS = frameRate;
if (frameRates != null) {
for(Integer frameRate:frameRates) {
if(frameRate > maxFPS) {
maxFPS = frameRate;
}
}
}

View File

@ -394,33 +394,35 @@ VideoCaptureAndroid::~VideoCaptureAndroid() {
}
}
// get the method ID for the Android Java CaptureClass static
// DeleteVideoCaptureAndroid method. Call this to release the camera so
// another application can use it.
jmethodID cid = env->GetStaticMethodID(
g_javaCmClass,
"DeleteVideoCaptureAndroid",
"(Lorg/webrtc/videoengine/VideoCaptureAndroid;)V");
if (cid != NULL) {
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
"%s: Call DeleteVideoCaptureAndroid", __FUNCTION__);
// Close the camera by calling the static destruct function.
env->CallStaticVoidMethod(g_javaCmClass, cid, _javaCaptureObj);
if (env) {
// get the method ID for the Android Java CaptureClass static
// DeleteVideoCaptureAndroid method. Call this to release the camera so
// another application can use it.
jmethodID cid = env->GetStaticMethodID(
g_javaCmClass,
"DeleteVideoCaptureAndroid",
"(Lorg/webrtc/videoengine/VideoCaptureAndroid;)V");
if (cid != NULL) {
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, -1,
"%s: Call DeleteVideoCaptureAndroid", __FUNCTION__);
// Close the camera by calling the static destruct function.
env->CallStaticVoidMethod(g_javaCmClass, cid, _javaCaptureObj);
// Delete global object ref to the camera.
env->DeleteGlobalRef(_javaCaptureObj);
// Clean up the global class references
env->DeleteGlobalRef(g_javaCmClass);
env->DeleteGlobalRef(g_javaCmDevInfoClass);
// Delete global object ref to the camera.
env->DeleteGlobalRef(_javaCaptureObj);
// Clean up the global class references
env->DeleteGlobalRef(g_javaCmClass);
env->DeleteGlobalRef(g_javaCmDevInfoClass);
_javaCaptureObj = NULL;
VideoCaptureAndroid::g_javaCmClass = NULL;
VideoCaptureAndroid::g_javaCmDevInfoClass = NULL;
}
else {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
"%s: Failed to find DeleteVideoCaptureAndroid id",
__FUNCTION__);
_javaCaptureObj = NULL;
VideoCaptureAndroid::g_javaCmClass = NULL;
VideoCaptureAndroid::g_javaCmDevInfoClass = NULL;
}
else {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
"%s: Failed to find DeleteVideoCaptureAndroid id",
__FUNCTION__);
}
}
// Detach this thread if it was attached