Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
BC
public
mediastreamer2
Commits
559c0081
Commit
559c0081
authored
Nov 30, 2010
by
Simon Morlat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add framework to retrieve java vm and jni env easily and in a safe manner
parent
a0e4a661
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
266 additions
and
100 deletions
+266
-100
build/android/Android.mk
build/android/Android.mk
+3
-2
include/mediastreamer2/Makefile.am
include/mediastreamer2/Makefile.am
+2
-1
include/mediastreamer2/mscommon.h
include/mediastreamer2/mscommon.h
+4
-2
include/mediastreamer2/msfilter.h
include/mediastreamer2/msfilter.h
+26
-0
include/mediastreamer2/msjava.h
include/mediastreamer2/msjava.h
+43
-0
src/Makefile.am
src/Makefile.am
+1
-1
src/android-display-bad.cpp
src/android-display-bad.cpp
+7
-31
src/android-display.c
src/android-display.c
+25
-38
src/audiostream.c
src/audiostream.c
+2
-0
src/mscommon.c
src/mscommon.c
+1
-1
src/msfilter.c
src/msfilter.c
+82
-24
src/msjava.c
src/msjava.c
+70
-0
No files found.
build/android/Android.mk
View file @
559c0081
...
...
@@ -67,7 +67,8 @@ LOCAL_SRC_FILES = \
kiss_fftr.c
\
void.c
\
msandroid.cpp
\
eventqueue.c
eventqueue.c
\
msjava.c
LOCAL_SRC_FILES
+=
audiostream.c
...
...
@@ -133,7 +134,7 @@ LOCAL_SRC_FILES += gsm.c
LOCAL_CFLAGS
+=
\
-UHAVE_CONFIG_H
\
-include
$(LOCAL_PATH)
/../build/android/libmediastreamer2_AndroidConfig.h
\
-D_POSIX_SOURCE
-D_POSIX_SOURCE
-Wall
ifeq
($(TARGET_ARCH_ABI),armeabi-v7a)
...
...
include/mediastreamer2/Makefile.am
View file @
559c0081
...
...
@@ -29,7 +29,8 @@ mediastreamer2_include_HEADERS= ice.h \
msaudiomixer.h
\
msitc.h
\
msextdisplay.h
\
msjpegwriter.h
msjpegwriter.h
\
msjava.h
EXTRA_DIST
=
$(mediastreamer2_include_HEADERS)
include/mediastreamer2/mscommon.h
View file @
559c0081
...
...
@@ -102,6 +102,8 @@ typedef struct _MSList MSList;
#define ms_list_next(elem) ((elem)->next)
typedef
int
(
*
MSCompareFunc
)(
const
void
*
a
,
const
void
*
b
);
#ifdef __cplusplus
extern
"C"
{
#endif
...
...
@@ -116,11 +118,11 @@ void ms_list_for_each(const MSList *list, void (*func)(void *));
void
ms_list_for_each2
(
const
MSList
*
list
,
void
(
*
func
)(
void
*
,
void
*
),
void
*
user_data
);
MSList
*
ms_list_remove_link
(
MSList
*
list
,
MSList
*
elem
);
MSList
*
ms_list_find
(
MSList
*
list
,
void
*
data
);
MSList
*
ms_list_find_custom
(
MSList
*
list
,
int
(
*
compare_func
)(
const
void
*
,
const
void
*
),
void
*
user_data
);
MSList
*
ms_list_find_custom
(
MSList
*
list
,
MSCompareFunc
compare_func
,
const
void
*
user_data
);
void
*
ms_list_nth_data
(
const
MSList
*
list
,
int
index
);
int
ms_list_position
(
const
MSList
*
list
,
MSList
*
elem
);
int
ms_list_index
(
const
MSList
*
list
,
void
*
data
);
MSList
*
ms_list_insert_sorted
(
MSList
*
list
,
void
*
data
,
int
(
*
compare_func
)(
const
void
*
,
const
void
*
)
);
MSList
*
ms_list_insert_sorted
(
MSList
*
list
,
void
*
data
,
MSCompareFunc
compare_func
);
MSList
*
ms_list_insert
(
MSList
*
list
,
MSList
*
before
,
void
*
data
);
MSList
*
ms_list_copy
(
const
MSList
*
list
);
...
...
include/mediastreamer2/msfilter.h
View file @
559c0081
...
...
@@ -95,6 +95,15 @@ enum _MSFilterFlags{
typedef
enum
_MSFilterFlags
MSFilterFlags
;
struct
_MSFilterStats
{
const
char
*
name
;
/*<filter name*/
uint64_t
elapsed
;
/*<cumulative number of nanoseconds elapsed */
unsigned
int
count
;
/*<number of time the filter is called for processing*/
};
typedef
struct
_MSFilterStats
MSFilterStats
;
struct
_MSFilterDesc
{
MSFilterId
id
;
/* the id declared in allfilters.h */
const
char
*
name
;
/* filter name */
...
...
@@ -130,6 +139,7 @@ struct _MSFilter{
struct
_MSTicker
*
ticker
;
/*private attributes */
uint32_t
last_tick
;
MSFilterStats
*
stats
;
bool_t
seen
;
bool_t
synchronous_notifies
;
};
...
...
@@ -433,6 +443,22 @@ int ms_connection_helper_link(MSConnectionHelper *h, MSFilter *f, int inpin, int
**/
int
ms_connection_helper_unlink
(
MSConnectionHelper
*
h
,
MSFilter
*
f
,
int
inpin
,
int
outpin
);
/**
* \brief Enable time measurements statistics for filters.
*
**/
void
ms_filter_enable_statistics
(
bool_t
enabled
);
/**
* \brief Retrieves statistics for running filters.
* Returns a list of MSFilterStats
**/
const
MSList
*
ms_filter_get_statistics
(
void
);
void
ms_filter_log_statistics
(
void
);
/* I define the id taking the lower bits of the address of the MSFilterDesc object,
the method index (_cnt_) and the argument size */
/* I hope using this to avoid type mismatch (calling a method on the wrong filter)*/
...
...
include/mediastreamer2/msjava.h
0 → 100644
View file @
559c0081
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2010 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef msjava_h
#define msjava_h
/* Helper routines for filters that use a jvm with upcalls to perform some processing */
#include <jni.h>
#ifdef __cplusplus
extern
"C"
{
#endif
void
ms_set_jvm
(
JavaVM
*
vm
);
JavaVM
*
ms_get_jvm
(
void
);
JNIEnv
*
ms_get_jni_env
(
void
);
#ifdef __cplusplus
}
#endif
#endif
src/Makefile.am
View file @
559c0081
...
...
@@ -2,7 +2,7 @@
EXTRA_DIST
=
winsnd2.c winsnd.c winvideo.c
\
winvideods.c wincevideods.c dxfilter.h dxfilter.cpp
\
msfileplayer_win.c msfilerec_win.c winsndds.cpp nowebcamCIF.jpg winsnd3.c vfw-missing.h
\
winvideo2.c
winvideo2.c
msjava.c
BUILT_SOURCES
=
alldescs.h
...
...
src/android-display-bad.cpp
View file @
559c0081
...
...
@@ -21,13 +21,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/msvideo.h"
#include "mediastreamer2/msjava.h"
#include "layouts.h"
#include <android/bitmap.h>
#include <jni.h>
#include <dlfcn.h>
/*defined in msandroid.cpp*/
extern
JavaVM
*
ms_andsnd_jvm
;
static
int
android_version
=
0
;
...
...
@@ -110,15 +109,11 @@ typedef struct AndroidDisplay{
static
void
android_display_init
(
MSFilter
*
f
){
AndroidDisplay
*
ad
=
(
AndroidDisplay
*
)
ms_new0
(
AndroidDisplay
,
1
);
JNIEnv
*
jenv
=
NULL
;
JNIEnv
*
jenv
=
ms_get_jni_env
()
;
jclass
wc
;
ad
->
jvm
=
ms_
andsnd
_jvm
;
ad
->
jvm
=
ms_
get
_jvm
()
;
if
(
ad
->
jvm
->
AttachCurrentThread
(
&
jenv
,
NULL
)
!=
0
){
ms_error
(
"Could not get JNIEnv"
);
return
;
}
wc
=
jenv
->
FindClass
(
"org/linphone/core/AndroidVideoWindowImpl"
);
if
(
wc
==
0
){
ms_fatal
(
"Could not find org.linphone.core.AndroidVideoWindowImpl class !"
);
...
...
@@ -161,13 +156,6 @@ static void android_display_process(MSFilter *f){
AndroidDisplay
*
ad
=
(
AndroidDisplay
*
)
f
->
data
;
MSPicture
pic
;
mblk_t
*
m
;
JNIEnv
*
jenv
=
NULL
;
jint
result
=
ad
->
jvm
->
AttachCurrentThread
(
&
jenv
,
NULL
);
if
(
result
!=
0
)
{
ms_error
(
"android_display_process(): cannot attach VM"
);
goto
end
;
}
ms_filter_lock
(
f
);
if
(
ad
->
surf
!=
NULL
){
...
...
@@ -214,32 +202,19 @@ static void android_display_process(MSFilter *f){
}
}
ms_filter_unlock
(
f
);
end:
ms_queue_flush
(
f
->
inputs
[
0
]);
ms_queue_flush
(
f
->
inputs
[
1
]);
if
(
jenv
!=
NULL
){
jint
result
=
ad
->
jvm
->
DetachCurrentThread
();
if
(
result
!=
0
)
{
ms_error
(
"android_display_process(): cannot detach VM"
);
}
}
}
static
int
android_display_set_window
(
MSFilter
*
f
,
void
*
arg
){
AndroidDisplay
*
ad
=
(
AndroidDisplay
*
)
f
->
data
;
unsigned
long
id
=*
(
unsigned
long
*
)
arg
;
int
err
;
JNIEnv
*
jenv
=
NULL
;
JNIEnv
*
jenv
=
ms_get_jni_env
();
jobject
jsurface
=
NULL
;
jobject
android_window
=
(
jobject
)
id
;
Surface
*
oldsurf
;
if
(
ad
->
jvm
->
AttachCurrentThread
(
&
jenv
,
NULL
)
!=
0
){
ms_error
(
"Could not get JNIEnv"
);
return
-
1
;
}
if
(
android_window
!=
NULL
)
jsurface
=
jenv
->
CallObjectMethod
(
android_window
,
ad
->
get_surface_id
);
...
...
@@ -254,6 +229,7 @@ static int android_display_set_window(MSFilter *f, void *arg){
ms_filter_unlock
(
f
);
ms_message
(
"Got new surface to draw (%p)"
,
ad
->
surf
);
return
0
;
}
static
MSFilterMethod
methods
[]
=
{
...
...
src/android-display.c
View file @
559c0081
...
...
@@ -21,17 +21,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/msvideo.h"
#include "mediastreamer2/msjava.h"
#include "layouts.h"
#include <android/bitmap.h>
#include <jni.h>
#include <dlfcn.h>
/*defined in msandroid.cpp*/
extern
JavaVM
*
ms_andsnd_jvm
;
typedef
struct
AndroidDisplay
{
JavaVM
*
jvm
;
JNIEnv
*
jenv
;
jobject
android_video_window
;
jobject
jbitmap
;
jmethodID
get_bitmap_id
;
...
...
@@ -53,7 +52,7 @@ static void android_display_init(MSFilter *f){
JNIEnv
*
jenv
=
NULL
;
jclass
wc
;
ad
->
jvm
=
ms_
andsnd
_jvm
;
ad
->
jvm
=
ms_
get
_jvm
()
;
if
((
*
(
ad
->
jvm
))
->
AttachCurrentThread
(
ad
->
jvm
,
&
jenv
,
NULL
)
!=
0
){
ms_error
(
"Could not get JNIEnv"
);
...
...
@@ -90,29 +89,23 @@ static int vsize_get_orientation(MSVideoSize vs){
return
vs
.
width
>=
vs
.
height
?
LANDSCAPE
:
PORTRAIT
;
}
static
bool_t
select_orientation
(
AndroidDisplay
*
ad
,
MSVideoSize
wsize
,
MSVideoSize
vsize
){
static
void
select_orientation
(
AndroidDisplay
*
ad
,
MSVideoSize
wsize
,
MSVideoSize
vsize
){
int
wo
,
vo
;
JNIEnv
*
jenv
=
ms_get_jni_env
();
wo
=
vsize_get_orientation
(
wsize
);
vo
=
vsize_get_orientation
(
vsize
);
if
(
wo
!=
vo
){
ms_message
(
"Requesting orientation change !"
);
(
*
ad
->
jenv
)
->
CallVoidMethod
(
ad
->
jenv
,
ad
->
android_video_window
,
ad
->
request_orientation_id
,
vo
);
(
*
jenv
)
->
CallVoidMethod
(
jenv
,
ad
->
android_video_window
,
ad
->
request_orientation_id
,
vo
);
ad
->
orientation_change_pending
=
TRUE
;
}
ad
->
orientation_change_pending
=
TRUE
;
}
static
void
android_display_process
(
MSFilter
*
f
){
AndroidDisplay
*
ad
=
(
AndroidDisplay
*
)
f
->
data
;
MSPicture
pic
;
mblk_t
*
m
;
if
(
ad
->
jenv
==
NULL
){
jint
result
=
(
*
(
ad
->
jvm
))
->
AttachCurrentThread
(
ad
->
jvm
,
&
ad
->
jenv
,
NULL
);
if
(
result
!=
0
)
{
ms_error
(
"android_display_process(): cannot attach VM"
);
goto
end
;
}
}
ms_filter_lock
(
f
);
if
(
ad
->
jbitmap
!=
0
&&
!
ad
->
orientation_change_pending
){
...
...
@@ -123,6 +116,7 @@ static void android_display_process(MSFilter *f){
MSRect
vrect
;
MSPicture
dest
=
{
0
};
void
*
pixels
=
NULL
;
JNIEnv
*
jenv
=
ms_get_jni_env
();
if
(
!
ms_video_size_equal
(
vsize
,
ad
->
vsize
)){
ms_message
(
"Video to display has size %ix%i"
,
vsize
.
width
,
vsize
.
height
);
...
...
@@ -143,46 +137,38 @@ static void android_display_process(MSFilter *f){
ms_fatal
(
"Could not obtain sws context !"
);
}
}
if
(
sym_AndroidBitmap_lockPixels
(
ad
->
jenv
,
ad
->
jbitmap
,
&
pixels
)
==
0
){
dest
.
planes
[
0
]
=
(
uint8_t
*
)
pixels
+
(
vrect
.
y
*
ad
->
bmpinfo
.
stride
)
+
(
vrect
.
x
*
2
);
dest
.
strides
[
0
]
=
ad
->
bmpinfo
.
stride
;
ms_sws_scale
(
ad
->
sws
,
pic
.
planes
,
pic
.
strides
,
0
,
pic
.
h
,
dest
.
planes
,
dest
.
strides
);
sym_AndroidBitmap_unlockPixels
(
ad
->
jenv
,
ad
->
jbitmap
);
if
(
sym_AndroidBitmap_lockPixels
(
jenv
,
ad
->
jbitmap
,
&
pixels
)
==
0
){
/*
if (pixels!=NULL){
dest.planes[0]=(uint8_t*)pixels+(vrect.y*ad->bmpinfo.stride)+(vrect.x*2);
dest.strides[0]=ad->bmpinfo.stride;
ms_sws_scale (ad->sws,pic.planes,pic.strides,0,pic.h,dest.planes,dest.strides);
}else ms_warning("Pixels==NULL in android bitmap !");
*/
sym_AndroidBitmap_unlockPixels
(
jenv
,
ad
->
jbitmap
);
}
else
{
ms_error
(
"AndroidBitmap_lockPixels() failed !"
);
}
(
*
ad
->
jenv
)
->
CallVoidMethod
(
ad
->
jenv
,
ad
->
android_video_window
,
ad
->
update_id
);
(
*
jenv
)
->
CallVoidMethod
(
jenv
,
ad
->
android_video_window
,
ad
->
update_id
);
}
}
}
ms_filter_unlock
(
f
);
end:
ms_queue_flush
(
f
->
inputs
[
0
]);
ms_queue_flush
(
f
->
inputs
[
1
]);
if
(
ad
->
jenv
!=
NULL
){
jint
result
=
(
*
(
ad
->
jvm
))
->
DetachCurrentThread
(
ad
->
jvm
);
if
(
result
!=
0
)
{
ms_error
(
"android_display_process(): cannot detach VM"
);
}
ad
->
jenv
=
NULL
;
}
}
static
int
android_display_set_window
(
MSFilter
*
f
,
void
*
arg
){
AndroidDisplay
*
ad
=
(
AndroidDisplay
*
)
f
->
data
;
unsigned
long
id
=*
(
unsigned
long
*
)
arg
;
int
err
;
JNIEnv
*
jenv
=
NULL
;
JNIEnv
*
jenv
=
ms_get_jni_env
()
;
jobject
window
=
(
jobject
)
id
;
if
((
*
(
ad
->
jvm
))
->
AttachCurrentThread
(
ad
->
jvm
,
&
jenv
,
NULL
)
!=
0
){
ms_error
(
"Could not get JNIEnv"
);
return
-
1
;
}
ms_filter_lock
(
f
);
if
(
window
!=
NULL
)
ad
->
jbitmap
=
(
*
jenv
)
->
CallObjectMethod
(
jenv
,
window
,
ad
->
get_bitmap_id
);
...
...
@@ -206,6 +192,7 @@ static int android_display_set_window(MSFilter *f, void *arg){
ms_filter_unlock
(
f
);
if
(
ad
->
jbitmap
!=
NULL
)
ms_message
(
"New java bitmap given with w=%i,h=%i,stride=%i,format=%i"
,
ad
->
bmpinfo
.
width
,
ad
->
bmpinfo
.
height
,
ad
->
bmpinfo
.
stride
,
ad
->
bmpinfo
.
format
);
return
0
;
}
static
MSFilterMethod
methods
[]
=
{
...
...
@@ -213,7 +200,7 @@ static MSFilterMethod methods[]={
{
0
,
NULL
}
};
static
MSFilterDesc
ms_android_display_desc
=
{
MSFilterDesc
ms_android_display_desc
=
{
.
id
=
MS_ANDROID_DISPLAY_ID
,
.
name
=
"MSAndroidDisplay"
,
.
text
=
"Video display filter for Android."
,
...
...
@@ -234,9 +221,9 @@ extern void libmsandroiddisplaybad_init(void);
void
libmsandroiddisplay_init
(
void
){
/*See if we can use AndroidBitmap_* symbols (only since android 2.2 normally)*/
void
*
handle
=
NULL
;
#if USE_ANDROID_BITMAP
void
*
handle
=
NULL
;
handle
=
dlopen
(
"libjnigraphics.so"
,
RTLD_LAZY
);
if
(
handle
!=
NULL
){
sym_AndroidBitmap_getInfo
=
dlsym
(
handle
,
"AndroidBitmap_getInfo"
);
...
...
src/audiostream.c
View file @
559c0081
...
...
@@ -475,6 +475,7 @@ AudioStream *audio_stream_new(int locport, bool_t ipv6){
stream
->
use_gc
=
FALSE
;
stream
->
use_agc
=
FALSE
;
stream
->
use_ng
=
FALSE
;
ms_filter_enable_statistics
(
TRUE
);
return
stream
;
}
...
...
@@ -578,6 +579,7 @@ void audio_stream_stop(AudioStream * stream)
}
audio_stream_free
(
stream
);
ms_filter_log_statistics
();
}
RingStream
*
ring_start
(
const
char
*
file
,
int
interval
,
MSSndCard
*
sndcard
){
...
...
src/mscommon.c
View file @
559c0081
...
...
@@ -163,7 +163,7 @@ MSList *ms_list_find(MSList *list, void *data){
return
NULL
;
}
MSList
*
ms_list_find_custom
(
MSList
*
list
,
int
(
*
compare_func
)(
const
void
*
,
const
void
*
),
void
*
user_data
){
MSList
*
ms_list_find_custom
(
MSList
*
list
,
int
(
*
compare_func
)(
const
void
*
,
const
void
*
),
const
void
*
user_data
){
for
(;
list
!=
NULL
;
list
=
list
->
next
){
if
(
compare_func
(
list
->
data
,
user_data
)
==
0
)
return
list
;
}
...
...
src/msfilter.c
View file @
559c0081
...
...
@@ -21,6 +21,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/mscommon.h"
static
MSList
*
desc_list
=
NULL
;
static
bool_t
statistics_enabled
=
FALSE
;
static
MSList
*
stats_list
=
NULL
;
static
int
compare_stats_with_name
(
const
MSFilterStats
*
stat
,
const
char
*
name
){
return
strcmp
(
stat
->
name
,
name
);
}
static
MSFilterStats
*
find_or_create_stats
(
MSFilterDesc
*
desc
){
MSList
*
elem
=
ms_list_find_custom
(
stats_list
,(
MSCompareFunc
)
compare_stats_with_name
,
desc
->
name
);
MSFilterStats
*
ret
=
NULL
;
if
(
elem
==
NULL
){
ret
=
ms_new0
(
MSFilterStats
,
1
);
ret
->
name
=
desc
->
name
;
stats_list
=
ms_list_append
(
stats_list
,
ret
);
}
else
ret
=
(
MSFilterStats
*
)
elem
->
data
;
return
ret
;
}
void
ms_filter_register
(
MSFilterDesc
*
desc
){
if
(
desc
->
id
==
MS_FILTER_NOT_SET_ID
){
...
...
@@ -31,7 +48,15 @@ void ms_filter_register(MSFilterDesc *desc){
}
void
ms_filter_unregister_all
(){
if
(
desc_list
!=
NULL
)
ms_list_free
(
desc_list
);
if
(
desc_list
!=
NULL
)
{
ms_list_free
(
desc_list
);
desc_list
=
NULL
;
}
if
(
stats_list
!=
NULL
){
ms_list_for_each
(
stats_list
,
ms_free
);
ms_list_free
(
stats_list
);
stats_list
=
NULL
;
}
}
bool_t
ms_filter_codec_supported
(
const
char
*
mime
){
...
...
@@ -83,6 +108,10 @@ MSFilter *ms_filter_new_from_desc(MSFilterDesc *desc){
obj
->
desc
=
desc
;
if
(
desc
->
ninputs
>
0
)
obj
->
inputs
=
(
MSQueue
**
)
ms_new0
(
MSQueue
*
,
desc
->
ninputs
);
if
(
desc
->
noutputs
>
0
)
obj
->
outputs
=
(
MSQueue
**
)
ms_new0
(
MSQueue
*
,
desc
->
noutputs
);
if
(
statistics_enabled
){
obj
->
stats
=
find_or_create_stats
(
desc
);
}
if
(
obj
->
desc
->
init
!=
NULL
)
obj
->
desc
->
init
(
obj
);
return
obj
;
...
...
@@ -202,19 +231,19 @@ void ms_filter_destroy(MSFilter *f){
ms_free
(
f
);
}
#ifdef DEBUG
static
long
filter_get_cur_time
(
void
*
unused
)
static
uint64_t
get_cur_time_ns
(
void
)
{
#if defined(_WIN32_WCE)
DWORD
timemillis
=
GetTickCount
();
return
timemillis
;
return
(
uint64_t
)
timemillis
*
1000000
;
#elif defined(WIN32)
return
timeGetTime
()
;
return
timeGetTime
()
*
1000000LL
;
#elif defined(__MACH__) && defined(__GNUC__) && (__GNUC__ >= 3)
struct
timeval
tv
;
gettimeofday
(
&
tv
,
NULL
);
return
(
tv
.
tv_sec
*
1000LL
)
+
(
tv
.
tv_usec
/
1000LL
);
return
(
tv
.
tv_sec
*
1000
000000
LL
)
+
(
tv
.
tv_usec
*
1000LL
);
#elif defined(__MACH__)
struct
timespec
ts
;
struct
timeb
time_val
;
...
...
@@ -222,35 +251,31 @@ static long filter_get_cur_time(void *unused)
ftime
(
&
time_val
);
ts
.
tv_sec
=
time_val
.
time
;
ts
.
tv_nsec
=
time_val
.
millitm
*
1000000
;
return
(
ts
.
tv_sec
*
1000LL
)
+
(
ts
.
tv_nsec
/
1000000LL
)
;
return
(
ts
.
tv_sec
*
1000
000000
LL
)
+
ts
.
tv_nsec
;
#else
struct
timespec
ts
;
if
(
clock_gettime
(
CLOCK_MONOTONIC
,
&
ts
)
<
0
){
fprintf
(
stderr
,
"clock_gettime() doesn't work: %s"
,
strerror
(
errno
));
ms_fatal
(
"clock_gettime() doesn't work: %s"
,
strerror
(
errno
));
}
return
(
ts
.
tv_sec
*
1000LL
)
+
(
ts
.
tv_nsec
/
1000000LL
)
;
return
(
ts
.
tv_sec
*
1000
000000
LL
)
+
ts
.
tv_nsec
;
#endif
}
#endif
void
ms_filter_process
(
MSFilter
*
f
){
uint64_t
start
=
0
,
stop
;
ms_debug
(
"Executing process of filter %s:%p"
,
f
->
desc
->
name
,
f
);
#ifdef DEBUG
long
start
,
stop
;
start
=
filter_
get_cur_time
(
NULL
);
#endif
if
(
f
->
stats
)
start
=
get_cur_time
_ns
(
);
f
->
desc
->
process
(
f
);
#ifdef DEBUG
stop
=
filter_get_cur_time
(
NULL
);
if
(
stop
-
start
>
10
)
{
ms_warning
(
"%s take too much time:%ldms
\n
"
,
f
->
desc
->
name
,
stop
-
start
);
}
else
{
ms_debug
(
"%s take:%ldms
\n
"
,
f
->
desc
->
name
,
stop
-
start
);
if
(
f
->
stats
){
stop
=
get_cur_time_ns
();
f
->
stats
->
count
++
;
f
->
stats
->
elapsed
+=
stop
-
start
;
}
#endif
}
void
ms_filter_preprocess
(
MSFilter
*
f
,
struct
_MSTicker
*
t
){
...
...
@@ -352,4 +377,37 @@ int ms_connection_helper_unlink(MSConnectionHelper *h, MSFilter *f, int inpin, i
return
err
;
}
void
ms_filter_enable_statistics
(
bool_t
enabled
){
statistics_enabled
=
enabled
;
}
const
MSList
*
ms_filter_get_statistics
(
void
){
return
stats_list
;
}
static
int
usage_compare
(
const
MSFilterStats
*
s1
,
const
MSFilterStats
*
s2
){
if
(
s1
->
elapsed
==
s2
->
elapsed
)
return
0
;
if
(
s1
->
elapsed
<
s2
->
elapsed
)
return
1
;
return
-
1
;
}
void
ms_filter_log_statistics
(
void
){
MSList
*
sorted
=
NULL
;
MSList
*
elem
;
uint64_t
total
=
0
;
ms_message
(
"Filter usage statistics:"
);
for
(
elem
=
stats_list
;
elem
!=
NULL
;
elem
=
elem
->
next
){
MSFilterStats
*
stats
=
(
MSFilterStats
*
)
elem
->
data
;
sorted
=
ms_list_insert_sorted
(
sorted
,
stats
,(
MSCompareFunc
)
usage_compare
);
total
+=
stats
->
elapsed
;
}
ms_message
(
"Name
\t
Count
\t
CPU Usage"
);
for
(
elem
=
sorted
;
elem
!=
NULL
;
elem
=
elem
->
next
){
MSFilterStats
*
stats
=
(
MSFilterStats
*
)
elem
->
data
;
double
percentage
=
100
.
0
*
((
double
)
stats
->
elapsed
)
/
(
double
)
total
;
ms_message
(
"%s %i %g"
,
stats
->
name
,
stats
->
count
,
percentage
);
}
ms_list_free
(
sorted
);
}
src/msjava.c
0 → 100644
View file @
559c0081
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2010 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "mediastreamer2/msjava.h"
#include "mediastreamer2/mscommon.h"
static
JavaVM
*
ms2_vm
=
NULL
;
#ifndef WIN32
#include <pthread.h>
static
pthread_key_t
jnienv_key
;
static
void
key_cleanup
(
void
*
data
){
(
*
ms2_vm
)
->
DetachCurrentThread
(
ms2_vm
);
}