📄 videooutput.cpp
字号:
*****************************************************************************/voidVideoWindow::_FreeBuffers(){ delete bitmap[0]; bitmap[0] = NULL; delete bitmap[1]; bitmap[1] = NULL; 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);}/***************************************************************************** * VideoWindow::_SaveScreenShot *****************************************************************************/voidVideoWindow::_SaveScreenShot( BBitmap* bitmap, char* path, uint32_t translatorID ) const{ // make the info object from the parameters screen_shot_info* info = new screen_shot_info; info->bitmap = bitmap; info->path = path; info->translatorID = translatorID; info->width = CorrectAspectRatio() ? i_width : fTrueWidth; info->height = CorrectAspectRatio() ? i_height : fTrueHeight; // spawn a new thread to take care of the actual saving to disk thread_id thread = spawn_thread( _save_screen_shot, "screen shot saver", B_LOW_PRIORITY, (void*)info ); // start thread or do the job ourself if something went wrong if ( thread < B_OK || resume_thread( thread ) < B_OK ) _save_screen_shot( (void*)info );}/***************************************************************************** * VideoWindow::_save_screen_shot *****************************************************************************/int32VideoWindow::_save_screen_shot( void* cookie ){ screen_shot_info* info = (screen_shot_info*)cookie; if ( info && info->bitmap && info->bitmap->IsValid() && info->path ) { // try to be as quick as possible creating the file (the user might have // taken the next screen shot already!) // make sure we have a unique name for the screen shot BString path( info->path ); // create the folder if it doesn't exist BString folder( info->path ); create_directory( folder.String(), 0777 ); path << "/vlc screenshot"; BEntry entry( path.String() ); int32_t appendedNumber = 0; if ( entry.Exists() && !entry.IsSymLink() ) { // we would clobber an existing entry bool foundUniqueName = false; appendedNumber = 1; while ( !foundUniqueName ) { BString newName( path.String() ); newName << " " << appendedNumber; BEntry possiblyClobberedEntry( newName.String() ); if ( possiblyClobberedEntry.Exists() && !possiblyClobberedEntry.IsSymLink() ) appendedNumber++; else foundUniqueName = true; } } if ( appendedNumber > 0 ) path << " " << appendedNumber; // there is still a slight chance to clobber an existing // file (if it was created in the "meantime"), but we take it... BFile outFile( path.String(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE ); // make colorspace converted copy of bitmap BBitmap* converted = new BBitmap( BRect( 0.0, 0.0, info->width, info->height ), B_RGB32 ); status_t status = convert_bitmap( info->bitmap, converted ); if ( status == B_OK ) { BTranslatorRoster* roster = BTranslatorRoster::Default(); uint32_t imageFormat = 0; translator_id translator = 0; bool found = false; // find suitable translator translator_id* ids = NULL; int32 count = 0; status = roster->GetAllTranslators( &ids, &count ); if ( status >= B_OK ) { for ( int tix = 0; tix < count; tix++ ) { const translation_format *formats = NULL; int32 num_formats = 0; bool ok = false; status = roster->GetInputFormats( ids[tix], &formats, &num_formats ); if (status >= B_OK) { for ( int iix = 0; iix < num_formats; iix++ ) { if ( formats[iix].type == B_TRANSLATOR_BITMAP ) { ok = true; break; } } } if ( !ok ) continue; status = roster->GetOutputFormats( ids[tix], &formats, &num_formats); if ( status >= B_OK ) { for ( int32_t oix = 0; oix < num_formats; oix++ ) { if ( formats[oix].type != B_TRANSLATOR_BITMAP ) { if ( formats[oix].type == info->translatorID ) { found = true; imageFormat = formats[oix].type; translator = ids[tix]; break; } } } } } } delete[] ids; if ( found ) { // make bitmap stream BBitmapStream outStream( converted ); status = outFile.InitCheck(); if (status == B_OK) { status = roster->Translate( &outStream, NULL, NULL, &outFile, imageFormat ); if ( status == B_OK ) { BNodeInfo nodeInfo( &outFile ); if ( nodeInfo.InitCheck() == B_OK ) { translation_format* formats; int32 count; status = roster->GetOutputFormats( translator, (const translation_format **) &formats, &count); if ( status >= B_OK ) { const char * mime = NULL; for ( int ix = 0; ix < count; ix++ ) { if ( formats[ix].type == imageFormat ) { mime = formats[ix].MIME; break; } } if ( mime ) nodeInfo.SetType( mime ); } } } } outStream.DetachBitmap( &converted ); outFile.Unset(); } } delete converted; } if ( info ) { delete info->bitmap; free( info->path ); } delete info; return B_OK;}/***************************************************************************** * 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(system_time()), fCursorHidden(false), fCursorInside(false), fIgnoreDoubleClick(false){ p_vout = p_vout_instance; SetViewColor(B_TRANSPARENT_32_BIT);}/***************************************************************************** * VLCView::~VLCView *****************************************************************************/VLCView::~VLCView(){}/***************************************************************************** * VLCVIew::AttachedToWindow *****************************************************************************/voidVLCView::AttachedToWindow(){ // in order to get keyboard events MakeFocus(true); // 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 =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -