13#include "kstars_debug.h" 
   14#include "collimationoverlayoptions.h" 
   15#include "qobjectdefs.h" 
   17#include <basedevice.h> 
   19#include <KLocalizedString> 
   27#include <QSocketNotifier> 
   34#include <QImageWriter> 
   35#include <QImageReader> 
   54    connect(selectDirB, SIGNAL(clicked()), 
this, SLOT(selectRecordDirectory()));
 
   57void RecordOptions::selectRecordDirectory()
 
   61                                          dirPath.toLocalFile());
 
   66    recordDirectoryEdit->setText(dir);
 
   73    streamWidth = streamHeight = -1;
 
   74    processStream = colorFrame = isRecording = 
false;
 
   76    options = 
new RecordOptions(
this);
 
   77    connect(optionsB, SIGNAL(clicked()), options, SLOT(show()));
 
   82        CollimationOverlayOptions::Instance(
this)->openEditor();
 
   86    connect(CollimationOverlayOptions::Instance(
this), SIGNAL(updated()), videoFrame, SLOT(modelChanged()));
 
   90    ccd->getSERNameDirectory(filename, directory);
 
   92    double duration = 0.1;
 
   93    bool hasStreamExposure = m_Camera->getStreamExposure(&duration);
 
   94    if (hasStreamExposure)
 
   95        targetFrameDurationSpin->setValue(duration);
 
   98        targetFrameDurationSpin->setEnabled(
false);
 
   99        changeFPSB->setEnabled(
false);
 
  102    options->recordFilenameEdit->setText(filename);
 
  103    options->recordDirectoryEdit->setText(directory);
 
  105    setWindowTitle(
i18nc(
"@title:window", 
"%1 Live Video", ccd->getDeviceName()));
 
  107#if defined(Q_OS_MACOS) 
  120    recordB->setIcon(recordIcon);
 
  123    connect(ccd, &ISD::Camera::videoRecordToggled, 
this, &StreamWG::updateRecordStatus);
 
  125    connect(videoFrame, &VideoWG::newSelection, 
this, &StreamWG::setStreamingFrame);
 
  126    connect(videoFrame, &VideoWG::imageChanged, 
this, &StreamWG::imageChanged);
 
  128    resize(Options::streamWindowWidth(), Options::streamWindowHeight());
 
  130    eoszoom = m_Camera->getProperty(
"eoszoom");
 
  131    if (eoszoom == 
nullptr)
 
  133        zoomLevelCombo->hide();
 
  139            auto tvp = eoszoom->getText();
 
  140            QString zoomLevel = zoomLevelCombo->currentText().
