AnimationSaveWidget Class Reference

Inheritance diagram for AnimationSaveWidget:

Inheritance graph
[legend]
Collaboration diagram for AnimationSaveWidget:

Collaboration graph
[legend]
List of all members.

Detailed Description

Definition at line 112 of file qvfb.cpp.

Public Member Functions

 AnimationSaveWidget (QVFbView *v)
 ~AnimationSaveWidget ()
bool detectPpmtoMpegCommand ()
void timerEvent (QTimerEvent *te)
void convertToMpeg (QString filename)
void removeTemporaryFiles ()

Protected Slots

void toggleRecord ()
void reset ()
void save ()

Private Attributes

QVFbViewview
QProgressBarprogressBar
QLabelstatusText
bool haveMpeg
bool savingAsMpeg
bool recording
QCheckBoxmpegSave
QAnimationWriteranimation
QPushButtonrecBt
QPushButtonresetBt
QPushButtonsaveBt
QLabeltimeDpy
QLabelrecLED
int timerId
int progressTimerId
QPixmap recOn
QPixmap recOff
QTime tm
int elapsed
int imageNum


Constructor & Destructor Documentation

AnimationSaveWidget::AnimationSaveWidget ( QVFbView v  ) 

Definition at line 713 of file qvfb.cpp.

References QBoxLayout::addWidget(), QObject::connect(), detectPpmtoMpegCommand(), elapsed, haveMpeg, QWidget::hide(), mpegSave, progressBar, QWidget::QWidget(), recBt, recLED, recOff, reset(), resetBt, save(), saveBt, savingAsMpeg, QAbstractButton::setChecked(), QWidget::setEnabled(), QWidget::setFixedWidth(), QLabel::setMargin(), QLayout::setMargin(), QLabel::setPixmap(), QLayout::setSpacing(), QProgressBar::setValue(), SIGNAL, SLOT, statusText, timeDpy, and toggleRecord().

00713                                                     :
00714   QWidget((QWidget*)0,0),
00715   view(v), recording(false), animation(0),
00716   timerId(-1), progressTimerId(-1),
00717   recOn(red_on_led_xpm), recOff(red_off_led_xpm),
00718   imageNum(0)
00719 {
00720     // Create the animation record UI dialog
00721     QVBoxLayout *vlayout = new QVBoxLayout( this );
00722 
00723     QWidget *hbox = new QWidget( this );
00724     vlayout->addWidget(hbox);
00725     QHBoxLayout *hlayout = new QHBoxLayout(hbox);
00726     recBt = new QPushButton( tr("Record"), hbox );
00727     hlayout->addWidget(recBt);
00728     resetBt = new QPushButton( tr("Reset"), hbox );
00729     hlayout->addWidget(resetBt);
00730     saveBt = new QPushButton( tr("Save"), hbox );
00731     hlayout->addWidget(saveBt);
00732     recBt->setFixedWidth( 100 );
00733     resetBt->setFixedWidth( 100 );
00734     saveBt->setFixedWidth( 100 );
00735     timeDpy = new QLabel( "00:00", hbox );
00736     hlayout->addWidget(timeDpy);
00737     recLED = new QLabel( hbox );
00738     hlayout->addWidget(recLED);
00739     recLED->setPixmap( recOff );
00740     timeDpy->setMargin( 5 );
00741     connect( recBt, SIGNAL(clicked()), this, SLOT(toggleRecord()) );
00742     connect( resetBt, SIGNAL(clicked()), this, SLOT(reset()) );
00743     connect( saveBt, SIGNAL(clicked()), this, SLOT(save()) );
00744     elapsed = 0;
00745     vlayout->setMargin( 5 );
00746     vlayout->setSpacing( 5 );
00747     haveMpeg = detectPpmtoMpegCommand();
00748     mpegSave = new QCheckBox( tr("Save in MPEG format (requires netpbm package installed)"), this );
00749     vlayout->addWidget(mpegSave);
00750     mpegSave->setChecked( haveMpeg );
00751     mpegSave->setEnabled( haveMpeg );
00752     savingAsMpeg = haveMpeg;
00753     QWidget *hbox2 = new QWidget( this );
00754     vlayout->addWidget(hbox2);
00755     QHBoxLayout *hlayout2 = new QHBoxLayout( hbox2 );
00756     statusText = new QLabel( tr("Click record to begin recording."), hbox2 );
00757     hlayout2->addWidget(statusText);
00758     progressBar = new QProgressBar( hbox2 );
00759     progressBar->setValue( 0 );
00760     hlayout2->addWidget(progressBar);
00761     progressBar->hide();
00762 }

