Ticket #5176: kenburns-no-fdlib.patch

File kenburns-no-fdlib.patch, 14.2 KB (added by joepadmiraal, 14 years ago)

Removed the face detection code and tested it with trunk r26628

  • mythgallery/mythgallery/glsingleview.cpp

     
    3131#include <QImage>
    3232#include <QDir>
    3333#include <QPainter>
     34#include <qbuffer.h>
    3435
    3536// MythTV plugin headers
    3637#include <mythcontext.h>
     
    3839#include <mythuihelper.h>
    3940
    4041// MythGallery headers
     42#include "config.h"
    4143#include "glsingleview.h"
    4244#include "galleryutil.h"
    4345
     
    9597      // Unshared effect state variables
    9698      m_effect_cube_xrot(0.0f),
    9799      m_effect_cube_yrot(0.0f),
    98       m_effect_cube_zrot(0.0f)
     100      m_effect_cube_zrot(0.0f),
     101      m_effect_kenBurns_image_ready(true),
     102      m_effect_kenBurns_initialized(false),
     103      m_effect_kenBurns_new_image_started(true)
    99104{
    100105    m_scaleMax = (ScaleMax) gCoreContext->GetNumSetting("GalleryScaleMax", 0);
    101106
     
    707712    m_effect_map.insert("slide (gl)",      "EffectSlide");
    708713    m_effect_map.insert("flutter (gl)",    "EffectFlutter");
    709714    m_effect_map.insert("cube (gl)",       "EffectCube");
     715    m_effect_map.insert("Ken Burns (gl)",  "EffectKenBurns");
    710716}
    711717
    712718void GLSingleView::RunEffect(const QString &effect)
     
    729735        EffectFlutter();
    730736    else if (effect == "EffectCube")
    731737        EffectCube();
     738    else if (effect == "EffectKenBurns")
     739        EffectKenBurns();
    732740    else //if (effect == "EffectNone")
    733741        EffectNone();
    734742}
     
    12121220    m_effect_current_frame++;
    12131221}
    12141222
     1223void GLSingleView::EffectKenBurns(void)
     1224{
     1225
     1226    float single_image_pct = 0.75;
     1227    float trans_pct = 1.0 - single_image_pct;
     1228    float scale_max, x_loc, y_loc;
     1229    float scale_factor = 0;
     1230
     1231    //initialize effect   
     1232    if (!m_effect_kenBurns_initialized)
     1233    {
     1234               
     1235        m_effect_kenBurns_initialized = !m_effect_kenBurns_initialized;
     1236        m_effect_kenBurns_item = NULL;
     1237        // Need to load images in the background to keep effect smooth
     1238        m_effect_kenBurns_imageLoadThread = new KenBurnsImageLoader(this, m_itemList, m_texSize, m_screenSize);
     1239        //Since total image time is longer/different than effect time, create image timers
     1240        m_effect_kenBurns_image_time[m_texCur ? 0 : 1].restart();
     1241        // Pan image to a random location
     1242        FindRandXY(m_effect_kenBurns_location_x[0], m_effect_kenBurns_location_y[0]);
     1243        // Since first two images are preloaded, hardcode  them to zoom in
     1244        m_effect_kenBurns_projection[0] = 1;
     1245        m_effect_kenBurns_projection[1] = 1;
     1246        m_effect_kenBurns_image_timeout = m_effect_transition_timeout +
     1247                (m_effect_transition_timeout * trans_pct);
     1248    }
     1249
     1250    if (m_effect_frame_time.elapsed() >= m_effect_transition_timeout)
     1251    {
     1252        // Effect timed out, move new image to old image but don't load new image yet...
     1253        m_tex1First = !m_tex1First;
     1254        m_texCur      = (m_texCur) ? 0 : 1;
     1255        m_effect_current_frame  = 0;
     1256        m_effect_frame_time.restart();
     1257
     1258        m_effect_kenBurns_image_ready = false;
     1259
     1260        // Find next image to be loaded
     1261        int oldpos = m_pos;
     1262
     1263        while (true)
     1264        {
     1265            m_pos = m_slideshow_sequence->next();
     1266            m_effect_kenBurns_item = m_itemList.at(m_pos);
     1267            if (m_effect_kenBurns_item)
     1268            {
     1269                // Skip movies
     1270                if (QFile::exists(m_effect_kenBurns_item->GetPath()) && !GalleryUtil::IsMovie(m_effect_kenBurns_item->GetPath()))
     1271                {
     1272                    break;
     1273                }
     1274            }
     1275            if (m_pos == oldpos)
     1276            {
     1277                // No valid items!!!
     1278                close();
     1279            }
     1280        }
     1281        m_effect_kenBurns_imageLoadThread->Initialize(m_pos);
     1282        m_effect_kenBurns_imageLoadThread->start();
     1283    }
     1284
     1285    float t[2], elapsed[2], s[2], effect_pct;
     1286    elapsed[m_texCur] = m_effect_kenBurns_image_time[m_texCur].elapsed();
     1287    elapsed[m_texCur ? 0 : 1] = m_effect_kenBurns_image_time[m_texCur ? 0 : 1].elapsed();
     1288    //progress linearly
     1289    t[m_texCur] = elapsed[m_texCur] / m_effect_kenBurns_image_timeout;
     1290    t[m_texCur ? 0 : 1] = elapsed[m_texCur ? 0 : 1] / m_effect_kenBurns_image_timeout;
     1291    //progress faster initially then slowing down- this is needed to ensure images zoom faster than they pan and
     1292    //therefore stay completely on the screen
     1293    s[m_texCur] = sqrt(elapsed[m_texCur]) / sqrt(m_effect_kenBurns_image_timeout);
     1294    s[m_texCur ? 0 : 1] = sqrt(elapsed[m_texCur ? 0 : 1]) / sqrt(m_effect_kenBurns_image_timeout);
     1295   
     1296    effect_pct = m_effect_frame_time.elapsed() *  m_effect_transition_timeout_inv;
     1297
     1298    // Load new image if its ready
     1299    if (effect_pct > single_image_pct && m_effect_kenBurns_image_ready)
     1300    {
     1301        if (!m_effect_kenBurns_new_image_started)
     1302        {                       
     1303            if (m_effect_kenBurns_item) //Do not create textures for first two images, since they are preloaded
     1304            {
     1305                m_texItem[!m_tex1First].SetItem(m_effect_kenBurns_item, m_effect_kenBurns_orig_image_size);
     1306                m_texItem[!m_tex1First].ScaleTo(m_screenSize, m_scaleMax);
     1307                m_texItem[!m_tex1First].Init(m_effect_kenBurns_image);
     1308                UpdateLCD(m_effect_kenBurns_item);
     1309               
     1310                //choose the location and projection (zoom in or out) randomly
     1311                FindRandXY(m_effect_kenBurns_location_x[m_texCur], m_effect_kenBurns_location_y[m_texCur]);
     1312                m_effect_kenBurns_projection[m_texCur] = 1 + (int)((2.0f * rand() / (RAND_MAX + 1.0f)));
     1313
     1314            }
     1315            else  //No item, must be 1 of the first two preloaded items
     1316            {
     1317                //start at random location and zoom out to face in center
     1318                FindRandXY(m_effect_kenBurns_location_x[m_texCur], m_effect_kenBurns_location_y[m_texCur]);
     1319                m_effect_kenBurns_projection[m_texCur] = 1;
     1320            }
     1321
     1322            m_effect_kenBurns_image_time[m_texCur].restart();
     1323            m_effect_kenBurns_new_image_started = true;
     1324        }
     1325        if (m_effect_kenBurns_projection[m_texCur] == 1) // Zoom in image
     1326        {
     1327            // Start in center and pan out
     1328            x_loc = m_effect_kenBurns_location_x[m_texCur] * t[m_texCur];
     1329            y_loc = m_effect_kenBurns_location_y[m_texCur] * t[m_texCur];               
     1330            scale_max = FindMaxScale(x_loc,y_loc);
     1331            scale_factor =      1.0f + (scale_max * s[m_texCur]);
     1332        }
     1333        else // Zoom out image
     1334        {
     1335            // Start at random location and pan to center
     1336            x_loc = m_effect_kenBurns_location_x[m_texCur] -  m_effect_kenBurns_location_x[m_texCur] * t[m_texCur];
     1337            y_loc = m_effect_kenBurns_location_y[m_texCur] -  m_effect_kenBurns_location_y[m_texCur] * t[m_texCur];
     1338            scale_max = FindMaxScale(x_loc,y_loc);
     1339            scale_factor =      1.0f + scale_max -  (scale_max * t[m_texCur]);
     1340        }
     1341
     1342        glMatrixMode(GL_MODELVIEW);
     1343        glLoadIdentity();
     1344        glTranslatef(x_loc, y_loc, 0.0f);
     1345
     1346        m_texItem[m_texCur].MakeQuad((effect_pct-single_image_pct)*4, scale_factor);
     1347    }
     1348   
     1349    //Load old picture
     1350    if (m_effect_kenBurns_projection[m_texCur ? 0 : 1] == 1)// Zoom in image
     1351    {
     1352        x_loc = m_effect_kenBurns_location_x[m_texCur ? 0 : 1] * t[m_texCur ? 0 : 1];
     1353        y_loc = m_effect_kenBurns_location_y[m_texCur ? 0 : 1] * t[m_texCur ? 0 : 1];
     1354        scale_max = FindMaxScale(x_loc,y_loc);
     1355        scale_factor =  1.0f + (scale_max * s[m_texCur ? 0 : 1]);
     1356    }
     1357    else // Zoom out image
     1358    {
     1359        x_loc = m_effect_kenBurns_location_x[m_texCur ? 0 : 1] - 
     1360            m_effect_kenBurns_location_x[m_texCur ? 0 : 1] * t[m_texCur ? 0 : 1];
     1361        y_loc = m_effect_kenBurns_location_y[m_texCur ? 0 : 1] - 
     1362            m_effect_kenBurns_location_y[m_texCur ? 0 : 1] * t[m_texCur ? 0 : 1];
     1363        scale_max = FindMaxScale(x_loc,y_loc);
     1364        scale_factor =  1.0f + scale_max -  (scale_max * t[m_texCur ? 0 : 1]);
     1365    }
     1366
     1367    glMatrixMode(GL_MODELVIEW);
     1368    glLoadIdentity();
     1369    glTranslatef(x_loc, y_loc, 0.0f);
     1370
     1371    if (effect_pct<= single_image_pct)
     1372    {
     1373        m_effect_kenBurns_new_image_started=false;
     1374        m_texItem[m_texCur ? 0 : 1].MakeQuad(1.0f, scale_factor); //
     1375    }
     1376    else // Fade out image
     1377    {
     1378        m_texItem[m_texCur ? 0 : 1].MakeQuad(1.0f - ((effect_pct-single_image_pct)*4), scale_factor);
     1379
     1380    }
     1381   
     1382    m_effect_current_frame++;
     1383}
     1384
    12151385void GLSingleView::SlideTimeout(void)
    12161386{
    12171387    bool wasMovie = false, isMovie = false;
     
    13181488    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    13191489    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    13201490}
     1491
     1492void GLSingleView::LoadImage(QImage image, QSize origSize)
     1493{
     1494    m_effect_kenBurns_image = image;
     1495    m_effect_kenBurns_orig_image_size = origSize;
     1496}
     1497
     1498float GLSingleView::FindMaxScale(float x_loc, float y_loc)
     1499{
     1500    // Zoom big enough to keep the entire image on screen when we pan
     1501    if (abs(x_loc) > abs(y_loc))
     1502        return abs(x_loc) * 2;
     1503    else
     1504        return abs(y_loc) * 2;
     1505}
     1506
     1507void GLSingleView::FindRandXY(float &x_loc, float &y_loc)
     1508{
     1509    x_loc = (0.5 * rand() / (RAND_MAX + 1.0f)) + 0.25;  //Random number between .25 and .75
     1510    if ((int)(2.0 * rand() / (RAND_MAX + 1.0f)) == 0)
     1511        x_loc = -1 * x_loc;
     1512    y_loc = (0.5 * rand() / (RAND_MAX + 1.0f)) + 0.25;  //Random number between .25 and .75
     1513    if ((int)(2.0 * rand() / (RAND_MAX + 1.0f)) == 0)
     1514        y_loc = -1 * y_loc;   
     1515}
     1516
     1517KenBurnsImageLoader::KenBurnsImageLoader(GLSingleView *singleView, ThumbList &itemList, QSize texSize, QSize screenSize)
     1518{
     1519    m_singleView = singleView;
     1520    m_itemList = itemList;
     1521    m_texSize = texSize;
     1522    m_screenSize = screenSize;
     1523}
     1524
     1525void KenBurnsImageLoader::Initialize(int pos)
     1526{
     1527    m_pos = pos;
     1528}
     1529
     1530void KenBurnsImageLoader::run()
     1531{
     1532    ThumbItem *item = m_itemList.at(m_pos);
     1533    if (!item)
     1534    {
     1535        VERBOSE(VB_IMPORTANT, LOC_ERR + "No item at "<<m_pos);
     1536        return;
     1537    }
     1538    QImage image(item->GetPath());
     1539    if (image.isNull())
     1540        return;
     1541   
     1542    m_singleView->LoadImage(QGLWidget::convertToGLFormat(image.scaled(m_texSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)), image.size());   
     1543    m_singleView->Ready();
     1544
     1545}
  • mythgallery/mythgallery/glsingleview.h

     
    2323#define GLSINGLEVIEW_H
    2424#ifdef USING_OPENGL
    2525
     26
    2627// MythTV plugin headers
    2728#include <util.h>
    2829#include <mythdialogs.h>
     
    3738class QTimer;
    3839
    3940class GLSingleView;
     41class KenBurnsImageLoader;
    4042
    4143class GLSDialog : public MythDialog
    4244{
     
    6264    ~GLSingleView();
    6365
    6466    void CleanUp(void);
     67    void Ready(){m_effect_kenBurns_image_ready = true;}
     68    void LoadImage(QImage image, QSize origSize);
     69   
    6570
    6671  protected:
    6772    void initializeGL(void);
     
    99104    void EffectSlide(void);
    100105    void EffectFlutter(void);
    101106    void EffectCube(void);
    102 
     107    void EffectKenBurns(void);
     108 
     109  private:
     110        float FindMaxScale(float x_loc, float y_loc);
     111        void FindRandXY(float &x_loc, float &y_loc);
     112   
    103113  private slots:
    104114    void SlideTimeout(void);
    105115
     
    130140    float         m_effect_cube_xrot;
    131141    float         m_effect_cube_yrot;
    132142    float         m_effect_cube_zrot;
     143    float         m_effect_kenBurns_location_x[2];
     144    float         m_effect_kenBurns_location_y[2];
     145    int           m_effect_kenBurns_projection[2];
     146    MythTimer     m_effect_kenBurns_image_time[2];
     147    float         m_effect_kenBurns_image_timeout;
     148    KenBurnsImageLoader *m_effect_kenBurns_imageLoadThread;
     149    bool          m_effect_kenBurns_image_ready;
     150    QImage        m_effect_kenBurns_image;
     151    QSize         m_effect_kenBurns_orig_image_size;
     152    ThumbItem     *m_effect_kenBurns_item;
     153    bool          m_effect_kenBurns_initialized;
     154    bool          m_effect_kenBurns_new_image_started;
     155   
    133156};
    134157
     158class KenBurnsImageLoader : public QThread
     159{
     160public:
     161    KenBurnsImageLoader(GLSingleView *singleView, ThumbList &itemList, QSize m_texSize, QSize m_screenSize);
     162    void Initialize(int pos);
     163    void run();
     164private:
     165        GLSingleView *m_singleView;
     166    ThumbList     m_itemList;
     167    int           m_pos;
     168    bool          m_tex1First;
     169    QSize         m_screenSize;
     170    QSize         m_texSize;
     171
     172};
     173
    135174#endif // USING_OPENGL
    136175#endif // GLSINGLEVIEW_H
  • mythgallery/mythgallery/imageview.cpp

     
    139139{
    140140    QMap<QString,QString> tmpMap = m_effect_map;
    141141    tmpMap.remove("none");
     142    tmpMap.remove("Ken Burns (gl)");
    142143    QStringList t = tmpMap.keys();
    143144    int i = (int) ( (float)(t.count()) * rand() / (RAND_MAX + 1.0f) );
    144145    return tmpMap[t[i]];
  • mythgallery/mythgallery/gallerysettings.cpp

     
    105105    gc->addSelection("flutter (gl)");
    106106    gc->addSelection("cube (gl)");
    107107    gc->addSelection("random (gl)");
     108    gc->addSelection("Ken Burns (gl)");
    108109    gc->setHelpText(QObject::tr("This is the type of OpenGL transition used "
    109110                    "between pictures in slideshow mode."));
    110111    return gc;
     
    113114static HostSpinBox *SlideshowOpenGLTransitionLength()
    114115{
    115116    HostSpinBox *gc = new HostSpinBox(
    116         "SlideshowOpenGLTransitionLength", 500, 10000, 500);
     117        "SlideshowOpenGLTransitionLength", 500, 30000, 500);
    117118    gc->setLabel(QObject::tr("Duration of OpenGL Transition (milliseconds)"));
    118119    gc->setValue(2000);
    119120    return gc;
     
    159160
    160161static HostSpinBox *SlideshowDelay()
    161162{
    162     HostSpinBox *gc = new HostSpinBox("SlideshowDelay", 1, 600, 1);
     163    HostSpinBox *gc = new HostSpinBox("SlideshowDelay", 0, 600, 1);
    163164    gc->setLabel(QObject::tr("Slideshow Delay"));
    164165    gc->setValue(5);
    165166    gc->setHelpText(QObject::tr("This is the number of seconds to display each "