File indexing completed on 2024-05-12 04:51:52
0001 /* 0002 SPDX-FileCopyrightText: 2006-2009 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-FileCopyrightText: 1998-2009 Sebastian Trueg <trueg@k3b.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "k3bvideodvdrippingdialog.h" 0009 #include "k3bapplication.h" 0010 #include "k3bfilesysteminfo.h" 0011 #include "k3bglobals.h" 0012 #include "k3bjobprogressdialog.h" 0013 #include "k3bmedium.h" 0014 #include "k3bmediacache.h" 0015 #include "k3bvideodvd.h" 0016 #include "k3bvideodvdaudiomodel.h" 0017 #include "k3bvideodvdrippingjob.h" 0018 #include "k3bvideodvdrippingwidget.h" 0019 #include "k3bvideodvdtitletranscodingjob.h" 0020 0021 #include <KComboBox> 0022 #include <KLineEdit> 0023 #include <KConfig> 0024 #include <KLocalizedString> 0025 #include <KUrlRequester> 0026 #include <KIO/Global> 0027 #include <KMessageBox> 0028 0029 #include <QList> 0030 #include <QLocale> 0031 #include <QMap> 0032 #include <QVector> 0033 #include <QFontMetrics> 0034 #include <QCheckBox> 0035 #include <QHBoxLayout> 0036 #include <QHeaderView> 0037 #include <QLayout> 0038 #include <QSpinBox> 0039 #include <QStyle> 0040 0041 0042 namespace { 0043 0044 QString videoCodecId( K3b::VideoDVDTitleTranscodingJob::VideoCodec codec ) 0045 { 0046 switch( codec ) { 0047 case K3b::VideoDVDTitleTranscodingJob::VIDEO_CODEC_FFMPEG_MPEG4: 0048 return "ffmpeg_mpeg4"; 0049 case K3b::VideoDVDTitleTranscodingJob::VIDEO_CODEC_XVID: 0050 return "xvid"; 0051 default: 0052 return "none"; 0053 } 0054 } 0055 0056 0057 QString audioCodecId( K3b::VideoDVDTitleTranscodingJob::AudioCodec codec ) 0058 { 0059 switch( codec ) { 0060 case K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_MP3: 0061 return "mp3"; 0062 case K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_AC3_STEREO: 0063 return "ac3_stereo"; 0064 case K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_AC3_PASSTHROUGH: 0065 return "ac3_passthrough"; 0066 default: 0067 return "none"; 0068 } 0069 } 0070 0071 0072 K3b::VideoDVDTitleTranscodingJob::VideoCodec videoCodecFromId( const QString& codec ) 0073 { 0074 if( codec == "xvid" ) 0075 return K3b::VideoDVDTitleTranscodingJob::VIDEO_CODEC_XVID; 0076 else // if( codec == "ffmpeg_mpeg4" ) 0077 return K3b::VideoDVDTitleTranscodingJob::VIDEO_CODEC_FFMPEG_MPEG4; 0078 } 0079 0080 0081 K3b::VideoDVDTitleTranscodingJob::AudioCodec audioCodecFromId( const QString& codec ) 0082 { 0083 if( codec == "ac3_stereo" ) 0084 return K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_AC3_STEREO; 0085 else if( codec == "ac3_passthrough" ) 0086 return K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_AC3_PASSTHROUGH; 0087 else // if( codec == "mp3" ) 0088 return K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_MP3; 0089 } 0090 0091 0092 // resize according to aspect ratio 0093 QSize resizeTitle( const K3b::VideoDVD::VideoStream& title, const QSize& size ) 0094 { 0095 int w = size.width(); 0096 int h = size.height(); 0097 int rw = title.realPictureWidth(); 0098 int rh = title.realPictureHeight(); 0099 0100 if( w == 0 && h == 0 ) { 0101 w = rw; 0102 h = rh; 0103 } 0104 else if( w == 0 ) { 0105 w = h * rw / rh; 0106 } 0107 else if( h == 0 ) { 0108 h = w * rh / rw; 0109 } 0110 0111 return QSize(w,h); 0112 } 0113 0114 typedef QMap< const K3b::VideoDVD::Title*, K3b::VideoDVDRippingJob::TitleRipInfo > TitleRipInfos; 0115 0116 } // namespace 0117 0118 0119 class K3b::VideoDVDRippingDialog::Private 0120 { 0121 public: 0122 Private( const K3b::VideoDVD::VideoDVD& d ) 0123 : dvd( d ), w( 0 ), audioModel( 0 ) {} 0124 0125 VideoDVD::VideoDVD dvd; 0126 VideoDVDRippingWidget* w; 0127 VideoDVDAudioModel* audioModel; 0128 TitleRipInfos titleRipInfos; 0129 K3b::FileSystemInfo fsInfo; 0130 0131 QString createFilename( const VideoDVDRippingJob::TitleRipInfo& info, const QString& pattern ) const; 0132 }; 0133 0134 0135 QString K3b::VideoDVDRippingDialog::Private::createFilename( const K3b::VideoDVDRippingJob::TitleRipInfo& info, const QString& pattern ) const 0136 { 0137 QString f; 0138 0139 const K3b::VideoDVD::Title& title = dvd[info.title-1]; 0140 0141 for( int i = 0; i < pattern.length(); ++i ) { 0142 // 0143 // every pattern starts with a % sign 0144 // 0145 if( pattern[i] == '%' && i+1 < pattern.length() ) { 0146 ++i; // skip the % 0147 char c = pattern[i].toLatin1(); 0148 0149 // 0150 // first check if we have a long keyword instead of a one-char 0151 // 0152 if( pattern[i] == '{' ) { 0153 int j = pattern.indexOf( '}', i ); 0154 if( j < 0 ) // no closing bracket -> no valid pattern 0155 c = '*'; 0156 else { 0157 QString keyword = pattern.mid( i+1, j-i-1 ); 0158 if( keyword == "titlenumber" || 0159 keyword == "title_number" || 0160 keyword == "title" ) { 0161 c = PATTERN_TITLE_NUMBER; 0162 } 0163 else if( keyword == "volumeid" || 0164 keyword == "volume_id" || 0165 keyword == "volid" || 0166 keyword == "vol_id" ) { 0167 c = PATTERN_VOLUME_ID; 0168 } 0169 else if( keyword == "beautifiedvolumeid" || 0170 keyword == "beautified_volumeid" || 0171 keyword == "beautified_volume_id" || 0172 keyword == "beautifiedvolid" || 0173 keyword == "beautified_volid" || 0174 keyword == "beautified_vol_id" || 0175 keyword == "nicevolid" || 0176 keyword == "nice_volid" || 0177 keyword == "nice_vol_id" ) { 0178 c = PATTERN_BEAUTIFIED_VOLUME_ID; 0179 } 0180 else if( keyword == "languagecode" || 0181 keyword == "language_code" || 0182 keyword == "langcode" || 0183 keyword == "lang_code" ) { 0184 c = PATTERN_LANGUAGE_CODE; 0185 0186 } 0187 else if( keyword == "lang" || 0188 keyword == "language" || 0189 keyword == "langname" || 0190 keyword == "languagename" || 0191 keyword == "lang_name" || 0192 keyword == "language_name" ) { 0193 c = PATTERN_LANGUAGE_NAME; 0194 } 0195 else if( keyword == "audioformat" || 0196 keyword == "audio_format" || 0197 keyword == "audio" ) { 0198 c = PATTERN_AUDIO_FORMAT; 0199 } 0200 else if( keyword == "channels" || 0201 keyword == "audiochannels" || 0202 keyword == "audio_channels" || 0203 keyword == "ch" ) { 0204 c = PATTERN_AUDIO_CHANNELS; 0205 } 0206 else if( keyword == "videosize" || 0207 keyword == "video_size" || 0208 keyword == "vsize" ) { 0209 c = PATTERN_VIDEO_SIZE; 0210 } 0211 else if( keyword == "originalvideosize" || 0212 keyword == "original_video_size" || 0213 keyword == "origvideosize" || 0214 keyword == "orig_video_size" || 0215 keyword == "origvsize" ) { 0216 c = PATTERN_ORIG_VIDEO_SIZE; 0217 } 0218 else if( keyword == "aspect_ratio" || 0219 keyword == "aspectratio" || 0220 keyword == "ratio" ) { 0221 c = PATTERN_ASPECT_RATIO; 0222 } 0223 else if( keyword == "current_date" || 0224 keyword == "currentdate" || 0225 keyword == "date" ) { 0226 c = PATTERN_CURRENT_DATE; 0227 } 0228 else { 0229 // unusable pattern 0230 c = '*'; 0231 } 0232 0233 // 0234 // skip the keyword and the closing bracket 0235 // 0236 if( c != '*' ) { 0237 i += keyword.length() + 1; 0238 } 0239 } 0240 } 0241 0242 switch( c ) { 0243 case PATTERN_TITLE_NUMBER: 0244 f.append( QString::number(info.title).rightJustified( 2, '0' ) ); 0245 break; 0246 case PATTERN_VOLUME_ID: 0247 f.append( dvd.volumeIdentifier() ); 0248 break; 0249 case PATTERN_BEAUTIFIED_VOLUME_ID: 0250 f.append( k3bappcore->mediaCache()->medium( dvd.device() ).beautifiedVolumeId() ); 0251 break; 0252 case PATTERN_LANGUAGE_CODE: 0253 if( title.numAudioStreams() > 0 ) 0254 f.append( title.audioStream( info.audioStream ).langCode() ); 0255 break; 0256 case PATTERN_LANGUAGE_NAME: 0257 if( title.numAudioStreams() > 0 ) 0258 f.append( QLocale( title.audioStream( info.audioStream ).langCode() ).nativeLanguageName() ); 0259 break; 0260 case PATTERN_AUDIO_FORMAT: 0261 // FIXME: what about MPEG audio streams? 0262 if( title.numAudioStreams() > 0 ) { 0263 if( w->selectedAudioCodec() == K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_MP3 ) 0264 f.append( K3b::VideoDVDTitleTranscodingJob::audioCodecString( w->selectedAudioCodec() ) ); 0265 else 0266 f.append( K3b::VideoDVD::audioFormatString( title.audioStream( info.audioStream ).format() ) ); 0267 } 0268 break; 0269 case PATTERN_AUDIO_CHANNELS: 0270 if( title.numAudioStreams() > 0 ) 0271 // xgettext: no-c-format 0272 f.append( i18ncp("Ch is short for Channels", "%1Ch", "%1Ch", 0273 w->selectedAudioCodec() == K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_AC3_PASSTHROUGH 0274 ? title.audioStream( info.audioStream ).channels() 0275 : 2 ) ); 0276 break; 0277 case PATTERN_ORIG_VIDEO_SIZE: 0278 f.append( QString("%1x%2") 0279 .arg(title.videoStream().pictureWidth()) 0280 .arg(title.videoStream().pictureHeight()) ); 0281 break; 0282 case PATTERN_VIDEO_SIZE: { 0283 QSize s( resizeTitle( dvd[info.title-1].videoStream(), w->selectedPictureSize() ) ); 0284 f.append( QString("%1x%2").arg(s.width()).arg(s.height()) ); 0285 break; 0286 } 0287 case PATTERN_ASPECT_RATIO: 0288 if( title.videoStream().displayAspectRatio() == K3b::VideoDVD::VIDEO_ASPECT_RATIO_4_3 ) 0289 f.append( "4:3" ); 0290 else 0291 f.append( "16:9" ); 0292 break; 0293 case PATTERN_CURRENT_DATE: 0294 f.append( QLocale().toString( QDate::currentDate() ) ); 0295 break; 0296 default: 0297 f.append( pattern[i-1] ); 0298 f.append( pattern[i] ); 0299 } 0300 } 0301 0302 // 0303 // normal character -> just append to filename 0304 // 0305 else { 0306 f.append( pattern[i] ); 0307 } 0308 } 0309 0310 // 0311 // and the extension (for now only avi) 0312 // 0313 f.append( ".avi" ); 0314 0315 return f; 0316 } 0317 0318 0319 K3b::VideoDVDRippingDialog::VideoDVDRippingDialog( const K3b::VideoDVD::VideoDVD& dvd, 0320 const QList<int>& titles, 0321 QWidget* parent ) 0322 : K3b::InteractionDialog( parent, 0323 i18n("Video DVD Ripping"), 0324 QString(), 0325 START_BUTTON|CANCEL_BUTTON, 0326 START_BUTTON, 0327 "VideoDVD Ripping" ), // config group 0328 d( new Private( dvd ) ) 0329 { 0330 d->audioModel = new VideoDVDAudioModel( dvd, titles, this ); 0331 0332 QWidget* frame = mainWidget(); 0333 d->w = new K3b::VideoDVDRippingWidget( frame ); 0334 d->w->m_titleView->setModel( d->audioModel ); 0335 d->w->m_titleView->expandAll(); 0336 d->w->m_titleView->header()->setSectionResizeMode( VideoDVDAudioModel::TitleColumn, QHeaderView::ResizeToContents ); 0337 d->w->m_titleView->header()->setSectionResizeMode( VideoDVDAudioModel::VideoSizeColumn, QHeaderView::ResizeToContents ); 0338 d->w->m_titleView->header()->setSectionResizeMode( VideoDVDAudioModel::FileSizeColumn, QHeaderView::ResizeToContents ); 0339 0340 QHBoxLayout* frameLayout = new QHBoxLayout( frame ); 0341 frameLayout->setContentsMargins( 0, 0, 0, 0 ); 0342 frameLayout->addWidget( d->w ); 0343 0344 connect( d->w, SIGNAL(changed()), 0345 this, SLOT(slotUpdateFilesizes()) ); 0346 connect( d->w, SIGNAL(changed()), 0347 this, SLOT(slotUpdateFilenames()) ); 0348 connect( d->w, SIGNAL(changed()), 0349 this, SLOT(slotUpdateVideoSizes()) ); 0350 connect( d->audioModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 0351 this, SLOT(slotAudioModelChanged(QModelIndex,QModelIndex)) ); 0352 0353 setTitle( i18n("Video DVD Ripping"), 0354 i18np("1 title from %2", "%1 titles from %2", titles.count(), 0355 k3bappcore->mediaCache()->medium(d->dvd.device()).beautifiedVolumeId() ) ); 0356 0357 // populate rip infos 0358 d->titleRipInfos.clear(); 0359 for( QList<int>::const_iterator it = titles.begin(); it != titles.end(); ++it ) { 0360 if( *it > 0 && *it <= static_cast<int>( d->dvd.numTitles() ) ) { 0361 const VideoDVD::Title& title = d->dvd[ *it-1 ]; 0362 K3b::VideoDVDRippingJob::TitleRipInfo ri( *it ); 0363 ri.audioStream = d->audioModel->chosenAudio( title ); 0364 d->titleRipInfos.insert( &title, ri ); 0365 } 0366 } 0367 } 0368 0369 0370 K3b::VideoDVDRippingDialog::~VideoDVDRippingDialog() 0371 { 0372 delete d; 0373 } 0374 0375 0376 void K3b::VideoDVDRippingDialog::slotUpdateFilenames() 0377 { 0378 QString baseDir = K3b::prepareDir( d->w->m_editBaseDir->url().toLocalFile() ); 0379 d->fsInfo.setPath( baseDir ); 0380 0381 for( TitleRipInfos::iterator it = d->titleRipInfos.begin(); it != d->titleRipInfos.end(); ++it ) { 0382 QString f = d->fsInfo.fixupPath( d->createFilename( it.value(), d->w->m_comboFilenamePattern->currentText() ) ); 0383 if( d->w->m_checkBlankReplace->isChecked() ) { 0384 static const QRegularExpression rx( "\\s" ); 0385 f.replace( rx, d->w->m_editBlankReplace->text() ); 0386 } 0387 it.value().filename = baseDir + f; 0388 0389 d->audioModel->setFileName( *it.key(), f ); 0390 } 0391 } 0392 0393 0394 void K3b::VideoDVDRippingDialog::slotUpdateFilesizes() 0395 { 0396 double bitrate = (double)d->w->m_spinVideoBitrate->value(); 0397 KIO::filesize_t overallSize = 0ULL; 0398 0399 // update file sizes 0400 for( TitleRipInfos::iterator it = d->titleRipInfos.begin(); it != d->titleRipInfos.end(); ++it ) { 0401 0402 double sec = d->dvd[it.value().title-1].playbackTime().totalSeconds(); 0403 0404 // estimate the filesize 0405 KIO::filesize_t size = (KIO::filesize_t)( sec * bitrate * 1000.0 / 8.0 ); 0406 0407 // add audio stream size 0408 // FIXME: consider AC3 passthrough 0409 size += (KIO::filesize_t)( sec * d->w->selectedAudioBitrate() / 8.0 * 1024.0 ); 0410 0411 d->audioModel->setFileSize( *it.key(), size ); 0412 0413 overallSize += size; 0414 } 0415 0416 d->w->setNeededSize( overallSize ); 0417 } 0418 0419 0420 void K3b::VideoDVDRippingDialog::slotUpdateVideoSizes() 0421 { 0422 QSize size = d->w->selectedPictureSize(); 0423 for( TitleRipInfos::iterator it = d->titleRipInfos.begin(); it != d->titleRipInfos.end(); ++it ) { 0424 QSize s( resizeTitle( d->dvd[it.value().title-1].videoStream(), size ) ); 0425 d->audioModel->setVideoSize( *it.key(), s ); 0426 } 0427 } 0428 0429 0430 void K3b::VideoDVDRippingDialog::slotAudioModelChanged( const QModelIndex& topLeft, const QModelIndex& /*bottomRight*/ ) 0431 { 0432 QModelIndex parent = topLeft.parent(); 0433 if( parent.isValid() ) { 0434 if( const VideoDVD::Title* title = d->audioModel->titleForIndex( parent ) ) { 0435 d->titleRipInfos[ title ].audioStream = d->audioModel->chosenAudio( *title ); 0436 slotUpdateFilenames(); 0437 } 0438 } 0439 } 0440 0441 0442 void K3b::VideoDVDRippingDialog::setBaseDir( const QString& path ) 0443 { 0444 d->w->m_editBaseDir->setUrl(QUrl::fromLocalFile(path)); 0445 } 0446 0447 0448 void K3b::VideoDVDRippingDialog::loadSettings( const KConfigGroup& c ) 0449 { 0450 d->w->m_spinVideoBitrate->setValue( c.readEntry( "video bitrate", 1200 ) ); 0451 d->w->m_checkTwoPassEncoding->setChecked( c.readEntry( "two pass encoding", true ) ); 0452 d->w->m_checkAudioResampling->setChecked( c.readEntry( "audio resampling", false ) ); 0453 d->w->m_checkAutoClipping->setChecked( c.readEntry( "auto clipping", false ) ); 0454 d->w->m_checkLowPriority->setChecked( c.readEntry( "low priority", true ) ); 0455 d->w->m_checkAudioVBR->setChecked( c.readEntry( "vbr audio", true ) ); 0456 d->w->setSelectedAudioBitrate( c.readEntry( "audio bitrate", 128 ) ); 0457 d->w->setSelectedVideoCodec( videoCodecFromId( c.readEntry( "video codec", videoCodecId( K3b::VideoDVDTitleTranscodingJob::VIDEO_CODEC_FFMPEG_MPEG4 ) ) ) ); 0458 d->w->setSelectedAudioCodec( audioCodecFromId( c.readEntry( "audio codec", audioCodecId( K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_MP3 ) ) ) ); 0459 d->w->m_checkBlankReplace->setChecked( c.readEntry( "replace blanks", false ) ); 0460 d->w->m_editBlankReplace->setText( c.readEntry( "blank replace string", "_" ) ); 0461 d->w->m_comboFilenamePattern->setEditText( c.readEntry( "filename pattern", d->w->m_comboFilenamePattern->itemText(0) ) ); 0462 d->w->m_editBaseDir->setUrl(QUrl::fromLocalFile(c.readPathEntry("base dir", K3b::defaultTempPath()))); 0463 } 0464 0465 0466 void K3b::VideoDVDRippingDialog::saveSettings( KConfigGroup c ) 0467 { 0468 c.writeEntry( "video bitrate", d->w->m_spinVideoBitrate->value() ); 0469 c.writeEntry( "two pass encoding", d->w->m_checkTwoPassEncoding->isChecked() ); 0470 c.writeEntry( "audio resampling", d->w->m_checkAudioResampling->isChecked() ); 0471 c.writeEntry( "auto clipping", d->w->m_checkAutoClipping->isChecked() ); 0472 c.writeEntry( "low priority", d->w->m_checkLowPriority->isChecked() ); 0473 c.writeEntry( "vbr audio", d->w->m_checkAudioVBR->isChecked() ); 0474 c.writeEntry( "audio bitrate", d->w->selectedAudioBitrate() ); 0475 c.writeEntry( "video codec", videoCodecId( d->w->selectedVideoCodec() ) ); 0476 c.writeEntry( "audio codec", audioCodecId( d->w->selectedAudioCodec() ) ); 0477 c.writeEntry( "replace blanks", d->w->m_checkBlankReplace->isChecked() ); 0478 c.writeEntry( "blank replace string", d->w->m_editBlankReplace->text() ); 0479 c.writeEntry( "filename pattern", d->w->m_comboFilenamePattern->currentText() ); 0480 c.writePathEntry( "base dir", d->w->m_editBaseDir->url().toLocalFile() ); 0481 } 0482 0483 0484 void K3b::VideoDVDRippingDialog::slotStartClicked() 0485 { 0486 // 0487 // check if the selected audio codec is usable for all selected audio streams 0488 // We can only use the AC3 pass-through mode for AC3 streams 0489 // 0490 if( d->w->selectedAudioCodec() == K3b::VideoDVDTitleTranscodingJob::AUDIO_CODEC_AC3_PASSTHROUGH ) { 0491 for( TitleRipInfos::iterator it = d->titleRipInfos.begin(); it != d->titleRipInfos.end(); ++it ) { 0492 if( d->dvd[it.value().title-1].numAudioStreams() > 0 && 0493 d->dvd[it.value().title-1].audioStream(it.value().audioStream).format() != K3b::VideoDVD::AUDIO_FORMAT_AC3 ) { 0494 KMessageBox::error( this, i18n("<p>When using the <em>AC3 pass-through</em> audio codec all selected audio " 0495 "streams need to be in AC3 format. Please select another audio codec or " 0496 "choose AC3 audio streams for all ripped titles."), 0497 i18n("AC3 Pass-through") ); 0498 return; 0499 } 0500 } 0501 } 0502 0503 // check if we need to overwrite some files... 0504 QStringList filesToOverwrite; 0505 for( TitleRipInfos::iterator it = d->titleRipInfos.begin(); it != d->titleRipInfos.end(); ++it ) { 0506 if( QFile::exists( it.value().filename ) ) 0507 filesToOverwrite.append( it.value().filename ); 0508 } 0509 0510 if( !filesToOverwrite.isEmpty() ) 0511 if( KMessageBox::questionTwoActionsList( this, 0512 i18n("Do you want to overwrite these files?"), 0513 filesToOverwrite, 0514 i18n("Files Exist"), 0515 KStandardGuiItem::overwrite(), 0516 KStandardGuiItem::cancel() ) == KMessageBox::SecondaryAction ) 0517 return; 0518 0519 0520 QSize videoSize = d->w->selectedPictureSize(); 0521 int i = 0; 0522 QVector<K3b::VideoDVDRippingJob::TitleRipInfo> titles( d->titleRipInfos.count() ); 0523 for( TitleRipInfos::const_iterator it = d->titleRipInfos.constBegin(); it != d->titleRipInfos.constEnd(); ++it ) { 0524 titles[i] = it.value(); 0525 titles[i].videoBitrate = 0; // use the global bitrate set below 0526 titles[i].width = videoSize.width(); 0527 titles[i].height = videoSize.height(); 0528 ++i; 0529 } 0530 0531 // sort the titles which come from a map and are thus not sorted properly 0532 // simple bubble sort for these small arrays is sufficient 0533 for( int i = 0; i < titles.count(); ++i ) { 0534 for( int j = i+1; j < titles.count(); ++j ) { 0535 if( titles[i].title > titles[j].title ) { 0536 K3b::VideoDVDRippingJob::TitleRipInfo tmp = titles[i]; 0537 titles[i] = titles[j]; 0538 titles[j] = tmp; 0539 } 0540 } 0541 } 0542 0543 // start the job 0544 K3b::JobProgressDialog dlg( parentWidget() ); 0545 K3b::VideoDVDRippingJob* job = new K3b::VideoDVDRippingJob( &dlg, &dlg ); 0546 job->setVideoDVD( d->dvd ); 0547 job->setTitles( titles ); 0548 0549 job->setVideoBitrate( d->w->m_spinVideoBitrate->value() ); 0550 job->setTwoPassEncoding( d->w->m_checkTwoPassEncoding->isChecked() ); 0551 job->setResampleAudioTo44100( d->w->m_checkAudioResampling->isChecked() ); 0552 job->setAutoClipping( d->w->m_checkAutoClipping->isChecked() ); 0553 job->setVideoCodec( d->w->selectedVideoCodec() ); 0554 job->setAudioCodec( d->w->selectedAudioCodec() ); 0555 job->setLowPriority( d->w->m_checkLowPriority->isChecked() ); 0556 job->setAudioBitrate( d->w->selectedAudioBitrate() ); 0557 job->setAudioVBR( d->w->m_checkAudioVBR->isChecked() ); 0558 0559 hide(); 0560 dlg.startJob( job ); 0561 close(); 0562 } 0563 0564 #include "moc_k3bvideodvdrippingdialog.cpp"