Here is the call graph for this function:

AnimationSaveWidget::~AnimationSaveWidget (  ) 

Definition at line 764 of file qvfb.cpp.

References animation, and removeTemporaryFiles().

00765 {
00766     // clean up
00767     removeTemporaryFiles();
00768     delete animation;
00769 }

Here is the call graph for this function:


Member Function Documentation

bool AnimationSaveWidget::detectPpmtoMpegCommand (  ) 

Definition at line 772 of file qvfb.cpp.

References QList< T >::count(), QFile::exists(), and i.

Referenced by AnimationSaveWidget().

00773 {
00774     // search the PATH for the ppmtompeg command to test we can record to mpeg
00775     QStringList paths = QString(::getenv("PATH")).split(":");
00776     for ( int i = 0; i < paths.count(); i++ )
00777   if ( QFile::exists( paths[i] + "/" + "ppmtompeg" ) )
00778       return true;
00779     return false;
00780 }

Here is the call graph for this function:

void AnimationSaveWidget::timerEvent ( QTimerEvent te  )  [virtual]

This event handler can be reimplemented in a subclass to receive timer events for the object.

QTimer provides a higher-level interface to the timer functionality, and also more general information about timers. The timer event is passed in the event parameter.

See also:
startTimer(), killTimer(), event()

Reimplemented from QObject.

Definition at line 782 of file qvfb.cpp.

References animation, QAnimationWriter::appendFrame(), buffer, QTime::elapsed(), QWidget::hide(), QVFbView::image(), imageNum, QString::indexOf(), QObject::killTimer(), QString::left(), QString::mid(), num, progressBar, progressTimerId, QIODevice::ReadOnly, recLED, recOff, recOn, removeTemporaryFiles(), reset(), QImage::save(), savingAsMpeg, QLabel::setPixmap(), QLabel::setText(), QProgressBar::setValue(), QString::sprintf(), statusText, timeDpy, QObject::timerEvent(), QTimerEvent::timerId(), timerId, tm, and view.

00783 {
00784     QString str;
00785 
00786     // Recording timer
00787     if ( te->timerId() == timerId ) {
00788 
00789   // Add a frame to the animation
00790   if ( savingAsMpeg && view )
00791       view->image().save( str.sprintf("/tmp/qvfb_tmp_image_%04d.ppm", imageNum), "PPM");
00792   else if ( animation && view )
00793       animation->appendFrame(view->image());//QPoint(0,0));
00794   imageNum++;
00795 
00796   // Update the display of number of seconds that have been recorded.
00797   int tmMsec = tm.elapsed();
00798   timeDpy->setText( str.sprintf("%02d:%02d", tmMsec/60000, (tmMsec%60000)/1000) );
00799   QObject::timerEvent( te );
00800 
00801   // Make the recording LED blink
00802   static int tick = 0;
00803   static bool on = false;
00804   if ( tick > 10 ) {
00805       tick = 0;
00806       if ( on )
00807     recLED->setPixmap( recOff );
00808       else
00809     recLED->setPixmap( recOn );
00810       on = !on;
00811   }
00812   tick++;
00813     }
00814 
00815     // Saving progress timer
00816     if ( te->timerId() == progressTimerId ) {
00817   // Parse output log file to work out the encoding progress.
00818   QFile f("/tmp/qvfb_tmp_output.log");
00819   f.open(QIODevice::ReadOnly);
00820   int largestNum = 0;
00821   bool done = false;
00822   char buffer[1024];
00823   while ( !f.atEnd() ) {
00824       // example of the output log entries
00825       //   During each frame:
00826       //      "FRAME 764 (B):  I BLOCKS:  0......
00827       //   When complete:
00828       //      "======FRAMES READ:  766"
00829       f.readLine(buffer, 1024);
00830       str = QString(buffer);
00831       if ( str.left(6) == "FRAME " ) {
00832     int num = str.mid(6, str.indexOf(QChar(' '), 6) - 6).toInt();
00833     if ( num > largestNum )
00834         largestNum = num;
00835       } else if ( str.left(18) == "======FRAMES READ:" ) {
00836     done = true;
00837       }
00838   }
00839   f.close();
00840 
00841   // Update the progress bar with the frame we are up to
00842   progressBar->setValue( largestNum );
00843 
00844   // Finished saving
00845   if ( done ) {
00846       progressBar->hide();
00847       statusText->setText( tr("Finished saving."));
00848       removeTemporaryFiles();
00849       killTimer( progressTimerId );
00850       progressTimerId = -1;
00851       reset();
00852   }
00853     }
00854 }

