Commit 500354f2 authored by Hugo Beauzee-Luyssen's avatar Hugo Beauzee-Luyssen

Big media code refactoring

We now have an InputMedia / OutputMedia that inherits from a generic class Media
Added .mpg .mpeg and .wmv
Preview is now working with drag and drop.
parent 762d293e
/*****************************************************************************
* InputMedia.cpp: Class for media handling
*****************************************************************************
* 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.
*****************************************************************************/
#include <QtDebug>
#include <QTemporaryFile>
#include "InputMedia.h"
InputMedia::InputMedia( const QString& mrl, LibVLCpp::Instance* instance /*= NULL*/ ) : Media( instance, mrl ), m_snapshot( NULL )
{
// m_vlcMedia->outputInVmem();
// m_vlcMedia->setLockCallback( InputMedia::lock );
// m_vlcMedia->setUnlockCallback( InputMedia::unlock );
char width[64], height[64], chroma[64], pitch[64];
sprintf( width, ":vmem-width=%i", VIDEOWIDTH );
sprintf( height, ":vmem-height=%i", VIDEOHEIGHT );
sprintf( chroma, ":vmem-chroma=%s", "RV32" );
sprintf( pitch, ":vmem-pitch=%i", VIDEOWIDTH * 4 );
// m_vlcMedia->addOption( width );
// m_vlcMedia->addOption( height );
// m_vlcMedia->addOption( chroma );
// m_vlcMedia->addOption( pitch );
// m_pixelBuffer = new uchar[ VIDEOHEIGHT * VIDEOWIDTH * 4 ];
// m_image = new QImage( m_pixelBuffer, VIDEOWIDTH, VIDEOHEIGHT, VIDEOWIDTH * 4, QImage::Format_RGB32 );
// m_image->fill( 0 );
//Once we got the pixel buffer up and running, we can put it in the "render context"
// m_vlcMedia->setPixelBuffer( m_pixelBuffer );
// m_vlcMedia->setDataCtx();
}
InputMedia::~InputMedia()
{
delete m_image;
delete m_pixelBuffer;
}
void InputMedia::lock( LibVLCpp::Media::DataCtx* ctx, void **renderPtr )
{
ctx->mutex->lock();
*renderPtr = ctx->media->getPixelBuffer();
}
void InputMedia::unlock( LibVLCpp::Media::DataCtx* ctx )
{
//qDebug() << "frame just rendered";
ctx->mutex->unlock();
}
QImage* InputMedia::takeSnapshot( unsigned int width, unsigned int height )
{
if ( m_snapshot == NULL )
{
// qint64 currentTime = m_vlcMediaPlayer->getTime();
// qint64 length = getLength();
// qDebug() << currentTime << length;
// m_vlcMediaPlayer->setTime(length / 2);
// qDebug() << "trying to take a snapshot";
QTemporaryFile tmp;
tmp.open();
char* tmpStr = const_cast<char*>(tmp.fileName().toStdString().c_str());
m_vlcMediaPlayer->takeSnapshot( tmpStr, width, height );
// qDebug() << "done snapshoting";
m_snapshot = new QImage( tmp.fileName() );
// qDebug() << "written to a QImage";
// m_vlcMediaPlayer->setTime(currentTime);
}
return m_snapshot;
}
bool InputMedia::isPlaying()
{
return m_vlcMediaPlayer->isPlaying();
}
bool InputMedia::isSeekable()
{
return m_vlcMediaPlayer->isSeekable();
}
qint64 InputMedia::getLength()
{
return m_vlcMediaPlayer->getLength();
}
QImage& InputMedia::getImage()
{
return *m_image;
}
void InputMedia::setDrawable( WId handle )
{
m_vlcMediaPlayer->setDrawable( handle );
}
void InputMedia::play()
{
Media::play();
}
/*****************************************************************************
* InputMedia.h: Class for media handling
*****************************************************************************
* 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.
*****************************************************************************/
#ifndef INPUTMEDIA_H
#define INPUTMEDIA_H
#include <QString>
#include <QImage>
#include <QThread>
#include "Media.h"
#include "Image.h"
class InputMedia : public Media
{
public:
InputMedia( const QString& mrl, LibVLCpp::Instance* instance = NULL );
~InputMedia();
static void lock( LibVLCpp::Media::DataCtx* dataCtx, void **pp_ret );
static void unlock( LibVLCpp::Media::DataCtx* dataCtx );
QImage* takeSnapshot( unsigned int width, unsigned int heigth );
/**
* Ask libvlc if the media is currently playing
*/
bool isPlaying();
/**
* Ask libvlc if the media can be seeked
*/
bool isSeekable();
/**
* Can be used to know if the Media is fully usable (IE. can be seeked, vmem can be used, etc...)
*/
bool isReady();
/**
* Return the length (duration) of a Media
*/
qint64 getLength();
/**
* Returns the last rendered frame
*/
QImage& getImage();
virtual void play();
void setDrawable( WId handle );
private:
QImage* m_snapshot;
uchar* m_pixelBuffer;
QImage* m_image;
};
#endif // INPUTMEDIA_H
/*****************************************************************************
* Media.cpp: Class for media handling
*****************************************************************************
* 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.
*****************************************************************************/
#include <QtDebug>
#include <QTemporaryFile>
#include "Media.h"
Media::Media( const QString& mrl ) : m_mrl( mrl ), m_snapshot( NULL )
{
char const *vlc_argv[] =
{
"-verbose", "3",
"--no-skip-frames",
"--no-audio",
//"--plugin-path", VLC_TREE "/modules",
//"--ignore-config", /* Don't use VLC's config files */
};
int vlc_argc = sizeof( vlc_argv ) / sizeof( *vlc_argv );
m_instance = new LibVLCpp::Instance( vlc_argc, vlc_argv );
m_vlcMedia = new LibVLCpp::Media( m_instance, m_mrl );
m_vlcMedia->outputInVmem();
m_vlcMedia->setLockCallback( Media::lock );
m_vlcMedia->setUnlockCallback( Media::unlock );
char width[64], height[64], chroma[64], pitch[64];
sprintf( width, ":vmem-width=%i", VIDEOWIDTH );
sprintf( height, ":vmem-height=%i", VIDEOHEIGHT );
sprintf( chroma, ":vmem-chroma=%s", "RV32" );
sprintf( pitch, ":vmem-pitch=%i", VIDEOWIDTH * 4 );
m_vlcMedia->addOption( width );
m_vlcMedia->addOption( height );
m_vlcMedia->addOption( chroma );
m_vlcMedia->addOption( pitch );
m_pixelBuffer = new uchar[ VIDEOHEIGHT * VIDEOWIDTH * 4 ];
m_image = new QImage( m_pixelBuffer, VIDEOWIDTH, VIDEOHEIGHT, VIDEOWIDTH * 4, QImage::Format_RGB32 );
m_image->fill( 0 );
//Once we got the pixel buffer up and running, we can put it in the "render context"
m_vlcMedia->setPixelBuffer( m_pixelBuffer );
m_vlcMedia->setDataCtx();
//And now we play the media
m_vlcMediaPlayer = new LibVLCpp::MediaPlayer( m_vlcMedia );
//And launch the checking thread
start();
}
void Media::run()
Media::Media(LibVLCpp::Instance* instance, const QString& mrl ) : m_instance( NULL ), m_vlcMedia( NULL ), m_vlcMediaPlayer( NULL ),
m_mrl( mrl )
{
m_vlcMediaPlayer->play();
while ( true )
if ( instance == NULL )
{
if( m_vlcMediaPlayer->isSeekable() && m_vlcMediaPlayer->getLength() > 0 )
char const *vlc_argv[] =
{
m_isMediaInitialized = true;
emit mediaReady();
m_vlcMediaPlayer->pause();
return ;
}
msleep(100);
"-verbose", "3",
"--no-skip-frames",
//"--plugin-path", VLC_TREE "/modules",
//"--ignore-config", //Don't use VLC's config files
};
int vlc_argc = sizeof( vlc_argv ) / sizeof( *vlc_argv );
instance = new LibVLCpp::Instance( vlc_argc, vlc_argv );
}
}
m_instance = instance;
Media::~Media()
{
delete m_image;
delete m_pixelBuffer;
delete m_vlcMedia;
delete m_vlcMediaPlayer;
delete m_instance;
}
void Media::lock( LibVLCpp::Media::DataCtx* ctx, void **renderPtr )
{
ctx->mutex->lock();
*renderPtr = ctx->media->getPixelBuffer();
m_vlcMedia = new LibVLCpp::Media( m_instance, mrl );
}
void Media::unlock( LibVLCpp::Media::DataCtx* ctx )
Media::~Media()
{
//qDebug() << "frame just rendered";
ctx->mutex->unlock();
if ( m_instance )
delete m_instance;
if ( m_vlcMedia )
delete m_vlcMedia;
if ( m_vlcMediaPlayer )
delete m_vlcMediaPlayer;
}
QImage* Media::takeSnapshot( unsigned int width, unsigned int height )
void Media::loadMedia( const QString& mrl )
{
if ( m_snapshot == NULL )
{
// qint64 currentTime = m_vlcMediaPlayer->getTime();
// qint64 length = getLength();
// qDebug() << currentTime << length;
// m_vlcMediaPlayer->setTime(length / 2);
if ( m_vlcMedia )
delete m_vlcMedia;
m_mrl = mrl;
// qDebug() << "trying to take a snapshot";
QTemporaryFile tmp;
tmp.open();
char* tmpStr = const_cast<char*>(tmp.fileName().toStdString().c_str());
m_vlcMediaPlayer->takeSnapshot( tmpStr, width, height );
// qDebug() << "done snapshoting";
m_snapshot = new QImage( tmp.fileName() );
// qDebug() << "written to a QImage";
// m_vlcMediaPlayer->setTime(currentTime);
}
return m_snapshot;
setupMedia();
}
bool Media::isPlaying()
void Media::setupMedia()
{
return m_vlcMediaPlayer->isPlaying();
}
if ( m_vlcMediaPlayer )
delete m_vlcMediaPlayer;
bool Media::isSeekable()
{
return m_vlcMediaPlayer->isSeekable();
}
bool Media::isReady()
{
//If the thread has finished without any error, then the media is ready o//
return m_isMediaInitialized;
}
//Flushing the args into the media :
QString param;
foreach ( param, m_parameters )
m_vlcMedia->addOption( param.toStdString().c_str() );
qint64 Media::getLength()
{
return m_vlcMediaPlayer->getLength();
m_vlcMediaPlayer = new LibVLCpp::MediaPlayer( m_vlcMedia );
qDebug() << "MediaPlayer is not build on top of" << (void*)m_vlcMedia;
}
void Media::play()
{
if( m_isMediaInitialized )
playSlot();
else
{
msleep(100);
play();
}
}
void Media::playSlot()
{
if ( m_vlcMediaPlayer == NULL )
setupMedia();
m_vlcMediaPlayer->play();
}
QImage& Media::getImage()
{
return *m_image;
}
void Media::setDrawable( WId handle )
void Media::addParam( const QString& param )
{
m_vlcMediaPlayer->setDrawable( handle );
m_parameters.append( param );
}
/*****************************************************************************
* Media.h: Class for media handling
* Media.cpp: Generic class for media handling
*****************************************************************************
* Copyright (C) 2008-2009 the VLMC team
*
......@@ -23,74 +23,35 @@
#ifndef MEDIA_H
#define MEDIA_H
#include <QList>
#include <QString>
#include <QImage>
#include <QThread>
#include "VLCMedia.h"
#include "VLCInstance.h"
#include "VLCMediaPlayer.h"
#include "Image.h"
class Media : private QThread
/**
* Generic class for media handling.
*/
class Media
{
Q_OBJECT
public:
Media( const QString& mrl );
~Media();
static void lock( LibVLCpp::Media::DataCtx* dataCtx, void **pp_ret );
static void unlock( LibVLCpp::Media::DataCtx* dataCtx );
virtual ~Media();
QImage* takeSnapshot( unsigned int width, unsigned int heigth );
void loadMedia( const QString& mrl );
virtual void play();
void addParam( const QString& param );
void setupMedia();
/**
* Ask libvlc if the media is currently playing
*/
bool isPlaying();
/**
* Ask libvlc if the media can be seeked
*/
bool isSeekable();
/**
* Can be used to know if the Media is fully usable (IE. can be seeked, vmem can be used, etc...)
*/
bool isReady();
/**
* Return the length (duration) of a Media
*/
qint64 getLength();
/**
* Returns the last rendered frame
*/
QImage& getImage();
/**
* Start the playback.
* This need to be called at least once in order to prepare the media. if not, the media can't be seeked or anything else.
* When pre-launching is completed, a "mediaReady" signal will be fired.
*/
void play();
void setDrawable( WId handle );
protected:
//Protected constructor so we can't use a Media without its sub-implementation
Media( LibVLCpp::Instance* instance, const QString& mrl );
private:
virtual void run();
private:
LibVLCpp::Instance* m_instance;
LibVLCpp::Media* m_vlcMedia;
LibVLCpp::MediaPlayer* m_vlcMediaPlayer;
LibVLCpp::Instance* m_instance;
QString m_mrl;
QImage* m_snapshot;
uchar* m_pixelBuffer;
QImage* m_image;
bool m_isMediaInitialized;
private slots:
void playSlot();
signals:
void mediaReady();
QList<QString> m_parameters;
};
#endif // MEDIA_H
#include <QtDebug>
#include "OutputMedia.h"
OutputMedia::OutputMedia() : m_pixelBuffer( NULL )
OutputMedia::OutputMedia( LibVLCpp::Instance* instance ) : Media( instance,"fake://" ), m_pixelBuffer( NULL )
{
char const *vlc_argv[] =
{
"-verbose",
"3",
"--codec", "invmem",
//"--snapshot-format", "jpg",
//"--plugin-path", VLC_TREE "/modules",
//"--ignore-config", /* Don't use VLC's config files */
};
int vlc_argc = sizeof( vlc_argv ) / sizeof( *vlc_argv );
m_instance = new LibVLCpp::Instance( vlc_argc, vlc_argv );
m_vlcMedia = new LibVLCpp::Media( m_instance, "fake://" );
m_dataCtx = new OutputMedia::DataCtx;
m_dataCtx->mutex = new QMutex;
m_dataCtx->outputMedia = this;
......@@ -29,14 +14,12 @@ OutputMedia::OutputMedia() : m_pixelBuffer( NULL )
sprintf( unlock, ":invmem-unlock=%lld", (long long int)(intptr_t)&OutputMedia::unlock );
sprintf( data, ":invmem-data=%lld", (long long int)(intptr_t)m_dataCtx );
m_vlcMedia->addOption( width );
m_vlcMedia->addOption( height );
m_vlcMedia->addOption( lock );
m_vlcMedia->addOption( unlock );
m_vlcMedia->addOption( data );
m_vlcMedia->addOption( ":vout=sdl" );
m_vlcMediaPlayer = new LibVLCpp::MediaPlayer( m_vlcMedia );
addParam( width );
addParam( height );
addParam( lock );
addParam( unlock );
addParam( data );
addParam( ":vout=sdl" );
}
uchar* OutputMedia::lock( OutputMedia::DataCtx* dataCtx )
......@@ -63,5 +46,5 @@ void OutputMedia::setVmem( uchar* pixelBuffer )
void OutputMedia::play()
{
m_vlcMediaPlayer->play();
Media::play();
}
......@@ -23,11 +23,9 @@
#ifndef OUTPUTMEDIA_H
#define OUTPUTMEDIA_H
#include "VLCMedia.h"
#include "VLCInstance.h"
#include "VLCMediaPlayer.h"
#include "Media.h"
class OutputMedia
class OutputMedia : public Media
{
public:
struct DataCtx
......@@ -36,17 +34,15 @@ public:
QMutex* mutex;
OutputMedia* outputMedia;
};
OutputMedia();
OutputMedia( LibVLCpp::Instance* instance );
//FIXME: destructor ?
static uchar* lock( OutputMedia::DataCtx* dataCtx );
static void unlock( OutputMedia::DataCtx* dataCtx );
void setVmem( uchar* pixelBuffer );
void play();
virtual void play();
private:
LibVLCpp::Media* m_vlcMedia;
LibVLCpp::MediaPlayer* m_vlcMediaPlayer;
LibVLCpp::Instance* m_instance;
OutputMedia::DataCtx* m_dataCtx;
uchar* m_pixelBuffer;
......
......@@ -128,7 +128,7 @@ void LibraryWidget::on_pushButtonAddMedia_clicked()
break;
case 1:
insertNewMediasFromFileDialog( tr( "Open Videos" ),
tr( "Video Files" ) + " (*.mov *.avi *.mkv)" ,
tr( "Video Files" ) + " (*.mov *.avi *.mkv *.mpg *.mpeg *.wmv)" ,
ListViewMediaItem::Video );
break;
case 2:
......
#include "PreviewWidget.h"
#include "ui_PreviewWidget.h"
#include "MediaListWidget.h"
PreviewWidget::PreviewWidget( QWidget *parent ) :
QDialog( parent ),
m_ui( new Ui::PreviewWidget )
m_ui( new Ui::PreviewWidget ), m_currentMedia( NULL )
{
m_ui->setupUi( this );
char const *vlc_argv[] =
{
"-verbose", "3",
"--no-skip-frames",
//"--plugin-path", VLC_TREE "/modules",
//"--ignore-config", //Don't use VLC's config files
};
int vlc_argc = sizeof( vlc_argv ) / sizeof( *vlc_argv );
setAcceptDrops(true);
m_currentInstance = new LibVLCpp::Instance( vlc_argc, vlc_argv );
}
PreviewWidget::~PreviewWidget()
......@@ -24,3 +36,20 @@ void PreviewWidget::changeEvent( QEvent *e )
break;
}
}
void PreviewWidget::dragEnterEvent( QDragEnterEvent* event )
{
event->accept();
}
void PreviewWidget::dropEvent( QDropEvent* event )
{
QListWidget* listWidget = reinterpret_cast<QListWidget*>( event->source() );
ListViewMediaItem* item = dynamic_cast<ListViewMediaItem*>( listWidget->currentItem() );
if ( item == NULL )
return ;
m_currentMedia = new InputMedia("file://" + item->fileInfo()->absoluteFilePath(), m_currentInstance );
m_currentMedia->setupMedia();
m_currentMedia->setDrawable( m_ui->clipRenderWidget->winId() );
m_currentMedia->play();
}
......@@ -2,6 +2,9 @@
#define PREVIEWWIDGET_H
#include <QtGui/QDialog>
#include <QDragEnterEvent>
#include "InputMedia.h"
namespace Ui {
class PreviewWidget;
......@@ -16,10 +19,14 @@ public:
virtual ~PreviewWidget();
protected:
virtual void changeEvent( QEvent *e );
virtual void changeEvent( QEvent *e );
virtual void dragEnterEvent( QDragEnterEvent* event );
virtual void dropEvent( QDropEvent* event );
private:
Ui::PreviewWidget *m_ui;
Ui::PreviewWidget* m_ui;
InputMedia* m_currentMedia;
LibVLCpp::Instance* m_currentInstance;
};
#endif // PREVIEWWIDGET_H
......@@ -50,7 +50,7 @@
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="ProjectTab">
<attribute name="title">
......@@ -61,6 +61,11 @@
<attribute name="title">
<string>Clip</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QWidget" name="clipRenderWidget" native="true"/>
</item>
</layout>
</widget>
</widget>
</item>
......
......@@ -7,7 +7,9 @@ MOC_DIR = build/moc
UI_DIR = build/ui
INCLUDEPATH = build/moc \
build/ui
QT += gui network svg
QT += gui \
network \
svg
SOURCES += src/main.cpp \
src/gui/MainWindow.cpp \
src/gui/LibraryWidget.cpp \
......@@ -27,7 +29,8 @@ SOURCES += src/main.cpp \
src/Media.cpp \
src/OutputMedia.cpp \
src/gui/About.cpp \
src/gui/Transcode.cpp
src/gui/Transcode.cpp \
src/InputMedia.cpp
HEADERS += src/gui/MainWindow.h \
src/gui/DockWidgetManager.h \
src/gui/LibraryWidget.h \
......@@ -48,7 +51,8 @@ HEADERS += src/gui/MainWindow.h \
src/gui/MediaListWidget.h \
src/OutputMedia.h \
src/gui/About.h \
src/gui/Transcode.h
src/gui/Transcode.h \
src/InputMedia.h
FORMS += src/gui/ui/MainWindow.ui \
src/gui/ui/PreviewWidget.ui \
src/gui/ui/Preferences.ui \
......@@ -61,7 +65,8 @@ TRANSLATIONS = ts/vlmc_es.ts \
ts/vlmc_fr.ts \
ts/vlmc_sv.ts
RESOURCES += ressources.qrc
INCLUDEPATH += src/LibVLCpp
INCLUDEPATH += src/LibVLCpp \
src
LIBS = -L/usr/local/lib \
-lvlc
CODECFORTR = UTF-8
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment