Merge "RTP: fix few leaks when fail to add streams into a group." into gingerbread
This commit is contained in:
@@ -49,27 +49,28 @@ public class AudioGroup {
|
|||||||
synchronized void add(AudioStream stream, AudioCodec codec, int codecType, int dtmfType) {
|
synchronized void add(AudioStream stream, AudioCodec codec, int codecType, int dtmfType) {
|
||||||
if (!mStreams.containsKey(stream)) {
|
if (!mStreams.containsKey(stream)) {
|
||||||
try {
|
try {
|
||||||
int id = add(stream.getMode(), stream.dup(),
|
int socket = stream.dup();
|
||||||
|
add(stream.getMode(), socket,
|
||||||
stream.getRemoteAddress().getHostAddress(), stream.getRemotePort(),
|
stream.getRemoteAddress().getHostAddress(), stream.getRemotePort(),
|
||||||
codec.name, codec.sampleRate, codec.sampleCount, codecType, dtmfType);
|
codec.name, codec.sampleRate, codec.sampleCount, codecType, dtmfType);
|
||||||
mStreams.put(stream, id);
|
mStreams.put(stream, socket);
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private native int add(int mode, int socket, String remoteAddress, int remotePort,
|
private native void add(int mode, int socket, String remoteAddress, int remotePort,
|
||||||
String codecName, int sampleRate, int sampleCount, int codecType, int dtmfType);
|
String codecName, int sampleRate, int sampleCount, int codecType, int dtmfType);
|
||||||
|
|
||||||
synchronized void remove(AudioStream stream) {
|
synchronized void remove(AudioStream stream) {
|
||||||
Integer id = mStreams.remove(stream);
|
Integer socket = mStreams.remove(stream);
|
||||||
if (id != null) {
|
if (socket != null) {
|
||||||
remove(id);
|
remove(socket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private native void remove(int id);
|
private native void remove(int socket);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a DTMF digit to every {@link AudioStream} in this group. Currently
|
* Sends a DTMF digit to every {@link AudioStream} in this group. Currently
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ void AudioStream::decode(int tick)
|
|||||||
MSG_TRUNC | MSG_DONTWAIT);
|
MSG_TRUNC | MSG_DONTWAIT);
|
||||||
|
|
||||||
// Do we need to check SSRC, sequence, and timestamp? They are not
|
// Do we need to check SSRC, sequence, and timestamp? They are not
|
||||||
// reliable but at least they can be used to identity duplicates?
|
// reliable but at least they can be used to identify duplicates?
|
||||||
if (length < 12 || length > (int)sizeof(buffer) ||
|
if (length < 12 || length > (int)sizeof(buffer) ||
|
||||||
(ntohl(*(uint32_t *)buffer) & 0xC07F0000) != mCodecMagic) {
|
(ntohl(*(uint32_t *)buffer) & 0xC07F0000) != mCodecMagic) {
|
||||||
LOGD("stream[%d] malformed packet", mSocket);
|
LOGD("stream[%d] malformed packet", mSocket);
|
||||||
@@ -697,6 +697,10 @@ bool AudioGroup::remove(int socket)
|
|||||||
for (AudioStream *stream = mChain; stream->mNext; stream = stream->mNext) {
|
for (AudioStream *stream = mChain; stream->mNext; stream = stream->mNext) {
|
||||||
AudioStream *target = stream->mNext;
|
AudioStream *target = stream->mNext;
|
||||||
if (target->mSocket == socket) {
|
if (target->mSocket == socket) {
|
||||||
|
if (epoll_ctl(mEventQueue, EPOLL_CTL_DEL, socket, NULL)) {
|
||||||
|
LOGE("epoll_ctl: %s", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
stream->mNext = target->mNext;
|
stream->mNext = target->mNext;
|
||||||
LOGD("stream[%d] leaves group[%d]", socket, mDeviceSocket);
|
LOGD("stream[%d] leaves group[%d]", socket, mDeviceSocket);
|
||||||
delete target;
|
delete target;
|
||||||
@@ -800,7 +804,7 @@ bool AudioGroup::deviceLoop()
|
|||||||
static jfieldID gNative;
|
static jfieldID gNative;
|
||||||
static jfieldID gMode;
|
static jfieldID gMode;
|
||||||
|
|
||||||
jint add(JNIEnv *env, jobject thiz, jint mode,
|
void add(JNIEnv *env, jobject thiz, jint mode,
|
||||||
jint socket, jstring jRemoteAddress, jint remotePort,
|
jint socket, jstring jRemoteAddress, jint remotePort,
|
||||||
jstring jCodecName, jint sampleRate, jint sampleCount,
|
jstring jCodecName, jint sampleRate, jint sampleCount,
|
||||||
jint codecType, jint dtmfType)
|
jint codecType, jint dtmfType)
|
||||||
@@ -813,7 +817,7 @@ jint add(JNIEnv *env, jobject thiz, jint mode,
|
|||||||
sockaddr_storage remote;
|
sockaddr_storage remote;
|
||||||
if (parse(env, jRemoteAddress, remotePort, &remote) < 0) {
|
if (parse(env, jRemoteAddress, remotePort, &remote) < 0) {
|
||||||
// Exception already thrown.
|
// Exception already thrown.
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
if (sampleRate < 0 || sampleCount < 0 || codecType < 0 || codecType > 127) {
|
if (sampleRate < 0 || sampleCount < 0 || codecType < 0 || codecType > 127) {
|
||||||
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
|
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
|
||||||
@@ -821,12 +825,12 @@ jint add(JNIEnv *env, jobject thiz, jint mode,
|
|||||||
}
|
}
|
||||||
if (!jCodecName) {
|
if (!jCodecName) {
|
||||||
jniThrowNullPointerException(env, "codecName");
|
jniThrowNullPointerException(env, "codecName");
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
codecName = env->GetStringUTFChars(jCodecName, NULL);
|
codecName = env->GetStringUTFChars(jCodecName, NULL);
|
||||||
if (!codecName) {
|
if (!codecName) {
|
||||||
// Exception already thrown.
|
// Exception already thrown.
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create audio stream.
|
// Create audio stream.
|
||||||
@@ -835,8 +839,10 @@ jint add(JNIEnv *env, jobject thiz, jint mode,
|
|||||||
codecType, dtmfType)) {
|
codecType, dtmfType)) {
|
||||||
jniThrowException(env, "java/lang/IllegalStateException",
|
jniThrowException(env, "java/lang/IllegalStateException",
|
||||||
"cannot initialize audio stream");
|
"cannot initialize audio stream");
|
||||||
|
env->ReleaseStringUTFChars(jCodecName, codecName);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
env->ReleaseStringUTFChars(jCodecName, codecName);
|
||||||
socket = -1;
|
socket = -1;
|
||||||
|
|
||||||
// Create audio group.
|
// Create audio group.
|
||||||
@@ -860,16 +866,13 @@ jint add(JNIEnv *env, jobject thiz, jint mode,
|
|||||||
|
|
||||||
// Succeed.
|
// Succeed.
|
||||||
env->SetIntField(thiz, gNative, (int)group);
|
env->SetIntField(thiz, gNative, (int)group);
|
||||||
env->ReleaseStringUTFChars(jCodecName, codecName);
|
return;
|
||||||
return socket;
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
delete group;
|
delete group;
|
||||||
delete stream;
|
delete stream;
|
||||||
close(socket);
|
close(socket);
|
||||||
env->SetIntField(thiz, gNative, NULL);
|
env->SetIntField(thiz, gNative, NULL);
|
||||||
env->ReleaseStringUTFChars(jCodecName, codecName);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(JNIEnv *env, jobject thiz, jint socket)
|
void remove(JNIEnv *env, jobject thiz, jint socket)
|
||||||
@@ -902,7 +905,7 @@ void sendDtmf(JNIEnv *env, jobject thiz, jint event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JNINativeMethod gMethods[] = {
|
JNINativeMethod gMethods[] = {
|
||||||
{"add", "(IILjava/lang/String;ILjava/lang/String;IIII)I", (void *)add},
|
{"add", "(IILjava/lang/String;ILjava/lang/String;IIII)V", (void *)add},
|
||||||
{"remove", "(I)V", (void *)remove},
|
{"remove", "(I)V", (void *)remove},
|
||||||
{"setMode", "(I)V", (void *)setMode},
|
{"setMode", "(I)V", (void *)setMode},
|
||||||
{"sendDtmf", "(I)V", (void *)sendDtmf},
|
{"sendDtmf", "(I)V", (void *)sendDtmf},
|
||||||
|
|||||||
Reference in New Issue
Block a user