Underscan issue with AirPlay mirroring - ios

I'm having some issues with AirPlay. The thing is, I'm developing with the ATV3, and my TV set supports 1080p. But when I start screen mirroring and receive the new instance of UIScreen, the bounds and the applicationFrame are both giving me a 720p resolution.
But it gets weird when I actually moved the subviews to a negative value, and the whole screen gets covered. So, technically my iPhone is streaming at 1080p, but the bounds returned by the UIScreen are underscanned.
I've tried modifying the overscanCompensation before getting the bounds or the applicationFrame (tried both with all 3 overscanCompensation values available) but I'm still getting the same result.
Here is a picture of what I'm getting (sorry, it's the worst picture in the planet, I know, but I was using my phone to stream the image to the ATV :) )
Red view is the 720p reported by bounds.
It gets even weirder when I actually try this out in my ATV2 (it is supposedly limited to 720p even if it supports 1080p) and the result is exactly the same.
Anyway, if someone knows the method to get the real screen display to avoid putting a settings view in my app, I'll really appreciate it.
Thanks in advance :)

When you mentioned that you tried all 3 overscanCompensation modes, I presume you mean the 3 documented modes:
typedef enum {
UIScreenOverscanCompensationScale,
UIScreenOverscanCompensationInsetBounds,
UIScreenOverscanCompensationInsetApplicationFrame,
} UIScreenOverscanCompensation;
However, there is a fourth mode, which is not there, but should fix your problems: just set your overscanCompensation to 3.
Also, take a look at this SO question.

The answer of Ivan solved the same issue for me! But I also had the borders when using AirPlay Mirroring. I got rid of the borders without setting the overscanCompensation property by changing a setting on my Apple TV: try setting 'Settings > Audio & Video > Adjust For AirPlay Overscan' to Off (default On).

The setting that works best for most TVs is:
externalScreen.overscanCompensation = UIScreenOverscanCompensationInsetBounds | UIScreenOverscanCompensationInsetApplicationFrame; // this is the same as setting it to 3
Just setting it to UIScreenOverscanCompensationInsetApplicationFrame can cause misalignment of the UIWindow contents.
3 is a bitmask of UIScreenOverscanCompensationInsetBounds(1) and UIScreenOverscanCompensationInsetApplicationFrame(2) for those wondering where that number comes from and why it works.

Related

ios landscape-orientation screen in portrait orientation results

when first entry, the result like this
App into the background and back, the orientation is normal
this is the code for the ViewController:
DDYLoveAutoHallViewController *autoHallViewController = [[DDYLoveAutoHallViewController alloc] initWithEvent:room.currentEventID type:AHRoom_System];
[self presentViewController:autoHallViewController animated:YES completion:nil];
i don't know why, the project is a litter old, it support iOS5 before.
Without understanding on how do you manage layouts it is difficult to give the exact reason, caused you problem, but, i can suggest you couple of little advices:
try to re-check orientation in - (void)viewDidLayoutSubviews, and you can re-position things from there. (probably it will work and solve your problem, but it is not very clean solution, because may be called a few times at time, knowing this you can make it cleaner)
play generally with the methods of layout-lifecycle, to detect where are things is going wrong. Dive deeper in modern way to layout on iOS. (better solution)
Without more details regarding your specific problem, and how you are detecting and adjusting the orientation, it is hard to understand the exact problem, but here are some observations I have made, working with iOS 5.x based (and earlier), apps, that might point you in the correct direction:
[1] Earlier versions of iOS set some defaults, before actually interrogating the hardware to determine orientation and app frame size information.
a) Initially orientation is set to PORTRAIT - along with portrait orientation frame dimensions - during initialization. (This is WRONG if you device is in landscape orientation - so DON’T USE this initial info). (left over from earlier “iPhone only days” - I guess)
b) This continues to be incorrect at the “ViewDidLoad” and “applicationDidBecomeActive” timeframes (at least for my app - possibly - depends on loading time etc…)
c) The correct orientation is yielded later, via the “didChangeStatusBarOrientation method invocation. You can use this information with Window.frame.size information, to display the correct image with the correct size.
This is effectively the trigger to indicate the orientation request will now be correct.
One stategy might be to : Don’t try to display anything until the “didChangeStatusBarOrientation” message has been received.
[2] Non-Code Solution: (using Settings : Supported interface Orientations)
a) If the app is designed to always work in the Landscape orientation, make sure this is reflected in the app settings/info.plist. I would suggest only allowing 1 “supported interface Orientations”, that being Landscape, and all views would reflect the landscape size and orientation.(if your code is not specifically setting or doing anything with orientation, then this might be a solution by setting everything to "landscape only". Otherwise this option probably won't help.)
[3] Last Solution:
a) If you can change the base iOS version higher, the iOS6 and greater versions initialize the orientation and frame sizes earlier in the initialization cycle, so the problem may just disappear due to this.
Here is some of the code used to discover this, along with output below (using an original ipad as a sample, in this case…running iOS 5.1.1 - started in landscape and orientation was unchanged)
-(void) OrientationAndScreenSizeHELPER : (NSString *)fromObject
{
//from:
// NSLog(#"%s:%d someObject=%#", __func__, __LINE__, someObject);
CGRect appFrame = [[UIScreen mainScreen ]applicationFrame];//using frame so status bar is not part of calculations.
appFrame = [[self.viewController view]frame];//using frame so status bar is not part of calculations.
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
NSLog(#"orientation[%ld] at time[%#] width[%ld] height[%ld]",
(long)orientation,
fromObject,
(long int)appFrame.size.width,
(long int)appFrame.size.height);
}
**Output:**
orientation[1] at time[ViewDidLoad Orientation] width[768] height[1024]
orientation[1] at time[applicationDidBecomeActive] width[768] height[1024]
orientation[3] at time[didChangeStatusBarOrientation] width[1024] height[768]

