* 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:
parent
f7526300d9
commit
f186fa405c
@ -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()
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user