Commit b184aec8 authored by Simon Morlat's avatar Simon Morlat
Browse files

Merge branch 'master' of git://git.linphone.org/mediastreamer2

parents fe5d5f0c 54678a7a
......@@ -372,6 +372,14 @@ MS2_PUBLIC void ice_session_set_keepalive_timeout(IceSession *session, uint8_t t
*/
MS2_PUBLIC int ice_session_nb_check_lists(IceSession *session);
/**
* Tell whether an ICE session has at least one completed check list.
*
* @param session A pointer to a session
* @return TRUE if the session has at least one completed check list, FALSE otherwise
*/
MS2_PUBLIC bool_t ice_session_has_completed_check_list(const IceSession *session);
/**
* Add an ICE check list to an ICE session.
*
......@@ -542,6 +550,13 @@ MS2_PUBLIC bool_t ice_check_list_selected_valid_local_candidate(const IceCheckLi
*/
MS2_PUBLIC bool_t ice_check_list_selected_valid_remote_candidate(const IceCheckList *cl, const char **rtp_addr, int *rtp_port, const char **rtcp_addr, int *rtcp_port);
/**
* Check if an ICE check list can be set in the Completed state after handling losing pairs.
*
* @param cl A pointer to a check list
*/
MS2_PUBLIC void ice_check_list_check_completed(IceCheckList *cl);
/**
* Get the candidate type as a string.
*
......
......@@ -125,6 +125,7 @@ static int ice_compare_candidates(const IceCandidate *c1, const IceCandidate *c2
static int ice_find_host_candidate(const IceCandidate *candidate, const uint16_t *componentID);
static int ice_find_nominated_valid_pair_from_componentID(const IceValidCandidatePair* valid_pair, const uint16_t* componentID);
static int ice_find_selected_valid_pair_from_componentID(const IceValidCandidatePair* valid_pair, const uint16_t* componentID);
static void ice_find_selected_valid_pair_for_componentID(const uint16_t *componentID, CheckList_Bool *cb);
static int ice_find_running_check_list(const IceCheckList *cl);
static int ice_find_pair_in_valid_list(IceValidCandidatePair *valid_pair, IceCandidatePair *pair);
static void ice_pair_set_state(IceCandidatePair *pair, IceCandidatePairState state);
......@@ -415,17 +416,28 @@ IceCheckListState ice_check_list_state(const IceCheckList* cl)
return cl->state;
}
static int ice_find_non_failed_check_list(const IceCheckList *cl)
static int ice_find_check_list_from_state(const IceCheckList *cl, const IceCheckListState *state)
{
return (cl->state == ICL_Failed);
return (cl->state == *state);
}
void ice_check_list_set_state(IceCheckList *cl, IceCheckListState state)
{
cl->state = state;
if (ms_list_find_custom(cl->session->streams, (MSCompareFunc)ice_find_non_failed_check_list, NULL) == NULL) {
/* Set the state of the session to Failed if all the check lists are in the Failed state. */
cl->session->state = IS_Failed;
IceCheckListState check_state;
if (cl->state != state) {
cl->state = state;
check_state = ICL_Running;
if (ms_list_find_custom(cl->session->streams, (MSCompareFunc)ice_find_check_list_from_state, &check_state) == NULL) {
check_state = ICL_Failed;
if (ms_list_find_custom(cl->session->streams, (MSCompareFunc)ice_find_check_list_from_state, &check_state) != NULL) {
/* Set the state of the session to Failed if at least one check list is in the Failed state. */
cl->session->state = IS_Failed;
} else {
/* All the check lists are in the Completed state, set the state of the session to Completed. */
cl->session->state = IS_Completed;
}
}
}
}
......@@ -567,6 +579,20 @@ bool_t ice_check_list_selected_valid_remote_candidate(const IceCheckList *cl, co
return TRUE;
}
void ice_check_list_check_completed(IceCheckList *cl)
{
CheckList_Bool cb;
if (cl->state != ICL_Completed) {
cb.cl = cl;
cb.result = TRUE;
ms_list_for_each2(cl->local_componentIDs, (void (*)(void*,void*))ice_find_selected_valid_pair_for_componentID, &cb);
if (cb.result == TRUE) {
ice_check_list_set_state(cl, ICL_Completed);
}
}
}
static void ice_check_list_queue_triggered_check(IceCheckList *cl, IceCandidatePair *pair)
{
MSList *elem = ms_list_find(cl->triggered_checks_queue, pair);
......@@ -704,6 +730,18 @@ int ice_session_nb_check_lists(IceSession *session)
return ms_list_size(session->streams);
}
static int ice_find_completed_check_list(const IceCheckList *cl, const void *dummy)
{
return (cl->state != ICL_Completed);
}
bool_t ice_session_has_completed_check_list(const IceSession *session)
{
MSList *elem = ms_list_find_custom(session->streams, (MSCompareFunc)ice_find_completed_check_list, NULL);
if (elem == NULL) return FALSE;
else return TRUE;
}
void ice_session_add_check_list(IceSession *session, IceCheckList *cl)
{
session->streams = ms_list_append(session->streams, cl);
......@@ -821,6 +859,8 @@ static void ice_check_list_select_candidates(IceCheckList *cl)
uint16_t componentID;
MSList *elem;
if (cl->state != ICL_Completed) return;
ms_list_for_each(cl->valid_list, (void (*)(void*))ice_unselect_valid_pair);
for (componentID = 1; componentID <= 2; componentID++) {
elem = ms_list_find_custom(cl->valid_list, (MSCompareFunc)ice_find_nominated_valid_pair_from_componentID, &componentID);
......@@ -2393,14 +2433,22 @@ static int ice_find_nominated_valid_pair_from_componentID(const IceValidCandidat
return !((valid_pair->valid->is_nominated == TRUE) && (valid_pair->valid->local->componentID == *componentID));
}
static void ice_find_nominated_valid_pair_for_componentID(const uint16_t *componentID, CheckList_Bool *cb)
{
MSList *elem = ms_list_find_custom(cb->cl->valid_list, (MSCompareFunc)ice_find_nominated_valid_pair_from_componentID, componentID);
if (elem == NULL) {
/* This component ID is not present in the valid list. */
cb->result = FALSE;
}
}
static int ice_find_selected_valid_pair_from_componentID(const IceValidCandidatePair *valid_pair, const uint16_t *componentID)
{
return !((valid_pair->selected == TRUE) && (valid_pair->valid->local->componentID == *componentID));
}
static void ice_find_nominated_valid_pair_for_componentID(const uint16_t *componentID, CheckList_Bool *cb)
static void ice_find_selected_valid_pair_for_componentID(const uint16_t *componentID, CheckList_Bool *cb)
{
MSList *elem = ms_list_find_custom(cb->cl->valid_list, (MSCompareFunc)ice_find_nominated_valid_pair_from_componentID, componentID);
MSList *elem = ms_list_find_custom(cb->cl->valid_list, (MSCompareFunc)ice_find_selected_valid_pair_from_componentID, componentID);
if (elem == NULL) {
/* This component ID is not present in the valid list. */
cb->result = FALSE;
......@@ -2662,6 +2710,15 @@ void ice_check_list_process(IceCheckList *cl, RtpSession *rtp_session)
}
}
/* Send event if needed. */
if ((cl->session->send_event == TRUE) && (curtime >= cl->session->event_time)) {
OrtpEvent *ev;
cl->session->send_event = FALSE;
ev = ortp_event_new(cl->session->event_value);
ortp_event_get_data(ev)->info.ice_processing_successful = (cl->session->state == IS_Completed);
rtp_session_dispatch_event(rtp_session, ev);
}
if ((cl->session->state == IS_Stopped) || (cl->session->state == IS_Failed)) return;
switch (cl->state) {
......@@ -2671,14 +2728,6 @@ void ice_check_list_process(IceCheckList *cl, RtpSession *rtp_session)
ice_send_keepalive_packets(cl, rtp_session);
cl->keepalive_time = curtime;
}
/* Send event if needed. */
if ((cl->session->send_event == TRUE) && (curtime >= cl->session->event_time)) {
OrtpEvent *ev;
cl->session->send_event = FALSE;
ev = ortp_event_new(cl->session->event_value);
ortp_event_get_data(ev)->info.ice_processing_successful = (cl->session->state == IS_Completed);
rtp_session_dispatch_event(rtp_session, ev);
}
/* No break to be able to respond to connectivity checks. */
case ICL_Running:
/* Check if some retransmissions are needed. */
......
......@@ -41,61 +41,36 @@
#include "opengles_display.h"
@interface IOSDisplay : UIView {
@private
UIView* imageView;
@public
struct opengles_display* display_helper;
@private
NSRecursiveLock* lock;
EAGLContext* context;
GLuint defaultFrameBuffer, colorRenderBuffer;
struct opengles_display* helper;
id displayLink;
BOOL animating;
int deviceRotation;
CGRect prevBounds;
}
- (void)drawView:(id)sender;
- (BOOL)loadShaders;
- (void)initIOSDisplay;
@property (nonatomic, retain) UIView* parentView;
@property (assign) int deviceRotation;
@property (assign) int displayRotation;
@end
@implementation IOSDisplay
@synthesize parentView;
- (id)init {
self = [super init];
if (self) {
[self initIOSDisplay];
}
return self;
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
[self initIOSDisplay];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initIOSDisplay];
}
return self;
}
@synthesize deviceRotation;
@synthesize displayRotation;
- (void)initIOSDisplay {
self->deviceRotation = 0;
self->helper = ogl_display_new();
self->lock = [[NSRecursiveLock alloc] init];
self->display_helper = ogl_display_new();
self->prevBounds = CGRectMake(0, 0, 0, 0);
// Init view
[self setOpaque:YES];
[self setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
......@@ -103,8 +78,10 @@
// Init layer
CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer;
[eaglLayer setOpaque:YES];
[eaglLayer setDrawableProperties: [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking,
kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
nil]];
// Init OpenGL context
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!context || ![EAGLContext setCurrentContext:context]) {
......@@ -114,28 +91,53 @@
glGenFramebuffers(1, &defaultFrameBuffer);
glGenRenderbuffers(1, &colorRenderBuffer);
glGenRenderbuffers(1, &colorRenderBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFrameBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderBuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderBuffer);
ogl_display_init(display_helper, prevBounds.size.width, prevBounds.size.height);
// release GL context for this thread
[EAGLContext setCurrentContext:nil];
}
- (void)drawView:(id)sender {
- (id)init {
self = [super init];
if (self) {
[self initIOSDisplay];
}
return self;
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
[self initIOSDisplay];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initIOSDisplay];
}
return self;
}
- (void)drawView {
/* no opengl es call made when in background */
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground)
return;
@synchronized(self) {
if([lock tryLock]) {
if (![EAGLContext setCurrentContext:context]) {
ms_error("Failed to bind GL context");
return;
}
if (!CGRectEqualToRect(prevBounds, [self bounds])) {
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderBuffer);
CAEAGLLayer* layer = (CAEAGLLayer*)self.layer;
if (prevBounds.size.width != 0 || prevBounds.size.height != 0) {
......@@ -146,24 +148,23 @@
prevBounds = [self bounds];
// allocate storage
if (![context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]) {
ms_error("Error in renderbufferStorage (layer %p frame size: %f x %f)", layer, layer.frame.size.width, layer.frame.size.height);
} else {
if ([context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]) {
ms_message("GL renderbuffer allocation size (layer %p frame size: %f x %f)", layer, layer.frame.size.width, layer.frame.size.height);
ogl_display_init(helper, prevBounds.size.width, prevBounds.size.height);
glClearColor(0, 0, 0, 1);
ogl_display_set_size(display_helper, prevBounds.size.width, prevBounds.size.height);
glClear(GL_COLOR_BUFFER_BIT);
} else {
ms_error("Error in renderbufferStorage (layer %p frame size: %f x %f)", layer, layer.frame.size.width, layer.frame.size.height);
}
}
}
if (!animating) {
glClear(GL_COLOR_BUFFER_BIT);
} else {
ogl_display_render(helper, 0);
ogl_display_render(display_helper, 0);
}
[context presentRenderbuffer:GL_RENDERBUFFER];
[lock unlock];
}
}
......@@ -179,7 +180,7 @@
[displayLink invalidate];
displayLink = nil;
[self drawView:0];
[self drawView];
// remove from parent
[self removeFromSuperview];
......@@ -199,7 +200,7 @@
[parentView addSubview:self];
// schedule rendering
displayLink = [self.window.screen displayLinkWithTarget:self selector:@selector(drawView:)];
displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView)];
[displayLink setFrameInterval:1];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
......@@ -209,30 +210,41 @@
return [CAEAGLLayer class];
}
static void iosdisplay_init(MSFilter *f) {
f->data = [[IOSDisplay alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
}
- (void)dealloc {
[EAGLContext setCurrentContext:context];
glFinish();
ogl_display_uninit(helper, TRUE);
ogl_display_free(helper);
helper = NULL;
ogl_display_uninit(display_helper, TRUE);
ogl_display_free(display_helper);
display_helper = NULL;
glDeleteFramebuffers(GL_FRAMEBUFFER, &defaultFrameBuffer);
glDeleteRenderbuffers(GL_RENDERBUFFER, &colorRenderBuffer);
[EAGLContext setCurrentContext:0];
[context release];
[parentView release];
[lock release];
self.parentView = nil;
[super dealloc];
}
@end
static void iosdisplay_init(MSFilter *f) {
NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
f->data = [[IOSDisplay alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[loopPool drain];
}
static void iosdisplay_process(MSFilter *f) {
IOSDisplay* thiz = (IOSDisplay*)f->data;
mblk_t *m = ms_queue_peek_last(f->inputs[0]);
if (thiz != nil && m != nil) {
ogl_display_set_yuv_to_display(thiz->helper, m);
ogl_display_set_yuv_to_display(thiz->display_helper, m);
}
ms_queue_flush(f->inputs[0]);
......@@ -240,36 +252,29 @@ static void iosdisplay_process(MSFilter *f) {
ms_queue_flush(f->inputs[1]);
}
static void iosdisplay_unit(MSFilter *f) {
static void iosdisplay_uninit(MSFilter *f) {
IOSDisplay* thiz = (IOSDisplay*)f->data;
if(thiz != nil) {
[thiz performSelectorOnMainThread:@selector(setParentView:) withObject:nil waitUntilDone:NO];
[thiz release];
f->data = NULL;
}
// Remove from parent view in order to release all reference to IOSDisplay
[thiz performSelectorOnMainThread:@selector(setParentView:) withObject:nil waitUntilDone:NO];
[thiz release];
}
/*filter specific method*/
/* This methods declare the PARENT window of the opengl view.
We'll create on gl view for once, and then simply change its parent.
This works only if parent size is the size in all possible orientation.
*/
static int iosdisplay_set_native_window(MSFilter *f, void *arg) {
UIView* parentView = *(UIView**)arg;
IOSDisplay *thiz = (IOSDisplay*)f->data;
if (thiz != nil) {
UIView* parentView = *(UIView**)arg;
if (thiz != nil) {
NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
// set current parent view
if (parentView) {
[thiz performSelectorOnMainThread:@selector(setParentView:) withObject:parentView waitUntilDone:NO];
}
[thiz performSelectorOnMainThread:@selector(setParentView:) withObject:parentView waitUntilDone:NO];
[loopPool drain];
}
return 0;
}
static int iosdisplay_get_native_window(MSFilter *f, void *arg) {
IOSDisplay* thiz=(IOSDisplay*)f->data;
arg = &thiz->parentView;
*(UIView**)arg = thiz.parentView;
return 0;
}
......@@ -277,7 +282,7 @@ static int iosdisplay_set_device_orientation(MSFilter* f, void* arg) {
IOSDisplay* thiz=(IOSDisplay*)f->data;
if (!thiz)
return 0;
//thiz->deviceRotation = 0;//*((int*)arg);
thiz.deviceRotation = *((int*)arg);
return 0;
}
......@@ -285,13 +290,13 @@ static int iosdisplay_set_device_orientation_display(MSFilter* f, void* arg) {
IOSDisplay* thiz=(IOSDisplay*)f->data;
if (!thiz)
return 0;
thiz->deviceRotation = *((int*)arg);
thiz.displayRotation = *((int*)arg);
return 0;
}
static int iosdisplay_set_zoom(MSFilter* f, void* arg) {
IOSDisplay* thiz=(IOSDisplay*)f->data;
ogl_display_zoom(thiz->helper, arg);
ogl_display_zoom(thiz->display_helper, arg);
}
static MSFilterMethod iosdisplay_methods[] = {
......@@ -303,8 +308,6 @@ static MSFilterMethod iosdisplay_methods[] = {
{ 0, NULL }
};
@end
MSFilterDesc ms_iosdisplay_desc = {
.id=MS_IOS_DISPLAY_ID, /* from Allfilters.h*/
.name="IOSDisplay",
......@@ -313,10 +316,8 @@ MSFilterDesc ms_iosdisplay_desc = {
.ninputs=2, /*number of inputs*/
.noutputs=0, /*number of outputs*/
.init=iosdisplay_init,
.preprocess=NULL,
.process=iosdisplay_process,
.postprocess=NULL,
.uninit=iosdisplay_unit,
.uninit=iosdisplay_uninit,
.methods=iosdisplay_methods
};
MS_FILTER_DESC_EXPORT(ms_iosdisplay_desc)
......@@ -12,32 +12,26 @@
@interface CAMsGLLayer : CAOpenGLLayer {
@public
struct opengles_display* display_helper;
CGSize sourceSize;
NSWindow *window;
@private
CGLPixelFormatObj cglPixelFormat;
CGLContextObj cglContext;
NSRecursiveLock *lock;
NSRecursiveLock* lock;
CGRect prevBounds;
}
- (void)resizeWindow;
- (void)resizeToWindow:(NSWindow *)window;
@property (assign) CGRect prevBounds;
@property (assign) CGSize sourceSize;
@property (readonly) NSRecursiveLock* lock;
@end
@implementation CAMsGLLayer
@synthesize prevBounds;
@synthesize sourceSize;
@synthesize lock;
- (id)init {
self = [super init];
if(self != nil) {
self->window = nil;
self->sourceSize = CGSizeMake(0, 0);
self->prevBounds = CGRectMake(0, 0, 0, 0);
self->lock = [[NSRecursiveLock alloc] init];
......@@ -63,6 +57,15 @@
cglContext = [super copyCGLContextForPixelFormat:cglPixelFormat];
assert(cglContext);
CGLContextObj savedContext = CGLGetCurrentContext();
CGLSetCurrentContext(cglContext);
CGLLockContext(cglContext);
ogl_display_init(display_helper, prevBounds.size.width, prevBounds.size.height);
CGLUnlockContext(cglContext);
CGLSetCurrentContext(savedContext);
}
return self;
}
......@@ -114,10 +117,9 @@
if (!NSEqualRects(prevBounds, [self bounds])) {
prevBounds = [self bounds];
ogl_display_init(display_helper, prevBounds.size.width, prevBounds.size.height);
ogl_display_set_size(display_helper, prevBounds.size.width, prevBounds.size.height);
}
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
ogl_display_render(display_helper, 0);
......@@ -134,7 +136,7 @@
}
}
- (void)resizeWindow {
- (void)resizeToWindow:(NSWindow *)window {
if(window != nil) {
// Centred resize
NSRect rect = [window frameRectForContentRect:NSMakeRect(0, 0, sourceSize.width, sourceSize.height)];
......@@ -149,73 +151,154 @@
@end
typedef struct GLOSXState {
NSWindow* window;
CALayer* layer;
CAMsGLLayer *glLayer;
} GLOSXState;
@interface OSXDisplay : NSObject
@property (assign) BOOL closeWindow;
@property (nonatomic, retain) NSWindow* window;
@property (nonatomic, retain) NSView* view;
@property (nonatomic, retain) CALayer* layer;
@property (nonatomic, retain) CAMsGLLayer* glLayer;
#include <OpenGL/CGLRenderers.h>
static void osx_gl_init(MSFilter* f) {
GLOSXState* s = (GLOSXState*) ms_new0(GLOSXState, 1);
f->data = s;
- (void)createWindowIfNeeded;
- (void)resetContainers;
@end
@implementation OSXDisplay
@synthesize closeWindow;
@synthesize window;
@synthesize view;
@synthesize layer;
@synthesize glLayer;
- (id)init {
self = [super init];
if(self != nil) {
self.glLayer = [[CAMsGLLayer alloc] init];
window = nil;