video out + retina display devices + iOS 5 = not displaying

Forums Programming cocos2d support (graphics engine) video out + retina display devices + iOS 5 = not displaying

This topic contains 19 replies, has 6 voices, and was last updated by  mikeytdan 2 years ago.

Viewing 20 posts - 1 through 20 (of 20 total)
Author Posts
Author Posts
October 18, 2011 at 1:28 am #236171

deeje
Participant
@deeje

Hi All,

I have an app in the store that uses Cocos2D and supports video out, but video out appears to be broken on Retinal Display devices running iOS 5.

The app is tappr.tv (v3), and was released back in March. Video out was working on my iPhone 4 as well as an iPod 4th Gen under iOS 4.x. When I updated to iOS 5 on each of these devices, video out stopped displaying. I’m using a standard Apple component video out cable.

This is occurring both in the shipping version of the app, as well as a recent build of a new version. I can confirm that the EAGLView itself is being added to the external UIScreen window because the window background is gray and the EAGLView clears to black. Furthermore, when I capture an OpenGL ES Frame in XCode 4.2, I can see that the rendering is taking place. Its just not being displayed on the external screen.

Also note that video out continues to work on both an iPad running iOS 4.x and an iPad 2 running iOS 5. It seems to be limited to Retina Display iDevices.

I can confirm that other apps, such as Video from Apple, still display video out under IOS 5, so it must be related to my app somehow?

Here is the gist of my code handling video out, all fairly standard stuff…

- (void)setupCocos2D
{
[CCDirector setDirectorType:kCCDirectorTypeNSTimer];

CCDirector *director = [CCDirector sharedDirector];

EAGLView *glView = [EAGLView viewWithFrame:CGRectZero
pixelFormat:kEAGLColorFormatRGBA8
depthFormat:GL_DEPTH_COMPONENT16_OES
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
glView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin |
UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
[director setOpenGLView:glView];
[director setDeviceOrientation:kCCDeviceOrientationPortrait];
[director enableRetinaDisplay:YES];

[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
}

- (void) startTVOut
{
// is there more than one screen?
NSArray* screens = [UIScreen screens];
if ([screens count] <= 1)
{
return;
}

UIScreen *external = [[UIScreen screens] objectAtIndex: 1];
CGSize maxSize = CGSizeMake(0, 0);
UIScreenMode *maxScreenMode = nil;
for(int i = 0; i < [[external availableModes] count]; i++)
{
UIScreenMode *current = [[[[UIScreen screens] objectAtIndex:1] availableModes] objectAtIndex: i];
if (current.size.width > maxSize.width)
{
maxSize = current.size;
maxScreenMode = current;
}
}
external.currentMode = maxScreenMode;
CGRect aFrame = CGRectMake(0,0, maxScreenMode.size.width, maxScreenMode.size.height);

tvoutWindow_ = [[UIWindow alloc] initWithFrame:aFrame];
tvoutWindow_.userInteractionEnabled = NO;
tvoutWindow_.screen = external;
tvoutWindow_.hidden = NO;
tvoutWindow_.backgroundColor = [UIColor darkGrayColor];

EAGLView *glView = [[CCDirector sharedDirector] openGLView];
glView.frame = tvoutWindow_.bounds;
[tvoutWindow_ addSubview:glView];

tvoutWindow_.hidden = NO;
}

Wondering if anyone else is seeing issues in their Cocos2D apps and video out? Anyone have a Cocos2D app that supports video out that IS working on a Retina Display iDevice?

peace

deeje

October 21, 2011 at 1:56 pm #351721

Nonames
@nonames

Hi,

I am exactly having the same issue. I have found out some strange case and I will post the solution if I can make my app working again. In the meantime, if you happen to resolve this issue, I would appreciate if you can pm as well.

Good luck!

October 21, 2011 at 8:03 pm #351722

deeje
Participant
@deeje

small comfort to know I’m not alone.

I filed a bug report with Apple #10301299, and they asked for a dump of the logs during the problem. Here are the interesting lines from that log…

Oct 21 12:53:05 deeje-iPhone-4 tappr.tv[7768] <Warning>: cocos2d: surface size: 854×480

Oct 21 12:53:05 deeje-iPhone-4 com.apple.SpringBoard[15] <Notice>: CADisplayIOMFB: swap_end returned error e00002c2

Oct 21 12:53:06 deeje-iPhone-4 kernel[0] <Debug>: eRGBOUT, UI-[0] Can’t scale in H3 – src.w = 648, dst.w = 648, src.h = 431, dst.h = 432

Oct 21 12:53:06 deeje-iPhone-4 kernel[0] <Debug>: AppleRGBOUT verify_swap failed

October 26, 2011 at 4:23 am #351723

deeje
Participant
@deeje

I was able to reproduce the problem with a fresh copy of cocos2d 1.0.1, editing EAGLViewTest.m to handle video out:

@implementation EAGLViewTestDelegate

@synthesize window=window_;
@synthesize glView=glView_;

#pragma mark -
#pragma mark Application Delegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// catch screen-related notifications
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(screenDidConnectNotification:)
name: UIScreenDidConnectNotification
object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(screenDidDisconnectNotification:)
name: UIScreenDidDisconnectNotification
object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(screenModeDidChangeNotification:)
name: UIScreenModeDidChangeNotification
object: nil];

if( ! [CCDirector setDirectorType:kCCDirectorTypeDisplayLink] )
[CCDirector setDirectorType:kCCDirectorTypeThreadMainLoop];

CCDirector *director = [CCDirector sharedDirector];
[director setDisplayFPS:YES];
[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];

[director setOpenGLView:glView_];

// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [director enableRetinaDisplay:YES] )
CCLOG(@"Retina Display Not supported");

// turn on multiple touches
[glView_ setMultipleTouchEnabled:YES];

CCScene *scene = [CCScene node];
[scene addChild: [LayerExample node]];

[director runWithScene:scene];

return YES;
}

