* Improvements to the aspect ratio handling. The "Keep Aspect Ratio" setting

is now superfluous.
* When switching aspect ratio and the current video size is 100%, always
  resize such that one side stays at 100% (which would be the height mostly)
  and the other is scaled up (mostly the width).
* In _SetupWindow(), which is triggered by a new stream for example, also
  check if the aspect ratio changed and resize accordingly.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31541 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2009-07-13 19:58:07 +00:00
parent f7526300d9
commit f186fa405c
2 changed files with 205 additions and 100 deletions

View File

@ -68,20 +68,23 @@ enum {
M_FILE_QUIT,
M_VIEW_SIZE,
M_TOGGLE_FULLSCREEN,
M_TOGGLE_KEEP_ASPECT_RATIO,
M_TOGGLE_ALWAYS_ON_TOP,
M_TOGGLE_NO_INTERFACE,
M_VOLUME_UP,
M_VOLUME_DOWN,
M_SKIP_NEXT,
M_SKIP_PREV,
M_ASPECT_100000_1,
M_ASPECT_106666_1,
M_ASPECT_109091_1,
M_ASPECT_141176_1,
M_ASPECT_720_576,
M_ASPECT_704_576,
M_ASPECT_544_576,
// The common display aspect ratios
M_ASPECT_SAME_AS_SOURCE,
M_ASPECT_NO_DISTORTION,
M_ASPECT_4_3,
M_ASPECT_16_9,
M_ASPECT_83_50,
M_ASPECT_7_4,
M_ASPECT_37_20,
M_ASPECT_47_20,
M_SELECT_AUDIO_TRACK = 0x00000800,
M_SELECT_AUDIO_TRACK_END = 0x00000fff,
M_SELECT_VIDEO_TRACK = 0x00010000,
@ -111,7 +114,6 @@ MainWin::MainWin()
| OBSERVE_PLAYBACK_STATE_CHANGES | OBSERVE_POSITION_CHANGES
| OBSERVE_VOLUME_CHANGES)),
fIsFullscreen(false),
fKeepAspectRatio(true),
fAlwaysOnTop(false),
fNoInterface(false),
fSourceWidth(-1),
@ -527,10 +529,6 @@ MainWin::MessageReceived(BMessage *msg)
_ToggleFullscreen();
break;
case M_TOGGLE_KEEP_ASPECT_RATIO:
_ToggleKeepAspectRatio();
break;
case M_TOGGLE_ALWAYS_ON_TOP:
_ToggleAlwaysOnTop();
break;
@ -591,39 +589,50 @@ MainWin::MessageReceived(BMessage *msg)
fController->VolumeDown();
break;
case M_ASPECT_100000_1:
VideoFormatChange(fSourceWidth, fSourceHeight,
fSourceWidth, fSourceHeight);
case M_ASPECT_SAME_AS_SOURCE:
if (fHasVideo) {
int width;
int height;
int widthAspect;
int heightAspect;
fController->GetSize(&width, &height,
&widthAspect, &heightAspect);
VideoFormatChange(width, fSourceHeight,
widthAspect, heightAspect);
}
break;
case M_ASPECT_106666_1:
VideoFormatChange(fSourceWidth, fSourceHeight,
lround(1.06666 * fSourceWidth), fSourceHeight);
case M_ASPECT_NO_DISTORTION:
if (fHasVideo) {
int width;
int height;
fController->GetSize(&width, &height);
VideoFormatChange(width, height, width, height);
}
break;
case M_ASPECT_109091_1:
VideoFormatChange(fSourceWidth, fSourceHeight,
lround(1.09091 * fSourceWidth), fSourceHeight);
case M_ASPECT_4_3:
VideoAspectChange(4, 3);
break;
case M_ASPECT_141176_1:
VideoFormatChange(fSourceWidth, fSourceHeight,
lround(1.41176 * fSourceWidth), fSourceHeight);
case M_ASPECT_16_9: // 1.77 : 1
VideoAspectChange(16, 9);
break;
case M_ASPECT_720_576:
VideoFormatChange(720, 576,
lround(1.06666 * fSourceWidth), fSourceHeight);
case M_ASPECT_83_50: // 1.66 : 1
VideoAspectChange(83, 50);
break;
case M_ASPECT_704_576:
VideoFormatChange(704, 576,
lround(1.09091 * fSourceWidth), fSourceHeight);
case M_ASPECT_7_4: // 1.75 : 1
VideoAspectChange(7, 4);
break;
case M_ASPECT_544_576:
VideoFormatChange(544, 576,
lround(1.41176 * fSourceWidth), fSourceHeight);
case M_ASPECT_37_20: // 1.85 : 1
VideoAspectChange(37, 20);
break;
case M_ASPECT_47_20: // 2.35 : 1
VideoAspectChange(47, 20);
break;
case M_SET_PLAYLIST_POSITION:
@ -700,6 +709,13 @@ MainWin::QuitRequested()
}
void
MainWin::MenusBeginning()
{
_SetupVideoAspectItems(fVideoAspectMenu);
}
// #pragma mark -
@ -782,21 +798,70 @@ MainWin::ShowPlaylistWindow()
}
void
MainWin::VideoAspectChange(int forcedWidth, int forcedHeight, float widthScale)
{
// Force specific source size and pixel width scale.
if (fHasVideo) {
int width;
int height;
fController->GetSize(&width, &height);
VideoFormatChange(forcedWidth, forcedHeight,
lround(width * widthScale), height);
}
}
void
MainWin::VideoAspectChange(float widthScale)
{
// Called when video aspect ratio changes and the original
// width/height should be restored too, display aspect is not known,
// only pixel width scale.
if (fHasVideo) {
int width;
int height;
fController->GetSize(&width, &height);
VideoFormatChange(width, height, lround(width * widthScale), height);
}
}
void
MainWin::VideoAspectChange(int widthAspect, int heightAspect)
{
// Called when video aspect ratio changes and the original
// width/height should be restored too.
if (fHasVideo) {
int width;
int height;
fController->GetSize(&width, &height);
VideoFormatChange(width, height, widthAspect, heightAspect);
}
}
void
MainWin::VideoFormatChange(int width, int height, int widthAspect,
int heightAspect)
{
// called when video format or aspect ratio changes
// Called when video format or aspect ratio changes.
printf("VideoFormatChange enter: width %d, height %d, "
"aspect ratio: %d:%d\n", width, height, widthAspect, heightAspect);
fSourceWidth = width;
fSourceHeight = height;
fWidthAspect = widthAspect;
fHeightAspect = heightAspect;
// remember current view scale
int percent = _CurrentVideoSizeInPercent();
FrameResized(Bounds().Width(), Bounds().Height());
fSourceWidth = width;
fSourceHeight = height;
fWidthAspect = widthAspect;
fHeightAspect = heightAspect;
if (percent == 100)
_ResizeWindow(100);
else
FrameResized(Bounds().Width(), Bounds().Height());
printf("VideoFormatChange leave\n");
}
@ -836,6 +901,8 @@ MainWin::_SetupWindow()
fAudioMenu->SetEnabled(fHasAudio);
int previousSourceWidth = fSourceWidth;
int previousSourceHeight = fSourceHeight;
int previousWidthAspect = fWidthAspect;
int previousHeightAspect = fHeightAspect;
if (fHasVideo) {
fController->GetSize(&fSourceWidth, &fSourceHeight,
&fWidthAspect, &fHeightAspect);
@ -849,7 +916,9 @@ MainWin::_SetupWindow()
// adopt the size and window layout if necessary
if (!fIsFullscreen && (previousSourceWidth != fSourceWidth
|| previousSourceHeight != fSourceHeight)) {
|| previousSourceHeight != fSourceHeight
|| previousWidthAspect != fWidthAspect
|| previousHeightAspect != fHeightAspect)) {
_ResizeWindow(100);
}
@ -936,10 +1005,6 @@ MainWin::_CreateMenu()
_SetupVideoAspectItems(fVideoAspectMenu);
fVideoMenu->AddItem(fVideoAspectMenu);
item = new BMenuItem("Keep Aspect Ratio",
new BMessage(M_TOGGLE_KEEP_ASPECT_RATIO), 'K');
item->SetMarked(fKeepAspectRatio);
fVideoMenu->AddItem(item);
fNoInterfaceMenuItem = new BMenuItem("No Interface",
new BMessage(M_TOGGLE_NO_INTERFACE), 'B');
@ -957,20 +1022,54 @@ MainWin::_CreateMenu()
void
MainWin::_SetupVideoAspectItems(BMenu* menu)
{
menu->AddItem(new BMenuItem("1 : 1",
new BMessage(M_ASPECT_100000_1)));
menu->AddItem(new BMenuItem("1.06666 : 1",
new BMessage(M_ASPECT_106666_1)));
menu->AddItem(new BMenuItem("1.09091 : 1",
new BMessage(M_ASPECT_109091_1)));
menu->AddItem(new BMenuItem("1.41176 : 1",
new BMessage(M_ASPECT_141176_1)));
menu->AddItem(new BMenuItem("Force 720 x 576, Aspect 4:3",
new BMessage(M_ASPECT_720_576)));
menu->AddItem(new BMenuItem("Force 704 x 576, Aspect 4:3",
new BMessage(M_ASPECT_704_576)));
menu->AddItem(new BMenuItem("Force 544 x 576, Aspect 4:3",
new BMessage(M_ASPECT_544_576)));
BMenuItem* item;
while ((item = menu->RemoveItem(0L)) != NULL)
delete item;
int width;
int height;
int widthAspect;
int heightAspect;
fController->GetSize(&width, &height, &widthAspect, &heightAspect);
// We don't care if there is a video track at all. In that
// case we should end up not marking any item.
// NOTE: The item marking may end up marking for example both
// "Stream Settings" and "16 : 9" if the stream settings happen to
// be "16 : 9".
menu->AddItem(item = new BMenuItem("Stream Settings",
new BMessage(M_ASPECT_SAME_AS_SOURCE)));
item->SetMarked(widthAspect == fWidthAspect
&& heightAspect == fHeightAspect);
menu->AddItem(item = new BMenuItem("No Aspect Correction",
new BMessage(M_ASPECT_NO_DISTORTION)));
item->SetMarked(width == fWidthAspect && height == fHeightAspect);
menu->AddSeparatorItem();
menu->AddItem(item = new BMenuItem("4 : 3",
new BMessage(M_ASPECT_4_3)));
item->SetMarked(fWidthAspect == 4 && fHeightAspect == 3);
menu->AddItem(item = new BMenuItem("16 : 9",
new BMessage(M_ASPECT_16_9)));
item->SetMarked(fWidthAspect == 16 && fHeightAspect == 9);
menu->AddSeparatorItem();
menu->AddItem(item = new BMenuItem("1.66 : 1",
new BMessage(M_ASPECT_83_50)));
item->SetMarked(fWidthAspect == 83 && fHeightAspect == 50);
menu->AddItem(item = new BMenuItem("1.75 : 1",
new BMessage(M_ASPECT_7_4)));
item->SetMarked(fWidthAspect == 7 && fHeightAspect == 4);
menu->AddItem(item = new BMenuItem("1.85 : 1 (American)",
new BMessage(M_ASPECT_37_20)));
item->SetMarked(fWidthAspect == 37 && fHeightAspect == 20);
menu->AddItem(item = new BMenuItem("2.35 : 1 (Cinemascope)",
new BMessage(M_ASPECT_47_20)));
item->SetMarked(fWidthAspect == 47 && fHeightAspect == 20);
}
@ -1057,6 +1156,28 @@ MainWin::_SetWindowSizeLimits()
}
int
MainWin::_CurrentVideoSizeInPercent() const
{
if (!fHasVideo)
return 0;
int videoWidth;
int videoHeight;
_GetUnscaledVideoSize(videoWidth, videoHeight);
int viewWidth = fVideoView->Bounds().IntegerWidth() + 1;
int viewHeight = fVideoView->Bounds().IntegerHeight() + 1;
int widthPercent = videoWidth * 100 / viewWidth;
int heightPercent = videoHeight * 100 / viewHeight;
if (widthPercent > heightPercent)
return widthPercent;
return heightPercent;
}
void
MainWin::_ResizeWindow(int percent)
{
@ -1086,32 +1207,26 @@ MainWin::_ResizeVideoView(int x, int y, int width, int height)
printf("_ResizeVideoView: %d,%d, width %d, height %d\n", x, y,
width, height);
if (fKeepAspectRatio) {
// Keep aspect ratio, place video view inside
// the background area (may create black bars).
int videoWidth;
int videoHeight;
_GetUnscaledVideoSize(videoWidth, videoHeight);
float scaledWidth = videoWidth;
float scaledHeight = videoHeight;
float factor = min_c(width / scaledWidth, height / scaledHeight);
int renderWidth = lround(scaledWidth * factor);
int renderHeight = lround(scaledHeight * factor);
if (renderWidth > width)
renderWidth = width;
if (renderHeight > height)
renderHeight = height;
// Keep aspect ratio, place video view inside
// the background area (may create black bars).
int videoWidth;
int videoHeight;
_GetUnscaledVideoSize(videoWidth, videoHeight);
float scaledWidth = videoWidth;
float scaledHeight = videoHeight;
float factor = min_c(width / scaledWidth, height / scaledHeight);
int renderWidth = lround(scaledWidth * factor);
int renderHeight = lround(scaledHeight * factor);
if (renderWidth > width)
renderWidth = width;
if (renderHeight > height)
renderHeight = height;
int xOffset = x + (width - renderWidth) / 2;
int yOffset = y + (height - renderHeight) / 2;
int xOffset = x + (width - renderWidth) / 2;
int yOffset = y + (height - renderHeight) / 2;
fVideoView->MoveTo(xOffset, yOffset);
fVideoView->ResizeTo(renderWidth - 1, renderHeight - 1);
} else {
fVideoView->MoveTo(x, y);
fVideoView->ResizeTo(width - 1, height - 1);
}
fVideoView->MoveTo(xOffset, yOffset);
fVideoView->ResizeTo(renderWidth - 1, renderHeight - 1);
}
@ -1248,11 +1363,6 @@ MainWin::_ShowContextMenu(const BPoint &screen_point)
menu->AddItem(item = new BMenuItem(aspectSubMenu));
item->SetEnabled(fHasVideo);
menu->AddItem(item = new BMenuItem("Keep Aspect Ratio",
new BMessage(M_TOGGLE_KEEP_ASPECT_RATIO), 'K'));
item->SetMarked(fKeepAspectRatio);
item->SetEnabled(fHasVideo);
menu->AddItem(item = new BMenuItem("No Interface",
new BMessage(M_TOGGLE_NO_INTERFACE), 'B'));
item->SetMarked(fNoInterface);
@ -1470,16 +1580,6 @@ MainWin::_ToggleFullscreen()
printf("_ToggleFullscreen leave\n");
}
void
MainWin::_ToggleKeepAspectRatio()
{
fKeepAspectRatio = !fKeepAspectRatio;
FrameResized(Bounds().Width(), Bounds().Height());
_MarkItem(fVideoMenu, M_TOGGLE_KEEP_ASPECT_RATIO, fKeepAspectRatio);
}
void
MainWin::_ToggleAlwaysOnTop()
{

View File

@ -51,6 +51,7 @@ public:
virtual void MessageReceived(BMessage* message);
virtual void WindowActivated(bool active);
virtual bool QuitRequested();
virtual void MenusBeginning();
void OpenPlaylistItem(const PlaylistItemRef& item);
@ -58,6 +59,11 @@ public:
void ShowPlaylistWindow();
void ShowSettingsWindow();
void VideoAspectChange(int forcedWidth,
int forcedHeight, float widthScale);
void VideoAspectChange(float widthScale);
void VideoAspectChange(int widthAspect,
int heightAspect);
void VideoFormatChange(int width, int height,
int widthAspect, int heightAspect);
@ -75,6 +81,7 @@ private:
void _SetWindowSizeLimits();
void _GetUnscaledVideoSize(int& videoWidth,
int& videoHeight) const;
int _CurrentVideoSizeInPercent() const;
void _ResizeWindow(int percent);
void _ResizeVideoView(int x, int y, int width,
int height);
@ -88,7 +95,6 @@ private:
status_t _KeyDown(BMessage* message);
void _ToggleFullscreen();
void _ToggleKeepAspectRatio();
void _ToggleAlwaysOnTop();
void _ToggleNoInterface();
@ -129,7 +135,6 @@ private:
Controller* fController;
ControllerObserver* fControllerObserver;
volatile bool fIsFullscreen;
volatile bool fKeepAspectRatio;
volatile bool fAlwaysOnTop;
volatile bool fNoInterface;
int fSourceWidth;