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
2cd5097c
Commit
2cd5097c
authored
Aug 14, 2009
by
Hugo Beauzee-Luyssen
Browse files
Working version of pause/unpause
This is really much cleaner than the old versions...
parent
ad9a3174
Changes
9
Hide whitespace changes
Inline
Side-by-side
src/LibVLCpp/VLCMediaPlayer.cpp
View file @
2cd5097c
...
...
@@ -85,11 +85,11 @@ void MediaPlayer::callbacks( const libvlc_event_t* ev
switch
(
event
->
type
)
{
case
libvlc_MediaPlayerPlaying
:
qDebug
()
<<
"Media player playing"
;
//
qDebug() << "Media player playing";
self
->
emit
playing
();
break
;
case
libvlc_MediaPlayerPaused
:
qDebug
()
<<
"Media player paused"
;
//
qDebug() << "Media player paused";
self
->
emit
paused
();
break
;
case
libvlc_MediaPlayerStopped
:
...
...
src/Workflow/ClipWorkflow.cpp
View file @
2cd5097c
...
...
@@ -97,7 +97,9 @@ void ClipWorkflow::unlock( ClipWorkflow* cw )
cw
->
m_renderWaitCond
->
wake
();
cw
->
emit
renderComplete
(
cw
);
qDebug
()
<<
"Entering condwait"
;
cw
->
m_waitCond
->
wait
(
cw
->
m_condMutex
);
qDebug
()
<<
"Leaving condwait"
;
cw
->
m_stateLock
->
lockForWrite
();
cw
->
m_state
=
Rendering
;
cw
->
m_stateLock
->
unlock
();
...
...
@@ -130,6 +132,7 @@ void ClipWorkflow::setVmem()
void
ClipWorkflow
::
initialize
()
{
qDebug
()
<<
"Initialize"
;
setState
(
Initializing
);
m_vlcMedia
=
new
LibVLCpp
::
Media
(
m_clip
->
getParent
()
->
getFileInfo
()
->
absoluteFilePath
()
);
setVmem
();
...
...
@@ -138,31 +141,37 @@ void ClipWorkflow::initialize()
connect
(
m_mediaPlayer
,
SIGNAL
(
playing
()
),
this
,
SLOT
(
setPositionAfterPlayback
()
),
Qt
::
DirectConnection
);
connect
(
m_mediaPlayer
,
SIGNAL
(
endReached
()
),
this
,
SLOT
(
clipEndReached
()
),
Qt
::
DirectConnection
);
connect
(
m_mediaPlayer
,
SIGNAL
(
paused
()
),
this
,
SLOT
(
pausedMediaPlayer
()
),
Qt
::
DirectConnection
);
m_mediaPlayer
->
play
();
qDebug
()
<<
"playback required"
;
}
void
ClipWorkflow
::
setPositionAfterPlayback
()
{
disconnect
(
m_mediaPlayer
,
SIGNAL
(
playing
()
),
this
,
SLOT
(
setPositionAfterPlayback
()
)
);
connect
(
m_mediaPlayer
,
SIGNAL
(
positionChanged
()
),
this
,
SLOT
(
pauseAfterPlaybackStarted
()
),
Qt
::
DirectConnection
);
m_mediaPlayer
->
setPosition
(
m_clip
->
getBegin
()
);
qDebug
()
<<
"Set position"
;
}
void
ClipWorkflow
::
pauseAfterPlaybackStarted
()
{
qDebug
()
<<
"pauseAfterPlaybackStarted();"
;
disconnect
(
m_mediaPlayer
,
SIGNAL
(
positionChanged
()
),
this
,
SLOT
(
pauseAfterPlaybackStarted
()
)
);
//FIXME: it seems that this signal is never connected :o
disconnect
(
m_mediaPlayer
,
SIGNAL
(
playing
()
),
this
,
SLOT
(
pauseAfterPlaybackStarted
()
)
);
connect
(
m_mediaPlayer
,
SIGNAL
(
paused
()
),
this
,
SLOT
(
initializedMediaPlayer
()
),
Qt
::
DirectConnection
);
m_mediaPlayer
->
pause
();
m_mediaPlayer
->
pause
();
}
void
ClipWorkflow
::
initializedMediaPlayer
()
{
qDebug
()
<<
"initializedMediaPlayer();"
;
disconnect
(
m_mediaPlayer
,
SIGNAL
(
paused
()
),
this
,
SLOT
(
initializedMediaPlayer
()
)
);
connect
(
m_mediaPlayer
,
SIGNAL
(
paused
()
),
this
,
SLOT
(
pausedMediaPlayer
()
),
Qt
::
DirectConnection
);
setState
(
Ready
);
qDebug
()
<<
"Ready"
;
}
bool
ClipWorkflow
::
isReady
()
const
...
...
@@ -300,6 +309,7 @@ void ClipWorkflow::pause()
void
ClipWorkflow
::
unpause
()
{
queryStateChange
(
ClipWorkflow
::
Rendering
);
connect
(
m_mediaPlayer
,
SIGNAL
(
playing
()
),
this
,
SLOT
(
unpausedMediaPlayer
()
),
Qt
::
DirectConnection
);
m_mediaPlayer
->
pause
();
}
...
...
@@ -328,4 +338,11 @@ LibVLCpp::MediaPlayer* ClipWorkflow::getMediaPlayer()
void
ClipWorkflow
::
pausedMediaPlayer
()
{
setState
(
Paused
);
emit
paused
();
}
void
ClipWorkflow
::
unpausedMediaPlayer
()
{
disconnect
(
m_mediaPlayer
,
SIGNAL
(
playing
()
),
this
,
SLOT
(
unpausedMediaPlayer
()
)
);
emit
unpaused
();
}
src/Workflow/ClipWorkflow.h
View file @
2cd5097c
...
...
@@ -211,12 +211,15 @@ class ClipWorkflow : public QObject
void
initializedMediaPlayer
();
void
setPositionAfterPlayback
();
void
pausedMediaPlayer
();
void
unpausedMediaPlayer
();
public
slots
:
void
clipEndReached
();
signals:
void
renderComplete
(
ClipWorkflow
*
);
void
paused
();
void
unpaused
();
};
#endif // CLIPWORKFLOW_H
src/Workflow/MainWorkflow.cpp
View file @
2cd5097c
...
...
@@ -46,6 +46,7 @@ MainWorkflow::MainWorkflow( int trackCount ) :
m_tracks
[
i
].
setPtr
(
new
TrackWorkflow
(
i
)
);
connect
(
m_tracks
[
i
],
SIGNAL
(
trackEndReached
(
unsigned
int
)
),
this
,
SLOT
(
trackEndReached
(
unsigned
int
)
)
);
connect
(
m_tracks
[
i
],
SIGNAL
(
trackPaused
()
),
this
,
SLOT
(
trackPaused
()
)
);
connect
(
m_tracks
[
i
],
SIGNAL
(
trackUnpaused
()
),
this
,
SLOT
(
trackUnpaused
()
)
);
connect
(
m_tracks
[
i
],
SIGNAL
(
renderCompleted
(
unsigned
int
)
),
this
,
SLOT
(
tracksRenderCompleted
(
unsigned
int
)
),
Qt
::
QueuedConnection
);
}
m_renderStartedLock
=
new
QReadWriteLock
;
...
...
@@ -148,6 +149,21 @@ void MainWorkflow::pause()
}
}
void
MainWorkflow
::
unpause
()
{
QMutexLocker
lock
(
m_renderMutex
);
m_nbTracksToUnpause
=
0
;
for
(
unsigned
int
i
=
0
;
i
<
m_trackCount
;
++
i
)
{
if
(
m_tracks
[
i
].
activated
()
==
true
)
{
m_nbTracksToUnpause
.
fetchAndAddAcquire
(
1
);
m_tracks
[
i
]
->
unpause
();
}
}
}
void
MainWorkflow
::
nextFrame
()
{
// qDebug() << "Going to the next frame";
...
...
@@ -258,15 +274,22 @@ void MainWorkflow::clipMoved( QUuid clipUuid, int oldTrack, int newTra
void
MainWorkflow
::
trackPaused
()
{
// qDebug() << "Track pausing finished...";
m_nbTracksToPause
.
fetchAndAddAcquire
(
-
1
);
if
(
m_nbTracksToPause
<=
0
)
{
// qDebug() << "\t\t...MainWorkflow is paused";
emit
mainWorkflowPaused
();
}
}
void
MainWorkflow
::
trackUnpaused
()
{
m_nbTracksToUnpause
.
fetchAndAddAcquire
(
-
1
);
if
(
m_nbTracksToUnpause
<=
0
)
{
emit
mainWorkflowUnpaused
();
}
}
void
MainWorkflow
::
tracksRenderCompleted
(
unsigned
int
trackId
)
{
m_nbTracksToRender
.
fetchAndAddAcquire
(
-
1
);
...
...
src/Workflow/MainWorkflow.h
View file @
2cd5097c
...
...
@@ -71,6 +71,7 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
* Pause the main workflow and all its sub-workflows
*/
void
pause
();
void
unpause
();
static
unsigned
char
*
blackOutput
;
void
nextFrame
();
...
...
@@ -87,7 +88,6 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
private:
static
MainWorkflow
*
m_instance
;
// QAtomicInt m_oneFrameOnly;
private:
void
computeLength
();
...
...
@@ -105,6 +105,7 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
QMutex
*
m_renderMutex
;
QAtomicInt
m_nbTracksToPause
;
QAtomicInt
m_nbTracksToUnpause
;
QAtomicInt
m_nbTracksToRender
;
QMutex
*
m_highestTrackNumberMutex
;
unsigned
int
m_highestTrackNumber
;
...
...
@@ -118,6 +119,7 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
private
slots
:
void
trackEndReached
(
unsigned
int
trackId
);
void
trackPaused
();
void
trackUnpaused
();
void
tracksRenderCompleted
(
unsigned
int
trackId
);
signals:
...
...
@@ -132,6 +134,7 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
void
mainWorkflowEndReached
();
void
mainWorkflowPaused
();
void
mainWorkflowUnpaused
();
};
#endif // MAINWORKFLOW_H
src/Workflow/TrackWorkflow.cpp
View file @
2cd5097c
...
...
@@ -61,6 +61,8 @@ void TrackWorkflow::addClip( ClipWorkflow* cw, qint64 start )
{
QWriteLocker
lock
(
m_clipsLock
);
connect
(
cw
,
SIGNAL
(
renderComplete
(
ClipWorkflow
*
)
),
this
,
SLOT
(
clipWorkflowRenderCompleted
(
ClipWorkflow
*
)
),
Qt
::
DirectConnection
);
connect
(
cw
,
SIGNAL
(
paused
()
),
this
,
SLOT
(
clipWorkflowPaused
()
)
);
connect
(
cw
,
SIGNAL
(
unpaused
()
),
this
,
SLOT
(
clipWorkflowUnpaused
()
)
);
m_clips
.
insert
(
start
,
cw
);
computeLength
();
}
...
...
@@ -130,6 +132,7 @@ void TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentFrame,
//Otherwise, it will start directly.
cw
->
getStateLock
()
->
unlock
();
cw
->
startRender
();
if
(
needRepositioning
==
true
)
{
float
pos
=
(
(
float
)(
currentFrame
-
start
)
/
(
float
)(
cw
->
getClip
()
->
getLength
())
);
...
...
@@ -292,24 +295,6 @@ bool TrackWorkflow::getOutput( qint64 currentFrame )
return
hasRendered
;
}
void
TrackWorkflow
::
pauseClipWorkflow
(
ClipWorkflow
*
cw
)
{
cw
->
getStateLock
()
->
lockForRead
();
if
(
cw
->
getState
()
==
ClipWorkflow
::
Stopped
)
{
cw
->
getStateLock
()
->
unlock
();
return
;
}
if
(
cw
->
getState
()
!=
ClipWorkflow
::
Paused
)
{
//TODO (redo actually...) :)
Q_ASSERT
(
false
);
}
else
cw
->
getStateLock
()
->
unlock
();
}
void
TrackWorkflow
::
pause
()
{
QReadLocker
lock
(
m_clipsLock
);
...
...
@@ -317,7 +302,6 @@ void TrackWorkflow::pause()
QMap
<
qint64
,
ClipWorkflow
*>::
iterator
it
=
m_clips
.
begin
();
QMap
<
qint64
,
ClipWorkflow
*>::
iterator
end
=
m_clips
.
end
();
//FIXME: it's probably bad to iterate over every clip workflows.
m_nbClipToPause
=
0
;
for
(
;
it
!=
end
;
++
it
)
{
...
...
@@ -333,7 +317,7 @@ void TrackWorkflow::pause()
{
cw
->
getStateLock
()
->
unlock
();
m_nbClipToPause
.
fetchAndAddAcquire
(
1
);
pause
ClipWorkflow
(
cw
);
cw
->
pause
(
);
}
else
{
...
...
@@ -343,8 +327,6 @@ void TrackWorkflow::pause()
}
}
m_paused
=
!
m_paused
;
if
(
m_paused
==
true
)
emit
trackPaused
();
}
void
TrackWorkflow
::
moveClip
(
const
QUuid
&
id
,
qint64
startingFrame
)
...
...
@@ -415,3 +397,49 @@ unsigned char* TrackWorkflow::getSynchroneOutput()
{
return
m_synchroneRenderBuffer
;
}
void
TrackWorkflow
::
clipWorkflowPaused
()
{
m_nbClipToPause
.
fetchAndAddAcquire
(
-
1
);
if
(
m_nbClipToPause
<=
0
)
{
emit
trackPaused
();
}
}
void
TrackWorkflow
::
unpause
()
{
QReadLocker
lock
(
m_clipsLock
);
QMap
<
qint64
,
ClipWorkflow
*>::
iterator
it
=
m_clips
.
begin
();
QMap
<
qint64
,
ClipWorkflow
*>::
iterator
end
=
m_clips
.
end
();
m_nbClipToUnpause
=
0
;
for
(
;
it
!=
end
;
++
it
)
{
ClipWorkflow
*
cw
=
it
.
value
();
cw
->
getStateLock
()
->
lockForRead
();
if
(
cw
->
getState
()
==
ClipWorkflow
::
Paused
)
{
cw
->
getStateLock
()
->
unlock
();
m_nbClipToUnpause
.
fetchAndAddAcquire
(
1
);
cw
->
unpause
();
}
else
{
cw
->
getStateLock
()
->
unlock
();
}
}
m_paused
=
!
m_paused
;
}
void
TrackWorkflow
::
clipWorkflowUnpaused
()
{
m_nbClipToUnpause
.
fetchAndAddAcquire
(
-
1
);
if
(
m_nbClipToUnpause
<=
0
)
{
qDebug
()
<<
"Track unpaused"
;
emit
trackUnpaused
();
}
}
src/Workflow/TrackWorkflow.h
View file @
2cd5097c
...
...
@@ -52,11 +52,8 @@ class TrackWorkflow : public QObject
bool
getOutput
(
qint64
currentFrame
);
qint64
getLength
()
const
;
void
stop
();
/**
* Will pause all the track's ClipWorkflow.
* This method *is synchrone*, and will not return until all of the ClipWorkflow's thread are asleep
*/
void
pause
();
void
unpause
();
void
moveClip
(
const
QUuid
&
id
,
qint64
startingFrame
);
Clip
*
removeClip
(
const
QUuid
&
id
);
void
addClip
(
Clip
*
,
qint64
start
);
...
...
@@ -75,7 +72,6 @@ class TrackWorkflow : public QObject
qint64
start
,
bool
needRepositioning
);
void
preloadClip
(
ClipWorkflow
*
cw
);
void
stopClipWorkflow
(
ClipWorkflow
*
cw
);
void
pauseClipWorkflow
(
ClipWorkflow
*
cw
);
bool
checkEnd
(
qint64
currentFrame
)
const
;
private:
...
...
@@ -100,17 +96,20 @@ class TrackWorkflow : public QObject
bool
m_paused
;
QAtomicInt
m_nbClipToPause
;
QAtomicInt
m_nbClipToUnpause
;
QAtomicInt
m_nbClipToRender
;
unsigned
char
*
m_synchroneRenderBuffer
;
private
slots
:
// void clipWorkflowPaused();
void
clipWorkflowPaused
();
void
clipWorkflowUnpaused
();
void
clipWorkflowRenderCompleted
(
ClipWorkflow
*
);
signals:
void
trackEndReached
(
unsigned
int
);
void
trackPaused
();
void
trackUnpaused
();
void
renderCompleted
(
unsigned
int
);
};
...
...
src/renderer/WorkflowRenderer.cpp
View file @
2cd5097c
...
...
@@ -30,6 +30,7 @@
WorkflowRenderer
::
WorkflowRenderer
(
MainWorkflow
*
mainWorkflow
)
:
m_mainWorkflow
(
mainWorkflow
),
m_pauseAsked
(
false
),
m_unpauseAsked
(
false
),
m_pausedMediaPlayer
(
false
)
{
char
buffer
[
64
];
...
...
@@ -93,8 +94,6 @@ void* WorkflowRenderer::lock( void* datas )
void
WorkflowRenderer
::
unlock
(
void
*
datas
)
{
WorkflowRenderer
*
self
=
reinterpret_cast
<
WorkflowRenderer
*>
(
datas
);
self
->
internalPlayPause
(
true
);
self
->
checkActions
();
}
...
...
@@ -136,8 +135,9 @@ void WorkflowRenderer::startPreview()
char
buff
[
128
];
connect
(
m_mainWorkflow
,
SIGNAL
(
frameChanged
(
qint64
)
),
Timeline
::
getInstance
()
->
tracksView
()
->
tracksCursor
(),
SLOT
(
updateCursorPos
(
qint64
)
)
);
Timeline
::
getInstance
()
->
tracksView
()
->
tracksCursor
(),
SLOT
(
updateCursorPos
(
qint64
)
)
);
connect
(
m_mainWorkflow
,
SIGNAL
(
mainWorkflowPaused
()
),
this
,
SLOT
(
mainWorkflowPaused
()
)
);
connect
(
m_mainWorkflow
,
SIGNAL
(
mainWorkflowUnpaused
()
),
this
,
SLOT
(
mainWorkflowUnpaused
()
)
);
m_mainWorkflow
->
startRender
();
sprintf
(
buff
,
":fake-duration=%lli"
,
m_mainWorkflow
->
getLength
()
/
FPS
*
1000
);
m_media
->
addOption
(
buff
);
...
...
@@ -168,6 +168,15 @@ void WorkflowRenderer::pauseMainWorkflow()
m_mainWorkflow
->
pause
();
}
void
WorkflowRenderer
::
unpauseMainWorkflow
()
{
qDebug
()
<<
"unpauseMainWorkflow();"
;
if
(
m_paused
==
false
)
return
;
m_pausedMediaPlayer
=
false
;
m_mainWorkflow
->
unpause
();
}
void
WorkflowRenderer
::
mainWorkflowPaused
()
{
m_paused
=
true
;
...
...
@@ -175,6 +184,14 @@ void WorkflowRenderer::mainWorkflowPaused()
emit
paused
();
}
void
WorkflowRenderer
::
mainWorkflowUnpaused
()
{
qDebug
()
<<
"Emmiting signal playing"
;
m_paused
=
false
;
m_unpauseAsked
=
false
;
emit
playing
();
}
void
WorkflowRenderer
::
togglePlayPause
(
bool
forcePause
)
{
if
(
m_isRendering
==
false
&&
forcePause
==
false
)
...
...
@@ -190,8 +207,11 @@ void WorkflowRenderer::internalPlayPause( bool forcePause )
{
if
(
m_paused
==
true
&&
forcePause
==
false
)
{
//This will automaticly unpause the ClipWorkflow... no worries
m_mediaPlayer
->
play
();
if
(
m_paused
==
true
)
{
m_unpauseAsked
=
true
;
m_mediaPlayer
->
play
();
}
}
else
{
...
...
@@ -236,14 +256,21 @@ void WorkflowRenderer::__positionChanged( float pos )
void
WorkflowRenderer
::
__videoPaused
()
{
pauseMainWorkflow
();
if
(
m_pauseAsked
==
true
)
pauseMainWorkflow
();
}
void
WorkflowRenderer
::
__videoPlaying
()
{
emit
playing
();
m_pausedMediaPlayer
=
false
;
m_paused
=
false
;
if
(
m_unpauseAsked
==
true
)
unpauseMainWorkflow
();
else
{
qDebug
()
<<
"Emmiting signal playing without mainworkflow"
;
m_paused
=
false
;
m_pausedMediaPlayer
=
false
;
emit
playing
();
}
}
void
WorkflowRenderer
::
__videoStopped
()
...
...
src/renderer/WorkflowRenderer.h
View file @
2cd5097c
...
...
@@ -40,7 +40,7 @@ class WorkflowRenderer : public GenericRenderer
enum
Actions
{
Pause
,
Unpause
,
//
Unpause,
};
WorkflowRenderer
(
MainWorkflow
*
mainWorkflow
);
~
WorkflowRenderer
();
...
...
@@ -65,6 +65,7 @@ class WorkflowRenderer : public GenericRenderer
private:
void
internalPlayPause
(
bool
forcePause
);
void
pauseMainWorkflow
();
void
unpauseMainWorkflow
();
virtual
void
startPreview
();
void
checkActions
();
...
...
@@ -75,6 +76,7 @@ class WorkflowRenderer : public GenericRenderer
QStack
<
Actions
>
m_actions
;
QReadWriteLock
*
m_actionsLock
;
bool
m_pauseAsked
;
bool
m_unpauseAsked
;
/**
* \brief This flag is used to avoid using libvlc function from the media player thread,
...
...
@@ -87,6 +89,7 @@ class WorkflowRenderer : public GenericRenderer
void
mediaUnloaded
(
const
QUuid
&
)
{}
void
mainWorkflowPaused
();
void
mainWorkflowUnpaused
();
void
__positionChanged
();
void
__positionChanged
(
float
pos
);
...
...
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