// purge memroy
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
[[CCDirector sharedDirector] purgeCachedData];
}

-(void) applicationDidEnterBackground:(UIApplication*)application
{
[[CCDirector sharedDirector] stopAnimation];
}

-(void) applicationWillEnterForeground:(UIApplication*)application
{
[[CCDirector sharedDirector] startAnimation];
}

- (void)applicationWillTerminate:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] removeObserver:self];

CCDirector *director = [CCDirector sharedDirector];
[[director openGLView] removeFromSuperview];
[director end];

// release glView here, else it won't be dealloced
[glView_ release];
glView_ = nil;
}

#pragma mark - TV out

- (void) startTVOut
{
// is there more than one screen?
NSArray* screens = [UIScreen screens];
if ([screens count] <= 1)
{
return;
}

if (tvoutWindow_)
{
[tvoutWindow_ release];
tvoutWindow_ = nil;
}

if (!tvoutWindow_)
{
UIScreen *external = [[UIScreen screens] objectAtIndex: 1];

CGSize maxSize = CGSizeMake(0, 0);
UIScreenMode *maxScreenMode = nil;
for(int i = 0; i < [[external availableModes] count]; i++)
{
UIScreenMode *current = [[[[UIScreen screens] objectAtIndex:1] availableModes] objectAtIndex: i];
if (current.size.width > maxSize.width)
{
maxSize = current.size;
maxScreenMode = current;
}
}
external.currentMode = maxScreenMode;
CGRect aFrame = CGRectMake(0,0, maxScreenMode.size.width, maxScreenMode.size.height);

tvoutWindow_ = [[UIWindow alloc] initWithFrame:aFrame];
tvoutWindow_.userInteractionEnabled = NO;
tvoutWindow_.screen = external;
tvoutWindow_.hidden = NO;
tvoutWindow_.backgroundColor = [UIColor darkGrayColor];

EAGLView *glView = [[CCDirector sharedDirector] openGLView];
glView.frame = tvoutWindow_.bounds;
[tvoutWindow_ addSubview:glView];

tvoutWindow_.hidden = NO;
}
}