remove(
"x");
 
  142            handLabel->setEnabled(
true);
 
  143            NSSlider->setEnabled(
true);
 
  144            WESlider->setEnabled(
true);
 
  146            m_Camera->sendNewProperty(tvp);
 
  149                m_Camera->sendNewProperty(tvp);
 
  155    eoszoomposition = m_Camera->getProperty(
"eoszoomposition");
 
  156    if (eoszoomposition == 
nullptr)
 
  168            auto tvp = eoszoomposition->getText();
 
  171            m_Camera->sendNewProperty(tvp);
 
  176            auto tvp = eoszoomposition->getText();
 
  179            m_Camera->sendNewProperty(tvp);
 
  185    connect(m_Camera, &ISD::Camera::newFPS, 
this, &StreamWG::updateFPS);
 
  186    connect(m_Camera, &ISD::Camera::propertyUpdated, 
this, [
this](INDI::Property prop)
 
  188        if (prop.isNameMatch(
"CCD_INFO") || prop.isNameMatch(
"CCD_CFA"))
 
  189            syncDebayerParameters();
 
  195            m_Camera->setVideoStreamEnabled(
false);
 
  198                m_Camera->setStreamExposure(targetFrameDurationSpin->value());
 
  199                m_Camera->setVideoStreamEnabled(
true);
 
  204    debayerB->setIcon(
QIcon(
":/icons/cfa.svg"));
 
  207        m_DebayerActive = !m_DebayerActive;
 
  209    syncDebayerParameters();
 
  212void StreamWG::syncDebayerParameters()
 
  214    m_DebayerSupported = queryDebayerParameters();
 
  215    debayerB->setEnabled(m_DebayerSupported);
 
  216    m_DebayerActive = m_DebayerSupported;
 
  219bool StreamWG::queryDebayerParameters()
 
  224    ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
  230    if (targetChip->getISOList().
isEmpty() == 
false)
 
  236    if (targetChip->getImageInfo(w, h, pixelX, pixelY, m_BBP) == 
false)
 
  245    if (targetChip->getBayerInfo(offsetX, offsetY, pattern) == 
false)
 
  248    m_DebayerParams.method = DC1394_BAYER_METHOD_NEAREST;
 
  249    m_DebayerParams.filter = DC1394_COLOR_FILTER_RGGB;
 
  251    if (pattern == 
"GBRG")
 
  252        m_DebayerParams.filter = DC1394_COLOR_FILTER_GBRG;
 
  253    else if (pattern == 
"GRBG")
 
  254        m_DebayerParams.filter = DC1394_COLOR_FILTER_GRBG;
 
  255    else if (pattern == 
"BGGR")
 
  256        m_DebayerParams.filter = DC1394_COLOR_FILTER_BGGR;
 
  261QSize StreamWG::sizeHint()
 const 
  263    QSize 
size(Options::streamWindowWidth(), Options::streamWindowHeight());
 
  273            zoomLevelCombo->setCurrentIndex(0);
 
  281    processStream = 
false;
 
  283    Options::setStreamWindowWidth(
width());
 
  284    Options::setStreamWindowHeight(
height());
 
  291void StreamWG::setColorFrame(
bool color)
 
  296void StreamWG::enableStream(
bool enable)
 
  300        processStream = 
true;
 
  305        processStream = 
false;
 
  307        avgFPS->setText(
"--");
 
  312void StreamWG::setSize(
int wd, 
int ht)
 
  314    if (wd != streamWidth || ht != streamHeight)
 
  319        NSSlider->setMaximum(ht);
 
  320        NSSlider->setSingleStep(ht / 30);
 
  321        WESlider->setMaximum(wd);
 
  322        WESlider->setSingleStep(wd / 30);
 
  324        videoFrame->setSize(wd, ht);
 
  334void StreamWG::updateRecordStatus(
bool enabled)
 
  343        recordB->setIcon(stopIcon);
 
  344        recordB->setToolTip(
i18n(
"Stop recording"));
 
  348        recordB->setIcon(recordIcon);
 
  349        recordB->setToolTip(
i18n(
"Start recording"));
 
  353void StreamWG::toggleRecord()
 
  357        recordB->setIcon(recordIcon);
 
  359        recordB->setToolTip(
i18n(
"Start recording"));
 
  361        m_Camera->stopRecording();
 
  365        QString directory, filename;
 
  366        m_Camera->getSERNameDirectory(filename, directory);
 
  367        if (filename != options->recordFilenameEdit->text() ||
 
  368                directory != options->recordDirectoryEdit->text())
 
  370            m_Camera->setSERNameDirectory(options->recordFilenameEdit->text(), options->recordDirectoryEdit->text());
 
  372            m_Camera->setConfig(SAVE_CONFIG);
 
  375        if (options->recordUntilStoppedR->isChecked())
 
  377            isRecording = m_Camera->startRecording();
 
  379        else if (options->recordDurationR->isChecked())
 
  381            isRecording = m_Camera->startDurationRecording(options->durationSpin->value());
 
  385            isRecording = m_Camera->startFramesRecording(options->framesSpin->value());
 
  390            recordB->setIcon(stopIcon);
 
  391            recordB->setToolTip(
i18n(
"Stop recording"));
 
  396void StreamWG::newFrame(INDI::Property prop)
 
  398    auto bp = prop.getBLOB()->at(0);
 
  400    bool rc = (m_DebayerActive
 
  401               && !strcmp(bp->getFormat(), 
".stream")) ? videoFrame->newBayerFrame(bp, m_DebayerParams) : videoFrame->newFrame(bp);
 
  404        qCWarning(KSTARS) << 
"Failed to load video frame.";
 
  407void StreamWG::resetFrame()
 
  410    if (m_Camera->getStreamExposure(&exposure))
 
  412        m_Camera->setVideoStreamEnabled(
false);
 
  415            m_Camera->setStreamExposure(exposure);
 
  416            m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD)->resetFrame();
 
  417            m_Camera->setVideoStreamEnabled(
true);
 
  421        m_Camera->resetStreamingFrame();
 
  424void StreamWG::setStreamingFrame(
QRect newFrame)
 
  426    if (newFrame.isNull())
 
  432    if (newFrame.width() < 5 || newFrame.height() < 5)
 
  437    m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD)->getFrame(&
x, &
y, &w, &h);
 
  438    auto subX = newFrame.x() + 
x;
 
  439    auto subY = newFrame.y() + 
y;
 
  440    auto subW = newFrame.width();
 
  441    auto subH = newFrame.width();
 
  444    if (m_Camera->getStreamExposure(&exposure))
 
  446        m_Camera->setVideoStreamEnabled(
false);
 
  449            m_Camera->setStreamExposure(exposure);
 
  450            m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD)->setFrame(subX, subY, subW, subH);
 
  451            m_Camera->setVideoStreamEnabled(
true);
 
  455        m_Camera->setStreamingFrame(newFrame.x(), newFrame.y(), w, newFrame.height());
 
  458void StreamWG::updateFPS(
double instantFPS, 
double averageFPS)
 
  467    CollimationOverlayOptions::Instance(
this)->release();
 
Camera class controls an INDI Camera device.
 
This is the main window for KStars.
 
static KStars * Instance()
 
QString i18nc(const char *context, const char *text, const TYPE &arg...)
 
QString i18n(const char *text, const TYPE &arg...)
 
KIOCORE_EXPORT QString dir(const QString &fileClass)
 
const char * constData() const const
 
void activated(int index)
 
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, Options options)
 
QIcon fromTheme(const QString &name)
 
bool isEmpty() const const
 
QString arg(Args &&... args) const const
 
const QChar at(qsizetype position) const const
 
bool isEmpty() const const
 
QString number(double n, char format, int precision)
 
QString & remove(QChar ch, Qt::CaseSensitivity cs)
 
QByteArray toLatin1() const const
 
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
 
QUrl fromLocalFile(const QString &localFile)