diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 20cb2cd..4833524 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -56,6 +56,8 @@ SET(Calyp_App_SRCS ResourceHandle.cpp VideoHandle.cpp VideoSubWindow.cpp + VideoStreamSubWindow.cpp + ModuleSubWindow.cpp ViewArea.cpp GridManager.cpp # Module Quality diff --git a/app/CalypAppModuleIf.cpp b/app/CalypAppModuleIf.cpp index eafb878..b83f442 100644 --- a/app/CalypAppModuleIf.cpp +++ b/app/CalypAppModuleIf.cpp @@ -29,6 +29,7 @@ #include #include "ModuleHandleDock.h" +#include "ModuleSubWindow.h" #include "VideoSubWindow.h" #include "lib/CalypFrame.h" #include "lib/CalypStream.h" @@ -55,16 +56,19 @@ CalypAppModuleIf::~CalypAppModuleIf() auto* ptr = m_pcModuleDock; m_pcModuleDock = NULL; ptr->close(); + delete ptr; } if( m_pcDisplaySubWindow ) { auto* ptr = m_pcDisplaySubWindow; m_pcDisplaySubWindow = NULL; ptr->closeSubWindow(); + delete ptr; } if( m_pcDockWidget ) { m_pcDockWidget->close(); + delete m_pcDockWidget; } if( m_pcModule ) { @@ -77,7 +81,7 @@ void CalypAppModuleIf::update( bool isPlaying ) { if( m_pcDisplaySubWindow ) { - m_pcDisplaySubWindow->refreshFrame(); + m_pcDisplaySubWindow->refreshSubWindow(); } else { @@ -85,13 +89,13 @@ void CalypAppModuleIf::update( bool isPlaying ) } } -void CalypAppModuleIf::setPlaying( bool isPlaying ) -{ - if( m_pcDisplaySubWindow ) - { - m_pcDisplaySubWindow->setPlaying( isPlaying ); - } -} +// void CalypAppModuleIf::setPlaying( bool isPlaying ) +// { +// if( m_pcDisplaySubWindow ) +// { +// m_pcDisplaySubWindow->setPlaying( isPlaying ); +// } +// } bool CalypAppModuleIf::isRunning() { @@ -154,7 +158,6 @@ bool CalypAppModuleIf::apply( bool isPlaying, bool disableThreads ) show(); } } - return moduleExecuted; } @@ -210,22 +213,25 @@ bool CalypAppModuleIf::process() void CalypAppModuleIf::show() { + if( m_canceling ) + return; switch( m_pcModule->m_iModuleType ) { case CLP_FRAME_PROCESSING_MODULE: { - auto displayWindow = m_pcDisplaySubWindow; + auto displayWindow = qobject_cast( m_pcDisplaySubWindow ); if( displayWindow == nullptr ) displayWindow = m_pcSubWindow[0]; #ifdef CALYP_THREADED_MODULES if( m_Mutex.try_lock() ) { - m_pcDisplaySubWindow->setFillWindow( false ); - m_pcDisplaySubWindow->setCurrFrame( m_pcProcessedFrame ); + displayWindow->setFillWindow( false ); + displayWindow->setCurrFrame( m_pcProcessedFrame ); m_Mutex.unlock(); } +#else + displayWindow->setFillWindow( false ); + displayWindow->setCurrFrame( m_pcProcessedFrame ); #endif - m_pcDisplaySubWindow->setFillWindow( false ); - m_pcDisplaySubWindow->setCurrFrame( m_pcProcessedFrame ); break; } case CLP_FRAME_MEASUREMENT_MODULE: @@ -238,7 +244,7 @@ void CalypAppModuleIf::disable() { QApplication::setOverrideCursor( Qt::WaitCursor ); #ifdef CALYP_THREADED_MODULES - QMutexLocker locker( &m_Mutex ); + m_canceling = true; m_Mutex.lock(); m_Mutex.unlock(); #endif diff --git a/app/CalypAppModuleIf.h b/app/CalypAppModuleIf.h index bdd77af..8c6203d 100644 --- a/app/CalypAppModuleIf.h +++ b/app/CalypAppModuleIf.h @@ -52,6 +52,7 @@ class CalypFrame; #define CLP_MODULE_MAX_NUM_FRAMES 5 class VideoSubWindow; +class ModuleSubWindow; class CalypAppModuleIf : std::enable_shared_from_this, #ifdef CALYP_THREADED_MODULES @@ -88,7 +89,7 @@ public: void update( bool isPlaying ); bool apply( bool isPlaying = false, bool disableThreads = false ); bool process(); - void setPlaying( bool isPlaying ); + // void setPlaying( bool isPlaying ); bool isRunning(); void show(); void disable(); @@ -105,7 +106,7 @@ private: std::vector m_pcSubWindow; // The module owns the related widgets - VideoSubWindow* m_pcDisplaySubWindow{ nullptr }; + ModuleSubWindow* m_pcDisplaySubWindow{ nullptr }; QDockWidget* m_pcDockWidget{ nullptr }; ModuleHandleDock* m_pcModuleDock{ nullptr }; @@ -119,6 +120,7 @@ private: #ifdef CALYP_THREADED_MODULES QMutex m_Mutex; + std::atomic m_canceling{ false }; #endif }; diff --git a/app/MainWindow.cpp b/app/MainWindow.cpp index ae6b3b7..7f3a79d 100644 --- a/app/MainWindow.cpp +++ b/app/MainWindow.cpp @@ -192,13 +192,13 @@ void MainWindow::loadFile( QString fileName, CalypFileInfo* pStreamInfo ) printMessage( "File " + fileName + " do not exist!", CLP_LOG_ERROR ); return; } - VideoSubWindow* videoSubWindow = MainWindow::findVideoStreamSubWindow( m_pcWindowHandle, fileName ); + auto* videoSubWindow = MainWindow::findVideoStreamSubWindow( m_pcWindowHandle, fileName ); if( videoSubWindow ) { m_pcWindowHandle->setActiveSubWindow( videoSubWindow ); return; } - videoSubWindow = new VideoSubWindow( VideoSubWindow::VIDEO_STREAM_SUBWINDOW ); // createSubWindow(); + videoSubWindow = new VideoStreamSubWindow(); // createSubWindow(); videoSubWindow->setResourceManaget( m_appResourceHandle.get() ); if( !pStreamInfo ) @@ -380,9 +380,8 @@ void MainWindow::saveStream() void MainWindow::format() { - if( m_pcCurrentVideoSubWindow ) + if( auto* pcVideoSubWindow = qobject_cast( m_pcCurrentVideoSubWindow ) ) { - VideoSubWindow* pcVideoSubWindow = m_pcCurrentVideoSubWindow; try { if( pcVideoSubWindow->loadFile( pcVideoSubWindow->getCurrentFileName(), true ) ) @@ -436,10 +435,10 @@ void MainWindow::reloadAll() void MainWindow::loadAll() { - if( m_pcCurrentVideoSubWindow ) + if( auto* pcVideoSubWindow = qobject_cast( m_pcCurrentVideoSubWindow ) ) { printMessage( "Loading file into memory...", CLP_LOG_INFO ); - m_pcCurrentVideoSubWindow->loadAll(); + pcVideoSubWindow->loadAll(); printMessage( "File loaded", CLP_LOG_INFO ); } } @@ -529,19 +528,18 @@ void MainWindow::dropEvent( QDropEvent* event ) // ----------------------- Sub Window Functions ----------------------- -VideoSubWindow* MainWindow::findVideoStreamSubWindow( const SubWindowHandle* windowManager, - const QString& fileName ) +VideoStreamSubWindow* MainWindow::findVideoStreamSubWindow( const SubWindowHandle* windowManager, + const QString& fileName ) { QString canonicalFilePath = QFileInfo( fileName ).canonicalFilePath(); - VideoSubWindow* pcSubWindow; QList subWindowList = windowManager->findSubWindow( SubWindowAbstract::VIDEO_STREAM_SUBWINDOW ); for( int i = 0; i < subWindowList.size(); i++ ) { - pcSubWindow = qobject_cast( subWindowList.at( i ) ); + auto* pcSubWindow = qobject_cast( subWindowList.at( i ) ); if( pcSubWindow->getCurrentFileName() == canonicalFilePath ) - return qobject_cast( pcSubWindow ); + return pcSubWindow; } - return 0; + return nullptr; } // ----------------------- Update Functions ----------------------- diff --git a/app/MainWindow.h b/app/MainWindow.h index fc6bfaf..ae731e2 100644 --- a/app/MainWindow.h +++ b/app/MainWindow.h @@ -41,6 +41,7 @@ #include #include "CommonDefs.h" +#include "VideoStreamSubWindow.h" #include "VideoSubWindow.h" #include "config.h" #ifdef USE_QTDBUS @@ -59,6 +60,7 @@ class QSignalMapper; class CalypOptions; class CalypStream; class SubWindowHandle; +class VideoStreamSubWindow; class VideoHandle; class QualityHandle; class ModulesHandle; @@ -130,8 +132,8 @@ private: QString m_cLastOpenPath; QStringList showFileDialog( bool bRead ); - static VideoSubWindow* findVideoStreamSubWindow( const SubWindowHandle* windowManager, - const QString& fileName ); + static VideoStreamSubWindow* findVideoStreamSubWindow( const SubWindowHandle* windowManager, + const QString& fileName ); void updateMenus(); diff --git a/app/ModuleSubWindow.cpp b/app/ModuleSubWindow.cpp new file mode 100644 index 0000000..bac54ff --- /dev/null +++ b/app/ModuleSubWindow.cpp @@ -0,0 +1,114 @@ +/* This file is a part of Calyp project + * Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com) + * Luis Lucas (luisfrlucas@gmail.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * \file ModuleSubWindow.cpp + * \brief Video Sub windows handling + */ + +#include "ModuleSubWindow.h" + +#include +#include +#include + +#include "ModulesHandle.h" + +ModuleSubWindow::ModuleSubWindow( CalypAppModuleIf* module, QWidget* parent ) + : VideoSubWindow( VideoSubWindow::MODULE_SUBWINDOW, parent ) +{ + m_pcDisplayModule = module; +} + +ModuleSubWindow::~ModuleSubWindow() +{ +} + +void ModuleSubWindow::resetWindowName() +{ + QString windowName{ "Module" }; + if( auto module_ptr = m_pcDisplayModule ) + { + windowName.append( " " ).append( module_ptr->getModule()->m_pchModuleLongName ); + } + setWindowName( windowName ); +} + +void ModuleSubWindow::updateVideoWindowInfo() +{ + m_cStreamInformation = ""; + + m_cStreamInformation = "Module"; + if( auto module_ptr = m_pcDisplayModule ) + { + const auto& arraySubWindows = module_ptr->getSubWindowList(); + QStringList windowInfoList; + if( arraySubWindows.size() > 0 ) + { + for( std::size_t i = 0; i < arraySubWindows.size(); i++ ) + { + if( arraySubWindows[i]->getWindowName() != getWindowName() ) + { + windowInfoList.append( QString( "Input %1 - " + arraySubWindows[i]->getWindowName() ).arg( i + 1 ) ); + } + } + } + if( module_ptr->getModuleRequirements() & CLP_MODULES_HAS_INFO ) + { + QStringList list = QString::fromStdString( module_ptr->moduleInfo() ).split( '\n' ); + windowInfoList.append( list ); + } + if( windowInfoList.size() > 0 ) + { + m_pcVideoInfo->setInformationTopLeft( windowInfoList ); + } + } + if( m_pcCurrFrameAsset ) + { + QString m_cPelFmtName = QString::fromStdString( m_pcCurrFrameAsset->getPelFmtName() ); + m_cStreamInformation += " | " + m_cPelFmtName; + } + if( m_cStreamInformation.isEmpty() ) + { + m_cStreamInformation = " "; + } +} + +bool ModuleSubWindow::isPlaying() +{ + if( auto module_ptr = m_pcDisplayModule ) + { + for( auto window : module_ptr->getSubWindowList() ) + { + if( window->isPlaying() ) + return true; + } + } + return false; +} + +void ModuleSubWindow::refreshSubWindow() +{ + if( auto module_ptr = m_pcDisplayModule ) + { + setFillWindow( true ); + updateVideoWindowInfo(); + module_ptr->apply( isPlaying(), false ); + } +} \ No newline at end of file diff --git a/app/ModuleSubWindow.h b/app/ModuleSubWindow.h new file mode 100644 index 0000000..29f2a50 --- /dev/null +++ b/app/ModuleSubWindow.h @@ -0,0 +1,64 @@ +/* This file is a part of Calyp project + * Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com) + * Luis Lucas (luisfrlucas@gmail.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * \file ModuleSubWindow.h + * \brief Video Sub windows handling + */ + +#ifndef __MODULESUBWINDOW_H__ +#define __MODULESUBWINDOW_H__ + +#include +#include +#include +#include +#include + +#include "CalypAppModuleIf.h" +#include "CommonDefs.h" +#include "VideoSubWindow.h" +#include "config.h" +#include "lib/CalypStream.h" + +class VideoInformation; + +class ModuleSubWindow : public VideoSubWindow +{ + Q_OBJECT + +public: + ModuleSubWindow( CalypAppModuleIf* module, QWidget* parent = 0 ); + ~ModuleSubWindow(); + + void resetWindowName(); + + void updateVideoWindowInfo(); + + bool isPlaying(); + void stop(){}; + void advanceOneFrame(){}; + auto getFrameNum() -> std::uint64_t { return 1; }; + + void refreshSubWindow(); + + void setCurrFrame( std::shared_ptr pcCurrFrame ); +}; + +#endif // __MODULESUBWINDOW_H__ diff --git a/app/ModulesHandle.cpp b/app/ModulesHandle.cpp index b96ed8d..1478381 100644 --- a/app/ModulesHandle.cpp +++ b/app/ModulesHandle.cpp @@ -27,6 +27,7 @@ #include #include "MainWindow.h" +#include "ModuleSubWindow.h" #include "ModulesHandleOptDialog.h" #include "SubWindowHandle.h" #include "SubWindowSelectorDialog.h" @@ -184,18 +185,17 @@ void ModulesHandle::updateMenus() if( pcSubWindow ) { - auto apcCurrentModule = pcSubWindow->getModuleArray(); - m_arrayActions[DISABLE_ACT]->setEnabled( apcCurrentModule.size() > 0 ); + m_arrayActions[DISABLE_ACT]->setEnabled( pcSubWindow->hasModules() ); if( pcSubWindow->getDisplayModule() ) { m_arrayActions[APPLY_ALL_ACT]->setEnabled( true ); m_arrayActions[SWAP_FRAMES_ACT]->setEnabled( true ); } - for( int i = 0; i < apcCurrentModule.size(); i++ ) - { - currModuleAction = apcCurrentModule.at( i )->m_pcModuleAction; - currModuleAction->setChecked( true ); - } + // for( int i = 0; i < apcCurrentModule.size(); i++ ) + // { + // currModuleAction = apcCurrentModule.at( i )->m_pcModuleAction; + // currModuleAction->setChecked( true ); + // } } } @@ -219,16 +219,15 @@ void ModulesHandle::processOpt( int index ) CalypAppModuleIf* pcCurrentModule = pcSubWindow->getDisplayModule(); if( pcCurrentModule ) { - CalypAppModuleIf* pcCurrModule = pcCurrentModule; switch( index ) { case INVALID_OPT: break; case SWAP_FRAMES_ACT: - swapModulesWindowsIf( pcCurrModule ); + swapModulesWindowsIf( pcCurrentModule ); break; case APPLY_ALL_ACT: - applyAllModuleIf( pcCurrModule ); + applyAllModuleIf( pcCurrentModule ); break; default: Q_ASSERT( 0 ); @@ -376,14 +375,12 @@ void ModulesHandle::activateModule() QString windowName; - VideoSubWindow* pcModuleSubWindow = NULL; if( pcCurrAppModuleIf->m_pcModule->m_iModuleType == CLP_FRAME_PROCESSING_MODULE ) { if( ( pcCurrAppModuleIf->m_pcModule->m_uiModuleRequirements & CLP_MODULE_REQUIRES_NEW_WINDOW ) || bShowModulesNewWindow ) { - pcModuleSubWindow = new VideoSubWindow( VideoSubWindow::MODULE_SUBWINDOW, pcCurrAppModuleIf.get() ); - windowName.append( QStringLiteral( "Module " ) ); - windowName.append( pcCurrAppModuleIf->m_pcModule->m_pchModuleLongName ); + auto pcModuleSubWindow = new ModuleSubWindow( pcCurrAppModuleIf.get() ); + pcModuleSubWindow->resetWindowName(); pcCurrAppModuleIf->m_pcDisplaySubWindow = pcModuleSubWindow; // connect( pcModuleSubWindow->getViewArea(), SIGNAL( selectionChanged( QRect ) ), m_appModuleVideo, // SLOT( updateSelectionArea( QRect ) ) ); @@ -445,12 +442,11 @@ void ModulesHandle::activateModule() QCoreApplication::processEvents(); - if( pcModuleSubWindow ) + if( pcCurrAppModuleIf->m_pcDisplaySubWindow ) { - pcModuleSubWindow->setWindowName( windowName ); - m_pcMainWindowManager->addSubWindow( pcModuleSubWindow ); - pcModuleSubWindow->show(); - m_appModuleVideo->addSubWindow( pcModuleSubWindow ); + m_pcMainWindowManager->addSubWindow( pcCurrAppModuleIf->m_pcDisplaySubWindow ); + pcCurrAppModuleIf->m_pcDisplaySubWindow->show(); + m_appModuleVideo->addSubWindow( pcCurrAppModuleIf->m_pcDisplaySubWindow ); } else { @@ -540,7 +536,7 @@ void ModulesHandle::applyAllModuleIf( CalypAppModuleIf* pcCurrModuleIf ) Height = pcCurrModuleIf->m_pcProcessedFrame->getHeight(); InputFormat = pcCurrModuleIf->m_pcProcessedFrame->getPelFormat(); BitsPixel = pcCurrModuleIf->m_pcProcessedFrame->getBitsPel(); - FrameRate = pcCurrModuleIf->m_pcSubWindow[0]->getInputStream()->getFrameRate(); + FrameRate = 30; pcCurrModuleIf->m_pcModuleStream = std::unique_ptr(); if( !pcCurrModuleIf->m_pcModuleStream->open( fileName.toStdString(), Width, Height, InputFormat, BitsPixel, @@ -558,7 +554,7 @@ void ModulesHandle::applyAllModuleIf( CalypAppModuleIf* pcCurrModuleIf ) std::uint64_t numberOfFrames = -1; for( unsigned int i = 0; i < numberOfWindows; i++ ) { - currFrames = pcCurrModuleIf->m_pcSubWindow[i]->getInputStream()->getFrameNum(); + currFrames = pcCurrModuleIf->m_pcSubWindow[i]->getFrameNum(); if( currFrames < numberOfFrames ) numberOfFrames = currFrames; pcCurrModuleIf->m_pcSubWindow[i]->stop(); @@ -571,8 +567,7 @@ void ModulesHandle::applyAllModuleIf( CalypAppModuleIf* pcCurrModuleIf ) pcCurrModuleIf->m_pcModuleStream->writeFrame( *pcCurrModuleIf->m_pcProcessedFrame ); for( unsigned int i = 0; i < numberOfWindows; i++ ) { - pcCurrModuleIf->m_pcSubWindow[i]->play(); - pcCurrModuleIf->m_pcSubWindow[i]->playEvent(); + pcCurrModuleIf->m_pcSubWindow[i]->advanceOneFrame(); } } for( unsigned int i = 0; i < numberOfWindows; i++ ) diff --git a/app/QualityHandle.cpp b/app/QualityHandle.cpp index 1c6cb36..46ca8de 100644 --- a/app/QualityHandle.cpp +++ b/app/QualityHandle.cpp @@ -169,10 +169,10 @@ void QualityHandle::measureQuality( QVector apcWindowList ) } VideoSubWindow* pcReferenceWindow = apcWindowList.at( 0 )->getRefSubWindow(); - numberOfFrames = pcReferenceWindow->getInputStream()->getFrameNum(); + numberOfFrames = pcReferenceWindow->getFrameNum(); for( unsigned i = 0; i < numberOfWindows; i++ ) { - currFrames = apcWindowList.at( i )->getInputStream()->getFrameNum(); + currFrames = apcWindowList.at( i )->getFrameNum(); if( currFrames < numberOfFrames ) numberOfFrames = currFrames; apcWindowList.at( i )->stop(); @@ -183,7 +183,6 @@ void QualityHandle::measureQuality( QVector apcWindowList ) QVector* padQualityValues = new QVector[numberOfWindows + 1]; double* padAverageQuality = new double[numberOfWindows + 1]; - double dCurrentQuality; for( unsigned i = 0; i < numberOfWindows + 1; i++ ) { @@ -199,12 +198,12 @@ void QualityHandle::measureQuality( QVector apcWindowList ) for( unsigned int i = 0; i < numberOfWindows; i++ ) { pcCurrFrame = apcWindowList.at( i )->getCurrFrame(); - dCurrentQuality = pcCurrFrame->getQuality( m_iQualityMetricIdx, pcReferenceFrame, CLP_LUMA ); + double dCurrentQuality = pcCurrFrame->getQuality( m_iQualityMetricIdx, pcReferenceFrame, CLP_LUMA ); padAverageQuality[i + 1] = ( padAverageQuality[i + 1] * double( f ) + dCurrentQuality ) / double( f + 1 ); padQualityValues[i + 1].append( dCurrentQuality ); - apcWindowList.at( i )->seekRelativeEvent( true ); + apcWindowList.at( i )->advanceOneFrame(); } - pcReferenceWindow->seekRelativeEvent( true ); + pcReferenceWindow->advanceOneFrame(); pcProgressBar->incrementProgress( 1 ); } for( unsigned int i = 0; i < numberOfWindows; i++ ) diff --git a/app/SubWindowAbstract.cpp b/app/SubWindowAbstract.cpp index 3a6d859..e2f8876 100644 --- a/app/SubWindowAbstract.cpp +++ b/app/SubWindowAbstract.cpp @@ -26,8 +26,10 @@ #include #include +#include #include #include +#include #include #include "MdiSubWindow.h" @@ -87,10 +89,20 @@ bool SubWindowAbstract::mayClose() QSize SubWindowAbstract::sizeHint() const { - return QSize(); + QSize maxSize; + QWidget* p = parentWidget(); + if( p ) + { + maxSize = p->size(); + } + else + { + maxSize = QGuiApplication::screens()[0]->availableGeometry().size(); + } + return sizeHint( maxSize ); } -QSize SubWindowAbstract::sizeHint( const QSize& ) const +QSize SubWindowAbstract::sizeHint( const QSize& maxSize ) const { return QSize(); } diff --git a/app/SubWindowAbstract.h b/app/SubWindowAbstract.h index 1e07411..166ac52 100644 --- a/app/SubWindowAbstract.h +++ b/app/SubWindowAbstract.h @@ -107,7 +107,7 @@ public: * Size related functions */ virtual QSize sizeHint() const; - virtual QSize sizeHint( const QSize& ) const; + virtual QSize sizeHint( const QSize& maxSize ) const; /** * Window name diff --git a/app/VideoHandle.cpp b/app/VideoHandle.cpp index 592dd80..1c3a75c 100644 --- a/app/VideoHandle.cpp +++ b/app/VideoHandle.cpp @@ -40,6 +40,7 @@ #include "SeekStreamDialog.h" #include "SubWindowHandle.h" #include "SubWindowSelectorDialog.h" +#include "VideoStreamSubWindow.h" #include "VideoSubWindow.h" VideoHandle::VideoHandle( QWidget* parent, SubWindowHandle* windowManager ) @@ -325,10 +326,16 @@ void VideoHandle::update() { if( m_pcCurrentVideoSubWindow ) { - const CalypStream* pcStream = m_pcCurrentVideoSubWindow->getInputStream(); - const CalypFrame* pcFrame = m_pcCurrentVideoSubWindow->getCurrFrame(); + bool isPlaying{ false }; + const CalypStream* pcStream{ nullptr }; + if( auto* videoStreamSubWindow = qobject_cast( m_pcCurrentVideoSubWindow ) ) + { + pcStream = videoStreamSubWindow->getInputStream(); + isPlaying = videoStreamSubWindow->isPlaying(); + } + auto pcFrame = m_pcCurrentVideoSubWindow->getCurrFrameAsset(); - m_pcVideoFormatLabel->setText( m_pcCurrentVideoSubWindow->getStreamInformation() ); + m_pcVideoFormatLabel->setText( m_pcCurrentVideoSubWindow->getVideoInformation() ); QString resolution; if( pcFrame ) @@ -362,7 +369,7 @@ void VideoHandle::update() } } m_pcResolutionLabel->setText( resolution ); - m_pcFramePropertiesSideBar->setFrame( m_pcCurrentVideoSubWindow->getCurrFrameAsset(), m_pcCurrentVideoSubWindow->isPlaying() ); + m_pcFramePropertiesSideBar->setFrame( pcFrame, isPlaying ); m_pcFrameNumInfo->setTotalFrameNum( total_frame_num ); m_pcFrameNumInfo->setCurrFrameNum( frame_num ); @@ -433,12 +440,11 @@ void VideoHandle::addSubWindow( VideoSubWindow* window ) void VideoHandle::closeSubWindow( SubWindowAbstract* subWindow ) { - VideoSubWindow* videoSubWindow = qobject_cast( subWindow ); + auto* videoStreamSubWindow = qobject_cast( subWindow ); - if( m_acPlayingSubWindows.contains( videoSubWindow ) ) + if( m_acPlayingSubWindows.contains( videoStreamSubWindow ) ) { - int pos = m_acPlayingSubWindows.indexOf( videoSubWindow ); - // m_acPlayingSubWindows.at( pos )->stop(); + int pos = m_acPlayingSubWindows.indexOf( videoStreamSubWindow ); m_acPlayingSubWindows.remove( pos ); if( m_acPlayingSubWindows.size() < 2 ) { @@ -541,18 +547,18 @@ unsigned long VideoHandle::getMaxFrameNumber() unsigned long maxFrames = INT_MAX; if( m_pcCurrentVideoSubWindow ) { - if( m_acPlayingSubWindows.contains( m_pcCurrentVideoSubWindow ) ) + if( m_acPlayingSubWindows.contains( qobject_cast( m_pcCurrentVideoSubWindow ) ) ) { for( int i = 0; i < m_acPlayingSubWindows.size(); i++ ) { - currFrames = m_acPlayingSubWindows.at( i )->getInputStream()->getFrameNum(); + currFrames = m_acPlayingSubWindows.at( i )->getFrameNum(); if( currFrames < maxFrames ) maxFrames = currFrames; } } else { - maxFrames = m_pcCurrentVideoSubWindow->getInputStream()->getFrameNum(); + maxFrames = m_pcCurrentVideoSubWindow->getFrameNum(); } } return maxFrames; @@ -565,9 +571,9 @@ void VideoHandle::setTimerStatus() { status |= m_acPlayingSubWindows.at( i )->isPlaying(); } - if( m_pcCurrentVideoSubWindow ) + if( auto* videoStreamSubWindow = qobject_cast( m_pcCurrentVideoSubWindow ) ) { - status |= m_pcCurrentVideoSubWindow->isPlaying(); + status |= videoStreamSubWindow->isPlaying(); } if( status ) { @@ -596,13 +602,12 @@ void VideoHandle::configureFrameRateTimer() void VideoHandle::play() { - if( !m_pcCurrentVideoSubWindow ) + auto* videoStreamSubWindow = qobject_cast( m_pcCurrentVideoSubWindow ); + + if( videoStreamSubWindow == nullptr ) return; - if( !m_pcCurrentVideoSubWindow->getInputStream() ) - return; - - if( !m_pcCurrentVideoSubWindow->isPlaying() ) // Not playing + if( !videoStreamSubWindow->isPlaying() ) // Not playing { if( m_acPlayingSubWindows.size() < 2 ) { @@ -611,9 +616,9 @@ void VideoHandle::play() m_acPlayingSubWindows.at( i )->pause(); } m_acPlayingSubWindows.clear(); - m_acPlayingSubWindows.append( m_pcCurrentVideoSubWindow ); + m_acPlayingSubWindows.append( videoStreamSubWindow ); } - if( m_acPlayingSubWindows.contains( m_pcCurrentVideoSubWindow ) ) + if( m_acPlayingSubWindows.contains( videoStreamSubWindow ) ) { for( int i = 0; i < m_acPlayingSubWindows.size(); i++ ) { @@ -624,7 +629,7 @@ void VideoHandle::play() } else { - if( m_acPlayingSubWindows.contains( m_pcCurrentVideoSubWindow ) ) + if( m_acPlayingSubWindows.contains( videoStreamSubWindow ) ) { for( int i = 0; i < m_acPlayingSubWindows.size(); i++ ) { @@ -633,12 +638,11 @@ void VideoHandle::play() } else { - m_pcCurrentVideoSubWindow->pause(); + videoStreamSubWindow->pause(); } } setTimerStatus(); emit changed(); - // update(); } void VideoHandle::stop() @@ -711,9 +715,7 @@ void VideoHandle::playEvent() } catch( const char* msg ) { - QString warningMsg = "Error while playing " + - QFileInfo( m_pcCurrentVideoSubWindow->getCurrentFileName() ).fileName() + - " with the following error: \n" + msg; + QString warningMsg = "Error while playing " + m_pcCurrentVideoSubWindow->getWindowName() + " with the following error: \n" + msg; QMessageBox::warning( m_pcParet, QApplication::applicationName(), warningMsg ); qDebug() << warningMsg; stop(); @@ -730,11 +732,11 @@ void VideoHandle::playEvent() void VideoHandle::seekEvent( int direction ) { - if( m_pcCurrentVideoSubWindow ) + if( auto* videoStreamSubWindow = qobject_cast( m_pcCurrentVideoSubWindow ) ) { - if( m_acPlayingSubWindows.contains( m_pcCurrentVideoSubWindow ) ) + if( m_acPlayingSubWindows.contains( videoStreamSubWindow ) ) { - if( !( (unsigned int)( m_pcCurrentVideoSubWindow->getInputStream()->getCurrFrameNum() + 1 ) >= getMaxFrameNumber() && + if( !( (unsigned int)( videoStreamSubWindow->getInputStream()->getCurrFrameNum() + 1 ) >= getMaxFrameNumber() && direction > 0 ) ) { for( auto playingSubWindow : m_acPlayingSubWindows ) @@ -745,7 +747,7 @@ void VideoHandle::seekEvent( int direction ) } else { - m_pcCurrentVideoSubWindow->seekRelativeEvent( direction > 0 ? true : false ); + videoStreamSubWindow->seekRelativeEvent( direction > 0 ? true : false ); } emit changed(); } @@ -753,37 +755,37 @@ void VideoHandle::seekEvent( int direction ) void VideoHandle::seekVideo() { - if( m_pcCurrentVideoSubWindow ) + if( auto* videoStreamSubWindow = qobject_cast( m_pcCurrentVideoSubWindow ) ) { - if( m_pcCurrentVideoSubWindow->getInputStream() ) + SeekStreamDialog* dialogSeekVideo = new SeekStreamDialog( videoStreamSubWindow->getInputStream(), m_pcParet ); + int newFrameNum = dialogSeekVideo->runDialog(); + if( newFrameNum >= 0 ) { - SeekStreamDialog* dialogSeekVideo = - new SeekStreamDialog( m_pcCurrentVideoSubWindow->getInputStream(), m_pcParet ); - int newFrameNum = dialogSeekVideo->runDialog(); - if( newFrameNum >= 0 ) + if( m_acPlayingSubWindows.contains( videoStreamSubWindow ) ) { - if( m_acPlayingSubWindows.contains( m_pcCurrentVideoSubWindow ) ) + for( auto playingSubWindow : m_acPlayingSubWindows ) { - for( auto playingSubWindow : m_acPlayingSubWindows ) - { - playingSubWindow->seekAbsoluteEvent( (unsigned int)newFrameNum ); - } + playingSubWindow->seekAbsoluteEvent( (unsigned int)newFrameNum ); } - else - { - m_pcCurrentVideoSubWindow->seekAbsoluteEvent( (unsigned int)newFrameNum ); - } - emit changed(); } + else + { + videoStreamSubWindow->seekAbsoluteEvent( (unsigned int)newFrameNum ); + } + emit changed(); } } } void VideoHandle::seekSliderEvent( int new_frame_num ) { - if( m_pcCurrentVideoSubWindow && !m_bIsPlaying ) // TODO: Fix this slot + // TODO: Fix this slot + if( m_bIsPlaying ) + return; + + if( auto* videoStreamSubWindow = qobject_cast( m_pcCurrentVideoSubWindow ) ) { - if( m_acPlayingSubWindows.contains( m_pcCurrentVideoSubWindow ) ) + if( m_acPlayingSubWindows.contains( videoStreamSubWindow ) ) { for( auto playingSubWindow : m_acPlayingSubWindows ) { @@ -792,7 +794,7 @@ void VideoHandle::seekSliderEvent( int new_frame_num ) } else { - m_pcCurrentVideoSubWindow->seekAbsoluteEvent( (unsigned int)new_frame_num ); + videoStreamSubWindow->seekAbsoluteEvent( (unsigned int)new_frame_num ); } emit changed(); } @@ -800,8 +802,6 @@ void VideoHandle::seekSliderEvent( int new_frame_num ) void VideoHandle::videoSelectionButtonEvent() { - VideoSubWindow* videoSubWindow; - Qt::KeyboardModifiers keyModifiers = QApplication::keyboardModifiers(); if( keyModifiers & Qt::ControlModifier ) { @@ -809,7 +809,7 @@ void VideoHandle::videoSelectionButtonEvent() m_pcMainWindowManager->findSubWindow( SubWindowAbstract::VIDEO_STREAM_SUBWINDOW ); for( auto subWindow : subWindowList ) { - videoSubWindow = qobject_cast( subWindow ); + auto* videoSubWindow = qobject_cast( subWindow ); m_acPlayingSubWindows.append( videoSubWindow ); } } @@ -829,7 +829,7 @@ void VideoHandle::videoSelectionButtonEvent() QList selectedSubWindowList = dialogWindowsSelection.getSelectedWindows(); for( auto window : selectedSubWindowList ) { - videoSubWindow = qobject_cast( window ); + auto* videoSubWindow = qobject_cast( window ); m_acPlayingSubWindows.append( videoSubWindow ); } } diff --git a/app/VideoHandle.h b/app/VideoHandle.h index 882905e..a5d8d05 100644 --- a/app/VideoHandle.h +++ b/app/VideoHandle.h @@ -33,6 +33,7 @@ #include #include "CommonDefs.h" +#include "VideoSubWindow.h" #include "config.h" class QToolBar; @@ -43,7 +44,7 @@ class QSlider; class SubWindowHandle; class SubWindowAbstract; -class VideoSubWindow; +class VideoStreamSubWindow; class FramePropertiesDock; class FrameNumberWidget; class QTimer; @@ -116,8 +117,8 @@ private: QLabel* m_pcVideoFormatLabel; QLabel* m_pcResolutionLabel; - VideoSubWindow* m_pcCurrentVideoSubWindow; - QVector m_acPlayingSubWindows; + QPointer m_pcCurrentVideoSubWindow; + QVector m_acPlayingSubWindows; QTimer* m_pcPlayingTimer; bool m_bIsPlaying; diff --git a/app/VideoStreamSubWindow.cpp b/app/VideoStreamSubWindow.cpp new file mode 100644 index 0000000..ac8198b --- /dev/null +++ b/app/VideoStreamSubWindow.cpp @@ -0,0 +1,595 @@ +/* This file is a part of Calyp project + * Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com) + * Luis Lucas (luisfrlucas@gmail.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * \file VideoStreamSubWindow.cpp + * \brief Video Sub windows handling + */ + +#include "VideoStreamSubWindow.h" + +#include +#include +#include +#include + +#include "ConfigureFormatDialog.h" +#include "ModulesHandle.h" +#include "QtConcurrent/qtconcurrentrun.h" +#include "ResourceHandle.h" +#include "SubWindowAbstract.h" + +#define QT_NO_CONCURRENT + +/** + * \brief Functions to control data stream from stream information + */ + +QDataStream& operator<<( QDataStream& out, const CalypFileInfoVector& array ) +{ + CalypFileInfo d; + out << array.size(); + for( int i = 0; i < array.size(); i++ ) + { + d = array.at( i ); + out << d.m_cFilename << d.m_uiWidth << d.m_uiHeight << d.m_iPelFormat << d.m_uiBitsPelPixel << d.m_iEndianness + << d.m_uiFrameRate << d.m_uiFileSize; + } + return out; +} + +QDataStream& operator>>( QDataStream& in, CalypFileInfoVector& array ) +{ + CalypFileInfo d; + int array_size{ 0 }; + in >> array_size; + for( int i = 0; i < array_size; i++ ) + { + in >> d.m_cFilename; + in >> d.m_uiWidth; + in >> d.m_uiHeight; + in >> d.m_iPelFormat; + in >> d.m_uiBitsPelPixel; + in >> d.m_iEndianness; + in >> d.m_uiFrameRate; + in >> d.m_uiFileSize; + array.append( d ); + } + return in; +} + +int findCalypStreamInfo( CalypFileInfoVector array, QString filename ) +{ + for( int i = 0; i < array.size(); i++ ) + if( array.at( i ).m_cFilename == filename ) + return i; + return -1; +} + +VideoStreamSubWindow::VideoStreamSubWindow( QWidget* parent ) + : VideoSubWindow( VideoSubWindow::VIDEO_STREAM_SUBWINDOW, parent ) + , m_pcResourceManager( nullptr ) + , m_pCurrStream( NULL ) + , m_bIsPlaying( false ) + +{ +} + +VideoStreamSubWindow::~VideoStreamSubWindow() +{ + if( m_pcResourceManager ) + m_pcResourceManager->removeResource( m_uiResourceId ); +} + +void VideoStreamSubWindow::resetWindowName() +{ + setWindowName( QFileInfo( m_cFilename ).fileName() ); +} + +void VideoStreamSubWindow::updateVideoWindowInfo() +{ + m_cStreamInformation = ""; + if( m_pcDisplayModule ) + { + m_cStreamInformation = "Module"; + const auto& arraySubWindows = m_pcDisplayModule->getSubWindowList(); + QStringList windowInfoList; + if( arraySubWindows.size() > 0 ) + { + for( std::size_t i = 0; i < arraySubWindows.size(); i++ ) + { + if( arraySubWindows[i]->getWindowName() != getWindowName() ) + { + windowInfoList.append( QString( "Input %1 - " + arraySubWindows[i]->getWindowName() ).arg( i + 1 ) ); + } + } + } + if( m_pcDisplayModule->getModuleRequirements() & CLP_MODULES_HAS_INFO ) + { + QStringList list = QString::fromStdString( m_pcDisplayModule->moduleInfo() ).split( '\n' ); + windowInfoList.append( list ); + } + if( windowInfoList.size() > 0 ) + { + m_pcVideoInfo->setInformationTopLeft( windowInfoList ); + } + } + else if( m_pCurrStream ) + { + QString m_cFormatName = QString::fromStdString( m_pCurrStream->getFormatName() ); + QString m_cCodedName = QString::fromStdString( m_pCurrStream->getCodecName() ); + m_cStreamInformation = m_cFormatName + " | " + m_cCodedName; + } + if( m_pcCurrFrameAsset ) + { + QString m_cPelFmtName = QString::fromStdString( m_pcCurrFrameAsset->getPelFmtName() ); + if( m_pCurrStream ) + if( !m_pCurrStream->isNative() ) + m_cPelFmtName += "*"; + m_cStreamInformation += " | " + m_cPelFmtName; + } + if( m_cStreamInformation.isEmpty() ) + { + m_cStreamInformation = " "; + } +} + +void VideoStreamSubWindow::loadAll() +{ + QApplication::setOverrideCursor( Qt::WaitCursor ); + m_pCurrStream->loadAll(); + refreshFrame(); + QApplication::restoreOverrideCursor(); +} + +bool VideoStreamSubWindow::loadFile( QString cFilename, bool bForceDialog ) +{ + assert( m_pcResourceManager != nullptr ); + + ConfigureFormatDialog formatDialog( this ); + unsigned int Width = 0, Height = 0, BitsPel = 8, FrameRate = 30; + int Endianness = CLP_LITTLE_ENDIAN; + int InputFormat = CLP_YUV420P; + QSettings appSettings; + + if( m_pCurrStream ) + m_pCurrStream->getFormat( Width, Height, InputFormat, BitsPel, Endianness, FrameRate ); + else + m_uiResourceId = m_pcResourceManager->getResource( nullptr ); + + m_pCurrStream = m_pcResourceManager->getResourceAsset( m_uiResourceId ); + + bool bConfig = true; + if( !bForceDialog ) + { + bConfig = guessFormat( cFilename, Width, Height, InputFormat, BitsPel, Endianness, FrameRate ); + if( bConfig ) + { + // Pre-load values with last opened file + Width = appSettings.value( "VideoStreamSubWindow/LastWidth" ).value(); + Height = appSettings.value( "VideoStreamSubWindow/LastHeight" ).value(); + BitsPel = appSettings.value( "VideoStreamSubWindow/LastBitsPerPixel" ).value(); + } + } + bool bRet = false; + for( int iPass = 0; iPass < 2 && !bRet; iPass++ ) + { + if( iPass || bConfig ) + { + if( formatDialog.runConfigureFormatDialog( QFileInfo( cFilename ).fileName(), Width, Height, InputFormat, BitsPel, + Endianness, FrameRate ) == QDialog::Rejected ) + { + return false; + } + } + try + { + bRet = m_pCurrStream->open( cFilename.toStdString(), Width, Height, InputFormat, BitsPel, Endianness, FrameRate, true ); + } + catch( CalypFailure& e ) + { + if( iPass == 1 ) + throw( e ); + } + } + + m_sStreamInfo.m_cFilename = cFilename; + m_sStreamInfo.m_uiWidth = Width; + m_sStreamInfo.m_uiHeight = Height; + m_sStreamInfo.m_iPelFormat = InputFormat; + m_sStreamInfo.m_uiBitsPelPixel = BitsPel; + m_sStreamInfo.m_iEndianness = Endianness; + m_sStreamInfo.m_uiFrameRate = FrameRate; + m_sStreamInfo.m_uiFileSize = QFileInfo( cFilename ).size(); + + QVariant var; + var.setValue( Width ); + appSettings.setValue( "VideoStreamSubWindow/LastWidth", var ); + var.setValue( Height ); + appSettings.setValue( "VideoStreamSubWindow/LastHeight", var ); + var.setValue( BitsPel ); + appSettings.setValue( "VideoStreamSubWindow/LastBitsPerPixel", var ); + +#ifdef CALYP_MANAGED_RESOURCES + m_pcResourceManager->startResourceWorker( m_uiResourceId ); +#endif + + QApplication::restoreOverrideCursor(); + + refreshFrame(); + + m_cFilename = cFilename; + + updateVideoWindowInfo(); + setWindowName( QFileInfo( m_cFilename ).fileName() ); + + return true; +} + +bool VideoStreamSubWindow::loadFile( CalypFileInfo* streamInfo ) +{ + assert( m_pcResourceManager != nullptr ); + + m_uiResourceId = m_pcResourceManager->getResource( m_pCurrStream ); + m_pCurrStream = m_pcResourceManager->getResourceAsset( m_uiResourceId ); + + if( !m_pCurrStream->open( streamInfo->m_cFilename.toStdString(), streamInfo->m_uiWidth, streamInfo->m_uiHeight, + streamInfo->m_iPelFormat, streamInfo->m_uiBitsPelPixel, streamInfo->m_iEndianness, + streamInfo->m_uiFrameRate, true ) ) + { + return false; + } + + m_sStreamInfo = *streamInfo; + +#ifdef CALYP_MANAGED_RESOURCES + m_pcResourceManager->startResourceWorker( m_uiResourceId ); +#endif + + QApplication::restoreOverrideCursor(); + + refreshFrame(); + + m_cFilename = streamInfo->m_cFilename; + updateVideoWindowInfo(); + setWindowName( QFileInfo( m_cFilename ).fileName() ); + return true; +} + +bool VideoStreamSubWindow::guessFormat( QString filename, unsigned int& rWidth, unsigned int& rHeight, int& rInputFormat, unsigned int& rBitsPerPixel, + int& rEndianness, unsigned int& rFrameRate ) +{ + std::vector stdResList = CalypStream::stdResolutionSizes(); + bool bGuessed = true; + bool bGuessedByFilesize = false; + QString FilenameShort = QFileInfo( filename ).fileName(); + QString fileExtension = QFileInfo( filename ).suffix(); + + if( filename.startsWith( "/dev/" ) ) + { + return false; + } + if( !fileExtension.compare( "yuv", Qt::CaseInsensitive ) || !fileExtension.compare( "rgb", Qt::CaseInsensitive ) || + !fileExtension.compare( "gray", Qt::CaseInsensitive ) ) + { + bGuessed = false; + // Guess pixel format + auto formats_list = CalypFrame::supportedPixelFormatListNames(); + for( std::size_t i = 0; i < formats_list.size(); i++ ) + { + if( FilenameShort.contains( formats_list[i].c_str(), Qt::CaseInsensitive ) ) + { + rInputFormat = i; + break; + } + } + + if( rWidth == 0 || rHeight == 0 ) + { + // Guess resolution - match resolution name + int iMatch = -1; + for( unsigned int i = 0; i < stdResList.size(); i++ ) + { + if( FilenameShort.contains( QString::fromStdString( stdResList[i].shortName ) ) ) + { + iMatch = i; + } + } + if( iMatch >= 0 ) + { + rWidth = stdResList[iMatch].uiWidth; + rHeight = stdResList[iMatch].uiHeight; + } + + // Guess resolution - match %dx%d + //QRegularExpressionMatch resolutionMatch = QRegularExpression( "_\\d*x\\d*" ).match( FilenameShort ); + QRegularExpressionMatch resolutionMatch = QRegularExpression( "_[0-9]+x[0-9]+" ).match( FilenameShort ); + if( resolutionMatch.hasMatch() ) + { + QString resolutionString = resolutionMatch.captured( resolutionMatch.lastCapturedIndex() ); + if( resolutionString.startsWith( "_" ) || resolutionString.endsWith( "_" ) ) + { + resolutionString.remove( "_" ); + QStringList resolutionArgs = resolutionString.split( "x" ); + if( resolutionArgs.size() == 2 ) + { + rWidth = resolutionArgs.at( 0 ).toUInt(); + rHeight = resolutionArgs.at( 1 ).toUInt(); + } + } + } + } + + // Guess resolution by file size + if( rWidth == 0 && rHeight == 0 ) + { + FILE* pF = fopen( filename.toStdString().c_str(), "rb" ); + if( pF ) + { + fseek( pF, 0, SEEK_END ); + unsigned long long int uiFileSize = ftell( pF ); + fclose( pF ); + + int count = 0, module, frame_bytes, match; + for( unsigned int i = 0; i < stdResList.size(); i++ ) + { + frame_bytes = + CalypFrame::getBytesPerFrame( stdResList[i].uiWidth, stdResList[i].uiHeight, rInputFormat, 8 ); + module = uiFileSize % frame_bytes; + if( module == 0 ) + { + match = i; + count++; + } + } + if( count == 1 ) + { + rWidth = stdResList[match].uiWidth; + rHeight = stdResList[match].uiHeight; + bGuessedByFilesize = true; + } + } + } + + // [.|_] + // Guess bits per pixel - match %dbpp + QRegularExpressionMatch BppMatch = QRegularExpression( "_[0-9]+bpp" ).match( FilenameShort ); + if( BppMatch.hasMatch() ) + { + QString matchString = BppMatch.captured( BppMatch.lastCapturedIndex() ); + matchString.remove( "_" ); + matchString.remove( "bpp" ); + rBitsPerPixel = matchString.toUInt(); + if( !( rBitsPerPixel > 0 && rBitsPerPixel < 16 ) ) + { + rBitsPerPixel = -1; + } + } + QRegularExpressionMatch BppOnlybMatch = QRegularExpression( "_[0-9]+b" ).match( FilenameShort ); + if( BppOnlybMatch.hasMatch() ) + { + QString matchString = BppOnlybMatch.captured( BppOnlybMatch.lastCapturedIndex() ); + matchString.remove( "_" ); + matchString.remove( "b" ); + rBitsPerPixel = matchString.toUInt(); + if( !( rBitsPerPixel > 0 && rBitsPerPixel < 16 ) ) + { + rBitsPerPixel = -1; + } + } + + // Guess frame rate - match %dbpp + QRegularExpressionMatch FpsMatch = QRegularExpression( "_[0-9]+fps" ).match( FilenameShort ); + if( FpsMatch.hasMatch() ) + { + QString matchString = FpsMatch.captured( FpsMatch.lastCapturedIndex() ); + matchString.remove( "_" ); + matchString.remove( "fps" ); + rFrameRate = matchString.toUInt(); + if( rFrameRate < 0 ) + { + rFrameRate = 30; + } + } + + // Guess Endianness + if( FilenameShort.contains( QStringLiteral( "be" ), Qt::CaseInsensitive ) ) + { + rEndianness = CLP_BIG_ENDIAN; + } + if( FilenameShort.contains( QStringLiteral( "le" ), Qt::CaseInsensitive ) ) + { + rEndianness = CLP_LITTLE_ENDIAN; + } + + if( rWidth > 0 && rHeight > 0 && rInputFormat >= 0 ) + bGuessed = true && !bGuessedByFilesize; + } + return !bGuessed; +} + +void VideoStreamSubWindow::refreshSubWindow() +{ +#ifdef CALYP_MANAGED_RESOURCES + m_pcResourceManager->stopResourceWorker( m_uiResourceId ); +#endif + if( !m_pCurrStream->reload() ) + { + close(); + return; + } +#ifdef CALYP_MANAGED_RESOURCES + m_pcResourceManager->startResourceWorker( m_uiResourceId ); +#endif + + updateVideoWindowInfo(); + refreshFrame(); +} + +void VideoStreamSubWindow::refreshFrame() +{ + bool bSetFrame = true; + m_pcCurrFrameAsset = m_pCurrStream->getCurrFrameAsset(); + + if( m_pcDisplayModule ) + { + //bool disableThreads = !m_bIsPlaying && hasAssociatedModule(); + m_pcDisplayModule->apply( m_bIsPlaying, true ); + bSetFrame = false; + } + if( bSetFrame ) + VideoSubWindow::refreshFrame(); +} + +void VideoStreamSubWindow::refreshFrame( bool bThreaded ) +{ +#ifndef QT_NO_CONCURRENT + m_cRefreshResult.waitForFinished(); + if( bThreaded ) + { + m_cRefreshResult = QtConcurrent::run( this, &VideoSubWindow::refreshFrame ); + } + else +#endif + { + refreshFrame(); + } +} + +bool VideoStreamSubWindow::goToNextFrame( bool bThreaded ) +{ +#ifndef QT_NO_CONCURRENT + m_cRefreshResult.waitForFinished(); + m_cReadResult.waitForFinished(); +#endif +#ifdef CALYP_MANAGED_RESOURCES + while( !m_pCurrStream->hasNextFrame() && !m_pCurrStream->isEof() ) + { + } +#endif + bool bEndOfSeq = m_pCurrStream->setNextFrame(); +#ifdef CALYP_MANAGED_RESOURCES + bThreaded = false; + m_pcResourceManager->wakeResourceWorker( m_uiResourceId ); +#endif + if( !bEndOfSeq ) + { +#ifndef QT_NO_CONCURRENT + m_cRefreshResult.waitForFinished(); + if( bThreaded ) + { + m_cReadResult = QtConcurrent::run( m_pCurrStream, &CalypStream::readNextFrameFillRGBBuffer ); + refreshFrame( bThreaded ); + } + else +#endif + { + refreshFrame( bThreaded ); +#ifndef CALYP_MANAGED_RESOURCES + m_pCurrStream->readNextFrameFillRGBBuffer(); +#endif + } + } + return bEndOfSeq; +} + +bool VideoStreamSubWindow::saveStream( QString filename ) +{ + bool iRet = false; + QApplication::setOverrideCursor( Qt::WaitCursor ); + + // TODO: implement this + QApplication::restoreOverrideCursor(); + return iRet; +} + +bool VideoStreamSubWindow::isPlaying() +{ + return m_bIsPlaying; +} + +bool VideoStreamSubWindow::play() +{ + bool isPlaying = false; + if( m_pCurrStream && m_pCurrStream->getFrameNum() > 1 ) + { + isPlaying = true; + } + m_bIsPlaying = isPlaying; + return m_bIsPlaying; +} + +bool VideoStreamSubWindow::playEvent() +{ + bool bEndOfSeq = false; + if( m_pCurrStream && m_bIsPlaying ) + { + bEndOfSeq = goToNextFrame( true ); + } + return bEndOfSeq; +} + +void VideoStreamSubWindow::pause() +{ + m_bIsPlaying = false; + refreshFrame(); +} + +void VideoStreamSubWindow::seekAbsoluteEvent( unsigned int new_frame_num ) +{ + if( m_pCurrStream ) + { + if( m_pCurrStream->seekInput( new_frame_num ) ) + refreshFrame(); + +#ifdef CALYP_MANAGED_RESOURCES + m_pcResourceManager->wakeResourceWorker( m_uiResourceId ); +#endif + } +} + +void VideoStreamSubWindow::seekRelativeEvent( bool bIsFoward ) +{ + if( m_pCurrStream ) + { + if( bIsFoward ) + { + goToNextFrame( true ); + } + else + { + m_pCurrStream->seekInputRelative( bIsFoward ); +#ifdef CALYP_MANAGED_RESOURCES + m_pcResourceManager->wakeResourceWorker( m_uiResourceId ); +#endif + refreshFrame(); + } + } +} + +void VideoStreamSubWindow::stop() +{ +#ifndef QT_NO_CONCURRENT + m_cRefreshResult.waitForFinished(); + m_cReadResult.waitForFinished(); +#endif + m_bIsPlaying = false; + seekAbsoluteEvent( 0 ); + return; +} diff --git a/app/VideoStreamSubWindow.h b/app/VideoStreamSubWindow.h new file mode 100644 index 0000000..f54173b --- /dev/null +++ b/app/VideoStreamSubWindow.h @@ -0,0 +1,132 @@ +/* This file is a part of Calyp project + * Copyright (C) 2014-2021 by Joao Carreira (jfmcarreira@gmail.com) + * Luis Lucas (luisfrlucas@gmail.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * \file VideoStreamSubWindow.h + * \brief Video Sub windows handling + */ + +#ifndef __VIDEOSTREAMSUBWINDOW_H__ +#define __VIDEOSTREAMSUBWINDOW_H__ + +#include +#include +#include +#include +#include +#include + +#include "CommonDefs.h" +#include "VideoSubWindow.h" +#include "config.h" +#include "lib/CalypStream.h" + +class QScrollArea; + +class VideoInformation; +class VideoStreamSubWindow; +class ResourceHandle; +class CalypAppModuleIf; + +typedef struct +{ + QString m_cFilename; + unsigned int m_uiWidth; + unsigned int m_uiHeight; + int m_iPelFormat; + unsigned int m_uiBitsPelPixel; + unsigned int m_iEndianness; + unsigned int m_uiFrameRate; + unsigned long long int m_uiFileSize; +} CalypFileInfo; +typedef QVector CalypFileInfoVector; + +QDataStream& operator<<( QDataStream& out, const CalypFileInfoVector& d ); +QDataStream& operator>>( QDataStream& in, CalypFileInfoVector& d ); +int findCalypStreamInfo( CalypFileInfoVector array, QString filename ); + +class VideoStreamSubWindow : public VideoSubWindow +{ + Q_OBJECT + +public: + VideoStreamSubWindow( QWidget* parent = 0 ); + ~VideoStreamSubWindow(); + + void resetWindowName() override; + void updateVideoWindowInfo() override; + + bool isPlaying() override; + void stop() override; + void advanceOneFrame() override { goToNextFrame( true ); } + auto getFrameNum() -> std::uint64_t override { return m_pCurrStream->getFrameNum(); } + + void setResourceManaget( ResourceHandle* resourceManager ) { m_pcResourceManager = resourceManager; } + + bool loadFile( QString cFilename, bool bForceDialog = false ); + bool loadFile( CalypFileInfo* streamInfo ); + void loadAll(); + bool saveStream( QString filename ); + + bool play(); + void pause(); + bool playEvent(); + void seekAbsoluteEvent( unsigned int new_frame_num ); + void seekRelativeEvent( bool bIsFoward ); + + CalypFileInfo getStreamInfo() { return m_sStreamInfo; } + + const CalypStream* getInputStream() { return m_pCurrStream; } + const CalypStream* getCurrStream() { return m_pCurrStream; } + + QString getCurrentFileName() { return m_cFilename; } + + void refreshSubWindow() override; + void refreshFrame(); + void refreshFrame( bool bThreaded ); + +private: + bool goToNextFrame( bool bThreaded ); + + static bool guessFormat( QString filename, unsigned int& rWidth, unsigned int& rHeight, int& rInputFormat, unsigned int& rBitsPerPixel, + int& rEndianness, unsigned int& rFrameRate ); + +private: // NO_LINT + ResourceHandle* m_pcResourceManager; + + QString m_cFilename; + CalypFileInfo m_sStreamInfo; + std::size_t m_uiResourceId; + CalypStream* m_pCurrStream; + QString m_cCurrFileName; + + bool m_bIsPlaying; + + /** + * Threads variables + * QtConcurrent + */ + QFuture m_cRefreshResult; + QFuture m_cReadResult; +}; + +Q_DECLARE_METATYPE( CalypFileInfo ) // NOLINT +Q_DECLARE_METATYPE( CalypFileInfoVector ) // NOLINT + +#endif // __VIDEOSTREAMSUBWINDOW_H__ diff --git a/app/VideoSubWindow.cpp b/app/VideoSubWindow.cpp index ef2072d..d182435 100644 --- a/app/VideoSubWindow.cpp +++ b/app/VideoSubWindow.cpp @@ -31,127 +31,59 @@ #include "ConfigureFormatDialog.h" #include "ModulesHandle.h" -#include "QtConcurrent/qtconcurrentrun.h" -#include "ResourceHandle.h" #include "SubWindowAbstract.h" -#define QT_NO_CONCURRENT - -/** - * \brief Functions to control data stream from stream information - */ - -QDataStream& operator<<( QDataStream& out, const CalypFileInfoVector& array ) +VideoInformation::VideoInformation( QWidget* parent ) + : QWidget( parent ), m_bBusyWindow( false ) { - CalypFileInfo d; - out << array.size(); - for( int i = 0; i < array.size(); i++ ) - { - d = array.at( i ); - out << d.m_cFilename << d.m_uiWidth << d.m_uiHeight << d.m_iPelFormat << d.m_uiBitsPelPixel << d.m_iEndianness - << d.m_uiFrameRate << d.m_uiFileSize; - } - return out; + setPalette( Qt::transparent ); + setAttribute( Qt::WA_TransparentForMouseEvents ); + m_cTopLeftTextFont.setPointSize( 8 ); + m_cCenterTextFont.setPointSize( 12 ); + m_pcRefreshTimer = new QTimer; + m_pcRefreshTimer->setSingleShot( true ); } -QDataStream& operator>>( QDataStream& in, CalypFileInfoVector& array ) +void VideoInformation::setInformationTopLeft( const QStringList& textLines ) { - CalypFileInfo d; - int array_size{ 0 }; - in >> array_size; - for( int i = 0; i < array_size; i++ ) + m_cTopLeftTextList.clear(); + for( int i = 0; i < textLines.size(); i++ ) { - in >> d.m_cFilename; - in >> d.m_uiWidth; - in >> d.m_uiHeight; - in >> d.m_iPelFormat; - in >> d.m_uiBitsPelPixel; - in >> d.m_iEndianness; - in >> d.m_uiFrameRate; - in >> d.m_uiFileSize; - array.append( d ); + m_cTopLeftTextList.append( QStaticText( textLines.at( i ) ) ); } - return in; } -int findCalypStreamInfo( CalypFileInfoVector array, QString filename ) +void VideoInformation::setBusyWindow( bool bFlag ) { - for( int i = 0; i < array.size(); i++ ) - if( array.at( i ).m_cFilename == filename ) - return i; - return -1; + m_bBusyWindow = bFlag; + // Do not show the refresh screen if it takes less than 500 ms + m_pcRefreshTimer->start( 500 ); } -/** - * \class VideoInformation - * \brief Shows information about video sub window - */ - -class VideoInformation : public QWidget +void VideoInformation::paintEvent( QPaintEvent* event ) { -private: - QTimer* m_pcRefreshTimer; - QList m_cTopLeftTextList; - QFont m_cTopLeftTextFont; - QFont m_cCenterTextFont; - bool m_bBusyWindow; - -public: - VideoInformation( QWidget* parent ) - : QWidget( parent ), m_bBusyWindow( false ) + QPainter painter( this ); + painter.setFont( m_cTopLeftTextFont ); + if( !m_cTopLeftTextList.isEmpty() && size().width() > 300 ) { - setPalette( Qt::transparent ); - setAttribute( Qt::WA_TransparentForMouseEvents ); - m_cTopLeftTextFont.setPointSize( 8 ); - m_cCenterTextFont.setPointSize( 12 ); - m_pcRefreshTimer = new QTimer; - m_pcRefreshTimer->setSingleShot( true ); - } - void setInformationTopLeft( const QStringList& textLines ) - { - m_cTopLeftTextList.clear(); - for( int i = 0; i < textLines.size(); i++ ) + QPoint topLeftCorner( 10, 10 ); + for( int i = 0; i < m_cTopLeftTextList.size(); i++ ) { - m_cTopLeftTextList.append( QStaticText( textLines.at( i ) ) ); + painter.drawStaticText( topLeftCorner, m_cTopLeftTextList.at( i ) ); + topLeftCorner += QPoint( 0, 15 ); } } - void setBusyWindow( bool bFlag ) + if( m_bBusyWindow && !m_pcRefreshTimer->isActive() ) { - m_bBusyWindow = bFlag; - // Do not show the refresh screen if it takes less than 500 ms - m_pcRefreshTimer->start( 500 ); + painter.setFont( m_cCenterTextFont ); + painter.drawText( rect(), Qt::AlignHCenter | Qt::AlignVCenter, QStringLiteral( "Refreshing..." ) ); + painter.fillRect( rect(), QBrush( QColor::fromRgb( 255, 255, 255, 50 ), Qt::SolidPattern ) ); } - -protected: - void paintEvent( QPaintEvent* event ) - { - QPainter painter( this ); - painter.setFont( m_cTopLeftTextFont ); - if( !m_cTopLeftTextList.isEmpty() && size().width() > 300 ) - { - QPoint topLeftCorner( 10, 10 ); - for( int i = 0; i < m_cTopLeftTextList.size(); i++ ) - { - painter.drawStaticText( topLeftCorner, m_cTopLeftTextList.at( i ) ); - topLeftCorner += QPoint( 0, 15 ); - } - } - if( m_bBusyWindow && !m_pcRefreshTimer->isActive() ) - { - painter.setFont( m_cCenterTextFont ); - painter.drawText( rect(), Qt::AlignHCenter | Qt::AlignVCenter, QStringLiteral( "Refreshing..." ) ); - painter.fillRect( rect(), QBrush( QColor::fromRgb( 255, 255, 255, 50 ), Qt::SolidPattern ) ); - } - } -}; +} VideoSubWindow::VideoSubWindow( enum VideoSubWindowCategories category, QWidget* parent ) : SubWindowAbstract( parent, SubWindowAbstract::VIDEO_SUBWINDOW | category ) - , m_pcResourceManager( nullptr ) - , m_bWindowBusy( false ) - , m_pCurrStream( NULL ) , m_pcReferenceSubWindow( NULL ) - , m_bIsPlaying( false ) , m_pcUpdateTimer( NULL ) { // Create a new scroll area inside the sub-window @@ -194,17 +126,16 @@ VideoSubWindow::VideoSubWindow( enum VideoSubWindowCategories category, QWidget* m_pcVideoInfo = new VideoInformation( this ); } -VideoSubWindow::VideoSubWindow( enum VideoSubWindowCategories category, CalypAppModuleIf* displayModule, QWidget* parent ) - : VideoSubWindow( category, parent ) -{ - m_pcCurrentDisplayModule = displayModule; -} - VideoSubWindow::~VideoSubWindow() { + auto tmpModules = m_associatedModules; + m_associatedModules.clear(); + for( auto module : tmpModules ) + { + module->disable(); + } + m_pcCurrFrameAsset = nullptr; - if( m_pcResourceManager ) - m_pcResourceManager->removeResource( m_uiResourceId ); delete m_pcUpdateTimer; } @@ -214,16 +145,9 @@ VideoSubWindow::~VideoSubWindow() void VideoSubWindow::closeEvent( QCloseEvent* event ) { - //stop(); - auto tmpModules = m_associatedModules; - m_associatedModules.clear(); - for( auto module : tmpModules ) + if( m_pcDisplayModule ) { - module->disable(); - } - if( m_pcCurrentDisplayModule ) - { - m_pcCurrentDisplayModule->disable(); + m_pcDisplayModule->disable(); event->ignore(); return; } @@ -232,24 +156,24 @@ void VideoSubWindow::closeEvent( QCloseEvent* event ) void VideoSubWindow::keyPressEvent( QKeyEvent* event ) { - if( m_pcCurrentDisplayModule ) + if( m_pcDisplayModule ) { - if( m_pcCurrentDisplayModule->getModuleRequirements() & CLP_MODULE_USES_KEYS ) + if( m_pcDisplayModule->getModuleRequirements() & CLP_MODULE_USES_KEYS ) { bool bRet = false; switch( event->key() ) { case Qt::Key_A: - bRet = m_pcCurrentDisplayModule->getModule()->keyPressed( MODULE_KEY_LEFT ); + bRet = m_pcDisplayModule->getModule()->keyPressed( MODULE_KEY_LEFT ); break; case Qt::Key_D: - bRet = m_pcCurrentDisplayModule->getModule()->keyPressed( MODULE_KEY_RIGHT ); + bRet = m_pcDisplayModule->getModule()->keyPressed( MODULE_KEY_RIGHT ); break; case Qt::Key_W: - bRet = m_pcCurrentDisplayModule->getModule()->keyPressed( MODULE_KEY_UP ); + bRet = m_pcDisplayModule->getModule()->keyPressed( MODULE_KEY_UP ); break; case Qt::Key_S: - bRet = m_pcCurrentDisplayModule->getModule()->keyPressed( MODULE_KEY_DOWN ); + bRet = m_pcDisplayModule->getModule()->keyPressed( MODULE_KEY_DOWN ); break; } if( bRet ) @@ -271,36 +195,18 @@ void VideoSubWindow::resizeEvent( QResizeEvent* event ) /** * Size related handlers */ - -QSize VideoSubWindow::sizeHint() const -{ - QSize maxSize; - - QWidget* p = parentWidget(); - if( p ) - { - maxSize = p->size(); - } - else - { - maxSize = QGuiApplication::screens()[0]->availableGeometry().size(); - } - return sizeHint( maxSize ); -} - QSize VideoSubWindow::sizeHint( const QSize& maxSize ) const { QSize isize; if( m_pcCurrFrameAsset ) - isize = QSize( m_pcCurrFrameAsset->getWidth() + 50, m_pcCurrFrameAsset->getHeight() + 50 ); - else if( m_pCurrStream ) - isize = QSize( m_pCurrStream->getWidth() + 50, m_pCurrStream->getHeight() + 50 ); - - // If the VideoSubWindow needs more space that the avaiable, we'll give - // to the subwindow a reasonable size preserving the image aspect ratio. - if( !( isize.width() < maxSize.width() && isize.height() < maxSize.height() ) ) { - isize.scale( maxSize, Qt::KeepAspectRatio ); + isize = QSize( m_pcCurrFrameAsset->getWidth() + 50, m_pcCurrFrameAsset->getHeight() + 50 ); + // If the VideoSubWindow needs more space that the avaiable, we'll give + // to the subwindow a reasonable size preserving the image aspect ratio. + if( !( isize.width() < maxSize.width() && isize.height() < maxSize.height() ) ) + { + isize.scale( maxSize, Qt::KeepAspectRatio ); + } } return isize; } @@ -310,348 +216,6 @@ void VideoSubWindow::updateWindowOnTimeout() m_pcVideoInfo->update(); } -void VideoSubWindow::loadAll() -{ - QApplication::setOverrideCursor( Qt::WaitCursor ); - m_pCurrStream->loadAll(); - refreshFrame(); - QApplication::restoreOverrideCursor(); -} - -void VideoSubWindow::refreshSubWindow() -{ - if( getCategory() & SubWindowAbstract::VIDEO_STREAM_SUBWINDOW ) - { -#ifdef CALYP_MANAGED_RESOURCES - m_pcResourceManager->stopResourceWorker( m_uiResourceId ); -#endif - if( !m_pCurrStream->reload() ) - { - close(); - return; - } -#ifdef CALYP_MANAGED_RESOURCES - m_pcResourceManager->startResourceWorker( m_uiResourceId ); -#endif - } - updateVideoWindowInfo(); - refreshFrame(); -} - -bool VideoSubWindow::loadFile( QString cFilename, bool bForceDialog ) -{ - assert( m_pcResourceManager != nullptr ); - - ConfigureFormatDialog formatDialog( this ); - unsigned int Width = 0, Height = 0, BitsPel = 8, FrameRate = 30; - int Endianness = CLP_LITTLE_ENDIAN; - int InputFormat = CLP_YUV420P; - QSettings appSettings; - - if( m_pCurrStream ) - m_pCurrStream->getFormat( Width, Height, InputFormat, BitsPel, Endianness, FrameRate ); - else - m_uiResourceId = m_pcResourceManager->getResource( nullptr ); - - m_pCurrStream = m_pcResourceManager->getResourceAsset( m_uiResourceId ); - - bool bConfig = true; - if( !bForceDialog ) - { - bConfig = guessFormat( cFilename, Width, Height, InputFormat, BitsPel, Endianness, FrameRate ); - if( bConfig ) - { - // Pre-load values with last opened file - Width = appSettings.value( "VideoSubWindow/LastWidth" ).value(); - Height = appSettings.value( "VideoSubWindow/LastHeight" ).value(); - BitsPel = appSettings.value( "VideoSubWindow/LastBitsPerPixel" ).value(); - } - } - bool bRet = false; - for( int iPass = 0; iPass < 2 && !bRet; iPass++ ) - { - if( iPass || bConfig ) - { - if( formatDialog.runConfigureFormatDialog( QFileInfo( cFilename ).fileName(), Width, Height, InputFormat, BitsPel, - Endianness, FrameRate ) == QDialog::Rejected ) - { - return false; - } - } - try - { - bRet = m_pCurrStream->open( cFilename.toStdString(), Width, Height, InputFormat, BitsPel, Endianness, FrameRate, true ); - } - catch( CalypFailure& e ) - { - if( iPass == 1 ) - throw( e ); - } - } - - m_sStreamInfo.m_cFilename = cFilename; - m_sStreamInfo.m_uiWidth = Width; - m_sStreamInfo.m_uiHeight = Height; - m_sStreamInfo.m_iPelFormat = InputFormat; - m_sStreamInfo.m_uiBitsPelPixel = BitsPel; - m_sStreamInfo.m_iEndianness = Endianness; - m_sStreamInfo.m_uiFrameRate = FrameRate; - m_sStreamInfo.m_uiFileSize = QFileInfo( cFilename ).size(); - - QVariant var; - var.setValue( Width ); - appSettings.setValue( "VideoSubWindow/LastWidth", var ); - var.setValue( Height ); - appSettings.setValue( "VideoSubWindow/LastHeight", var ); - var.setValue( BitsPel ); - appSettings.setValue( "VideoSubWindow/LastBitsPerPixel", var ); - -#ifdef CALYP_MANAGED_RESOURCES - m_pcResourceManager->startResourceWorker( m_uiResourceId ); -#endif - - QApplication::restoreOverrideCursor(); - - refreshFrame(); - - m_cFilename = cFilename; - - updateVideoWindowInfo(); - setWindowName( QFileInfo( m_cFilename ).fileName() ); - - return true; -} - -bool VideoSubWindow::loadFile( CalypFileInfo* streamInfo ) -{ - assert( m_pcResourceManager != nullptr ); - - m_uiResourceId = m_pcResourceManager->getResource( m_pCurrStream ); - m_pCurrStream = m_pcResourceManager->getResourceAsset( m_uiResourceId ); - - if( !m_pCurrStream->open( streamInfo->m_cFilename.toStdString(), streamInfo->m_uiWidth, streamInfo->m_uiHeight, - streamInfo->m_iPelFormat, streamInfo->m_uiBitsPelPixel, streamInfo->m_iEndianness, - streamInfo->m_uiFrameRate, true ) ) - { - return false; - } - - m_sStreamInfo = *streamInfo; - -#ifdef CALYP_MANAGED_RESOURCES - m_pcResourceManager->startResourceWorker( m_uiResourceId ); -#endif - - QApplication::restoreOverrideCursor(); - - refreshFrame(); - - m_cFilename = streamInfo->m_cFilename; - updateVideoWindowInfo(); - setWindowName( QFileInfo( m_cFilename ).fileName() ); - return true; -} - -void VideoSubWindow::updateVideoWindowInfo() -{ - m_cStreamInformation = ""; - if( m_pcCurrentDisplayModule ) - { - m_cStreamInformation = "Module"; - const auto& arraySubWindows = m_pcCurrentDisplayModule->getSubWindowList(); - QStringList windowInfoList; - if( arraySubWindows.size() > 0 ) - { - for( std::size_t i = 0; i < arraySubWindows.size(); i++ ) - { - if( arraySubWindows[i]->getWindowName() != getWindowName() ) - { - windowInfoList.append( QString( "Input %1 - " + arraySubWindows[i]->getWindowName() ).arg( i + 1 ) ); - } - } - } - if( m_pcCurrentDisplayModule->getModuleRequirements() & CLP_MODULES_HAS_INFO ) - { - QStringList list = QString::fromStdString( m_pcCurrentDisplayModule->moduleInfo() ).split( '\n' ); - windowInfoList.append( list ); - } - if( windowInfoList.size() > 0 ) - { - m_pcVideoInfo->setInformationTopLeft( windowInfoList ); - } - } - else if( m_pCurrStream ) - { - QString m_cFormatName = QString::fromStdString( m_pCurrStream->getFormatName() ); - QString m_cCodedName = QString::fromStdString( m_pCurrStream->getCodecName() ); - m_cStreamInformation = m_cFormatName + " | " + m_cCodedName; - } - if( m_pcCurrFrameAsset ) - { - QString m_cPelFmtName = QString::fromStdString( m_pcCurrFrameAsset->getPelFmtName() ); - if( m_pCurrStream ) - if( !m_pCurrStream->isNative() ) - m_cPelFmtName += "*"; - m_cStreamInformation += " | " + m_cPelFmtName; - } - if( m_cStreamInformation.isEmpty() ) - { - m_cStreamInformation = " "; - } -} - -bool VideoSubWindow::guessFormat( QString filename, unsigned int& rWidth, unsigned int& rHeight, int& rInputFormat, unsigned int& rBitsPerPixel, - int& rEndianness, unsigned int& rFrameRate ) -{ - std::vector stdResList = CalypStream::stdResolutionSizes(); - bool bGuessed = true; - bool bGuessedByFilesize = false; - QString FilenameShort = QFileInfo( filename ).fileName(); - QString fileExtension = QFileInfo( filename ).suffix(); - - if( filename.startsWith( "/dev/" ) ) - { - return false; - } - if( !fileExtension.compare( "yuv", Qt::CaseInsensitive ) || !fileExtension.compare( "rgb", Qt::CaseInsensitive ) || - !fileExtension.compare( "gray", Qt::CaseInsensitive ) ) - { - bGuessed = false; - // Guess pixel format - auto formats_list = CalypFrame::supportedPixelFormatListNames(); - for( std::size_t i = 0; i < formats_list.size(); i++ ) - { - if( FilenameShort.contains( formats_list[i].c_str(), Qt::CaseInsensitive ) ) - { - rInputFormat = i; - break; - } - } - - if( rWidth == 0 || rHeight == 0 ) - { - // Guess resolution - match resolution name - int iMatch = -1; - for( unsigned int i = 0; i < stdResList.size(); i++ ) - { - if( FilenameShort.contains( QString::fromStdString( stdResList[i].shortName ) ) ) - { - iMatch = i; - } - } - if( iMatch >= 0 ) - { - rWidth = stdResList[iMatch].uiWidth; - rHeight = stdResList[iMatch].uiHeight; - } - - // Guess resolution - match %dx%d - //QRegularExpressionMatch resolutionMatch = QRegularExpression( "_\\d*x\\d*" ).match( FilenameShort ); - QRegularExpressionMatch resolutionMatch = QRegularExpression( "_[0-9]+x[0-9]+" ).match( FilenameShort ); - if( resolutionMatch.hasMatch() ) - { - QString resolutionString = resolutionMatch.captured( resolutionMatch.lastCapturedIndex() ); - if( resolutionString.startsWith( "_" ) || resolutionString.endsWith( "_" ) ) - { - resolutionString.remove( "_" ); - QStringList resolutionArgs = resolutionString.split( "x" ); - if( resolutionArgs.size() == 2 ) - { - rWidth = resolutionArgs.at( 0 ).toUInt(); - rHeight = resolutionArgs.at( 1 ).toUInt(); - } - } - } - } - - // Guess resolution by file size - if( rWidth == 0 && rHeight == 0 ) - { - FILE* pF = fopen( filename.toStdString().c_str(), "rb" ); - if( pF ) - { - fseek( pF, 0, SEEK_END ); - unsigned long long int uiFileSize = ftell( pF ); - fclose( pF ); - - int count = 0, module, frame_bytes, match; - for( unsigned int i = 0; i < stdResList.size(); i++ ) - { - frame_bytes = - CalypFrame::getBytesPerFrame( stdResList[i].uiWidth, stdResList[i].uiHeight, rInputFormat, 8 ); - module = uiFileSize % frame_bytes; - if( module == 0 ) - { - match = i; - count++; - } - } - if( count == 1 ) - { - rWidth = stdResList[match].uiWidth; - rHeight = stdResList[match].uiHeight; - bGuessedByFilesize = true; - } - } - } - - // [.|_] - // Guess bits per pixel - match %dbpp - QRegularExpressionMatch BppMatch = QRegularExpression( "_[0-9]+bpp" ).match( FilenameShort ); - if( BppMatch.hasMatch() ) - { - QString matchString = BppMatch.captured( BppMatch.lastCapturedIndex() ); - matchString.remove( "_" ); - matchString.remove( "bpp" ); - rBitsPerPixel = matchString.toUInt(); - if( !( rBitsPerPixel > 0 && rBitsPerPixel < 16 ) ) - { - rBitsPerPixel = -1; - } - } - QRegularExpressionMatch BppOnlybMatch = QRegularExpression( "_[0-9]+b" ).match( FilenameShort ); - if( BppOnlybMatch.hasMatch() ) - { - QString matchString = BppOnlybMatch.captured( BppOnlybMatch.lastCapturedIndex() ); - matchString.remove( "_" ); - matchString.remove( "b" ); - rBitsPerPixel = matchString.toUInt(); - if( !( rBitsPerPixel > 0 && rBitsPerPixel < 16 ) ) - { - rBitsPerPixel = -1; - } - } - - // Guess frame rate - match %dbpp - QRegularExpressionMatch FpsMatch = QRegularExpression( "_[0-9]+fps" ).match( FilenameShort ); - if( FpsMatch.hasMatch() ) - { - QString matchString = FpsMatch.captured( FpsMatch.lastCapturedIndex() ); - matchString.remove( "_" ); - matchString.remove( "fps" ); - rFrameRate = matchString.toUInt(); - if( rFrameRate < 0 ) - { - rFrameRate = 30; - } - } - - // Guess Endianness - if( FilenameShort.contains( QStringLiteral( "be" ), Qt::CaseInsensitive ) ) - { - rEndianness = CLP_BIG_ENDIAN; - } - if( FilenameShort.contains( QStringLiteral( "le" ), Qt::CaseInsensitive ) ) - { - rEndianness = CLP_LITTLE_ENDIAN; - } - - if( rWidth > 0 && rHeight > 0 && rInputFormat >= 0 ) - bGuessed = true && !bGuessedByFilesize; - } - return !bGuessed; -} - void VideoSubWindow::updateSelectedArea( QRect area ) { m_cSelectedArea = area; @@ -669,24 +233,24 @@ void VideoSubWindow::updateSelectedArea( QRect area ) // { // m_associatedModules.erase( it ); // } -// m_pcCurrentDisplayModule = std::move( pcModule ); +// m_pcDisplayModule = std::move( pcModule ); // updateVideoWindowInfo(); // } bool VideoSubWindow::hasAssociatedModule() { - if( m_pcCurrentDisplayModule == nullptr ) + if( m_pcDisplayModule == nullptr ) return !m_associatedModules.empty(); return m_associatedModules.size() > 1; } void VideoSubWindow::setDisplayModule( CalypAppModuleIf* pcModule ) { - if( m_pcCurrentDisplayModule != nullptr ) + if( m_pcDisplayModule != nullptr ) { - m_pcCurrentDisplayModule->disable(); + m_pcDisplayModule->disable(); } - m_pcCurrentDisplayModule = pcModule; + m_pcDisplayModule = pcModule; updateVideoWindowInfo(); } @@ -712,15 +276,15 @@ void VideoSubWindow::disableModule( CalypAppModuleIf* pcModule ) { m_associatedModules.erase( it ); } - if( pcModule == m_pcCurrentDisplayModule ) + if( pcModule == m_pcDisplayModule ) { bRefresh |= true; - m_pcCurrentDisplayModule = nullptr; - setWindowName( QFileInfo( m_cFilename ).fileName() ); + m_pcDisplayModule = nullptr; + resetWindowName(); } if( bRefresh ) { - refreshFrame(); + refreshSubWindow(); updateVideoWindowInfo(); } // if( pcModule ) @@ -732,10 +296,10 @@ void VideoSubWindow::disableModule( CalypAppModuleIf* pcModule ) // ModulesHandle::destroyModuleIf( pcModule ); // bRefresh |= true; // } - // if( pcModule == m_pcCurrentDisplayModule ) + // if( pcModule == m_pcDisplayModule ) // { - // pcModule = m_pcCurrentDisplayModule; - // m_pcCurrentDisplayModule = 0; + // pcModule = m_pcDisplayModule; + // m_pcDisplayModule = 0; // ModulesHandle::destroyModuleIf( pcModule ); // setWindowName( QFileInfo( m_cFilename ).fileName() ); // bRefresh |= true; @@ -751,10 +315,10 @@ void VideoSubWindow::disableModule( CalypAppModuleIf* pcModule ) // bRefresh |= true; // } // assert( m_apcCurrentModule.size() == 0 ); - // if( m_pcCurrentDisplayModule ) + // if( m_pcDisplayModule ) // { - // pcModule = m_pcCurrentDisplayModule; - // m_pcCurrentDisplayModule = NULL; + // pcModule = m_pcDisplayModule; + // m_pcDisplayModule = NULL; // ModulesHandle::destroyModuleIf( pcModule ); // setWindowName( QFileInfo( m_cFilename ).fileName() ); // bRefresh |= true; @@ -791,114 +355,34 @@ void VideoSubWindow::setFillWindow( bool bFlag ) m_pcVideoInfo->setBusyWindow( bFlag ); } -std::shared_ptr VideoSubWindow::getCurrFrameAsset() -{ - if( m_pcCurrFrameAsset == nullptr && m_pCurrStream != nullptr ) - { - m_pcCurrFrameAsset = m_pCurrStream->getCurrFrameAsset(); - } - return m_pcCurrFrameAsset; -}; - void VideoSubWindow::setCurrFrame( std::shared_ptr pcCurrFrame ) { m_pcCurrFrameAsset = std::move( pcCurrFrame ); + refreshFrame(); +} + +void VideoSubWindow::refreshFrame() +{ m_cViewArea->setImage( m_pcCurrFrameAsset ); for( auto& module : m_associatedModules ) { - if( module.get() != m_pcCurrentDisplayModule ) - module->update( m_bIsPlaying ); + if( module.get() != m_pcDisplayModule ) + module->update( isPlaying() ); } } -void VideoSubWindow::refreshFrameOperation() -{ - bool bSetFrame = false; - if( m_pCurrStream ) - { - m_pcCurrFrameAsset = m_pCurrStream->getCurrFrameAsset(); - bSetFrame |= true; - } - - if( m_pcCurrentDisplayModule ) - { - m_bWindowBusy = true; - bool disableThreads = !m_bIsPlaying && hasAssociatedModule(); - m_pcCurrentDisplayModule->apply( m_bIsPlaying, disableThreads ); - bSetFrame = false; - } - if( bSetFrame ) - { - m_cViewArea->setImage( m_pcCurrFrameAsset ); - for( auto& module : m_associatedModules ) - { - if( module.get() != m_pcCurrentDisplayModule ) - module->update( m_bIsPlaying ); - } - } -} - -void VideoSubWindow::refreshFrame( bool bThreaded ) -{ -#ifndef QT_NO_CONCURRENT - m_cRefreshResult.waitForFinished(); - if( bThreaded ) - { - m_cRefreshResult = QtConcurrent::run( this, &VideoSubWindow::refreshFrameOperation ); - } - else -#endif - { - refreshFrameOperation(); - } -} - -bool VideoSubWindow::goToNextFrame( bool bThreaded ) -{ -#ifndef QT_NO_CONCURRENT - m_cRefreshResult.waitForFinished(); - m_cReadResult.waitForFinished(); -#endif -#ifdef CALYP_MANAGED_RESOURCES - while( !m_pCurrStream->hasNextFrame() && !m_pCurrStream->isEof() ) - ; -#endif - bool bEndOfSeq = m_pCurrStream->setNextFrame(); -#ifdef CALYP_MANAGED_RESOURCES - bThreaded = false; - m_pcResourceManager->wakeResourceWorker( m_uiResourceId ); -#endif - if( !bEndOfSeq ) - { -#ifndef QT_NO_CONCURRENT - m_cRefreshResult.waitForFinished(); - if( bThreaded ) - { - m_cReadResult = QtConcurrent::run( m_pCurrStream, &CalypStream::readNextFrameFillRGBBuffer ); - refreshFrame( bThreaded ); - } - else -#endif - { - refreshFrame( bThreaded ); -#ifndef CALYP_MANAGED_RESOURCES - m_pCurrStream->readNextFrameFillRGBBuffer(); -#endif - } - } - return bEndOfSeq; -} - bool VideoSubWindow::save( QString filename ) { bool iRet = false; QApplication::setOverrideCursor( Qt::WaitCursor ); + std::unique_ptr new_frame{ nullptr }; CalypFrame* saveFrame = m_pcCurrFrameAsset.get(); if( m_cSelectedArea.isValid() ) { - saveFrame = new CalypFrame( m_pcCurrFrameAsset.get(), m_cSelectedArea.x(), m_cSelectedArea.y(), m_cSelectedArea.width(), - m_cSelectedArea.height() ); + new_frame = std::make_unique( m_pcCurrFrameAsset.get(), m_cSelectedArea.x(), m_cSelectedArea.y(), m_cSelectedArea.width(), + m_cSelectedArea.height() ); + saveFrame = new_frame.get(); } if( !saveFrame ) { @@ -909,109 +393,6 @@ bool VideoSubWindow::save( QString filename ) return iRet; } -bool VideoSubWindow::saveStream( QString filename ) -{ - bool iRet = false; - QApplication::setOverrideCursor( Qt::WaitCursor ); - - // TODO: implement this - QApplication::restoreOverrideCursor(); - return iRet; -} - -void VideoSubWindow::setPlaying( bool isPlaying ) -{ - m_bIsPlaying = isPlaying; - for( auto module : m_associatedModules ) - { - module->setPlaying( isPlaying ); - } -} - -bool VideoSubWindow::isPlaying() -{ - if( getCategory() & SubWindowCategory::MODULE_SUBWINDOW ) - { - for( auto window : m_pcCurrentDisplayModule->getSubWindowList() ) - { - if( window->isPlaying() ) - return true; - } - return false; - } - return m_bIsPlaying; -} - -bool VideoSubWindow::play() -{ - bool isPlaying = false; - if( m_pCurrStream && m_pCurrStream->getFrameNum() > 1 ) - { - isPlaying = true; - } - setPlaying( isPlaying ); - return m_bIsPlaying; -} - -bool VideoSubWindow::playEvent() -{ - bool bEndOfSeq = false; - if( m_pCurrStream && m_bIsPlaying ) - { - bEndOfSeq = goToNextFrame( true ); - } - return bEndOfSeq; -} - -void VideoSubWindow::pause() -{ - setPlaying( false ); - refreshFrame(); -} - -void VideoSubWindow::seekAbsoluteEvent( unsigned int new_frame_num ) -{ - if( m_pCurrStream ) - { - if( m_pCurrStream->seekInput( new_frame_num ) ) - refreshFrame(); - -#ifdef CALYP_MANAGED_RESOURCES - m_pcResourceManager->wakeResourceWorker( m_uiResourceId ); -#endif - } -} - -void VideoSubWindow::seekRelativeEvent( bool bIsFoward ) -{ - if( m_pCurrStream ) - { - if( bIsFoward ) - { - goToNextFrame( true ); - } - else - { - m_pCurrStream->seekInputRelative( bIsFoward ); -#ifdef CALYP_MANAGED_RESOURCES - m_pcResourceManager->wakeResourceWorker( m_uiResourceId ); -#endif - refreshFrame(); - } - } -} - -void VideoSubWindow::stop() -{ -#ifndef QT_NO_CONCURRENT - m_cRefreshResult.waitForFinished(); - m_cReadResult.waitForFinished(); -#endif - setPlaying( false ); - seekAbsoluteEvent( 0 ); - return; -} - QSize VideoSubWindow::getScrollSize() { return QSize( m_pcScrollArea->viewport()->size().width() - 5, m_pcScrollArea->viewport()->size().height() - 5 ); @@ -1095,14 +476,6 @@ void VideoSubWindow::updateScrollValues() m_dVerScroll = yPos / double( m_pcScrollArea->verticalScrollBar()->maximum() ); } -//void VideoSubWindow::setCurScrollValues() -//{ -// QScrollBar* scrollBar = m_pcScrollArea->horizontalScrollBar(); -// scrollBar->setValue( m_cCurrScroll.x() ); -// scrollBar = m_pcScrollArea->verticalScrollBar(); -// scrollBar->setValue( m_cCurrScroll.y() ); -//} - void VideoSubWindow::normalSize() { double factor = 1.0; @@ -1149,8 +522,8 @@ void VideoSubWindow::scaleView( const QSize& size, QPoint center ) QSize imgViewSize; if( m_pcCurrFrameAsset ) imgViewSize = QSize( m_pcCurrFrameAsset->getWidth(), m_pcCurrFrameAsset->getHeight() ); - else - imgViewSize = QSize( m_pCurrStream->getWidth(), m_pCurrStream->getHeight() ); + //else + // imgViewSize = QSize( m_pCurrStream->getWidth(), m_pCurrStream->getHeight() ); QSize newSize = imgViewSize; newSize.scale( size, Qt::KeepAspectRatio ); diff --git a/app/VideoSubWindow.h b/app/VideoSubWindow.h index e65a3bf..4ae030c 100644 --- a/app/VideoSubWindow.h +++ b/app/VideoSubWindow.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -45,69 +46,32 @@ class VideoSubWindow; class ResourceHandle; class CalypAppModuleIf; -typedef struct +/** + * \class VideoInformation + * \brief Shows information about video sub window + */ +class VideoInformation : public QWidget { - QString m_cFilename; - unsigned int m_uiWidth; - unsigned int m_uiHeight; - int m_iPelFormat; - unsigned int m_uiBitsPelPixel; - unsigned int m_iEndianness; - unsigned int m_uiFrameRate; - unsigned long long int m_uiFileSize; -} CalypFileInfo; -typedef QVector CalypFileInfoVector; +public: + VideoInformation( QWidget* parent ); + void setInformationTopLeft( const QStringList& textLines ); + void setBusyWindow( bool bFlag ); -QDataStream& operator<<( QDataStream& out, const CalypFileInfoVector& d ); -QDataStream& operator>>( QDataStream& in, CalypFileInfoVector& d ); -int findCalypStreamInfo( CalypFileInfoVector array, QString filename ); +protected: + void paintEvent( QPaintEvent* event ); + +private: + QTimer* m_pcRefreshTimer; + QList m_cTopLeftTextList; + QFont m_cTopLeftTextFont; + QFont m_cCenterTextFont; + bool m_bBusyWindow; +}; class VideoSubWindow : public SubWindowAbstract { Q_OBJECT -private: - ResourceHandle* m_pcResourceManager; - - bool m_bWindowBusy; - - QScrollArea* m_pcScrollArea; - QPoint m_cCurrScroll; - double m_dHorScroll; - double m_dVerScroll; - - ViewArea* m_cViewArea; - - VideoInformation* m_pcVideoInfo; - - QString m_cFilename; - QString m_cStreamInformation; - CalypFileInfo m_sStreamInfo; - std::size_t m_uiResourceId; - CalypStream* m_pCurrStream; - std::shared_ptr m_pcCurrFrameAsset; - //CalypFrame* m_pcCurrFrame; - QRect m_cSelectedArea; - - CalypAppModuleIf* m_pcCurrentDisplayModule{ nullptr }; - std::vector> m_associatedModules; - bool m_hasAssociatedModules; - - VideoSubWindow* m_pcReferenceSubWindow; - - // QString m_cWindowShortName; - QString m_cCurrFileName; - - bool m_bIsPlaying; - - QTimer* m_pcUpdateTimer; - /** - * Threads variables - * QtConcurrent - */ - QFuture m_cRefreshResult; - QFuture m_cReadResult; - public: enum VideoSubWindowCategories { @@ -115,41 +79,26 @@ public: MODULE_SUBWINDOW = SubWindowAbstract::MODULE_SUBWINDOW, }; VideoSubWindow( enum VideoSubWindowCategories category, QWidget* parent = 0 ); - VideoSubWindow( enum VideoSubWindowCategories category, CalypAppModuleIf* displayModule, QWidget* parent = 0 ); ~VideoSubWindow(); - void setResourceManaget( ResourceHandle* resourceManager ) { m_pcResourceManager = resourceManager; } + virtual void resetWindowName() = 0; + virtual void updateVideoWindowInfo() = 0; - void updateVideoWindowInfo(); + virtual bool isPlaying() = 0; + virtual void stop() = 0; + virtual void advanceOneFrame() = 0; + virtual auto getFrameNum() -> std::uint64_t { return 1; }; - bool loadFile( QString cFilename, bool bForceDialog = false ); - bool loadFile( CalypFileInfo* streamInfo ); - void loadAll(); + QString getVideoInformation() { return m_cStreamInformation; } bool save( QString filename ); - bool saveStream( QString filename ); - - void refreshSubWindow(); - void refreshFrame( bool bThreaded = false ); - - bool play(); - void pause(); - bool playEvent(); - void stop(); - - void setPlaying( bool isPlaying ); - bool isPlaying(); - void seekAbsoluteEvent( unsigned int new_frame_num ); - void seekRelativeEvent( bool bIsFoward ); void setCurrFrame( std::shared_ptr pcCurrFrame ); - CalypFileInfo getStreamInfo() { return m_sStreamInfo; } - QString getStreamInformation() { return m_cStreamInformation; } - const CalypStream* getInputStream() { return m_pCurrStream; } - const CalypStream* getCurrStream() { return m_pCurrStream; } - CalypFrame* getCurrFrame() { return m_pcCurrFrameAsset.get(); } - std::shared_ptr getCurrFrameAsset(); - ViewArea* getViewArea() { return m_cViewArea; } + auto getCurrFrame() -> CalypFrame* { return m_pcCurrFrameAsset.get(); } + auto getCurrFrameAsset() -> std::shared_ptr { return m_pcCurrFrameAsset; }; + auto getViewArea() -> ViewArea* { return m_cViewArea; } + + VideoSubWindow* getRefSubWindow() { return m_pcReferenceSubWindow; } void setRefSubWindow( VideoSubWindow* subWindow ) { m_pcReferenceSubWindow = NULL; @@ -158,59 +107,37 @@ public: m_pcReferenceSubWindow = subWindow; } - VideoSubWindow* getRefSubWindow() { return m_pcReferenceSubWindow; } /** * Functions to enable a module in the * current SubWindow */ - //void enableModule( std::shared_ptr pcModule ); + auto hasModules() -> bool { return m_associatedModules.size() > 0; } bool hasAssociatedModule(); void setDisplayModule( CalypAppModuleIf* pcModule ); void associateModule( std::shared_ptr pcModule ); void disableModule( CalypAppModuleIf* pcModule ); bool disableAllModules(); - - CalypAppModuleIf* getDisplayModule() { return m_pcCurrentDisplayModule; } - QVector getModuleArray() - { - QVector apcModulesArray; - if( m_pcCurrentDisplayModule ) - apcModulesArray.append( m_pcCurrentDisplayModule ); - for( const auto& module : m_associatedModules ) - { - apcModulesArray.append( module.get() ); - } - return apcModulesArray; - } + CalypAppModuleIf* getDisplayModule() { return m_pcDisplayModule; } /** * Virtual functions from SubWindowAbstract */ - void normalSize(); - void zoomToFit(); - void scaleView( double scale, QPoint center = QPoint() ); - void zoomToFactor( double factor, QPoint center = QPoint() ); + void normalSize() override; + void zoomToFit() override; + void scaleView( double scale, QPoint center = QPoint() ) override; + void zoomToFactor( double factor, QPoint center = QPoint() ) override; - double getScaleFactor() { return m_cViewArea->getZoomFactor(); } + double getScaleFactor() override { return m_cViewArea->getZoomFactor(); } /** * Size related functions */ - QSize sizeHint() const; - QSize sizeHint( const QSize& ) const; + QSize sizeHint( const QSize& ) const override; - QString getCurrentFileName() { return m_cFilename; } - void clearWindowBusy() { m_bWindowBusy = false; } void setFillWindow( bool bFlag ); void adjustScrollBarToRatio( const double& horRatio, const double& verRatio ); private: - void refreshFrameOperation(); - bool goToNextFrame( bool bThreaded = false ); - - static bool guessFormat( QString filename, unsigned int& rWidth, unsigned int& rHeight, int& rInputFormat, unsigned int& rBitsPerPixel, - int& rEndianness, unsigned int& rFrameRate ); - bool hasRunningModule(); /** @@ -222,6 +149,8 @@ private: QSize getScrollSize(); protected: + void refreshFrame(); + void keyPressEvent( QKeyEvent* event ) override; void resizeEvent( QResizeEvent* event ) override; void closeEvent( QCloseEvent* event ) override; @@ -233,9 +162,27 @@ public Q_SLOTS: void updateScrollValues(); void updateSelectedArea( QRect area ); void updatePixelValueStatusBar( const QPoint& pos ); + +protected: + VideoInformation* m_pcVideoInfo; + QString m_cStreamInformation; + std::shared_ptr m_pcCurrFrameAsset; + //bool m_bWindowBusy; + //bool m_bIsPlaying; + + std::vector> m_associatedModules; + CalypAppModuleIf* m_pcDisplayModule{ nullptr }; + //bool m_hasAssociatedModules; + +private: + QScrollArea* m_pcScrollArea; + QPoint m_cCurrScroll; + double m_dHorScroll; + double m_dVerScroll; + ViewArea* m_cViewArea; + QRect m_cSelectedArea; + VideoSubWindow* m_pcReferenceSubWindow; + QTimer* m_pcUpdateTimer; }; -Q_DECLARE_METATYPE( CalypFileInfo ) // NOLINT -Q_DECLARE_METATYPE( CalypFileInfoVector ) // NOLINT - #endif // __VIDEOSUBWINDOW_H__ diff --git a/lib/CalypModuleIf.h b/lib/CalypModuleIf.h index b04ddf3..4709531 100644 --- a/lib/CalypModuleIf.h +++ b/lib/CalypModuleIf.h @@ -127,7 +127,7 @@ public: const char* m_pchModuleCategory{ "" }; const char* m_pchModuleName{ "" }; const char* m_pchModuleTooltip{ "" }; - const char* m_pchModuleLongName{ "" }; + const char* m_pchModuleLongName{ nullptr }; //! Number of frames unsigned int m_uiNumberOfFrames{ 1 }; @@ -135,12 +135,15 @@ public: unsigned int m_uiModuleRequirements{ CLP_MODULE_REQUIRES_NOTHING }; unsigned int m_iFrameBufferCount{ 0 }; - //CalypFrame* m_pcOutputFrame; CalypOptions m_cModuleOptions; CalypModuleIf() = default; - virtual ~CalypModuleIf() {} + CalypModuleIf( const CalypModuleIf& other ) noexcept = delete; + CalypModuleIf( CalypModuleIf&& other ) noexcept = delete; + auto operator=( const CalypModuleIf& other ) -> CalypModuleIf& = delete; + auto operator=( CalypModuleIf&& other ) noexcept -> CalypModuleIf& = delete; + virtual ~CalypModuleIf() = default; virtual void destroy() = 0; const char* getModuleLongName() diff --git a/modules/DisparityStereoSGBM.cpp b/modules/DisparityStereoSGBM.cpp index 5207335..b4460d8 100644 --- a/modules/DisparityStereoSGBM.cpp +++ b/modules/DisparityStereoSGBM.cpp @@ -32,7 +32,7 @@ DisparityStereoSGBM::DisparityStereoSGBM() m_iModuleType = CLP_FRAME_PROCESSING_MODULE; m_pchModuleCategory = "Stereo"; m_pchModuleName = "Disparity-SGBM"; - m_pchModuleName = "SGBM based disparity"; + m_pchModuleLongName = "SGBM based disparity"; m_pchModuleTooltip = "Measure the disparity between two images using the " "Stereo SGBM method (OpenCV)"; m_uiNumberOfFrames = 2; diff --git a/modules/SaliencyBasedFiltering.cpp b/modules/SaliencyBasedFiltering.cpp index 1b8ede1..26dc989 100644 --- a/modules/SaliencyBasedFiltering.cpp +++ b/modules/SaliencyBasedFiltering.cpp @@ -36,6 +36,7 @@ SaliencyBasedFiltering::SaliencyBasedFiltering() m_iModuleType = CLP_FRAME_PROCESSING_MODULE; m_pchModuleCategory = "Quality"; m_pchModuleName = "SaliencyBasedFiltering"; + m_pchModuleLongName = "Saliency Based Filtering"; m_pchModuleTooltip = "Image filter based on a map"; m_uiModuleRequirements = CLP_MODULE_REQUIRES_NOTHING; m_uiNumberOfFrames = 2;