- (void) stopTVOut;
{
if (tvoutWindow_)
{
EAGLView *glView = [[CCDirector sharedDirector] openGLView];
[window_ addSubview:glView];
glView.frame = window_.bounds;

[tvoutWindow_ release];
tvoutWindow_ = nil;
}
}

-(void) screenDidConnectNotification: (NSNotification*) notification
{
NSLog(@"Screen connected: %@", [notification object]);
[self startTVOut];
}

-(void) screenDidDisconnectNotification: (NSNotification*) notification
{
NSLog(@"Screen disconnected: %@", [notification object]);
[self stopTVOut];
}

-(void) screenModeDidChangeNotification: (NSNotification*) notification
{
NSLog(@"Screen mode changed: %@", [notification object]);
[self startTVOut];
}

@end

Works fine on an iPad with iOS 4.x and an iPad 2 with iOS 5. Does not work on an iPhone 4 with iOS 5.

October 26, 2011 at 9:24 am #351724

Nonames
@nonames

sorry i was busy and forgot to inform you on what i have found out on this case. if you leave the orientation as landscape, it actually display the UI on the external screen. however, if it try to stretch, the error you posted will be shown. another wierd case is that even when it is stretched, you let it autorotate, the animation actually shows that the UI is display on the TV but half of it clipped.

i am also frustrated on this issue and it seems that we are the only one having this problem. in fact, i found the same problem when i implement the GLKit with the same error. hope Apple can get this fix asap.

October 26, 2011 at 12:26 pm #351725

omody
@omody

I am having a similar issue but the iPhone 4S running iOS5 works with both the composite cable as well as HDMI adapter. This is only happening for the iPhone4 running iOS5 and the composite cable (worked with iOS4.x with both composite and HDMI)

I have the same code as Rob Terrell TVOutManager. To add further mystery, the same code works on iPad2 with composite or HDMI running iOS5, also work with iPad1 running 4.x with HDMI or composite but does not work iPad1 running iOS5 and composite cable….

Nonames: You suggested it might be caused by stretching, so I just need to set the view “autoresizingMask = UIViewAutoresizingNone”

October 26, 2011 at 2:41 pm #351726

CJ
Moderator
@wiseganesha

Have you tried disabling “retina” within cocos2d? I think the api for doing this is different with different versions but it’s either in ccConfig.h or a method of CCDirector.

October 26, 2011 at 3:01 pm #351727

deeje
Participant
@deeje

in my case, enabling Retina or not makes no difference.

October 27, 2011 at 1:20 am #351728

omody
@omody

mirrorView.transform = CGAffineTransformRotate(CGAffineTransformIdentity, M_PI * -1.5);

Based on Nonames suggestion to just try it out, I added the above line of code to my mirrorView which I am adding to my tvOutWindow and then I could see the output on the TV Out sideway for both HDMI or composite cable, ofcourse the picture is sideways an not useable but atleast I made progress… The moment I changed the orientation or transformed the app crashed or just go the tvoutWindow.backgroundColor that I had set in the tvOutWindow.

I tried to send tvout directly to tvoutWindow since UIWindow is a UIView but that did not make a difference I had to do the same:

tvoutWindow.transform = CGAffineTransformRotate(CGAffineTransformIdentity, M_PI * -1.5);

and then it would displayOut to the window.

Definitely seems like an Apple bug. I will try to submit a bug report myself, maybe we all do a submission then Apple my look at it sooner rather than later….

October 27, 2011 at 7:16 pm #351729

Nonames
@nonames

hi omody, great that we have some clue on this. as for now, i have used your method by rotating the window and at least, i can see everything on the external display. however, i need to confirm with you again that does iPhone 4S has the same issue? what i have done is that i will check whether retina display is enabled, if yes, i will rotate the window, otherwise everything stays the same.