iOS5: Best method of forcing UI orientation programmatically

[I know this has been done to death, and I'd ask follow up questions on an existing question were it not for not having enough stackoverflow points to make one:(]
I'm after an App Store valid way of forcing an existing UI to re-orientate without having to destroy the main ViewController or View. We work in fullscreen mode, so I'm assuming I can't use any of the toolbar approaches normally quoted. Finally I'm only interested in iOS5.
For iOS6 I have a solution based on the answers in How to change the device orientation programmatically in iOS 6. I used the solution which includes ForcePortrait, with the variation that I changed it so I can supply the required orientation as a parameter.
For iOS5 I have experimented with the suggestion of:
[UIDevice currentDevice] performSelector:NSSelectorFromString(#"setOrientation:") withObject:(id)UIInterfaceOrientationPortrait];
from How to set device (UI) orientation programmatically?. This works well but I'm worried that it would be rejected by App Store (complete no no for us).
Has anyone used this on something that has App Store approval and/or got a better suggestion?
Check this out: Force Rotate UIViewController.
Maybe it will work. This is however very hackish.
[Found a solution, at any rate. Not sure if it the best.]
Got the temporary UIViewController approach to work by adding shouldAutorotateToInterfaceOrientation. The meaning of this is overloaded by iOS5 to discover not only should it autoRotate but also should it start in a particular orientation to start with - I guess that is why it is replaced by several methods at iOS6.. Thus we return true in orientations that are OK.
Perhaps should have realised that before.
Not quite as neat as the setOrientation hack. Key glitch we've noticed is that when you then rotate the device around to the proper orientation you still get a rotation animation. This does not occur on iOS6. Oh well, you win some, you lose some.

AVCam Demo OverscanCompensation implementation

I'm currently working with the AVCam demo app to present a live camera feed over airplay or apple hdmi adapter for import into a HD camera switcher.
The issue I'm having is with OverScanCompensation to remove the huge black border from the mirrored view.
The only documentation I have found is to implement the screen.overscanCompensation = 3; method someplace? I have tried to put it into viewDidLoad and it will let me, but it doesn't change anything on the external view?
I had success of sorts with the Airplay Demo (quellish) using UIImagePicker, but I would much prefer to implement AVFoundation for this exercise.
Is there a better way to achieve what I'm looking for without having to implement separate view controllers?
All you need to do is, upon setting up the external screen (via, say, if ([[UIScreen screens] count] > 1) externalScreen = (UIScreen *)[[UIScreen screens] objectAtIndex:1];), set the overscanCompensation property of the above UIScreen instance to UIScreenOverscanCompensationInsetApplicationFrame (=2). It'll entirely get rid of both the border (overscanning) and image quality-deterioating scaling.
See http://www.iphonelife.com/blog/87/tv-display-output-why-does-your-picture-have-black-border-and-how-can-it-be-fixed for more info.

presentationLayer position property yielding bad values on iPad, no problem with iPhone

I have a game with several small objects animated using CAKeyframeAnimation. Objects animate perfectly for BOTH iPhone and iPad. However, the value of the position property of the animated CALayers' presentationLayers only yield reasonable values on the iPhone. I use the current position of the animating objects for hit testing. Any ideas of differences in this area between iPad and iPhone/iPod Touch?
The position points for iPhone show expected incremental change as objects animate; on iPad I see peculiar values, for example this sequence:
<-36893488147419103232.000000,2.607987>,
<-0.000000,2.658927>,
<0.000000,2.709929>,
<36893488147419103232.000000,2.755450>, ...
Other properties of the presentationLayer are correct (these are properties whose values don't change during the animation, however).
After the animation finishes, the presentationLayer position value IS accurate.
Exactly same problem here!! and it looks that is a bug starting with 3.2 version of the SDK...
Actually I did a iPhone app (using 3.1 SDK) that it is completely based on CAAnimation, when I installed and ran the the app on an iPhone with 3.2 nothing works!!!... but on devices that has 3.1 works perfectly. I google it and I found another people with exactly the same problem.
take a look at the bottom of the following forum
http://www.iphonedevsdk.com/forum/iphone-sdk-development/19622-current-position-animating-calayer.html
Could you solved this issue or found a workaround?

D3D10 (DirectX10) fullscreen performance issue

I have a bit of a problem setting up my DirectX10 (Win32/c++) application for fullscreen mode. The problem is that I want to have my app running in fullscreen right from the start. This can be done by taking the DXGISwapChain::SetFullScreenState function. This works, but i get a small notice in my Visualc++ 2008 debugger which states:
"DXGI Warning: IDXGISwapChain::Present: Fullscreen presentation inefficiencies incurred due to application not using IDXGISwapChain::ResizeBuffers appropriately, specifying a DXGI_MODE_DESC not available in IDXGIOutput::GetDisplayModeList, or not using DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH."
What this means is that DirectX will not take full ownership of the graphicscard and flip the images from front to backbuffer but instead blit them which is much slower.
Now, i do have the DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH enabled and i did try to resize my buffers but i have absolutely no idea what would be the best way to go into fullscreen mode. I have looked on MSDN but there they mostly assume you will only go into Fullscreen by pressing Alt+Enter which lest DXGI do all the work. If someone please could post a bit of code which takes DirectX10 into fullscreen mode and takes full advantage of the "flipping" it would be greatly appriciated!
For anybody interested in the code used on resize:
ReleaseCOM(m_pD3DRenderTargetView);
ReleaseCOM(m_pD3DDepthStencilView);
ReleaseCOM(m_pD3DDepthStencilBuffer);
DXGI_MODE_DESC* mod = new DXGI_MODE_DESC;
mod->Format = DXGI_FORMAT_R8G8B8A8_UNORM;
mod->Height = m_ScreenHeight;
mod->Width = m_ScreenWidth;
mod->RefreshRate.Denominator = 0;
mod->RefreshRate.Numerator = 0;
mod->ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
mod->Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
delete mod; mod = 0;
m_pSwapChain->ResizeTarget(mod);
HR(m_pSwapChain->ResizeBuffers(1, m_ScreenWidth, m_ScreenHeight, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH))
throw(Exception(GET_BUFFER_FAIL, AT));
//problem area
m_pSwapChain->SetFullscreenState(TRUE, NULL);
ID3D10Texture2D* pBackBuffer;
HR( m_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer))
throw(Exception(GET_BUFFER_FAIL, AT)); //continues as usual
Is there any reason you delete your mode desc?
Have you also tried putting your mode desc through "FindClosestMatchingMode"?
Check out http://msdn.microsoft.com/en-us/library/cc627095(VS.85).aspx The "Full-Screen issues" section contains a lot of useful information.
There are some prerequisites for enabling flipping in DXGI (which is the most efficient fullscreen presentation mode):
1) You should go into fullscreen state specifying a mode that exists in the system (you could do that either by using mode from IDXGIOutput::GetDisplayModeList or finding it using IDXGIOutput::FindClosestMatchingMode). Your code just specifies screen resolution, so most likely mode is set correctly.
2) After SetFullscreenState, you should call ResizeBuffers with the right buffer size matching mode, this is where DXGI would setup flipping mode.
Typically, it should happen naturally as reaction to WM_SIZE message send by SetFullscreenState transition, so if your app doesn't call ResizeBuffers on WM_SIZE, it probably should.
You can call ResizeBuffers manually after SetFullscreenState and that should work as well.
And yeah, MSDN has a good article about DXGI practices, including fullscreen transition:
http://msdn.microsoft.com/en-us/library/cc627095(VS.85).aspx#Full_Screen_Issues

Resources