Commit 54e7cf21 authored by Ghislain MARY's avatar Ghislain MARY
Browse files

Merge branch 'master' into dev_ice

parents 3b034c00 b72c1460
......@@ -63,6 +63,7 @@ public final class Hacks {
private static boolean isSGHI896() {return Build.DEVICE.startsWith("SGH-I896");} // Captivate
private static boolean isGT9000() {return Build.DEVICE.startsWith("GT-I9000");} // Galaxy S
private static boolean isGTI9100() {return Build.DEVICE.startsWith("GT-I9100");} // Galaxy S II
private static boolean isGTI9300() {return Build.DEVICE.startsWith("GT-I9300");} // Galaxy S III
private static boolean isSC02B() {return Build.DEVICE.startsWith("SC-02B");} // Docomo
private static boolean isGTP1000() {return Build.DEVICE.startsWith("GT-P1000");} // Tab
......@@ -135,6 +136,6 @@ public final class Hacks {
}
public static boolean hasBuiltInEchoCanceller() {
return isGTI9100();
return isGTI9100() || isGTI9300();
}
}
......@@ -228,7 +228,7 @@ libmediastreamer_la_LDFLAGS+= -framework CoreGraphics
endif
if BUILD_MACOSX
libmediastreamer_la_LDFLAGS+= -framework Cocoa -framework OpenGL
libmediastreamer_la_LDFLAGS+= -framework Cocoa -framework OpenGL -framework QuartzCore
endif
if BUILD_WIN32
......
......@@ -140,6 +140,9 @@ static int dtmfgen_put(MSFilter *f, void *arg){
s->lowfreq=941;
s->highfreq=1633;
break;
case '!':
ms_message("flash dtmf");
return 0;
case ' ':
/*ignore*/
return 0;
......
This diff is collapsed.
/*
iosdisplay.m
Copyright (C) 2011 Belledonne Communications, Grenoble, France
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.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/EAGLDrawable.h>
#import <OpenGLES/ES2/gl.h>
#include "mediastreamer2/msfilter.h"
#include "opengles_display.h"
@interface IOSDisplay : UIView {
@private
UIView* imageView;
EAGLContext* context;
GLuint defaultFrameBuffer, colorRenderBuffer;
struct opengles_display* helper;
BOOL glInitDone;
id displayLink;
BOOL animating;
int deviceRotation;
int allocatedW, allocatedH;
}
- (void) drawView:(id)sender;
- (void) startRendering:(id)ignore;
- (void) stopRendering:(id)ignore;
@property (nonatomic, retain) UIView* imageView;
@end
......@@ -27,51 +27,86 @@
#include "mediastreamer2/mswebcam.h"
#include "mediastreamer2/mscommon.h"
#include "nowebcam.h"
#include "mediastreamer2/msfilter.h"
#include "scaler.h"
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/EAGLDrawable.h>
#import <OpenGLES/ES2/gl.h>
#import "iosdisplay.h"
#include "mediastreamer2/msfilter.h"
#include "scaler.h"
#include "opengles_display.h"
@interface IOSDisplay : UIView {
@private
UIView* imageView;
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;
@interface IOSDisplay (PrivateMethods)
- (BOOL) loadShaders;
- (void) initGlRendering;
@end
@implementation IOSDisplay
@synthesize imageView;
@synthesize parentView;
- (id)initWithCoder:(NSCoder *)coder
{
- (id)init {
self = [super init];
if (self) {
[self initIOSDisplay];
}
return self;
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
[self initGlRendering];
[self initIOSDisplay];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initGlRendering];
[self initIOSDisplay];
}
return self;
}
- (void)initGlRendering
{
- (void)initIOSDisplay {
self->deviceRotation = 0;
self->helper = ogl_display_new();
self->prevBounds = CGRectMake(0, 0, 0, 0);
// Initialization code
// Init view
[self setOpaque:YES];
[self setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
// Init layer
CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer;
eaglLayer.opaque = TRUE;
[eaglLayer setOpaque:YES];
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
// Init OpenGL context
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!context || ![EAGLContext setCurrentContext:context]) {
ms_error("Opengl context failure");
return;
......@@ -83,17 +118,12 @@
glBindFramebuffer(GL_FRAMEBUFFER, defaultFrameBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderBuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderBuffer);
// release GL context for this thread
[EAGLContext setCurrentContext:nil];
glInitDone = FALSE;
allocatedW = allocatedH = 0;
deviceRotation = 0;
}
- (void) drawView:(id)sender
{
- (void)drawView:(id)sender {
/* no opengl es call made when in background */
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground)
return;
......@@ -104,95 +134,86 @@
return;
}
[self updateRenderStorageIfNeeded];
glBindFramebuffer(GL_FRAMEBUFFER, defaultFrameBuffer);
if (!glInitDone || !animating) {
if (!CGRectEqualToRect(prevBounds, [self bounds])) {
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderBuffer);
CAEAGLLayer* layer = (CAEAGLLayer*)self.layer;
if (prevBounds.size.width != 0 || prevBounds.size.height != 0) {
// release previously allocated storage
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:nil];
}
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 {
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);
glClear(GL_COLOR_BUFFER_BIT);
}
}
if (!animating) {
glClear(GL_COLOR_BUFFER_BIT);
}else ogl_display_render(helper, deviceRotation);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderBuffer);
} else {
ogl_display_render(helper, 0);
}
[context presentRenderbuffer:GL_RENDERBUFFER];
}
}
- (void) updateRenderStorageIfNeeded
{
@synchronized(self) {
if (!(allocatedW == self.superview.frame.size.width && allocatedH == self.superview.frame.size.height)) {
if (![EAGLContext setCurrentContext:context]) {
ms_error("Failed to set EAGLContext - expect issues");
}
glFinish();
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderBuffer);
CAEAGLLayer* layer = (CAEAGLLayer*)self.layer;
- (void)setParentView:(UIView*)aparentView{
if (parentView == aparentView) {
return;
}
if(parentView != nil) {
animating = FALSE;
if (allocatedW != 0 || allocatedH != 0) {
// release previously allocated storage
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:nil];
allocatedW = allocatedH = 0;
}
// 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 {
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &allocatedW);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &allocatedH);
ms_message("GL renderbuffer allocation size: %dx%d (layer frame size: %f x %f)", allocatedW, allocatedH, layer.frame.size.width, layer.frame.size.height);
ogl_display_init(helper, self.superview.frame.size.width, self.superview.frame.size.height);
// stop schedule rendering
[displayLink invalidate];
displayLink = nil;
glBindFramebuffer(GL_FRAMEBUFFER, defaultFrameBuffer);
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
}
}
[self drawView:0];
// remove from parent
[self removeFromSuperview];
[parentView release];
parentView = nil;
}
glInitDone = TRUE;
}
- (void) startRendering: (id)ignore
{
if (!animating)
{
if (self.superview != self.imageView) {
// remove from old parent
[self removeFromSuperview];
// add to new parent
[self.imageView addSubview:self];
}
parentView = aparentView;
if(parentView != nil) {
[parentView retain];
animating = TRUE;
// add to new parent
[self setFrame: [parentView bounds]];
[parentView addSubview:self];
// schedule rendering
displayLink = [self.window.screen displayLinkWithTarget:self selector:@selector(drawView:)];
[displayLink setFrameInterval:1];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
animating = TRUE;
}
}
- (void) stopRendering: (id)ignore
{
if (animating)
{
[displayLink invalidate];
displayLink = nil;
animating = FALSE;
[self drawView:0];
// remove from parent
[self removeFromSuperview];
}
}
+ (Class)layerClass
{
+ (Class)layerClass {
return [CAEAGLLayer class];
}
static void iosdisplay_init(MSFilter *f){
static void iosdisplay_init(MSFilter *f) {
f->data = [[IOSDisplay alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
}
-(void) dealloc {
- (void)dealloc {
[EAGLContext setCurrentContext:context];
glFinish();
ogl_display_uninit(helper, TRUE);
......@@ -201,14 +222,14 @@ static void iosdisplay_init(MSFilter *f){
[EAGLContext setCurrentContext:0];
[context release];
[imageView release];
[parentView release];
[super dealloc];
}
static void iosdisplay_process(MSFilter *f){
IOSDisplay* thiz=(IOSDisplay*)f->data;
mblk_t *m=ms_queue_peek_last(f->inputs[0]);
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);
......@@ -219,13 +240,14 @@ static void iosdisplay_process(MSFilter *f){
ms_queue_flush(f->inputs[1]);
}
static void iosdisplay_unit(MSFilter *f){
IOSDisplay* thiz=(IOSDisplay*)f->data;
[thiz performSelectorOnMainThread:@selector(stopRendering:) withObject:nil waitUntilDone:YES];
static void iosdisplay_unit(MSFilter *f) {
IOSDisplay* thiz = (IOSDisplay*)f->data;
[thiz release];
if(thiz != nil) {
[thiz performSelectorOnMainThread:@selector(setParentView:) withObject:nil waitUntilDone:NO];
[thiz release];
f->data = NULL;
}
}
/*filter specific method*/
......@@ -235,32 +257,31 @@ static void iosdisplay_unit(MSFilter *f){
*/
static int iosdisplay_set_native_window(MSFilter *f, void *arg) {
UIView* parentView = *(UIView**)arg;
IOSDisplay* thiz;
if (f->data != nil) {
thiz = f->data;
NSLog(@"OpenGL view parent changed (%p -> %p)", thiz.imageView, *((unsigned long*)arg));
thiz.frame = CGRectMake(0, 0, parentView.frame.size.width, parentView.frame.size.height);
[thiz performSelectorOnMainThread:@selector(stopRendering:) withObject:nil waitUntilDone:YES];
} else if (parentView == nil) {
return 0;
} else {
thiz = f->data = [[IOSDisplay alloc] initWithFrame:CGRectMake(0, 0, parentView.frame.size.width, parentView.frame.size.height)];
IOSDisplay *thiz = (IOSDisplay*)f->data;
if (thiz != nil) {
// set current parent view
if (parentView) {
[thiz performSelectorOnMainThread:@selector(setParentView:) withObject:parentView waitUntilDone:NO];
}
}
thiz.imageView = parentView;
if (parentView)
[thiz performSelectorOnMainThread:@selector(startRendering:) withObject:nil waitUntilDone:YES];
return 0;
}
static int iosdisplay_get_native_window(MSFilter *f, void *arg) {
IOSDisplay* thiz=(IOSDisplay*)f->data;
arg = &thiz->imageView;
arg = &thiz->parentView;
return 0;
}
static int iosdisplay_set_device_orientation(MSFilter* f, void* arg) {
IOSDisplay* thiz=(IOSDisplay*)f->data;
if (!thiz)
return 0;
//thiz->deviceRotation = 0;//*((int*)arg);
return 0;
}
static int iosdisplay_set_device_orientation_display(MSFilter* f, void* arg) {
IOSDisplay* thiz=(IOSDisplay*)f->data;
if (!thiz)
return 0;
......@@ -273,17 +294,18 @@ static int iosdisplay_set_zoom(MSFilter* f, void* arg) {
ogl_display_zoom(thiz->helper, arg);
}
static MSFilterMethod iosdisplay_methods[]={
{ MS_VIDEO_DISPLAY_SET_NATIVE_WINDOW_ID , iosdisplay_set_native_window },
{ MS_VIDEO_DISPLAY_GET_NATIVE_WINDOW_ID , iosdisplay_get_native_window },
{ MS_VIDEO_DISPLAY_SET_DEVICE_ORIENTATION, iosdisplay_set_device_orientation },
{ MS_VIDEO_DISPLAY_ZOOM, iosdisplay_set_zoom},
{ 0, NULL}
static MSFilterMethod iosdisplay_methods[] = {
{ MS_VIDEO_DISPLAY_SET_NATIVE_WINDOW_ID, iosdisplay_set_native_window },
{ MS_VIDEO_DISPLAY_GET_NATIVE_WINDOW_ID, iosdisplay_get_native_window },
{ MS_VIDEO_DISPLAY_SET_DEVICE_ORIENTATION, iosdisplay_set_device_orientation },
{ MS_VIDEO_DISPLAY_SET_DEVICE_ORIENTATION, iosdisplay_set_device_orientation_display },
{ MS_VIDEO_DISPLAY_ZOOM, iosdisplay_set_zoom },
{ 0, NULL }
};
@end
MSFilterDesc ms_iosdisplay_desc={
MSFilterDesc ms_iosdisplay_desc = {
.id=MS_IOS_DISPLAY_ID, /* from Allfilters.h*/
.name="IOSDisplay",
.text="IOS Display filter.",
......
......@@ -248,6 +248,10 @@ static int video_set_native_preview_window(MSFilter *f, void *arg) {
} else {
ms_message("Preview capture window set but camera not created yet; remembering it for later use\n");
}
if (d->previewWindow) {
ms_message("Deleting previous preview window %p", d->previewWindow);
env->DeleteGlobalRef(d->previewWindow);
}
d->previewWindow = w;
ms_mutex_unlock(&d->mutex);
......
......@@ -6,51 +6,154 @@
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include "opengles_display.h"
@interface NsMsGLDisplay : NSOpenGLView
{
#import <QuartzCore/CATransaction.h>
@interface CAMsGLLayer : CAOpenGLLayer {
@public
struct opengles_display* display_helper;
int w, h;
CGSize sourceSize;
NSWindow *window;
CGLPixelFormatObj cglPixelFormat;
CGLContextObj cglContext;
NSRecursiveLock *lock;
CGRect prevBounds;
}
- (void) drawRect: (NSRect) bounds;
-(void) reshape;
-(void) resizeWindow: (id) window;
- (void)resizeWindow;
@property (assign) CGRect prevBounds;
@property (assign) CGSize sourceSize;
@property (readonly) NSRecursiveLock* lock;
@end
typedef struct GLOSXState {
NSWindow* window;
NsMsGLDisplay* disp;
} GLOSXState;
@implementation CAMsGLLayer
@implementation NsMsGLDisplay
@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];
self->display_helper = ogl_display_new();
[self setOpaque:YES];
[self setAsynchronous:NO];
[self setAutoresizingMask: kCALayerWidthSizable | kCALayerHeightSizable];
//[self setNeedsDisplayOnBoundsChange:YES];
// FBO Support
GLint numPixelFormats = 0;
CGLPixelFormatAttribute attributes[] =
{
kCGLPFAAccelerated,
kCGLPFANoRecovery,
kCGLPFADoubleBuffer,
0
};
CGLChoosePixelFormat(attributes, &cglPixelFormat, &numPixelFormats);
assert(cglPixelFormat);
cglContext = [super copyCGLContextForPixelFormat:cglPixelFormat];
assert(cglContext);
}
return self;
}
-(void) reshape {
CGLContextObj obj = CGLGetCurrentContext();
NSOpenGLContext* ctx = [self openGLContext];
[ctx makeCurrentContext];
ogl_display_init(display_helper, self.bounds.size.width, self.bounds.size.height);
[NSOpenGLContext clearCurrentContext];
- (void)dealloc {
ogl_display_uninit(display_helper, TRUE);
ogl_display_free(display_helper);
[self releaseCGLContext:cglContext];
[self releaseCGLPixelFormat:cglPixelFormat];
[lock release];
[super dealloc];
}
- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask {
CGLRetainPixelFormat(cglPixelFormat);
return cglPixelFormat;
}
- (void)releaseCGLPixelFormat:(CGLPixelFormatObj)pixelFormat {
CGLReleasePixelFormat(cglPixelFormat);
}
- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat {
CGLRetainContext(cglContext);
return cglContext;
}
- (void)releaseCGLContext:(CGLContextObj)glContext {
CGLReleaseContext(cglContext);
}
- (void)drawInCGLContext:(CGLContextObj)glContext
pixelFormat:(CGLPixelFormatObj)pixelFormat
forLayerTime:(CFTimeInterval)timeInterval
displayTime:(const CVTimeStamp *)timeStamp {
if([lock tryLock]) {
CGLContextObj savedContext = CGLGetCurrentContext();
CGLSetCurrentContext(cglContext);
CGLLockContext(cglContext);