Пример #1
0
bool PreviewGenerator::SavePreview(QString filename,
                                   const unsigned char *data,
                                   uint width, uint height, float aspect,
                                   int desired_width, int desired_height)
{
    if (!data || !width || !height)
        return false;

    if( height == 1088 )
    {
        // Remove the extra 8 pixels at the bottom of 1080i recordings that
        // decode to 1088 rows as these are bogus pixels and make the previews
        // look a bit wrong.  The worst offender seems to be H.264 captures
        // from HDPVR.  Apparently, BBC HD also may exhibit the same behavior
        // in the UK, although with a different width.
        height = 1080;
    }

    const QImage img((unsigned char*) data,
                     width, height, QImage::Format_RGB32);

    float ppw = max(desired_width, 0);
    float pph = max(desired_height, 0);
    bool desired_size_exactly_specified = true;
    if ((ppw < 1.0f) && (pph < 1.0f))
    {
        ppw = gCoreContext->GetNumSetting("PreviewPixmapWidth",  320);
        pph = gCoreContext->GetNumSetting("PreviewPixmapHeight", 240);
        desired_size_exactly_specified = false;
    }

    aspect = (aspect <= 0.0f) ? ((float) width) / height : aspect;
    pph = (pph < 1.0f) ? (ppw / aspect) : pph;
    ppw = (ppw < 1.0f) ? (pph * aspect) : ppw;

    if (!desired_size_exactly_specified)
    {
        if (aspect > ppw / pph)
            pph = (ppw / aspect);
        else
            ppw = (pph * aspect);
    }

    ppw = max(1.0f, ppw);
    pph = max(1.0f, pph);;

    QImage small_img = img.scaled((int) ppw, (int) pph,
        Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    QTemporaryFile f(QFileInfo(filename).absoluteFilePath()+".XXXXXX");
    f.setAutoRemove(false);
    if (f.open() && small_img.save(&f, "PNG"))
    {
        // Let anybody update it
        makeFileAccessible(f.fileName().toLocal8Bit().constData());
        QFile of(filename);
        of.remove();
        if (f.rename(filename))
        {
            LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Saved preview '%0' %1x%2")
                    .arg(filename).arg((int) ppw).arg((int) pph));
            return true;
        }
        f.remove();
    }

    return false;
}
Пример #2
0
QFileInfo Content::GetPreviewImage(        int        nRecordedId,
                                           int        nChanId,
                                     const QDateTime &recstarttsRaw,
                                           int        nWidth,
                                           int        nHeight,
                                           int        nSecsIn,
                                     const QString   &sFormat )
{
    if ((nRecordedId <= 0) &&
        (nChanId <= 0 || !recstarttsRaw.isValid()))
        throw QString("Recorded ID or Channel ID and StartTime appears invalid.");

    if (!sFormat.isEmpty()
        && !QImageWriter::supportedImageFormats().contains(sFormat.toLower().toLocal8Bit()))
    {
        throw "GetPreviewImage: Specified 'Format' is not supported.";
    }

    // ----------------------------------------------------------------------
    // Read Recording From Database
    // ----------------------------------------------------------------------

    // TODO Should use RecordingInfo
    ProgramInfo pginfo;
    if (nRecordedId > 0)
        pginfo = ProgramInfo(nRecordedId);
    else
        pginfo = ProgramInfo(nChanId, recstarttsRaw.toUTC());

    if (!pginfo.GetChanID())
    {
        LOG(VB_GENERAL, LOG_ERR,
            QString("GetPreviewImage: No recording for '%1'")
            .arg(nRecordedId));
        return QFileInfo();
    }

    if (pginfo.GetHostname().toLower() != gCoreContext->GetHostName().toLower())
    {
        QString sMsg =
            QString("GetPreviewImage: Wrong Host '%1' request from '%2'")
                          .arg( gCoreContext->GetHostName())
                          .arg( pginfo.GetHostname() );

        LOG(VB_UPNP, LOG_ERR, sMsg);

        throw HttpRedirectException( pginfo.GetHostname() );
    }

    QString sImageFormat = sFormat;
    if (sImageFormat.isEmpty())
        sImageFormat = "PNG";

    QString sFileName = GetPlaybackURL(&pginfo);

    // ----------------------------------------------------------------------
    // check to see if default preview image is already created.
    // ----------------------------------------------------------------------

    QString sPreviewFileName;

    if (nSecsIn <= 0)
    {
        nSecsIn = -1;
        sPreviewFileName = QString("%1.png").arg(sFileName);
    }
    else
    {
        sPreviewFileName = QString("%1.%2.png").arg(sFileName).arg(nSecsIn);
    }

    if (!QFile::exists( sPreviewFileName ))
    {
        // ------------------------------------------------------------------
        // Must generate Preview Image, Generate Image and save.
        // ------------------------------------------------------------------
        if (!pginfo.IsLocal() && sFileName.startsWith("/"))
            pginfo.SetPathname(sFileName);

        if (!pginfo.IsLocal())
            return QFileInfo();

        PreviewGenerator *previewgen = new PreviewGenerator( &pginfo, 
                                                             QString(), 
                                                             PreviewGenerator::kLocal);
        previewgen->SetPreviewTimeAsSeconds( nSecsIn          );
        previewgen->SetOutputFilename      ( sPreviewFileName );

        bool ok = previewgen->Run();

        previewgen->deleteLater();

        if (!ok)
            return QFileInfo();
    }

    bool bDefaultPixmap = (nWidth == 0) && (nHeight == 0);

    QString sNewFileName;

    if (bDefaultPixmap)
        sNewFileName = sPreviewFileName;
    else
    {
        sNewFileName = QString( "%1.%2.%3x%4.%5" )
                          .arg( sFileName )
                          .arg( nSecsIn   )
                          .arg( nWidth == 0 ? -1 : nWidth )
                          .arg( nHeight == 0 ? -1 : nHeight )
                          .arg( sImageFormat.toLower() );

        // ----------------------------------------------------------------------
        // check to see if scaled preview image is already created and isn't
        // out of date
        // ----------------------------------------------------------------------
        if (QFile::exists( sNewFileName ))
        {
            if (QFileInfo(sPreviewFileName).lastModified() <=
                QFileInfo(sNewFileName).lastModified())
                return QFileInfo( sNewFileName );
        }

        QImage image = QImage(sPreviewFileName);

        if (image.isNull())
            return QFileInfo();

        // We can just re-scale the default (full-size version) to avoid
        // a preview generator run
        if ( nWidth <= 0 )
            image = image.scaledToHeight(nHeight, Qt::SmoothTransformation);
        else if ( nHeight <= 0 )
            image = image.scaledToWidth(nWidth, Qt::SmoothTransformation);
        else
            image = image.scaled(nWidth, nHeight, Qt::IgnoreAspectRatio,
                                        Qt::SmoothTransformation);

        image.save(sNewFileName, sImageFormat.toUpper().toLocal8Bit());

        // Let anybody update it
        bool ret = makeFileAccessible(sNewFileName.toLocal8Bit().constData());
        if (!ret)
        {
            LOG(VB_GENERAL, LOG_ERR, "Unable to change permissions on "
                                     "preview image. Backends and frontends "
                                     "running under different users will be "
                                     "unable to access it");
        }
    }

    if (QFile::exists( sNewFileName ))
        return QFileInfo( sNewFileName );

    PreviewGenerator *previewgen = new PreviewGenerator( &pginfo,
                                                         QString(),
                                                         PreviewGenerator::kLocal);
    previewgen->SetPreviewTimeAsSeconds( nSecsIn             );
    previewgen->SetOutputFilename      ( sNewFileName        );
    previewgen->SetOutputSize          (QSize(nWidth,nHeight));

    bool ok = previewgen->Run();

    previewgen->deleteLater();

    if (!ok)
        return QFileInfo();

    return QFileInfo( sNewFileName );
}
Пример #3
0
bool PreviewGenerator::SavePreview(const QString &filename,
                                   const unsigned char *data,
                                   uint width, uint height, float aspect,
                                   int desired_width, int desired_height,
                                   const QString &format)
{
    if (!data || !width || !height)
        return false;

    const QImage img((unsigned char*) data,
                     width, height, QImage::Format_RGB32);

    float ppw = max(desired_width, 0);
    float pph = max(desired_height, 0);
    bool desired_size_exactly_specified = true;
    if ((ppw < 1.0f) && (pph < 1.0f))
    {
        ppw = img.width();
        pph = img.height();
        desired_size_exactly_specified = false;
    }

    aspect = (aspect <= 0.0f) ? ((float) width) / height : aspect;
    pph = (pph < 1.0f) ? (ppw / aspect) : pph;
    ppw = (ppw < 1.0f) ? (pph * aspect) : ppw;

    if (!desired_size_exactly_specified)
    {
        if (aspect > ppw / pph)
            pph = (ppw / aspect);
        else
            ppw = (pph * aspect);
    }

    ppw = max(1.0f, ppw);
    pph = max(1.0f, pph);;

    QImage small_img = img.scaled((int) ppw, (int) pph,
        Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    QTemporaryFile f(QFileInfo(filename).absoluteFilePath()+".XXXXXX");
    f.setAutoRemove(false);
    if (f.open() && small_img.save(&f, format.toLocal8Bit().constData()))
    {
        // Let anybody update it
        bool ret = makeFileAccessible(f.fileName().toLocal8Bit().constData());
        if (!ret)
        {
            LOG(VB_GENERAL, LOG_ERR, "Unable to change permissions on "
                                     "preview image. Backends and frontends "
                                     "running under different users will be "
                                     "unable to access it");
        }
        QFile of(filename);
        of.remove();
        if (f.rename(filename))
        {
            LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Saved preview '%0' %1x%2")
                    .arg(filename).arg((int) ppw).arg((int) pph));
            return true;
        }
        f.remove();
    }

    return false;
}