Here is the call graph for this function:

void AnimationSaveWidget::convertToMpeg ( QString  filename  ) 

Definition at line 857 of file qvfb.cpp.

References QFile::close(), imageNum, QObject::killTimer(), QFile::open(), progressBar, progressTimerId, recLED, recOff, QLabel::setPixmap(), QProgressBar::setRange(), QProgressBar::setValue(), QWidget::show(), QString::sprintf(), QObject::startTimer(), t, timerId, and QIODevice::WriteOnly.

Referenced by save().

00858 {
00859     recLED->setPixmap( recOff );
00860     killTimer( timerId );
00861 
00862     progressBar->show();
00863     progressBar->setRange( 0, imageNum );
00864     progressBar->setValue( 0 );
00865 
00866     // Build parameter file required by ppmtompeg
00867     QFile file("/tmp/qvfb_tmp_ppmtompeg.params");
00868     if ( file.open( QIODevice::WriteOnly ) ) {
00869   QTextStream t( &file );
00870   t << "PATTERN IBBPBBPBBPBBPBB\n";
00871   t << "OUTPUT " << filename << "\n";
00872   t << "INPUT_DIR /tmp\n";
00873   t << "INPUT\n";
00874   QString str;
00875   str = str.sprintf("%04d", imageNum - 1);
00876   t << "qvfb_tmp_image_*.ppm [0000-" << str << "]\n";
00877   t << "END_INPUT\n";
00878   t << "BASE_FILE_FORMAT PPM\n";
00879   t << "INPUT_CONVERT *\n";
00880   t << "GOP_SIZE 15\n";
00881   t << "SLICES_PER_FRAME 1\n";
00882   t << "PIXEL HALF\n";
00883   t << "RANGE 5\n";
00884   t << "PSEARCH_ALG LOGARITHMIC\n";
00885   t << "BSEARCH_ALG SIMPLE\n";
00886   t << "IQSCALE 1\n";
00887   t << "PQSCALE 1\n";
00888   t << "BQSCALE 1\n";
00889   t << "REFERENCE_FRAME DECODED\n";
00890   t << "ASPECT_RATIO 1\n";
00891   t << "FRAME_RATE 24\n";
00892   t << "BIT_RATE 64000\n";      // Quality
00893   t << "BUFFER_SIZE 2048\n";
00894     }
00895     file.close();
00896 
00897     // ### can't use QProcess, not in Qt 2.3
00898     // Execute the ppmtompeg command as a seperate process to do the encoding
00899     pid_t pid = ::fork();
00900     if ( !pid ) {
00901   // Child process
00902   // redirect stdout to log file
00903   freopen("/tmp/qvfb_tmp_output.log", "w", stdout);
00904   // ppmtompeg tool is from the netpbm package
00905   ::execlp("ppmtompeg", "ppmtompeg", "/tmp/qvfb_tmp_ppmtompeg.params", (void *)0);
00906   exit(0);
00907     }
00908 
00909     // Update the saving progress bar every 200ms
00910     progressTimerId = startTimer( 200 );
00911 }

Here is the call graph for this function:

void AnimationSaveWidget::removeTemporaryFiles (  ) 

Definition at line 914 of file qvfb.cpp.

