void CaptureDialog::CheckAndroidSetup(QString &filename) { ui->androidScan->setVisible(true); ui->androidWarn->setVisible(false); LambdaThread *scan = new LambdaThread([this, filename]() { rdcstr host = m_Ctx.Replay().CurrentRemote()->hostname; RENDERDOC_CheckAndroidPackage(host.c_str(), filename.toUtf8().data(), &m_AndroidFlags); const bool debuggable = bool(m_AndroidFlags & AndroidFlags::Debuggable); const bool hasroot = bool(m_AndroidFlags & AndroidFlags::RootAccess); if(!debuggable && !hasroot) { // Check failed - set the warning visible GUIInvoke::call([this]() { ui->androidScan->setVisible(false); ui->androidWarn->setVisible(true); }); } else { // Check passed, either app is debuggable or we have root - no warnings needed GUIInvoke::call([this]() { ui->androidScan->setVisible(false); ui->androidWarn->setVisible(false); }); } }); scan->start(); scan->deleteLater(); }
void CaptureContext::RecompressCapture() { QString destFilename = GetCaptureFilename(); QString tempFilename; ICaptureFile *cap = NULL; ICaptureFile *tempCap = NULL; bool inplace = false; if(IsCaptureTemporary() || !IsCaptureLocal()) { QMessageBox::StandardButton res = RDDialog::question(m_MainWindow, tr("Unsaved capture"), tr("To recompress a capture you must save it first. Save this capture?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); if(res == QMessageBox::Cancel || res == QMessageBox::No) return; destFilename = m_MainWindow->GetSavePath(); // if it's already local, we'll do the save as part of the recompression convert. If it's // remote, we need to copy it first, but we copy it to a temporary so we can do the conversion // to the target location if(IsCaptureLocal()) { tempFilename = GetCaptureFilename(); } else { tempFilename = TempCaptureFilename(lit("recompress")); Replay().CopyCaptureFromRemote(GetCaptureFilename(), tempFilename, m_MainWindow); if(!QFile::exists(tempFilename)) { RDDialog::critical(m_MainWindow, tr("Failed to save capture"), tr("Capture couldn't be saved from remote.")); return; } } } else { // if we're doing this inplace on an already saved capture, then we need to recompress to a // temporary and close/move it afterwards. inplace = true; destFilename = TempCaptureFilename(lit("recompress")); } if(IsCaptureLocal()) { // for local files we already have a handle. We'll reuse it, then re-open cap = Replay().GetCaptureFile(); } else { // for remote files we open a new short-lived handle on the temporary file tempCap = cap = RENDERDOC_OpenCaptureFile(); cap->OpenFile(tempFilename.toUtf8().data(), "rdc"); } if(!cap) { RDDialog::critical(m_MainWindow, tr("Unexpected missing handle"), tr("Couldn't get open handle to file for recompression.")); return; } int index = cap->FindSectionByType(SectionType::FrameCapture); SectionProperties props = cap->GetSectionProperties(index); if(props.flags & SectionFlags::ZstdCompressed) { RDDialog::information(m_MainWindow, tr("Capture already compressed"), tr("This capture is already compressed as much as is possible.")); if(tempCap) tempCap->Shutdown(); if(!tempFilename.isEmpty()) QFile::remove(tempFilename); return; } // convert from the currently open cap to the destination float progress = 0.0f; LambdaThread *th = new LambdaThread([this, cap, destFilename, &progress]() { cap->Convert(destFilename.toUtf8().data(), "rdc", [&progress](float p) { progress = p; }); }); th->start(); // wait a few ms before popping up a progress bar th->wait(500); if(th->isRunning()) { ShowProgressDialog(m_MainWindow, tr("Recompressing file."), [th]() { return !th->isRunning(); }, [&progress]() { return progress; }); } th->deleteLater(); if(inplace) { // if we're recompressing "in place", we need to close our capture, move the temporary over // the original, then re-open. // this releases the hold over the real desired location. cap->OpenFile("", ""); // now remove the old capture QFile::remove(GetCaptureFilename()); // move the recompressed one over QFile::rename(destFilename, GetCaptureFilename()); // and re-open cap->OpenFile(GetCaptureFilename().c_str(), "rdc"); } else { // we've converted into the desired location. We don't have to do anything else but mark our // new locally saved non-temporary status. m_CaptureFile = destFilename; m_CaptureLocal = true; m_CaptureTemporary = false; // open the saved capture file. This will let us remove the old file too Replay().ReopenCaptureFile(m_CaptureFile); m_CaptureMods = CaptureModifications::All; SaveChanges(); } // close any temporary resources if(tempCap) tempCap->Shutdown(); if(!tempFilename.isEmpty()) QFile::remove(tempFilename); }