MetaDataWorker.cpp 8.08 KB
Newer Older
Christophe Courtaut's avatar
Christophe Courtaut committed
1
/*****************************************************************************
2
 * MetaDataWorker.cpp: Implement the thread that will get the media informations
Christophe Courtaut's avatar
Christophe Courtaut committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 *****************************************************************************
 * Copyright (C) 2008-2009 the VLMC team
 *
 * Authors: Hugo Beauzee-Luyssen <hugo@vlmc.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/
22

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
23
#include <QtDebug>
24 25

#include "vlmc.h"
26
#include "MetaDataWorker.h"
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
27 28
#include "Library.h"

29 30 31
MetaDataWorker::MetaDataWorker( Media* media ) :
        m_currentMedia( media ),
        m_mediaIsPlaying( false),
32
        m_lengthHasChanged( true )
33 34 35 36
{
    m_mediaPlayer = new LibVLCpp::MediaPlayer();
}

37
MetaDataWorker::~MetaDataWorker()
38 39 40 41 42
{
    if (m_mediaPlayer)
        delete m_mediaPlayer;
}

43
void    MetaDataWorker::run()
44
{
45
    if ( m_currentMedia->getFileType() == Media::Video )
46
    {
47
        computeVideoMetaData();
48
    }
49 50 51 52 53 54 55 56
    else if ( m_currentMedia->getFileType() == Media::Image )
    {
        computeImageMetaData();
    }
    m_mediaPlayer->setMedia( m_currentMedia->getVLCMedia() );
    connect( m_mediaPlayer, SIGNAL( playing() ), this, SLOT( entrypointPlaying() ) );
    m_mediaPlayer->play();
    m_currentMedia->flushVolatileParameters();
57 58
}

59
void    MetaDataWorker::computeVideoMetaData()
60 61
{
    //Disabling audio for this specific use of the media
62
    m_currentMedia->addVolatileParam( ":no-audio", ":audio" );
63
    m_currentMedia->addConstantParam( ":vout=dummy" );
64

65
    connect( m_mediaPlayer, SIGNAL( lengthChanged() ), this, SLOT( entrypointLengthChanged() ) );
66 67
}

68
void    MetaDataWorker::computeImageMetaData()
69
{
70 71
    m_currentMedia->addVolatileParam( ":access=fake", ":access=''" );
    m_currentMedia->addVolatileParam( ":fake-duration=10000", ":fake-duration=''" );
72 73
}

74
void    MetaDataWorker::getMetaData()
75
{
76
    m_mediaIsPlaying = false;
77
    m_lengthHasChanged = true;
78

79
    //In order to wait for the VOUT to be ready:
80 81 82
    //Until we have a way of knowing when it is, both getWidth and getHeight method
    //will trigger exception... so we shut it up.
    LibVLCpp::Exception::setErrorCallback( LibVLCpp::Exception::silentExceptionHandler );
83 84
    while ( m_mediaPlayer->getWidth() == 0 )
        SleepMS( 1 ); //Ugly isn't it :)
85 86
    LibVLCpp::Exception::setErrorCallback( NULL );

87
    m_currentMedia->setLength( m_mediaPlayer->getLength() );
88

89 90
    m_currentMedia->setWidth( m_mediaPlayer->getWidth() );
    m_currentMedia->setHeight( m_mediaPlayer->getHeight() );
91
    m_currentMedia->setFps( m_mediaPlayer->getFps() );
92

93
    //Setting time for snapshot :
94
    if ( m_currentMedia->getFileType() == Media::Video )
95 96 97 98 99 100
    {
        connect( m_mediaPlayer, SIGNAL( positionChanged() ), this, SLOT( renderSnapshot() ) );
        m_mediaPlayer->setTime( m_mediaPlayer->getLength() / 3 );
    }
    else
        renderSnapshot();
101
}
102

103
void    MetaDataWorker::renderSnapshot()
104
{
105
    if ( m_currentMedia->getFileType() == Media::Video )
106
        disconnect( m_mediaPlayer, SIGNAL( positionChanged() ), this, SLOT( renderSnapshot() ) );
107 108 109
    QTemporaryFile tmp;
    tmp.setAutoRemove( false );
    tmp.open();
110
    m_tmpSnapshotFilename = tmp.fileName();
111

112
    connect( m_mediaPlayer, SIGNAL( snapshotTaken() ), this, SLOT( setSnapshot() ), Qt::QueuedConnection );
113 114

    //The slot should be triggered in this methode
115
    m_mediaPlayer->takeSnapshot( m_tmpSnapshotFilename.toStdString().c_str()
116
                                 , 0, 0 );
117 118 119
    //Snapshot slot should has been called (but maybe not in next version...)
}

120
void    MetaDataWorker::setSnapshot()
121
{
122 123 124 125
    QPixmap* pixmap = new QPixmap( m_tmpSnapshotFilename );
    if ( pixmap->isNull() )
        delete pixmap;
    else
126
        m_currentMedia->setSnapshot( pixmap );
127 128 129 130
    //TODO : we shouldn't have to do this... patch vlc to get a memory snapshot.
    QFile   tmp( m_tmpSnapshotFilename );
    tmp.remove();

131 132
    disconnect( m_mediaPlayer, SIGNAL( snapshotTaken() ), this, SLOT( setSnapshot() ) );

133 134
    m_currentMedia->emitMetaDataComputed();

135 136
    //CHECKME:
    //This is synchrone, but it may become asynchrone in the future...
137
    m_mediaPlayer->stop();
138
    //startAudioDataParsing();
139
    delete this;
140
}
141

142
void    MetaDataWorker::startAudioDataParsing()
143
{
144 145 146
    qDebug() << "Starting audio parsing";
    char    osb[64], psb[64], csb[64], iph[64], data[64];

147
//    disconnect( m_mediaPlayer, SIGNAL( stopped() ), this, SLOT( startAudioDataParsing() ) );
148

149 150 151 152
    sprintf( osb, ":amem-opensb=%lld", (long long int)(intptr_t) &MetaDataWorker::openSoundBuffer);
    sprintf( psb, ":amem-playsb=%lld", (long long int)(intptr_t) &MetaDataWorker::playSoundBuffer);
    sprintf( csb, ":amem-closesb=%lld", (long long int)(intptr_t) &MetaDataWorker::closeSoundBuffer);
    sprintf( iph, ":amem-iph=%lld", (long long int)(intptr_t) &MetaDataWorker::instanceParameterHandler);
153
    sprintf( data, ":amem-data=%lld", (long long int)(intptr_t) this);
154 155 156 157 158 159 160 161 162 163 164
    m_currentMedia->addVolatileParam( ":no-video", ":video" );
    m_currentMedia->addConstantParam( ":audio" );
    m_currentMedia->addVolatileParam( ":aout=amem", ":aout=''" ); //I'm really not sure about this one...
    m_currentMedia->addConstantParam( osb );
    m_currentMedia->addConstantParam( psb );
    m_currentMedia->addConstantParam( csb );
    m_currentMedia->addConstantParam( iph );
    m_currentMedia->addConstantParam( data );

    m_mediaPlayer->setMedia( m_currentMedia->getVLCMedia() );
    m_currentMedia->flushVolatileParameters();
165
    connect( m_mediaPlayer, SIGNAL( endReached() ), this, SLOT( stopAudioDataParsing() ) );
166
    qDebug() << "Starting playback again";
167
    m_mediaPlayer->play();
168 169
}

170
void    MetaDataWorker::stopAudioDataParsing()
171
{
172 173
    qDebug() << "Stopping AudioDataParsing";
    m_mediaPlayer->stop();
174 175
}

176
void    MetaDataWorker::openSoundBuffer( void* datas, unsigned int* freq, unsigned int* nbChannels, unsigned int* fourCCFormat, unsigned int* frameSize )
177 178
{
    //qDebug() << "Opening sound buffer with freq =" << *freq << "nbChannels =" << *nbChannels << "frameSize =" << *frameSize;
179 180
    MetaDataWorker* self = reinterpret_cast<MetaDataWorker*>( datas );
    self->m_currentMedia->initAudioData( datas, freq, nbChannels, fourCCFormat, frameSize );
181 182
 }

183
void    MetaDataWorker::playSoundBuffer( void* datas, unsigned char* buffer, size_t buffSize, unsigned int nbSample )
184
{
185
    //qDebug() << "Playing sound buffer with nbSample =" << nbSample << "buffSize =" << buffSize;
186
//    qDebug() << "Buff[0] = " << (unsigned int)buffer[0];
187 188 189
    //if (MetaDataWorker::getInstance()->getCurrentMedia()->getAudioData()->frameList.size() < 500 )
    MetaDataWorker* self = reinterpret_cast<MetaDataWorker*>( datas );
    self->m_currentMedia->addAudioFrame( datas, buffer, buffSize, nbSample );
190
    //else
191
//        MetaDataWorker::getInstance()->getMediaPlayer()->stop();
192 193
}

194
void    MetaDataWorker::closeSoundBuffer( void* datas )
195 196
{
    qDebug() << "Closing sound buffer";
197 198 199
    MetaDataWorker* self = reinterpret_cast<MetaDataWorker*>( datas );

    self->m_mediaPlayer->stop();
200 201
}

202
void    MetaDataWorker::instanceParameterHandler( void*, char*, char* )
203 204
{
}
205

206
void    MetaDataWorker::entrypointLengthChanged()
207 208 209 210 211 212 213
{
    disconnect( m_mediaPlayer, SIGNAL( lengthChanged() ), this, SLOT( entrypointLengthChanged() ) );
    m_lengthHasChanged = true;
    if ( m_mediaIsPlaying == true )
        getMetaData();
}

214
void    MetaDataWorker::entrypointPlaying()
215 216 217 218 219 220
{
    disconnect( m_mediaPlayer, SIGNAL( playing() ), this, SLOT( entrypointPlaying() ) );
    m_mediaIsPlaying = true;
    if ( m_lengthHasChanged == true )
        getMetaData();
}