References i, imageNum, QFile::remove(), and QString::sprintf().

Referenced by reset(), timerEvent(), and ~AnimationSaveWidget().

00915 {
00916     QString str;
00917     for ( int i = 0; i < imageNum; i++ )
00918   QFile::remove( str.sprintf("/tmp/qvfb_tmp_image_%04d.ppm", i) );
00919     QFile::remove("/tmp/qvfb_tmp_ppmtompeg.params");
00920     QFile::remove("/tmp/qvfb_tmp_output.log");
00921     imageNum = 0;
00922 }

Here is the call graph for this function:

void AnimationSaveWidget::toggleRecord (  )  [protected, slot]

Definition at line 925 of file qvfb.cpp.

References QTime::addMSecs(), animation, QAnimationWriter::appendFrame(), elapsed, QTime::elapsed(), QVFbView::image(), QAbstractButton::isChecked(), QObject::killTimer(), mpegSave, recBt, recLED, recOff, recOn, recording, savingAsMpeg, QAnimationWriter::setFrameRate(), QLabel::setPixmap(), QAbstractButton::setText(), QLabel::setText(), QTime::start(), QObject::startTimer(), statusText, timerId, tm, and view.

Referenced by AnimationSaveWidget(), reset(), and save().

00926 {
00927     if ( recording ) {
00928   recLED->setPixmap( recOff );
00929   recBt->setText( tr("Record") );
00930   statusText->setText( tr("Paused. Click record to resume, or save if done."));
00931   killTimer( timerId );
00932   timerId = -1;
00933   elapsed = tm.elapsed();
00934     } else {
00935   recLED->setPixmap( recOn );
00936   recBt->setText( tr("Pause") );
00937   statusText->setText( tr("Recording..."));
00938   tm.start();
00939   if ( elapsed == 0 ) {
00940       savingAsMpeg = mpegSave->isChecked();
00941       if ( !savingAsMpeg ) {
00942     delete animation;
00943     animation = new QAnimationWriter("/tmp/qvfb_tmp_animation.mng","MNG");
00944     animation->setFrameRate(24);
00945     if ( view )
00946         animation->appendFrame(view->image());
00947       }
00948   }
00949   tm = tm.addMSecs(-elapsed);
00950   elapsed = 0;
00951   timerId = startTimer(1000 / 24);
00952     }
00953     recording = !recording;
00954 }

void AnimationSaveWidget::reset (  )  [protected, slot]

Definition at line 957 of file qvfb.cpp.

References animation, elapsed, imageNum, progressBar, recording, removeTemporaryFiles(), QLabel::setText(), QProgressBar::setValue(), statusText, timeDpy, and toggleRecord().

Referenced by AnimationSaveWidget(), save(), and timerEvent().

00958 {
00959     if ( recording ) {
00960   toggleRecord();
00961   statusText->setText( tr("Click record to begin recording."));
00962   removeTemporaryFiles();
00963     }
00964     progressBar->setValue( 0 );
00965     timeDpy->setText( "00:00" );
00966     elapsed = 0;
00967     imageNum = 0;
00968     delete animation;
00969     animation = 0;
00970 }

void AnimationSaveWidget::save (  )  [protected, slot]

Definition at line 973 of file qvfb.cpp.

References convertToMpeg(), QFileDialog::getSaveFileName(), QString::isNull(), recording, QFile::remove(), QFile::rename(), reset(), savingAsMpeg, QLabel::setText(), statusText, and toggleRecord().

Referenced by AnimationSaveWidget().

00974 {
00975     if ( recording )
00976   toggleRecord(); // pauses
00977     statusText->setText( tr("Saving... "));
00978 
00979     QString filename;
00980     if ( savingAsMpeg ) {
00981   filename = QFileDialog::getSaveFileName(this, tr("Save animation..."), "", "*.mpg");
00982   if ( !filename.isNull() )
00983       convertToMpeg(filename);
00984     } else {
00985   filename = QFileDialog::getSaveFileName(this, tr("Save animation..."), "", "*.mng");
00986   if (filename.isNull()) {
00987             statusText->setText(tr("Save canceled."));
00988         } else {
00989             QFile::remove(filename);
00990             bool success = QFile::rename(QLatin1String("/tmp/qvfb_tmp_animation.mng"),
00991                                          filename);
00992             if (success) {
00993                 statusText->setText(tr("Finished saving."));
00994                 reset();
00995             } else {
00996                 statusText->setText(tr("Save failed!"));
00997             }
00998   }
00999     }
01000 }