finally, is there anyway we can submit the bug togther? i have submitted once before and it is still opened. :(

October 27, 2011 at 7:23 pm #351730

deeje
Participant
@deeje

Hi all,

I just recreated the same problem using Apple’s GLCameraRipple sample code, which uses GLKit. I’ve updated my bug report to apple, and encourage you each to file a separate bug at http://bugreport.apple.com, as I believe a volume of reports will get their attention sooner. If you’d like to reference my bug report it is # 10301299

October 27, 2011 at 7:25 pm #351731

Nonames
@nonames

thanks deeje, yes i have also tested with the same problem with GLKit. I have file a report as GLKit bug. but omody stated that iPhone 4S is ok. this is something I am worried as I am still waiting for my 4S to test it.

October 27, 2011 at 11:45 pm #351732

omody
@omody

yes iPhone4S works and so does iPad2. only iPhone4 and iPad1 running iOS5 have this issue…. Based on “Nonames” suggestion I did some coding here (i’m not a great coder), but it is working no iPhone4 running iOS5

My new code:

if ([[UIDevice currentDevice].systemVersion doubleValue] >= 5.) {

BOOL bSafeMode = [[NSUserDefaults standardUserDefaults] boolForKey:@”enableSafeMode”];

if(bSafeMode == YES) {

if([[TVOutManager sharedInstance] isTVOutON]) {

float screenWidth = [[TVOutManager sharedInstance] getTVView].bounds.size.width;

float screenHeight = [[TVOutManager sharedInstance] getTVView].bounds.size.height;

float movieWidth = mainView.frame.size.width;

float movieHeight = mainView.frame.size.height;

if(movieWidth > 0) {

CGFloat horizM = movieWidth / screenWidth;

CGFloat vertM = movieHeight / screenHeight;

CGFloat bigScaleM = horizM < vertM ? vertM : horizM;

CGFloat horizS = screenWidth / movieWidth;

CGFloat vertS = screenHeight / movieHeight;

CGFloat bigScaleS = horizS < vertS ? vertS : horizS;

CGFloat bigScale = bigScaleM < bigScaleS ? bigScaleS : bigScaleM;

[[TVOutManager sharedInstance] getTVView].transform = CGAffineTransformScale([[TVOutManager sharedInstance] getTVView].transform, bigScale, bigScale);

}

}

}

}

Let me know your thoughts guys?

November 15, 2011 at 2:59 am #351733

djayc
Participant
@djayc

Did anyone ever figure this out? I’ve got a very simliar problem happening… I’ve reduced it to a very simple example and I’m getting the same behavior.

November 15, 2011 at 5:58 am #351734

Nonames
@nonames

djayc, it is working on the latest iOS 5.0.1 already. Apple has fixed this problem already. Try it out :))

November 15, 2011 at 6:56 am #351735

deeje
Participant
@deeje

still not working for me on 5.0.1

November 15, 2011 at 8:57 am #351736

djayc
Participant
@djayc

Yeah, I’ve been testing on iOS 5.0.1 and I’m still having a hard time getting external display + openGL rendering correctly. I did notice that if I make the output a few pixels shorter than the window height it DOES work. IE:when the external screen is 640×480, it actually works if I create an openGL view that is 640×449 .. 450 wont work.. strange.

November 15, 2011 at 1:41 pm #351737

omody
@omody

Based on the explanation on Nonames I did the scaling and I have had it working since my last post where I posted the the scaling code – the picture is a “zoomed-in” but been better than having no picture atall.

April 14, 2012 at 5:03 am #351738

mikeytdan
Participant
@mikeytdan

Can someone post an example project for tv out using cocos2D? I’ve been looking everywhere. The best I can do is mirror the ipad to my apple tv. I want to draw a different view to the tv than what is on the device. I want to be able to take up the whole tv screen.

April 14, 2012 at 9:06 am #351739

mikeytdan
Participant
@mikeytdan

I’ve continued in my efforts to make this work but no luck. I can get a UIView loaded and even a CCGLView loaded to the screen but I don’t know how to draw any cocos2D objects to the views. All the scene drawing stuff is tied up with the CCDirector. If anyone can post links of where to go for solutions or even better post an example project. I’ve been most everywhere and have had no luck.

Viewing 20 posts - 1 through 20 (of 20 total)

You must be logged in to reply to this topic.