#include "RenderMPEGDialog.h" #include #include #include #include #include #include #include #include "define.h" #include "Config.h" #include "TiffFlip.h" //==================================================================== RenderMPEGDialog::RenderMPEGDialog(TiffFlip &tf, QWidget *parent, const char *name) : QDialog(parent, name, true), tiffFlip(tf) { pcommand = NULL; topVLayout = new QVBoxLayout(this, 5, 5); gridLayout = new QGridLayout(NumFields, 3, 3); butLayout = new QHBoxLayout(5); szX = tiffFlip.getOrigWidth(); szY = tiffFlip.getOrigHeight(); int i; QLabel *tmpLabel; for(i = 0; i < (int)NumFields; i++) { tmpLabel = newLabel((Field)i); gridLayout->addWidget(tmpLabel, i, 0); } outputEdit = new QLineEdit(this); outputBut = new QToolButton(this); outputBut->setText("..."); patternEdit = new QLineEdit(this); pSearchCombo = new QComboBox(this); pSearchCombo->setFixedHeight(patternEdit->sizeHint().height()); pSearchCombo->insertItem(" LOGARITHMIC "); pSearchCombo->insertItem(" SUBSAMPLE "); pSearchCombo->insertItem(" TWOLEVEL "); pSearchCombo->insertItem(" EXHAUSTIVE "); bSearchCombo = new QComboBox(this); bSearchCombo->setFixedHeight(patternEdit->sizeHint().height()); bSearchCombo->insertItem(" EXHAUSTIVE "); bSearchCombo->insertItem(" CROSS2 "); bSearchCombo->insertItem(" SIMPLE "); iQScaleSpin = new QSpinBox(1, 31, 1, this); pQScaleSpin = new QSpinBox(1, 31, 1, this); bQScaleSpin = new QSpinBox(1, 31, 1, this); frameRateCombo = new QComboBox(this); frameRateCombo->setFixedHeight(patternEdit->sizeHint().height()); frameRateCombo->insertItem(" 23.976 "); frameRateCombo->insertItem(" 24 "); frameRateCombo->insertItem(" 25 "); frameRateCombo->insertItem(" 29.97 "); frameRateCombo->insertItem(" 30 "); frameRateCombo->insertItem(" 50 "); frameRateCombo->insertItem(" 59.94 "); frameRateCombo->insertItem(" 60 "); frameSizeCombo = new QComboBox(this); frameSizeCombo->setFixedHeight(patternEdit->sizeHint().height()); QString szStr; for(int i = 1; i < 5; i++) { szStr.sprintf(" %d x %d ", tf.getFileWidth()/i, tf.getFileHeight()/i); frameSizeCombo->insertItem(szStr); } gridLayout->addWidget(outputEdit, (int)Output, 1); gridLayout->addWidget(outputBut, (int)Output, 2); gridLayout->addWidget(patternEdit, (int)Pattern, 1); gridLayout->addWidget(pSearchCombo, (int)PSearch, 1); gridLayout->addWidget(bSearchCombo, (int)BSearch, 1); gridLayout->addWidget(iQScaleSpin, (int)IQScale, 1); gridLayout->addWidget(pQScaleSpin, (int)PQScale, 1); gridLayout->addWidget(bQScaleSpin, (int)BQScale, 1); gridLayout->addWidget(frameRateCombo, (int)FrameRate, 1); gridLayout->addWidget(frameSizeCombo, (int)FrameSize, 1); encodeOutput = new QMultiLineEdit(this); encodeOutput->setFont(QFont("system", 8)); encodeOutput->setText("mpeg_encode output:\n-------------------"); // encodeOutput->setEnabled(false); encodeBut = new QPushButton("&encode", this); cancelBut = new QPushButton("&close", this); //-- Connect ------------- QObject::connect(encodeBut, SIGNAL(clicked()), this, SLOT(doEncode()) ); QObject::connect(cancelBut, SIGNAL(clicked()), this, SLOT(cancelPressed()) ); QObject::connect(outputBut, SIGNAL(clicked()), this, SLOT(browseFilename()) ); //-- Layout -------------- butLayout->addWidget(encodeBut); butLayout->addStretch(1); butLayout->addWidget(cancelBut); topVLayout->addLayout(gridLayout, 0); topVLayout->addWidget(encodeOutput, 1); topVLayout->addLayout(butLayout, 0); resize(400, 400); setDefaults(); } RenderMPEGDialog::~RenderMPEGDialog() { } //---------------------------------------------------------- QLabel *RenderMPEGDialog::newLabel(Field field) { QLabel *tmpLabel; QString text; switch(field) { case Output: text = "Output File : "; break; case Pattern: text = "Pattern : "; break; case PSearch: text = "PSearch : "; break; case BSearch: text = "BSearch : "; break; case IQScale: text = "IQScale : "; break; case PQScale: text = "PQScale : "; break; case BQScale: text = "BQScale : "; break; case FrameRate: text = "FrameRate : "; break; case FrameSize: text = "FrameSize : "; break; default: text = "ERROR"; break; } tmpLabel = new QLabel(this); tmpLabel->setAlignment(AlignVCenter | AlignRight); tmpLabel->setText(text); tmpLabel->setMinimumHeight(25); tmpLabel->setMinimumWidth(100); return tmpLabel; } //---------------------------------------------------------- void RenderMPEGDialog::setDefaults() { QString tmpString; Config *cfg = Config::getInstance(); dirString = tiffFlip.getBaseString(); fileString = tiffFlip.getBaseString(); int tmp; tmp = dirString.findRev("/"); dirString.truncate(tmp); fileString.remove(0, tmp+1); tmpString = tiffFlip.getBaseString(); tmpString += ".mpg"; outputEdit->setText(tmpString); patternEdit->setText(cfg->mpegPattern); pSearchCombo->setCurrentItem(cfg->mpegPSearch); bSearchCombo->setCurrentItem(cfg->mpegBSearch); iQScaleSpin->setValue(cfg->mpegIQScale); pQScaleSpin->setValue(cfg->mpegPQScale); bQScaleSpin->setValue(cfg->mpegBQScale); frameRateCombo->setCurrentItem(cfg->mpegFrameRate); } //---------------------------------------------------------- void RenderMPEGDialog::cancelPressed() { reject(); } //---------------------------------------------------------- void RenderMPEGDialog::doEncode() { Config *cfg = Config::getInstance(); char buffer[1024]; char mssg[1024] = "mpeg_encode exited."; char *tmpchr; saveDefaults(); writeParamFile(); sprintf(buffer, "%s %s", (const char*)cfg->mpegExec, (const char*)tmpParamName); fprintf(stderr, "popen(\"%s\", \"r\");\n", buffer); fflush(NULL); setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); pcommand = popen(buffer, "r"); int cnt = 0; int bFrame = tiffFlip.getCurMinFrame(); int eFrame = tiffFlip.getCurMaxFrame(); int numFrames = eFrame - bFrame; int curFrame = 0; if(pcommand) { fflush(pcommand); setvbuf(pcommand, NULL, _IONBF, 0); encodeBut->setEnabled(false); cancelBut->setEnabled(false); QProgressDialog progress( "encoding mpeg...", "&abort", numFrames, this, "progress", true ); progress.setMinimumDuration(0); progress.setProgress(0); qApp->processEvents(); while( pcommand && fgets(buffer, 1024, pcommand) != NULL) { if(strstr(buffer, "created")) //--copy buffer to completed message strcpy(mssg, buffer); if(strncmp(buffer, "FRAME ", 6) == 0) sscanf(buffer, "FRAME %d (", &curFrame); progress.setProgress(curFrame); qApp->processEvents(); cnt++; tmpchr = strchr(buffer, '\n'); if(tmpchr) *tmpchr = ' '; encodeOutput->append(buffer); encodeOutput->setCursorPosition(cnt+1, 0); qApp->processEvents(); fflush(NULL); if(progress.wasCancelled()) break; } progress.setProgress(numFrames); pclose(pcommand); pcommand = NULL; QMessageBox::information(this, APP_NAME, mssg); encodeBut->setEnabled(true); cancelBut->setEnabled(true); } } //---------------------------------------------------------- bool RenderMPEGDialog::writeParamFile() { bool retVal = true; char buffer[512]; FILE *paramFile; char *userName; userName = getenv("USER"); if(!userName) userName = ""; tmpParamName.sprintf("/tmp/flipMPEG-%s.param", userName); paramFile = fopen(tmpParamName, "w"); int sz; int x = szX; int y = szY; QString scaleFrame; if( (sz = frameSizeCombo->currentItem()) ) { x = tiffFlip.getFileWidth()/(sz+1); y = tiffFlip.getFileHeight()/(sz+1); scaleFrame.sprintf("tifftopnm * | pnmscale -xysize %d %d", x, y); } else { scaleFrame.sprintf("tifftopnm *"); } if(paramFile) { time_t time_val; struct tm *ptm; time(&time_val); ptm = localtime(&time_val); strftime(buffer, 64, "%A, %B %d, %Y %l:%M %P", ptm); fprintf(paramFile, "#####################################################\n"); fprintf(paramFile, "# mpeg_encode parameter file\n"); fprintf(paramFile, "# written by flip on %s\n", buffer); fprintf(paramFile, "#####################################################\n"); fprintf(paramFile, "\n"); fprintf(paramFile, "OUTPUT %s\n", (const char*)outputEdit->text()); fprintf(paramFile, "PATTERN %s\n", (const char*)patternEdit->text()); fprintf(paramFile, "\n"); fprintf(paramFile, "YUV_SIZE %dx%d\n", x, y); fprintf(paramFile, "YUV_FORMAT UCB\n"); fprintf(paramFile, "\n"); fprintf(paramFile, "BASE_FILE_FORMAT PPM\n"); fprintf(paramFile, "INPUT_DIR %s\n", (const char*)dirString); fprintf(paramFile, "INPUT_CONVERT %s\n", (const char*)scaleFrame); fprintf(paramFile, "\n"); fprintf(paramFile, "INPUT\n"); fprintf(paramFile, "%s*.tif [%04d-%04d]\n", (const char*)fileString, tiffFlip.getCurMinFrame(), tiffFlip.getCurMaxFrame()); fprintf(paramFile, "END_INPUT\n"); fprintf(paramFile, "\n"); fprintf(paramFile, "SLICES_PER_FRAME 1\n"); fprintf(paramFile, "GOP_SIZE 15\n"); fprintf(paramFile, "PIXEL FULL\n"); fprintf(paramFile, "RANGE 10\n"); fprintf(paramFile, "\n"); fprintf(paramFile, "PSEARCH_ALG %s\n", (const char*)(pSearchCombo->currentText().simplifyWhiteSpace())); fprintf(paramFile, "BSEARCH_ALG %s\n", (const char*)(bSearchCombo->currentText().simplifyWhiteSpace())); fprintf(paramFile, "\n"); fprintf(paramFile, "IQSCALE %d\n", iQScaleSpin->value()); fprintf(paramFile, "PQSCALE %d\n", pQScaleSpin->value()); fprintf(paramFile, "BQSCALE %d\n", bQScaleSpin->value()); fprintf(paramFile, "\n"); fprintf(paramFile, "FRAME_RATE %s\n", (const char*)(frameRateCombo->currentText().simplifyWhiteSpace())); fprintf(paramFile, "\n"); fprintf(paramFile, "USER_DATA /dev/null\n"); fprintf(paramFile, "BUFFER_SIZE 5242880\n"); fprintf(paramFile, "REFERENCE_FRAME DECODED\n"); fprintf(paramFile, "\n"); fprintf(paramFile, "FORCE_ENCODE_LAST_FRAME\n"); fprintf(paramFile, "\n"); fflush(paramFile); fclose(paramFile); } else { QMessageBox::critical(this, APP_NAME, "ERROR: Could not open \"/tmp/flipMPEG.param\" for write!"); retVal = false; } return retVal; } //---------------------------------------------------------- void RenderMPEGDialog::saveDefaults() { Config *cfg = Config::getInstance(); cfg->mpegPattern = patternEdit->text(); cfg->mpegPSearch = pSearchCombo->currentItem(); cfg->mpegBSearch = bSearchCombo->currentItem(); cfg->mpegIQScale = iQScaleSpin->value(); cfg->mpegPQScale = pQScaleSpin->value(); cfg->mpegBQScale = bQScaleSpin->value(); cfg->mpegFrameRate = frameRateCombo->currentItem(); Config::commit(); } //---------------------------------------------------------- void RenderMPEGDialog::browseFilename() { QString fileName; fileName = QFileDialog::getSaveFileName(outputEdit->text(), "*.mpg", this); if(!fileName.isEmpty()) outputEdit->setText(fileName); }