Commit 85b735fc authored by Hugo Beauzee-Luyssen's avatar Hugo Beauzee-Luyssen

Operational video exporting.

parent 865045d4
......@@ -26,17 +26,20 @@
#include "MainWorkflow.h"
unsigned char* MainWorkflow::blackOutput = NULL;
MainWorkflow* MainWorkflow::m_instance = NULL;
MainWorkflow::MainWorkflow( QObject* parent, int trackCount ) :
QObject( parent ),
m_length( 0 ),
m_trackCount( trackCount ),
m_renderStarted( false )
{
if ( MainWorkflow::blackOutput == NULL )
{
MainWorkflow::blackOutput = new unsigned char[VIDEOHEIGHT * VIDEOWIDTH * 3];
memset( MainWorkflow::blackOutput, 0, VIDEOHEIGHT * VIDEOWIDTH * 3 );
}
Q_ASSERT_X( MainWorkflow::m_instance == NULL,
"MainWorkflow constructor", "Can't have more than one MainWorkflow instance" );
m_instance = this;
MainWorkflow::blackOutput = new unsigned char[VIDEOHEIGHT * VIDEOWIDTH * 3];
memset( MainWorkflow::blackOutput, 0, VIDEOHEIGHT * VIDEOWIDTH * 3 );
m_tracks = new Toggleable<TrackWorkflow*>[trackCount];
for (int i = 0; i < trackCount; ++i)
......@@ -53,7 +56,6 @@ MainWorkflow::~MainWorkflow()
for (unsigned int i = 0; i < m_trackCount; ++i)
delete m_tracks[i];
delete[] m_tracks;
//FIXME: if we have two main workflows (which is very unlikely) this will crash...
delete[] blackOutput;
}
......@@ -117,6 +119,7 @@ unsigned char* MainWorkflow::getOutput()
void MainWorkflow::nextFrame()
{
++m_currentFrame;
//FIXME: This is probably a bit much...
emit frameChanged( m_currentFrame );
emit positionChanged( (float)m_currentFrame / (float)m_length );
}
......@@ -124,6 +127,7 @@ void MainWorkflow::nextFrame()
void MainWorkflow::previousFrame()
{
--m_currentFrame;
//FIXME: This is probably a bit much...
emit frameChanged( m_currentFrame );
emit positionChanged( (float)m_currentFrame / (float)m_length );
}
......@@ -183,3 +187,9 @@ void MainWorkflow::stop()
m_currentFrame = 0;
emit frameChanged( 0 );
}
MainWorkflow* MainWorkflow::getInstance()
{
Q_ASSERT( m_instance != NULL );
return m_instance;
}
......@@ -25,12 +25,13 @@
#define MAINWORKFLOW_H
#include <QObject>
#include <QReadWriteLock>
#include "tools/Toggleable.hpp"
#include "TrackWorkflow.h"
#include <QReadWriteLock>
#include "tools/Singleton.hpp"
class MainWorkflow : public QObject
class MainWorkflow : public QObject, public Singleton<MainWorkflow>
{
Q_OBJECT
......@@ -68,6 +69,10 @@ class MainWorkflow : public QObject
void nextFrame();
void previousFrame();
static MainWorkflow* getInstance();
private:
static MainWorkflow* m_instance;
private:
Toggleable<TrackWorkflow*>* m_tracks;
qint64 m_currentFrame;
......
#include "WorkflowFileRenderer.h"
WorkflowFileRenderer::WorkflowFileRenderer( QWidget* parent, const QString& outputFileName ) :
QDialog( parent ), m_outputFileName( outputFileName )
{
m_ui.setupUi( this );
m_ui.nameLabel->setText( outputFileName );
m_mediaPlayer = new LibVLCpp::MediaPlayer;
m_mainWorkflow = MainWorkflow::getInstance();
}
WorkflowFileRenderer::~WorkflowFileRenderer()
{
delete m_mediaPlayer;
}
void* WorkflowFileRenderer::lock( void* datas )
{
WorkflowFileRenderer* self = reinterpret_cast<WorkflowFileRenderer*>( datas );
return self->m_mainWorkflow->getOutput();
}
void WorkflowFileRenderer::unlock( void* )
{
}
void WorkflowFileRenderer::run()
{
m_media = new LibVLCpp::Media( "fake://" );
char buffer[256];
sprintf( buffer, ":invmem-width=%i", VIDEOWIDTH );
m_media->addOption( ":codec=invmem" );
m_media->addOption( buffer );
sprintf( buffer, ":invmem-height=%i", VIDEOHEIGHT );
m_media->addOption( buffer );
sprintf( buffer, ":invmem-lock=%lld", (qint64)WorkflowFileRenderer::lock );
m_media->addOption( buffer );
sprintf( buffer, ":invmem-unlock=%lld", (qint64)WorkflowFileRenderer::unlock );
m_media->addOption( buffer );
sprintf( buffer, ":invmem-data=%lld", (qint64)this );
m_media->addOption( buffer );
m_media->addOption( ":no-audio" );
m_media->addOption( ":fake" );
QString transcodeStr = "sout=#transcode{vcodec=mp4v,vb=800,acodec=mpga,ab=128}"
":standard{access=file,mux=ps,dst=\""
+ m_outputFileName + "\"}";
m_media->addOption( transcodeStr.toStdString().c_str() );
m_mediaPlayer->setMedia( m_media );
connect( m_mediaPlayer, SIGNAL( stopped() ), this, SLOT( stop() ) );
connect( m_mainWorkflow, SIGNAL( mainWorkflowEndReached() ), this, SLOT( stop() ) );
connect( m_mainWorkflow, SIGNAL( positionChanged( float ) ), this, SLOT( positionChanged( float ) ) );
show();
m_mainWorkflow->startRender();
m_mediaPlayer->play();
}
void WorkflowFileRenderer::stop()
{
disconnect( m_mediaPlayer, SIGNAL( stopped() ), this, SLOT( stop() ) );
disconnect( m_mainWorkflow, SIGNAL( mainWorkflowEndReached() ), this, SLOT( stop() ) );
m_mainWorkflow->stop();
m_mediaPlayer->stop();
done( 0 );
}
void WorkflowFileRenderer::positionChanged( float newPos )
{
m_ui.progressBar->setValue( newPos * 100 );
}
void WorkflowFileRenderer::on_cancelButton_clicked()
{
stop();
}
/*****************************************************************************
* WorkflowFileRenderer.h: Output the workflow to a file
*****************************************************************************
* 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 WORKFLOWFILERENDERER_H
#define WORKFLOWFILERENDERER_H
#include <QDialog>
#include "VLCMediaPlayer.h"
#include "Workflow/MainWorkflow.h"
#include "ui_WorkflowFileRenderer.h"
class WorkflowFileRenderer : public QDialog
{
Q_OBJECT
Q_DISABLE_COPY( WorkflowFileRenderer )
public:
WorkflowFileRenderer( QWidget* parent, const QString& outputFileName );
virtual ~WorkflowFileRenderer();
static void* lock( void* datas );
static void unlock( void* datas );
void run();
private:
LibVLCpp::MediaPlayer* m_mediaPlayer;
LibVLCpp::Media* m_media;
MainWorkflow* m_mainWorkflow;
const QString m_outputFileName;
Ui::WorkflowFileRenderer m_ui;
private slots:
void stop();
void positionChanged( float newPos );
void on_cancelButton_clicked();
};
#endif // WORKFLOWFILERENDERER_H
......@@ -37,7 +37,7 @@
#include "PreviewWidget.h"
MainWindow::MainWindow( QWidget *parent ) :
QMainWindow( parent )
QMainWindow( parent ), m_renderer( NULL )
{
m_ui.setupUi( this );
DockWidgetManager::instance( this )->setMainWindow( this );
......@@ -59,6 +59,8 @@ MainWindow::MainWindow( QWidget *parent ) :
MainWindow::~MainWindow()
{
if ( m_renderer )
delete m_renderer;
}
void MainWindow::changeEvent( QEvent *e )
......@@ -172,6 +174,27 @@ void MainWindow::on_actionTranscode_File_triggered()
Transcode::instance( this )->exec();
}
void MainWindow::on_actionRender_triggered()
{
if ( MainWorkflow::getInstance()->getLength() <= 0 )
{
QMessageBox::warning( NULL, "VLMC Renderer", "There is nothing to render." );
return ;
}
QString outputFileName =
QFileDialog::getSaveFileName( NULL, "Enter the output file name",
QString(), "Videos(*.avi *.mpg)" );
if ( outputFileName.length() == 0 )
return ;
else
{
if ( m_renderer )
delete m_renderer;
m_renderer = new WorkflowFileRenderer( this, outputFileName );
m_renderer->run();
}
}
void MainWindow::on_actionNew_Project_triggered()
{
//TODO : clear the library, the timeline, and show the configuration box
......
......@@ -25,11 +25,15 @@
#include <QApplication>
#include <QSlider>
#include "ui_MainWindow.h"
#include "DockWidgetManager.h"
#include "Preferences.h"
#include "MetaDataManager.h"
#include "Timeline.h"
#include "WorkflowFileRenderer.h"
class MainWindow : public QMainWindow
{
......@@ -53,10 +57,11 @@ private:
void createStatusBar();
Ui::MainWindow m_ui;
MetaDataManager* m_metaDataManager;
QSlider* m_zoomSlider;
Timeline* m_timeline;
Ui::MainWindow m_ui;
MetaDataManager* m_metaDataManager;
QSlider* m_zoomSlider;
Timeline* m_timeline;
WorkflowFileRenderer* m_renderer;
private slots:
void on_actionFullscreen_triggered( bool checked );
......@@ -64,6 +69,7 @@ private slots:
void on_actionAbout_triggered();
void on_actionPreferences_triggered();
void on_actionTranscode_File_triggered();
void on_actionRender_triggered();
void on_actionNew_Project_triggered();
void on_actionOpen_Project_triggered();
......
......@@ -91,7 +91,7 @@ void RenderPreviewWidget::unlock( void* datas )
void RenderPreviewWidget::stopPreview()
{
//This might be called multiple times, but this is due to Qt message loop
//FIXME: shouldn't this call MainWorkflow::stop() ??!!
m_mediaPlayer->stop();
m_isRendering = false;
m_paused = false;
......
......@@ -14,7 +14,7 @@
<string>VideoLAN Movie Creator</string>
</property>
<property name="windowIcon">
<iconset>
<iconset resource="../../../ressources.qrc">
<normaloff>:/images/images/vlmc.png</normaloff>:/images/images/vlmc.png</iconset>
</property>
<property name="dockNestingEnabled">
......@@ -27,7 +27,7 @@
<x>0</x>
<y>0</y>
<width>800</width>
<height>26</height>
<height>25</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
......@@ -37,6 +37,7 @@
<addaction name="actionNew_Project"/>
<addaction name="actionOpen_Project"/>
<addaction name="actionTranscode_File"/>
<addaction name="actionRender"/>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuEdit">
......@@ -159,7 +160,14 @@
<string>F</string>
</property>
</action>
<action name="actionRender">
<property name="text">
<string>Render</string>
</property>
</action>
</widget>
<resources/>
<resources>
<include location="../../../ressources.qrc"/>
</resources>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WorkflowFileRenderer</class>
<widget class="QDialog" name="WorkflowFileRenderer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>300</width>
<height>104</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Render in progress...</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
......@@ -44,7 +44,8 @@ SOURCES += src/main.cpp \
src/gui/RenderPreviewWidget.cpp \
src/API/vlmc_module_variables.cpp \
src/API/Module.cpp \
src/API/ModuleManager.cpp
src/API/ModuleManager.cpp \
src/WorkflowFileRenderer.cpp
HEADERS += src/gui/MainWindow.h \
src/gui/DockWidgetManager.h \
src/gui/LibraryWidget.h \
......@@ -84,7 +85,8 @@ HEADERS += src/gui/MainWindow.h \
src/API/vlmc_module.h \
src/API/Module.h \
src/API/ModuleManager.h \
src/API/vlmc_module_internal.h
src/API/vlmc_module_internal.h \
src/WorkflowFileRenderer.h
FORMS += src/gui/ui/MainWindow.ui \
src/gui/ui/PreviewWidget.ui \
src/gui/ui/Preferences.ui \
......@@ -92,7 +94,8 @@ FORMS += src/gui/ui/MainWindow.ui \
src/gui/ui/LibraryWidget.ui \
src/gui/ui/About.ui \
src/gui/ui/Transcode.ui \
src/gui/ui/FileBrowser.ui
src/gui/ui/FileBrowser.ui \
src/gui/ui/WorkflowFileRenderer.ui
FORMS +=
TRANSLATIONS = ts/vlmc_es.ts \
ts/vlmc_fr.ts \
......
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