Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
VideoLAN
VLMC
Commits
c56fd547
Commit
c56fd547
authored
May 28, 2009
by
Hugo Beauzee-Luyssen
Browse files
You can now use the slider to change position in the render preview.
parent
cd4b84ea
Changes
10
Hide whitespace changes
Inline
Side-by-side
src/Workflow/ClipWorkflow.cpp
View file @
c56fd547
...
...
@@ -123,16 +123,16 @@ void ClipWorkflow::initialize( LibVLCpp::MediaPlayer* mediaPlayer )
m_mediaPlayer
=
mediaPlayer
;
m_mediaPlayer
->
setMedia
(
m_clip
->
getParent
()
->
getVLCMedia
()
);
connect
(
m_mediaPlayer
,
SIGNAL
(
playing
()
),
this
,
SLOT
(
setPosition
()
),
Qt
::
DirectConnection
);
connect
(
m_mediaPlayer
,
SIGNAL
(
playing
()
),
this
,
SLOT
(
setPosition
AfterPlayback
()
),
Qt
::
DirectConnection
);
connect
(
m_mediaPlayer
,
SIGNAL
(
endReached
()
),
this
,
SLOT
(
endReached
()
),
Qt
::
DirectConnection
);
// qDebug() << "Launching playback";
m_mediaPlayer
->
play
();
}
void
ClipWorkflow
::
setPosition
()
void
ClipWorkflow
::
setPosition
AfterPlayback
()
{
// qDebug() << "Setting position";
disconnect
(
m_mediaPlayer
,
SIGNAL
(
playing
()
),
this
,
SLOT
(
setPosition
()
)
);
disconnect
(
m_mediaPlayer
,
SIGNAL
(
playing
()
),
this
,
SLOT
(
setPosition
AfterPlayback
()
)
);
connect
(
m_mediaPlayer
,
SIGNAL
(
positionChanged
()
),
this
,
SLOT
(
pauseAfterPlaybackStarted
()
),
Qt
::
DirectConnection
);
m_mediaPlayer
->
setPosition
(
m_clip
->
getBegin
()
);
}
...
...
@@ -169,8 +169,19 @@ bool ClipWorkflow::isEndReached() const
void
ClipWorkflow
::
startRender
()
{
Q_ASSERT
(
m_isReady
==
true
);
bool
isReady
;
{
QReadLocker
lock
(
m_initMutex
);
isReady
=
m_isReady
;
}
while
(
isReady
==
false
)
{
usleep
(
150
);
{
QReadLocker
lock
(
m_initMutex
);
isReady
=
m_isReady
;
}
}
m_mediaPlayer
->
play
();
}
...
...
@@ -180,7 +191,32 @@ void ClipWorkflow::endReached()
m_endReached
=
true
;
}
const
Clip
*
ClipWorkflow
::
getClip
()
const
const
Clip
*
ClipWorkflow
::
getClip
()
const
{
return
m_clip
;
}
void
ClipWorkflow
::
stop
()
{
{
QWriteLocker
lock2
(
m_mutex
);
m_renderComplete
=
false
;
}
{
QWriteLocker
lock2
(
m_endReachedLock
);
m_endReached
=
false
;
}
{
QWriteLocker
lock
(
m_initMutex
);
m_isReady
=
false
;
}
m_mediaPlayer
->
stop
();
m_mediaPlayer
=
NULL
;
qDebug
()
<<
"Stoped ClipWorkflow"
;
}
void
ClipWorkflow
::
setPosition
(
float
pos
)
{
qDebug
()
<<
"Setting position :"
<<
pos
;
m_mediaPlayer
->
setPosition
(
pos
);
}
src/Workflow/ClipWorkflow.h
View file @
c56fd547
...
...
@@ -57,6 +57,11 @@ class ClipWorkflow : public QObject
\return A pointer to a constant clip instance.
*/
const
Clip
*
getClip
()
const
;
/**
\brief Stop this workflow.
*/
void
stop
();
void
setPosition
(
float
pos
);
private:
static
void
lock
(
ClipWorkflow
*
clipWorkflow
,
void
**
pp_ret
);
...
...
@@ -80,7 +85,7 @@ class ClipWorkflow : public QObject
public
slots
:
void
pauseAfterPlaybackStarted
();
void
pausedMediaPlayer
();
void
setPosition
();
void
setPosition
AfterPlayback
();
void
endReached
();
};
...
...
src/Workflow/MainWorkflow.cpp
View file @
c56fd547
...
...
@@ -45,6 +45,7 @@ void MainWorkflow::startRender()
{
m_currentFrame
=
0
;
emit
frameChanged
(
0
);
m_length
=
m_tracks
[
0
]
->
getLength
();
m_tracks
[
0
]
->
startRender
();
}
...
...
@@ -55,3 +56,17 @@ unsigned char* MainWorkflow::getOutput()
emit
frameChanged
(
m_currentFrame
);
return
ret
;
}
void
MainWorkflow
::
setPosition
(
float
pos
)
{
qint64
frame
=
(
float
)
m_length
*
pos
;
qDebug
()
<<
"Setting current frame to "
<<
frame
<<
'('
<<
m_length
<<
'*'
<<
pos
<<
')'
;
m_tracks
[
0
]
->
setPosition
(
pos
);
m_currentFrame
=
frame
;
emit
frameChanged
(
frame
);
}
qint64
MainWorkflow
::
getLength
()
const
{
return
m_length
;
}
src/Workflow/MainWorkflow.h
View file @
c56fd547
...
...
@@ -42,9 +42,23 @@ class MainWorkflow : public QObject
void
startRender
();
unsigned
char
*
getOutput
();
/**
\brief Set the workflow position
\param pos: The position in vlc position
*/
void
setPosition
(
float
pos
);
/**
\return Returns the global length of the workflow
in frames.
*/
qint64
getLength
()
const
;
private:
TrackWorkflow
**
m_tracks
;
qint64
m_currentFrame
;
qint64
m_length
;
signals:
void
frameChanged
(
qint64
currentFrame
);
...
...
src/Workflow/TrackWorkflow.cpp
View file @
c56fd547
...
...
@@ -26,11 +26,12 @@
unsigned
char
*
TrackWorkflow
::
blackOutput
=
NULL
;
TrackWorkflow
::
TrackWorkflow
()
:
m_isRendering
(
false
)
TrackWorkflow
::
TrackWorkflow
()
{
m_condMutex
=
new
QMutex
;
m_waitCondition
=
new
QWaitCondition
;
m_mediaPlayer
=
new
LibVLCpp
::
MediaPlayer
();
m_currentLock
=
new
QReadWriteLock
();
if
(
TrackWorkflow
::
blackOutput
==
NULL
)
{
TrackWorkflow
::
blackOutput
=
new
unsigned
char
[
VIDEOHEIGHT
*
VIDEOWIDTH
*
3
];
...
...
@@ -43,6 +44,7 @@ void TrackWorkflow::addClip( Clip* clip, qint64 start )
qDebug
()
<<
"Inserting clip at frame nb"
<<
start
;
ClipWorkflow
*
cw
=
new
ClipWorkflow
(
clip
,
m_condMutex
,
m_waitCondition
);
m_clips
.
insert
(
start
,
cw
);
computeLength
();
}
void
TrackWorkflow
::
startRender
()
...
...
@@ -54,6 +56,7 @@ void TrackWorkflow::startRender()
// qDebug() << "Next clip is less than" << nbFrameBeforePreload<< "frame ahead";
m_clips
.
begin
().
value
()
->
initialize
(
m_mediaPlayer
);
// qDebug() << "Waiting for the first clip to be ready";
//We wait to be sure the ClipWorkflow will be ready when we really start to render.
while
(
m_clips
.
begin
().
value
()
->
isReady
()
==
false
)
usleep
(
150
);
if
(
m_current
.
key
()
==
0
)
...
...
@@ -61,7 +64,6 @@ void TrackWorkflow::startRender()
m_current
=
m_clips
.
begin
();
// qDebug() << "Clip workflow is at first frame";
m_current
.
value
()
->
startRender
();
m_isRendering
=
true
;
}
}
}
...
...
@@ -100,13 +102,18 @@ bool TrackWorkflow::checkNextClip( qint64 currentFrame )
return
true
;
}
qint64
TrackWorkflow
::
get
Length
()
const
void
TrackWorkflow
::
compute
Length
()
{
if
(
m_clips
.
count
()
==
0
)
return
0
;
m_length
=
0
;
QMap
<
qint64
,
ClipWorkflow
*>::
const_iterator
it
=
m_clips
.
end
()
-
1
;
qDebug
()
<<
"Last clip Uuid : "
<<
it
.
value
()
->
getClip
()
->
getUuid
();
return
(
it
.
key
()
+
it
.
value
()
->
getClip
()
->
getLength
()
);
m_length
=
(
it
.
key
()
+
it
.
value
()
->
getClip
()
->
getLength
()
);
}
qint64
TrackWorkflow
::
getLength
()
const
{
return
m_length
;
}
unsigned
char
*
TrackWorkflow
::
getOutput
(
qint64
currentFrame
)
...
...
@@ -114,6 +121,8 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
unsigned
char
*
ret
=
TrackWorkflow
::
blackOutput
;
bool
clipsRemaining
;
QReadLocker
lock
(
m_currentLock
);
// qDebug() << "Frame nb" << m_currentFrame;
clipsRemaining
=
checkNextClip
(
currentFrame
);
if
(
m_current
==
m_clips
.
end
()
)
...
...
@@ -137,3 +146,93 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
}
return
ret
;
}
void
TrackWorkflow
::
setPosition
(
float
pos
)
{
qint64
frame
=
(
float
)
m_length
*
pos
;
QMap
<
qint64
,
ClipWorkflow
*>::
iterator
it
=
m_clips
.
begin
();
const
QMap
<
qint64
,
ClipWorkflow
*>::
iterator
end
=
m_clips
.
end
();
QMap
<
qint64
,
ClipWorkflow
*>::
iterator
next
=
m_clips
.
end
();
QWriteLocker
lock
(
m_currentLock
);
qDebug
()
<<
m_length
;
if
(
frame
>
m_length
)
{
qDebug
()
<<
"setting position after the end of this track"
;
if
(
m_current
!=
end
)
{
m_current
.
value
()
->
stop
();
m_current
=
end
;
return
;
}
}
//Locate the new clip workflow
while
(
it
!=
end
)
{
if
(
it
.
key
()
<=
frame
&&
(
it
.
key
()
+
it
.
value
()
->
getClip
()
->
getLength
()
)
>
frame
)
{
qDebug
()
<<
"Found new current clip workflow"
;
break
;
}
else
if
(
next
==
m_clips
.
end
()
&&
it
.
key
()
>
frame
)
{
// If this clip doesn't match, but starts AFTER the frame we aim,
// we can assume that it's the next clip.
// We can break, and put it to end() in order to simulate the
// normal end of the loop.
next
=
it
;
if
(
next
!=
m_clips
.
begin
()
)
{
qDebug
()
<<
"Next clip isn't the first one"
;
next
=
next
-
1
;
//Since the iterator must point to the previous video
}
else
{
next
=
end
;
qDebug
()
<<
"Next clip is the first of the track"
;
}
// in order to checkNextClip() to work.
it
=
end
;
break
;
}
++
it
;
}
if
(
it
==
m_clips
.
end
()
)
{
qDebug
()
<<
"No clip matched. Utilisation du Clip precedent le clip suivant la frame selectionnee"
;
if
(
m_current
!=
end
)
m_current
.
value
()
->
stop
();
m_current
=
next
;
}
else
if
(
it
==
m_current
)
{
qDebug
()
<<
"Changing the position of the current clip"
;
//We're changing the position of the current clip
// qDebug() << "frame =" << frame << " key = "<< it.key() <<
it
.
value
()
->
setPosition
(
(
float
)(
frame
-
it
.
key
()
)
/
(
float
)(
it
.
value
()
->
getClip
()
->
getLength
())
);
//Awaking renderers to avoid them to be stuck inside of the lock...
qDebug
()
<<
"Waking all renderer threads"
;
m_waitCondition
->
wakeAll
();
}
else
{
qDebug
()
<<
"Switching to other Clip"
;
if
(
m_current
!=
end
)
{
m_current
.
value
()
->
stop
();
// m_waitCondition->wakeAll();
}
it
.
value
()
->
initialize
(
m_mediaPlayer
);
while
(
it
.
value
()
->
isReady
()
==
false
)
usleep
(
150
);
it
.
value
()
->
startRender
();
m_current
=
it
;
qDebug
()
<<
"Switched current clip workflow"
;
}
//Don't forget to wake the renderer so they can process the events
}
src/Workflow/TrackWorkflow.h
View file @
c56fd547
...
...
@@ -27,6 +27,7 @@
#include <QMutex>
#include <QWaitCondition>
#include <QMap>
#include <QReadWriteLock>
#include "ClipWorkflow.h"
#include "VLCMediaPlayer.h"
...
...
@@ -47,23 +48,46 @@ class TrackWorkflow : public QObject
unsigned
char
*
getOutput
(
qint64
currentFrame
);
qint64
getLength
()
const
;
/**
\brief Set the track workflow position
\param pos: The new pos in VLC position
*/
void
setPosition
(
float
pos
);
//FIXME: this won't be reliable as soon as we change the fps from the configuration
static
const
unsigned
int
nbFrameBeforePreload
=
60
;
static
unsigned
char
*
blackOutput
;
private:
/**
* \return true if at least one video remains, false otherwise (IE end of this track)
* \brief Check if there's a ClipWorkflow that's comming soon. If so, it preload it to avoid
freeze when switching video.
This does NOT search for the next current clip !
* \return true if at least one video remains, false otherwise (IE end of this track)
*/
bool
checkNextClip
(
qint64
currentFrame
);
void
computeLength
();
private:
QMap
<
qint64
,
ClipWorkflow
*>
m_clips
;
/**
* \brief An iterator that "point" the current ClipWorkflow used.
*
* This holds the current ClipWorkflow, and the current starting frame
* of this ClipWorkflow.
* If the track is empty at a T time, this iterator still points to the last
* ClipWorkflow used. However, if the next video occurs to be the first one
* in the Track, this iterators is equal to m_clips.end();
*/
QMap
<
qint64
,
ClipWorkflow
*>::
iterator
m_current
;
QMutex
*
m_condMutex
;
QReadWriteLock
*
m_currentLock
;
QWaitCondition
*
m_waitCondition
;
LibVLCpp
::
MediaPlayer
*
m_mediaPlayer
;
bool
m_isRendering
;
/**
\brief The track length in frames.
*/
qint64
m_length
;
public:
void
addClip
(
Clip
*
,
qint64
start
);
...
...
src/gui/ClipPreviewWidget.cpp
View file @
c56fd547
...
...
@@ -54,7 +54,7 @@ void ClipPreviewWidget::setPosition( float newPos )
{
if
(
m_clipLoaded
==
false
||
m_videoStopped
==
true
)
return
;
m_mediaPlayer
->
setPosition
(
newPos
/
1000.0
);
m_mediaPlayer
->
setPosition
(
newPos
);
}
void
ClipPreviewWidget
::
togglePlayPause
(
bool
forcePause
)
...
...
src/gui/PreviewWidget.cpp
View file @
c56fd547
...
...
@@ -154,7 +154,8 @@ void PreviewWidget::seekSliderMoved( int )
return
;
}
m_endReached
=
false
;
m_currentPreviewRenderer
->
setPosition
(
(
float
)
m_ui
->
seekSlider
->
value
()
);
//Putting back the slider value into vlc position
m_currentPreviewRenderer
->
setPosition
(
(
float
)
m_ui
->
seekSlider
->
value
()
/
1000.0
f
);
}
void
PreviewWidget
::
seekSliderReleased
()
...
...
src/gui/RenderPreviewWidget.cpp
View file @
c56fd547
...
...
@@ -84,8 +84,9 @@ void RenderPreviewWidget::startPreview( Media* )
m_isRendering
=
true
;
}
void
RenderPreviewWidget
::
setPosition
(
float
/*
newPos
*/
)
void
RenderPreviewWidget
::
setPosition
(
float
newPos
)
{
m_mainWorkflow
->
setPosition
(
newPos
);
}
void
RenderPreviewWidget
::
togglePlayPause
(
bool
/*forcePause*/
)
...
...
src/gui/RenderPreviewWidget.h
View file @
c56fd547
...
...
@@ -30,7 +30,6 @@
#include "Workflow/MainWorkflow.h"
#include "GenericPreviewWidget.h"
//TODO: This should really share a common interface with ClipPreviewWorkflow
class
RenderPreviewWidget
:
public
GenericPreviewWidget
{
Q_OBJECT
...
...
@@ -41,6 +40,13 @@ class RenderPreviewWidget : public GenericPreviewWidget
~
RenderPreviewWidget
();
virtual
void
startPreview
(
Media
*
);
/**
\brief Set the preview position
\param newPos : The new position in vlc position (between
0 and 1)
*/
virtual
void
setPosition
(
float
newPos
);
virtual
void
togglePlayPause
(
bool
forcePause
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment