📄 videooutput.cpp
字号:
boolVideoWindow::IsSyncedToRetrace() const{ return fSettings->HasFlags(VideoSettings::FLAG_SYNC_RETRACE);}/***************************************************************************** * VideoWindow::_AllocateBuffers *****************************************************************************/status_tVideoWindow::_AllocateBuffers(int width, int height, int* mode){ // clear any old buffers _FreeBuffers(); // set default mode *mode = BITMAP; bitmap_count = 3; BRect bitmapFrame( 0, 0, width, height ); // read from config, if we are supposed to use overlay at all int noOverlay = !config_GetInt( p_vout, "overlay" ); /* Test for overlay capability: for every chroma in colspace, we try to do double-buffered overlay, single-buffered overlay or basic overlay. If nothing worked, we then have to work with a non-overlay BBitmap. */ for( int i = 0; i < COLOR_COUNT; i++ ) { if( noOverlay ) break; bitmap[0] = new BBitmap( bitmapFrame, B_BITMAP_WILL_OVERLAY | B_BITMAP_RESERVE_OVERLAY_CHANNEL, colspace[i].colspace ); if( bitmap[0] && bitmap[0]->InitCheck() == B_OK ) { colspace_index = i; *mode = OVERLAY; rgb_color key; view->SetViewOverlay( bitmap[0], bitmap[0]->Bounds(), view->Bounds(), &key, B_FOLLOW_ALL, B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL ); view->SetViewColor( key ); SetTitle( "VLC " PACKAGE_VERSION " (Overlay)" ); bitmap[1] = new BBitmap( bitmapFrame, B_BITMAP_WILL_OVERLAY, colspace[colspace_index].colspace); if( bitmap[1] && bitmap[1]->InitCheck() == B_OK ) { bitmap[2] = new BBitmap( bitmapFrame, B_BITMAP_WILL_OVERLAY, colspace[colspace_index].colspace); if( bitmap[2] && bitmap[2]->InitCheck() == B_OK ) { msg_Dbg( p_vout, "using double-buffered overlay" ); } else { msg_Dbg( p_vout, "using single-buffered overlay" ); bitmap_count = 2; if( bitmap[2] ) { delete bitmap[2]; bitmap[2] = NULL; } } } else { msg_Dbg( p_vout, "using simple overlay" ); bitmap_count = 1; if( bitmap[1] ) { delete bitmap[1]; bitmap[1] = NULL; } } break; } else { if( bitmap[0] ) { delete bitmap[0]; bitmap[0] = NULL; } } } if (*mode == BITMAP) { msg_Warn( p_vout, "no possible overlay" ); // fallback to RGB colspace_index = DEFAULT_COL; // B_RGB32 bitmap[0] = new BBitmap( bitmapFrame, colspace[colspace_index].colspace ); bitmap[1] = new BBitmap( bitmapFrame, colspace[colspace_index].colspace ); bitmap[2] = new BBitmap( bitmapFrame, colspace[colspace_index].colspace ); SetTitle( "VLC " PACKAGE_VERSION " (Bitmap)" ); } // see if everything went well status_t status = B_ERROR; for (int32_t i = 0; i < bitmap_count; i++) { if (bitmap[i]) status = bitmap[i]->InitCheck(); if (status < B_OK) break; } if (status >= B_OK) { // clear bitmaps to black for (int32_t i = 0; i < bitmap_count; i++) _BlankBitmap(bitmap[i]); } return status;}/***************************************************************************** * VideoWindow::_FreeBuffers *****************************************************************************/voidVideoWindow::_FreeBuffers(){ if( bitmap[0] ) { delete bitmap[0]; bitmap[0] = NULL; } if( bitmap[1] ) { delete bitmap[1]; bitmap[1] = NULL; } if( bitmap[2] ) { delete bitmap[2]; bitmap[2] = NULL; } fInitStatus = B_ERROR;}/***************************************************************************** * VideoWindow::_BlankBitmap *****************************************************************************/voidVideoWindow::_BlankBitmap(BBitmap* bitmap) const{ // no error checking (we do that earlier on and since it's a private function... // YCbCr: // Loss/Saturation points are Y 16-235 (absoulte); Cb/Cr 16-240 (center 128) // YUV: // Extrema points are Y 0 - 207 (absolute) U -91 - 91 (offset 128) V -127 - 127 (offset 128) // we only handle weird colorspaces with special care switch (bitmap->ColorSpace()) { case B_YCbCr422: { // Y0[7:0] Cb0[7:0] Y1[7:0] Cr0[7:0] Y2[7:0] Cb2[7:0] Y3[7:0] Cr2[7:0] int32_t height = bitmap->Bounds().IntegerHeight() + 1; uint8_t* bits = (uint8_t*)bitmap->Bits(); int32_t bpr = bitmap->BytesPerRow(); for (int32_t y = 0; y < height; y++) { // handle 2 bytes at a time for (int32_t i = 0; i < bpr; i += 2) { // offset into line bits[i] = 16; bits[i + 1] = 128; } // next line bits += bpr; } break; } case B_YCbCr420: {// TODO: untested!! // Non-interlaced only, Cb0 Y0 Y1 Cb2 Y2 Y3 on even scan lines ... // Cr0 Y0 Y1 Cr2 Y2 Y3 on odd scan lines int32_t height = bitmap->Bounds().IntegerHeight() + 1; uint8_t* bits = (uint8_t*)bitmap->Bits(); int32_t bpr = bitmap->BytesPerRow(); for (int32_t y = 0; y < height; y += 1) { // handle 3 bytes at a time for (int32_t i = 0; i < bpr; i += 3) { // offset into line bits[i] = 128; bits[i + 1] = 16; bits[i + 2] = 16; } // next line bits += bpr; } break; } case B_YUV422: {// TODO: untested!! // U0[7:0] Y0[7:0] V0[7:0] Y1[7:0] U2[7:0] Y2[7:0] V2[7:0] Y3[7:0] int32_t height = bitmap->Bounds().IntegerHeight() + 1; uint8_t* bits = (uint8_t*)bitmap->Bits(); int32_t bpr = bitmap->BytesPerRow(); for (int32_t y = 0; y < height; y += 1) { // handle 2 bytes at a time for (int32_t i = 0; i < bpr; i += 2) { // offset into line bits[i] = 128; bits[i + 1] = 0; } // next line bits += bpr; } break; } default: memset(bitmap->Bits(), 0, bitmap->BitsLength()); break; }}/***************************************************************************** * VideoWindow::_SetVideoSize *****************************************************************************/voidVideoWindow::_SetVideoSize(uint32_t mode){ // let size depend on aspect correction int32_t width = CorrectAspectRatio() ? i_width : fTrueWidth; int32_t height = CorrectAspectRatio() ? i_height : fTrueHeight; switch (mode) { case RESIZE_50: width /= 2; height /= 2; break; case RESIZE_200: width *= 2; height *= 2; break; case RESIZE_100: default: break; } fSettings->ClearFlags(VideoSettings::FLAG_FULL_SCREEN); ResizeTo(width, height);}/***************************************************************************** * VideoWindow::_SetToSettings *****************************************************************************/voidVideoWindow::_SetToSettings(){ // adjust dimensions uint32_t mode = RESIZE_100; switch (fSettings->VideoSize()) { case VideoSettings::SIZE_50: mode = RESIZE_50; break; case VideoSettings::SIZE_200: mode = RESIZE_200; break; case VideoSettings::SIZE_100: case VideoSettings::SIZE_OTHER: default: break; } bool fullscreen = IsFullScreen(); // remember settings _SetVideoSize(mode); // because this will reset settings // the fullscreen status is reflected in the settings, // but not yet in the windows state if (fullscreen) SetFullScreen(true); if (fSettings->HasFlags(VideoSettings::FLAG_ON_TOP_ALL)) fCachedFeel = B_FLOATING_ALL_WINDOW_FEEL; else fCachedFeel = B_NORMAL_WINDOW_FEEL; SetFeel(fCachedFeel);}/***************************************************************************** * VLCView::VLCView *****************************************************************************/VLCView::VLCView(BRect bounds, vout_thread_t *p_vout_instance ) : BView(bounds, "video view", B_FOLLOW_NONE, B_WILL_DRAW | B_PULSE_NEEDED), fLastMouseMovedTime(mdate()), fCursorHidden(false), fCursorInside(false), fIgnoreDoubleClick(false){ p_vout = p_vout_instance; SetViewColor(B_TRANSPARENT_32_BIT);}/***************************************************************************** * VLCView::~VLCView *****************************************************************************/VLCView::~VLCView(){}/***************************************************************************** * VLCVIew::AttachedToWindow *****************************************************************************/voidVLCView::AttachedToWindow(){ // periodically check if we want to hide the pointer Window()->SetPulseRate(1000000);}/***************************************************************************** * VLCVIew::MouseDown *****************************************************************************/voidVLCView::MouseDown(BPoint where){ VideoWindow* videoWindow = dynamic_cast<VideoWindow*>(Window()); BMessage* msg = Window()->CurrentMessage(); int32 clicks; uint32_t buttons; msg->FindInt32("clicks", &clicks); msg->FindInt32("buttons", (int32*)&buttons); if (videoWindow) { if (buttons & B_PRIMARY_MOUSE_BUTTON) { if (clicks == 2 && !fIgnoreDoubleClick) Window()->Zoom(); /* else videoWindow->ToggleInterfaceShowing(); */ fIgnoreDoubleClick = false; } else { if (buttons & B_SECONDARY_MOUSE_BUTTON) { // clicks will be 2 next time (if interval short enough) // even if the first click and the second // have not been made with the same mouse button fIgnoreDoubleClick = true; // launch popup menu BPopUpMenu *menu = new BPopUpMenu("context menu"); menu->SetRadioMode(false); // In full screen, add an item to show/hide the interface if( videoWindow->IsFullScreen() ) { BMenuItem *intfItem = new BMenuItem( _("Show Interface"), new BMessage(SHOW_INTERFACE) ); menu->AddItem( intfItem ); } // Resize to 50% BMenuItem *halfItem = new BMenuItem(_("50%"), new BMessage(RESIZE_50)); menu->AddItem(halfItem); // Resize to 100% BMenuItem *origItem = new BMenuItem(_("100%"), new BMessage(RESIZE_100)); menu->AddItem(origItem); // Resize to 200% BMenuItem *doubleItem = new BMenuItem(_("200%"), new BMessage(RESIZE_200)); menu->AddItem(doubleItem); // Toggle FullScreen BMenuItem *zoomItem = new BMenuItem(_("Fullscreen"), new BMessage(TOGGLE_FULL_SCREEN)); zoomItem->SetMarked(videoWindow->IsFullScreen()); menu->AddItem(zoomItem); menu->AddSeparatorItem(); // Toggle vSync BMenuItem *vsyncItem = new BMenuItem(_("Vertical Sync"), new BMessage(VERT_SYNC)); vsyncItem->SetMarked(videoWindow->IsSyncedToRetrace()); menu->AddItem(vsyncItem); // Correct Aspect Ratio BMenuItem *aspectItem = new BMenuItem(_("Correct Aspect Ratio"), new BMessage(ASPECT_CORRECT)); aspectItem->SetMarked(videoWindow->CorrectAspectRatio()); menu->AddItem(aspectItem);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -