Files
calyp/app/VideoStreamSubWindow.cpp

424 lines
12 KiB
C++

/* 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 <QScrollArea>
#include <QSettings>
#include <QStaticText>
#include <cassert>
#include "ConfigureFormatDialog.h"
#include "ModulesHandle.h"
#include "QtConcurrent/qtconcurrentrun.h"
#include "ResourceHandle.h"
#include "SubWindowAbstract.h"
#define QT_NO_CONCURRENT
VideoStreamSubWindow::VideoStreamSubWindow( ResourceHandle* resourceManager, QWidget* parent )
: VideoSubWindow( VideoSubWindow::VIDEO_STREAM_SUBWINDOW, parent )
, m_pcResourceManager{ resourceManager }
, 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->hasFeature( ClpModuleFeature::HasInfo ) )
{
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();
}
void VideoStreamSubWindow::setResource( std::size_t id )
{
m_uiResourceId = id;
m_pCurrStream = m_pcResourceManager->getResourceAsset( m_uiResourceId );
#ifdef CALYP_MANAGED_RESOURCES
m_pcResourceManager->startResourceWorker( m_uiResourceId );
#endif
QApplication::restoreOverrideCursor();
refreshFrame();
m_cFilename = QString::fromStdString( m_pCurrStream->getFileName() );
updateVideoWindowInfo();
setWindowName( QFileInfo( m_cFilename ).fileName() );
}
// 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;
// auto InputFormat = ClpPixelFormats::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<unsigned int>();
// Height = appSettings.value( "VideoStreamSubWindow/LastHeight" ).value<unsigned int>();
// BitsPel = appSettings.value( "VideoStreamSubWindow/LastBitsPerPixel" ).value<unsigned int>();
// }
// }
// bool bRet{ false };
// bool forceRaw{ 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,
// iPass == 1, CalypStream::Type::Input );
// forceRaw = iPass > 0;
// }
// catch( CalypFailure& e )
// {
// if( iPass > 0 )
// throw( e );
// }
// }
// if( !bRet )
// {
// return false;
// }
// 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();
// m_sStreamInfo.m_bForceRaw = forceRaw;
// QVariant var;
// var.setValue<unsigned int>( Width );
// appSettings.setValue( "VideoStreamSubWindow/LastWidth", var );
// var.setValue<unsigned int>( Height );
// appSettings.setValue( "VideoStreamSubWindow/LastHeight", var );
// var.setValue<unsigned int>( 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,
// static_cast<ClpPixelFormats>( streamInfo.m_iPelFormat ), streamInfo.m_uiBitsPelPixel,
// streamInfo.m_iEndianness, streamInfo.m_uiFrameRate, streamInfo.m_bForceRaw,
// CalypStream::Type::Input ) )
// {
// return false;
// }
// m_cFilename = streamInfo.m_cFilename;
// m_sStreamInfo = std::move( streamInfo );
// #ifdef CALYP_MANAGED_RESOURCES
// m_pcResourceManager->startResourceWorker( m_uiResourceId );
// #endif
// QApplication::restoreOverrideCursor();
// refreshFrame();
// updateVideoWindowInfo();
// setWindowName( QFileInfo( m_cFilename ).fileName() );
// return true;
// }
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( const 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 bIsForward )
{
if( m_pCurrStream )
{
if( bIsForward )
{
goToNextFrame( true );
}
else
{
m_pCurrStream->seekInputRelative( bIsForward );
#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;
}