Diffstat (limited to 'noncore/multimedia/camera/mainwindow.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/multimedia/camera/mainwindow.cpp | 198 |
1 files changed, 190 insertions, 8 deletions
diff --git a/noncore/multimedia/camera/mainwindow.cpp b/noncore/multimedia/camera/mainwindow.cpp index 8e89039..6141fd1 100644 --- a/noncore/multimedia/camera/mainwindow.cpp +++ b/noncore/multimedia/camera/mainwindow.cpp @@ -7,51 +7,61 @@ ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** **********************************************************************/ #include "mainwindow.h" #include "previewwidget.h" #include "zcameraio.h" +#include "imageio.h" #include <qapplication.h> #include <qaction.h> #include <qvbox.h> #include <qcombobox.h> #include <qcursor.h> #include <qdatastream.h> #include <qfile.h> #include <qimage.h> #include <qlabel.h> #include <qpopupmenu.h> +#include <qprogressbar.h> #include <qpushbutton.h> #include <qmessagebox.h> +#include <qlayout.h> #include <qdirectpainter_qws.h> #include <qpe/global.h> #include <qpe/resource.h> #include <qpe/qcopenvelope_qws.h> #include <opie/ofiledialog.h> #include <opie/odevice.h> using namespace Opie; - #include <opie2/odebug.h> #include <assert.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> + +#define CAPTUREFILE "/tmp/capture.dat" CameraMainWindow::CameraMainWindow( QWidget * parent, const char * name, WFlags f ) - :QMainWindow( parent, name, f ), _pics( 0 ) + :QMainWindow( parent, name, f ), _capturing( false ), _pics( 0 ) { #ifdef QT_NO_DEBUG if ( !ZCameraIO::instance()->isOpen() ) { QVBox* v = new QVBox( this ); v->setMargin( 10 ); QLabel* l1 = new QLabel( v ); l1->setPixmap( Resource::loadPixmap( "camera/error" ) ); QLabel* l2 = new QLabel( v ); l2->setText( "<b>Sorry. could not detect your camera :-(</b><p>" "* Is the sharpzdc_cs module loaded ?<br>" "* Is /dev/sharpzdc read/writable ?<p>" ); @@ -69,35 +79,39 @@ CameraMainWindow::CameraMainWindow( QWidget * parent, const char * name, WFlags //setCentralWidget( preview ); <--- don't do this! preview->resize( QSize( 240, 288 ) ); preview->show(); // construct a System Channel to receive setRotation messages _sysChannel = new QCopChannel( "QPE/System", this ); connect( _sysChannel, SIGNAL( received( const QCString&, const QByteArray& ) ), this, SLOT( systemMessage( const QCString&, const QByteArray& ) ) ); connect( preview, SIGNAL( contextMenuRequested() ), this, SLOT( showContextMenu() ) ); connect( ZCameraIO::instance(), SIGNAL( shutterClicked() ), this, SLOT( shutterClicked() ) ); + + updateCaption(); + }; CameraMainWindow::~CameraMainWindow() { } void CameraMainWindow::init() { // TODO: Save this stuff in config + flip = 'A'; // auto quality = 50; zoom = 1; captureX = 640; captureY = 480; captureFormat = "JPEG"; resog = new QActionGroup( 0, "reso", true ); resog->setToggleAction( true ); new QAction( " 64 x 48", 0, 0, resog, 0, true ); new QAction( "128 x 96", 0, 0, resog, 0, true ); new QAction( "192 x 144", 0, 0, resog, 0, true ); new QAction( "256 x 192", 0, 0, resog, 0, true ); @@ -112,34 +126,45 @@ void CameraMainWindow::init() qualityg->setToggleAction( true ); new QAction( " 0 (minimal)", 0, 0, qualityg, 0, true ); new QAction( " 25 (low)", 0, 0, qualityg, 0, true ); ( new QAction( " 50 (good)", 0, 0, qualityg, 0, true ) )->setOn( true ); new QAction( " 75 (better)", 0, 0, qualityg, 0, true ); new QAction( "100 (best)", 0, 0, qualityg, 0, true ); zoomg = new QActionGroup( 0, "zoom", true ); zoomg->setToggleAction( true ); ( new QAction( "x 1", 0, 0, zoomg, 0, true ) )->setOn( true ); new QAction( "x 2", 0, 0, zoomg, 0, true ); + flipg = new QActionGroup( 0, "flip", true ); + flipg->setToggleAction( true ); + ( new QAction( "Auto (recommended)", 0, 0, flipg, 0, true ) )->setOn( true ); + new QAction( "0 (always off)", 0, 0, flipg, 0, true ); + new QAction( "X (always horizontal)", 0, 0, flipg, 0, true ); + new QAction( "Y (always vertical)", 0, 0, flipg, 0, true ); + new QAction( "* (always both)", 0, 0, flipg, 0, true ); + outputg = new QActionGroup( 0, "output", true ); outputg->setToggleAction( true ); ( new QAction( "JPEG", 0, 0, outputg, 0, true ) )->setOn( true ); new QAction( "PNG", 0, 0, outputg, 0, true ); new QAction( "BMP", 0, 0, outputg, 0, true ); + new QAction( "AVI", 0, 0, outputg, 0, true ); connect( resog, SIGNAL( selected(QAction*) ), this, SLOT( resoMenuItemClicked(QAction*) ) ); connect( qualityg, SIGNAL( selected(QAction*) ), this, SLOT( qualityMenuItemClicked(QAction*) ) ); connect( zoomg, SIGNAL( selected(QAction*) ), this, SLOT( zoomMenuItemClicked(QAction*) ) ); + connect( flipg, SIGNAL( selected(QAction*) ), this, SLOT( flipMenuItemClicked(QAction*) ) ); connect( outputg, SIGNAL( selected(QAction*) ), this, SLOT( outputMenuItemClicked(QAction*) ) ); + } void CameraMainWindow::systemMessage( const QCString& msg, const QByteArray& data ) { QDataStream stream( data, IO_ReadOnly ); odebug << "received system message: " << msg << oendl; if ( msg == "setCurrentRotation(int)" ) { stream >> _rotation; odebug << "received setCurrentRotation(" << _rotation << ")" << oendl; @@ -160,94 +185,251 @@ void CameraMainWindow::changeZoom( int zoom ) int z; switch ( zoom ) { case 0: z = 128; break; case 1: z = 256; break; case 2: z = 512; break; default: assert( 0 ); break; } ZCameraIO::instance()->setCaptureFrame( 240, 160, z ); } + void CameraMainWindow::showContextMenu() { QPopupMenu reso; reso.setCheckable( true ); resog->addTo( &reso ); QPopupMenu quality; quality.setCheckable( true ); qualityg->addTo( &quality ); + QPopupMenu flip; + flip.setCheckable( true ); + flipg->addTo( &flip ); + QPopupMenu zoom; zoom.setCheckable( true ); zoomg->addTo( &zoom ); QPopupMenu output; output.setCheckable( true ); outputg->addTo( &output ); QPopupMenu m( this ); m.insertItem( "&Resolution", &reso ); m.insertItem( "&Zoom", &zoom ); + m.insertItem( "&Flip", &flip ); m.insertItem( "&Quality", &quality ); m.insertItem( "&Output As", &output ); m.exec( QCursor::pos() ); } void CameraMainWindow::resoMenuItemClicked( QAction* a ) { captureX = a->text().left(3).toInt(); captureY = a->text().right(3).toInt(); odebug << "Capture Resolution now: " << captureX << ", " << captureY << oendl; + updateCaption(); } void CameraMainWindow::qualityMenuItemClicked( QAction* a ) { quality = a->text().left(3).toInt(); odebug << "Quality now: " << quality << oendl; + updateCaption(); } void CameraMainWindow::zoomMenuItemClicked( QAction* a ) { - zoom = QString( a->text()[2] ).toInt(); + zoom = QString( a->text().at(2) ).toInt(); odebug << "Zoom now: " << zoom << oendl; ZCameraIO::instance()->setZoom( zoom ); + updateCaption(); +} + + +void CameraMainWindow::flipMenuItemClicked( QAction* a ) +{ + flip = QString( a->text().at(0) ); + odebug << "Flip now: " << flip << oendl; + if ( flip == "A" ) + ZCameraIO::instance()->setFlip( ZCameraIO::AUTOMATICFLIP ); + else if ( flip == "0" ) + ZCameraIO::instance()->setFlip( ZCameraIO::XNOFLIP | ZCameraIO::YNOFLIP ); + else if ( flip == "X" ) + ZCameraIO::instance()->setFlip( ZCameraIO::XFLIP ); + else if ( flip == "Y" ) + ZCameraIO::instance()->setFlip( ZCameraIO::YFLIP ); + else if ( flip == "*" ) + ZCameraIO::instance()->setFlip( ZCameraIO::XFLIP | ZCameraIO::YFLIP ); + + updateCaption(); } void CameraMainWindow::outputMenuItemClicked( QAction* a ) { captureFormat = a->text(); odebug << "Output format now: " << captureFormat << oendl; + updateCaption(); } void CameraMainWindow::shutterClicked() { - Global::statusMessage( "CAPTURING..." ); - qApp->processEvents(); + if ( captureFormat != "AVI" ) // capture one photo per shutterClick + { + Global::statusMessage( "CAPTURING..." ); + qApp->processEvents(); - odebug << "Shutter has been pressed" << oendl; - ODevice::inst()->touchSound(); + odebug << "Shutter has been pressed" << oendl; + ODevice::inst()->touchSound(); + + performCapture( captureFormat ); + } + else // capture video! start with one shutter click and stop with the next + { + !_capturing ? startVideoCapture() : stopVideoCapture(); + } +} + + +void CameraMainWindow::performCapture( const QString& format ) +{ QString name; name.sprintf( "/tmp/image-%d_%d_%d_q%d.%s", _pics++, captureX, captureY, quality, (const char*) captureFormat.lower() ); QImage i; ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, &i ); QImage im = i.convertDepth( 32 ); - bool result = im.save( name, captureFormat, quality ); + bool result = im.save( name, format, quality ); if ( !result ) { oerr << "imageio-Problem while writing." << oendl; Global::statusMessage( "Error!" ); } else { odebug << captureFormat << "-image has been successfully captured" << oendl; Global::statusMessage( "Ok." ); } } + +void CameraMainWindow::startVideoCapture() +{ + //ODevice::inst()->touchSound(); + ODevice::inst()->setLedState( Led_Mail, Led_BlinkSlow ); + + _capturefd = ::open( CAPTUREFILE, O_WRONLY | O_CREAT ); + if ( _capturefd == -1 ) + { + owarn << "can't open capture file: " << strerror(errno) << oendl; + return; + } + + _capturebuf = new unsigned char[captureX*captureY*2]; + _capturing = true; + _videopics = 0; + updateCaption(); + _time.start(); + preview->setRefreshingRate( 1000 ); + startTimer( 100 ); // too fast but that is ok +} + + +void CameraMainWindow::timerEvent( QTimerEvent* ) +{ + if ( !_capturing ) + { + owarn << "timer event in CameraMainWindow without capturing video ?" << oendl; + return; + } + + ZCameraIO::instance()->captureFrame( captureX, captureY, zoom, _capturebuf ); + _videopics++; + ::write( _capturefd, _capturebuf, captureX*captureY*2 ); + setCaption( QString().sprintf( "Capturing %dx%d @ %.2f fps %d", + captureX, captureY, 1000.0 / (_time.elapsed()/_videopics), _videopics ) ); +} + + +void CameraMainWindow::stopVideoCapture() +{ + killTimers(); + //ODevice::inst()->touchSound(); + ODevice::inst()->setLedState( Led_Mail, Led_Off ); + _capturing = false; + updateCaption(); + ::close( _capturefd ); + + //postProcessVideo(); + + #ifndef QT_NO_DEBUG + preview->setRefreshingRate( 1500 ); + #else + preview->setRefreshingRate( 200 ); + #endif + + //delete[] _capturebuf; //FIXME: close memory leak +} + +void CameraMainWindow::postProcessVideo() +{ + preview->setRefreshingRate( 0 ); + + /* + + QDialog* fr = new QDialog( this, "splash" ); //, false, QWidget::WStyle_NoBorder | QWidget::WStyle_Customize ); + fr->setCaption( "Please wait..." ); + QVBoxLayout* box = new QVBoxLayout( fr, 2, 2 ); + QProgressBar* bar = new QProgressBar( fr ); + bar->setCenterIndicator( true ); + bar->setTotalSteps( _videopics-1 ); + QLabel* label = new QLabel( "Post processing frame bla/bla", fr ); + box->addWidget( bar ); + box->addWidget( label ); + fr->show(); + qApp->processEvents(); + + for ( int i = 0; i < _videopics; ++i ) + { + label->setText( QString().sprintf( "Post processing frame %d / %d", i+1, _videopics ) ); + bar->setProgress( i ); + qApp->processEvents(); + } + + */ + + int infd = ::open( CAPTUREFILE, O_RDONLY ); + if ( infd == -1 ) + { + owarn << "couldn't open capture file: " << strerror(errno) << oendl; + return; + } + + int outfd = ::open( "/tmp/output.avi", O_WRONLY ); + if ( outfd == -1 ) + { + owarn << "couldn't open output file: " << strerror(errno) << oendl; + return; + } + + + + +} + +void CameraMainWindow::updateCaption() +{ + if ( !_capturing ) + setCaption( QString().sprintf( "Opie-Camera: %dx%d %s q%d z%d (%s)", captureX, captureY, (const char*) captureFormat.lower(), quality, zoom, (const char*) flip ) ); + else + setCaption( "Opie-Camera: => CAPTURING <=" ); +} + + |