qtconcurrent::map pause with a for loop
Unsolved
General and Desktop
-
wrote on 3 Feb 2016, 03:20 last edited by
ok I have the following code for the function called by map
void MainWindow::processVideo( QString &video) { if (video.isEmpty()) return; QFileInfo video_info(video); QString tempstring; int interval = 500; int current_interval = 0; UMat frame; vector< cv::KeyPoint > keypoints; Ptr<DescriptorExtractor> odetector = cv::ORB::create(500); UMat imgDescriptor; VideoCapture videocap(video.toStdString()); if (!videocap.isOpened()) { failedstream << video << " could not be opened. Check permissions" << endl; return; } QSqlQuery check(db); check.prepare("SELECT size FROM videos WHERE file = :video"); check.bindValue(":video",video); check.exec(); if (check.next()) if (check.value("size").toInt() == video_info.size()) { qDebug() << video << "already processed skipping"; return; } db.transaction(); QSqlQuery insert_video(db); int ex = videocap.get(CV_CAP_PROP_FOURCC); char vcodec[] = {(char)(ex & 0XFF) , (char)((ex & 0XFF00) >> 8),(char)((ex & 0XFF0000) >> 16),(char)((ex & 0XFF000000) >> 24), 0}; insert_video.prepare("INSERT OR FAIL INTO videos (file, resolution, vcodec, duration, size) VALUES (:file, :resolution, :vcodec, :duration, :size)"); insert_video.bindValue(":file", video); insert_video.bindValue(":resolution", QString::number(videocap.get(CV_CAP_PROP_FRAME_WIDTH)) + "X" + QString::number(videocap.get(CV_CAP_PROP_FRAME_HEIGHT))); insert_video.bindValue(":vcodec",vcodec); insert_video.bindValue(":duration",videocap.get(CV_CAP_PROP_FRAME_COUNT) / videocap.get(CV_CAP_PROP_FPS)); insert_video.bindValue(":size",video_info.size()); qDebug() << "filename: " << video; qDebug() << "video codec: " << insert_video.boundValue(":vcodec").toString() << ex; qDebug() << "resolution: " << insert_video.boundValue(":resolution").toString(); qDebug() << "size: " << insert_video.boundValue(":size").toInt(); qDebug() << "fps: " << videocap.get(CV_CAP_PROP_FPS); if (!insert_video.exec()) qWarning() << "couldn't insert video" << insert_video.lastError(); QSqlQuery create_frames(db); /* * frames table * - file - full path of video this frame belongs to * - position - the position in msec * - descriptors - text - the computed descriptors of the frame */ if (!create_frames.exec("CREATE TABLE IF NOT EXISTS frames(file text, position integer, descriptors text)")) qWarning() << "could not create frames table" << create_frames.lastError(); if (scanwatcher.isCanceled()) { db.rollback(); frame.release(); imgDescriptor.release(); videocap.release(); return; } for(; ; ) { if (scanwatcher.isCanceled()) { db.rollback(); frame.release(); imgDescriptor.release(); videocap.release(); return; } if (current_interval != 0) videocap.set(CV_CAP_PROP_POS_MSEC,current_interval); if (current_interval > videocap.get(CV_CAP_PROP_POS_MSEC) + 400) break; if (!videocap.read(frame)) break; current_interval += interval; if (frame.empty() || !frame.isContinuous()) continue; cv::Size fsize = frame.size(); QTime timestamp(0,0,0,0); timestamp = timestamp.addMSecs(videocap.get(CV_CAP_PROP_POS_MSEC)); qDebug() << timestamp.toString("hh:mm:ss") << fsize.width << fsize.height; // if (fsize.width != videocap.get(CV_CAP_PROP_FRAME_WIDTH) && fsize.height != videocap.get(CV_CAP_PROP_FRAME_HEIGHT)) // continue; odetector->detect(frame,keypoints); odetector->compute(frame,keypoints,imgDescriptor); if (imgDescriptor.empty() || !imgDescriptor.isContinuous()) { qDebug() << "descriptors empty or corrupted" << imgDescriptor.empty() << imgDescriptor.isContinuous(); continue; } // qDebug() << "UMat" << imgDescriptor.empty() << "columns" << imgDescriptor.cols; QSqlQuery frame_insert(db); frame_insert.prepare("INSERT INTO frames(file, position, descriptors) VALUES(:file, :position, :descriptors)"); frame_insert.bindValue(":file",video); frame_insert.bindValue(":position",videocap.get(CV_CAP_PROP_POS_MSEC)); { Mat imgDescriptorMat = imgDescriptor.getMat(cv::ACCESS_READ); FileStorage tempfs("", FileStorage::WRITE | FileStorage::MEMORY | FileStorage::FORMAT_YAML); tempfs << "descriptors" << imgDescriptorMat; string ts = tempfs.releaseAndGetString(); // qDebug() << ts.c_str(); frame_insert.bindValue(":descriptors", ts.c_str()); } if (!frame_insert.exec()) qWarning() << "could not insert frame" << frame_insert.lastError(); keypoints.clear(); } db.commit(); frame.release(); imgDescriptor.release(); videocap.release(); video = ""; }
now when i call qfuture::pause on the instance, of course it will not pause until it exits the function. So is there any way to check in the for loop for if qfuture is paused and pause the loop somehow and resume when resume is called?
If that is not possible is there a way to make the map function reprocess the items it was on when paused and I can just kill the loop?
If it didn't require void function I would just return -1 so it would know it failed.Any ideas??
1/1