Member Data Documentation

QVFbView* AnimationSaveWidget::view [private]

Definition at line 126 of file qvfb.cpp.

Referenced by timerEvent(), and toggleRecord().

QProgressBar* AnimationSaveWidget::progressBar [private]

Definition at line 127 of file qvfb.cpp.

Referenced by AnimationSaveWidget(), convertToMpeg(), reset(), and timerEvent().

QLabel* AnimationSaveWidget::statusText [private]

Definition at line 128 of file qvfb.cpp.

Referenced by AnimationSaveWidget(), reset(), save(), timerEvent(), and toggleRecord().

bool AnimationSaveWidget::haveMpeg [private]

Definition at line 129 of file qvfb.cpp.

Referenced by AnimationSaveWidget().

bool AnimationSaveWidget::savingAsMpeg [private]

Definition at line 129 of file qvfb.cpp.

Referenced by AnimationSaveWidget(), save(), timerEvent(), and toggleRecord().

bool AnimationSaveWidget::recording [private]

Definition at line 129 of file qvfb.cpp.

Referenced by reset(), save(), and toggleRecord().

QCheckBox* AnimationSaveWidget::mpegSave [private]

Definition at line 130 of file qvfb.cpp.

Referenced by AnimationSaveWidget(), and toggleRecord().

QAnimationWriter* AnimationSaveWidget::animation [private]

Definition at line 131 of file qvfb.cpp.

Referenced by reset(), timerEvent(), toggleRecord(), and ~AnimationSaveWidget().

QPushButton* AnimationSaveWidget::recBt [private]

Definition at line 132 of file qvfb.cpp.

Referenced by AnimationSaveWidget(), and toggleRecord().

QPushButton * AnimationSaveWidget::resetBt [private]

Definition at line 132 of file qvfb.cpp.

Referenced by AnimationSaveWidget().

QPushButton * AnimationSaveWidget::saveBt [private]

Definition at line 132 of file qvfb.cpp.

Referenced by AnimationSaveWidget().

QLabel* AnimationSaveWidget::timeDpy [private]

Definition at line 133 of file qvfb.cpp.

Referenced by AnimationSaveWidget(), reset(), and timerEvent().

QLabel * AnimationSaveWidget::recLED [private]

Definition at line 133 of file qvfb.cpp.

Referenced by AnimationSaveWidget(), convertToMpeg(), timerEvent(), and toggleRecord().

int AnimationSaveWidget::timerId [private]

Definition at line 134 of file qvfb.cpp.

Referenced by convertToMpeg(), timerEvent(), and toggleRecord().

int AnimationSaveWidget::progressTimerId [private]

Definition at line 134 of file qvfb.cpp.

Referenced by convertToMpeg(), and timerEvent().

QPixmap AnimationSaveWidget::recOn [private]

Definition at line 135 of file qvfb.cpp.

Referenced by timerEvent(), and toggleRecord().

QPixmap AnimationSaveWidget::recOff [private]

Definition at line 135 of file qvfb.cpp.

Referenced by AnimationSaveWidget(), convertToMpeg(), timerEvent(), and toggleRecord().

QTime AnimationSaveWidget::tm [private]

Definition at line 136 of file qvfb.cpp.

Referenced by timerEvent(), and toggleRecord().

int AnimationSaveWidget::elapsed [private]

Definition at line 137 of file qvfb.cpp.

Referenced by AnimationSaveWidget(), reset(), and toggleRecord().

int AnimationSaveWidget::imageNum [private]

Definition at line 137 of file qvfb.cpp.

Referenced by convertToMpeg(), removeTemporaryFiles(), reset(), and timerEvent().


The documentation for this class was generated from the following file:
Generated on Thu Mar 15 14:44:02 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1