Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
VLMC
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
21
Issues
21
List
Boards
Labels
Service Desk
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
VideoLAN
VLMC
Commits
2cf157ac
Commit
2cf157ac
authored
Jun 01, 2009
by
Hugo Beauzee-Luyssen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactored TrackWorkflow
parent
3467724d
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
224 additions
and
285 deletions
+224
-285
src/Workflow/ClipWorkflow.cpp
src/Workflow/ClipWorkflow.cpp
+71
-26
src/Workflow/ClipWorkflow.h
src/Workflow/ClipWorkflow.h
+40
-5
src/Workflow/MainWorkflow.cpp
src/Workflow/MainWorkflow.cpp
+0
-2
src/Workflow/TrackWorkflow.cpp
src/Workflow/TrackWorkflow.cpp
+110
-204
src/Workflow/TrackWorkflow.h
src/Workflow/TrackWorkflow.h
+3
-48
No files found.
src/Workflow/ClipWorkflow.cpp
View file @
2cf157ac
...
...
@@ -24,41 +24,51 @@
#include "ClipWorkflow.h"
ClipWorkflow
::
ClipWorkflow
(
Clip
::
Clip
*
clip
,
QMutex
*
renderMutex
,
QMutex
*
condMutex
,
QWaitCondition
*
waitCond
)
:
int
g_debugId
=
0
;
ClipWorkflow
::
ClipWorkflow
(
Clip
::
Clip
*
clip
)
:
m_clip
(
clip
),
m_buffer
(
NULL
),
m_renderMutex
(
renderMutex
),
m_condMutex
(
condMutex
),
m_waitCond
(
waitCond
),
m_usingBackBuffer
(
false
),
m_mediaPlayer
(
NULL
),
m_state
(
ClipWorkflow
::
Stopped
)
m_state
(
ClipWorkflow
::
Stopped
),
m_requiredState
(
ClipWorkflow
::
None
)
{
m_buffer
=
new
unsigned
char
[
VIDEOHEIGHT
*
VIDEOWIDTH
*
4
];
m_backBuffer
=
new
unsigned
char
[
VIDEOHEIGHT
*
VIDEOWIDTH
*
4
];
m_stateLock
=
new
QReadWriteLock
;
m_requiredStateLock
=
new
QMutex
;
m_condMutex
=
new
QMutex
;
m_waitCond
=
new
QWaitCondition
;
m_backBufferLock
=
new
QReadWriteLock
;
this
->
debugId
=
g_debugId
++
;
}
ClipWorkflow
::~
ClipWorkflow
()
{
delete
[]
m_buffer
;
delete
[]
m_backBuffer
;
delete
m_stateLock
;
delete
m_requiredStateLock
;
delete
m_backBufferLock
;
}
unsigned
char
*
ClipWorkflow
::
getOutput
()
{
QMutexLocker
lock
(
m_renderMutex
);
return
m_buffer
;
QReadLocker
lock
(
m_backBufferLock
);
if
(
m_usingBackBuffer
==
true
)
return
m_buffer
;
return
m_backBuffer
;
}
void
ClipWorkflow
::
checkStateChange
()
{
QMutexLocker
lock
(
m_requiredStateLock
);
QWriteLocker
lock2
(
m_stateLock
);
QWriteLocker
lock2
(
m_stateLock
);
if
(
m_requiredState
!=
ClipWorkflow
::
None
)
{
qDebug
()
<<
"
Changing state"
;
qDebug
()
<<
"
Setting required state : "
<<
m_requiredState
;
m_state
=
m_requiredState
;
m_requiredState
=
ClipWorkflow
::
None
;
}
...
...
@@ -66,29 +76,42 @@ void ClipWorkflow::checkStateChange()
void
ClipWorkflow
::
lock
(
ClipWorkflow
*
clipWorkflow
,
void
**
pp_ret
)
{
//In any case, we give vlc a buffer to render in...
//If we don't, segmentation fault will catch us and eat our brains !! ahem...
// qDebug() << "Locking in ClipWorkflow::lock";
clipWorkflow
->
m_renderMutex
->
lock
();
// qDebug() << clipWorkflow->getState();
*
pp_ret
=
clipWorkflow
->
m_buffer
;
QReadLocker
lock
(
clipWorkflow
->
m_backBufferLock
);
if
(
clipWorkflow
->
m_usingBackBuffer
)
*
pp_ret
=
clipWorkflow
->
m_backBuffer
;
else
*
pp_ret
=
clipWorkflow
->
m_buffer
;
}
void
ClipWorkflow
::
unlock
(
ClipWorkflow
*
c
lipWorkflo
w
)
void
ClipWorkflow
::
unlock
(
ClipWorkflow
*
cw
)
{
c
lipWorkflow
->
m_renderMutex
->
unlock
();
c
w
->
m_stateLock
->
lockForWrite
();
clipWorkflow
->
checkStateChange
();
clipWorkflow
->
m_stateLock
->
lockForRead
();
if
(
clipWorkflow
->
m_state
==
Rendering
)
if
(
cw
->
m_state
==
Rendering
)
{
QMutexLocker
lock
(
clipWorkflow
->
m_condMutex
);
clipWorkflow
->
m_stateLock
->
unlock
();
clipWorkflow
->
m_waitCond
->
wait
(
clipWorkflow
->
m_condMutex
);
cw
->
m_state
=
Sleeping
;
cw
->
m_stateLock
->
unlock
();
QMutexLocker
lock
(
cw
->
m_condMutex
);
cw
->
m_waitCond
->
wait
(
cw
->
m_condMutex
);
{
QWriteLocker
lock2
(
cw
->
m_backBufferLock
);
cw
->
m_usingBackBuffer
=
!
cw
->
m_usingBackBuffer
;
}
cw
->
m_stateLock
->
lockForWrite
();
cw
->
m_state
=
Rendering
;
}
else
qDebug
()
<<
clipWorkflow
->
m_state
;
clipWorkflow
->
m_stateLock
->
unlock
();
{
qDebug
()
<<
"UnLocking. State = "
<<
cw
->
m_state
<<
"Debug Id = "
<<
cw
->
debugId
;
}
cw
->
m_stateLock
->
unlock
();
cw
->
checkStateChange
();
// qDebug() << "UnLocking in ClipWorkflow::unlock";
}
...
...
@@ -96,6 +119,7 @@ void ClipWorkflow::setVmem()
{
char
buffer
[
32
];
qDebug
()
<<
"Setting vmem from clip "
<<
this
->
debugId
;
//TODO: it would be good if we somehow backup the old media parameters to restore it later.
m_clip
->
getParent
()
->
getVLCMedia
()
->
addOption
(
":vout=vmem"
);
m_clip
->
getParent
()
->
getVLCMedia
()
->
setDataCtx
(
this
);
...
...
@@ -146,6 +170,7 @@ void ClipWorkflow::pausedMediaPlayer()
{
disconnect
(
m_mediaPlayer
,
SIGNAL
(
paused
()
),
this
,
SLOT
(
pausedMediaPlayer
()
)
);
setState
(
Ready
);
qDebug
()
<<
"Set Ready state"
;
}
bool
ClipWorkflow
::
isReady
()
const
...
...
@@ -168,7 +193,6 @@ bool ClipWorkflow::isStopped() const
ClipWorkflow
::
State
ClipWorkflow
::
getState
()
const
{
QReadLocker
lock
(
m_stateLock
);
return
m_state
;
}
...
...
@@ -199,6 +223,8 @@ void ClipWorkflow::stop()
qDebug
()
<<
"Stopped media player"
;
m_mediaPlayer
=
NULL
;
setState
(
Stopped
);
QMutexLocker
lock
(
m_requiredStateLock
);
m_requiredState
=
ClipWorkflow
::
None
;
qDebug
()
<<
"Changed state"
;
}
...
...
@@ -215,6 +241,7 @@ bool ClipWorkflow::isRendering() const
void
ClipWorkflow
::
setState
(
State
state
)
{
qDebug
()
<<
"Setting state : "
<<
state
;
QWriteLocker
lock
(
m_stateLock
);
m_state
=
state
;
}
...
...
@@ -225,3 +252,21 @@ void ClipWorkflow::queryStateChange( State newState )
QMutexLocker
lock
(
m_requiredStateLock
);
m_requiredState
=
newState
;
}
void
ClipWorkflow
::
wake
()
{
m_waitCond
->
wakeAll
();
}
QReadWriteLock
*
ClipWorkflow
::
getStateLock
()
{
return
m_stateLock
;
}
void
ClipWorkflow
::
reinitialize
()
{
QWriteLocker
lock
(
m_stateLock
);
m_state
=
Stopped
;
queryStateChange
(
None
);
}
src/Workflow/ClipWorkflow.h
View file @
2cf157ac
...
...
@@ -49,11 +49,13 @@ class ClipWorkflow : public QObject
Initializing
,
Ready
,
Rendering
,
Sleeping
,
Stopping
,
EndReached
,
StopRequired
,
};
int
debugId
;
ClipWorkflow
(
Clip
*
clip
,
QMutex
*
renderMutex
,
QMutex
*
condMutex
,
QWaitCondition
*
waitCond
);
ClipWorkflow
(
Clip
*
clip
);
virtual
~
ClipWorkflow
();
/**
...
...
@@ -89,6 +91,9 @@ class ClipWorkflow : public QObject
/**
* Returns the current workflow state.
* Be carrefull, as this function is NOT thread safe, and return the
* state without locking the state.
* It's your job to do it, by calling the getStateLock() method.
*/
State
getState
()
const
;
...
...
@@ -120,23 +125,53 @@ class ClipWorkflow : public QObject
*/
void
queryStateChange
(
State
newState
);
/**
* This method will wake the renderer thread for one iteration.
*/
void
wake
();
/**
* This returns the QReadWriteLock that protects the ClipWorkflow's state.
* It should be use to lock the value when checking states from outside this
* class.
*/
QReadWriteLock
*
getStateLock
();
/**
* Put back the ClipWorkflow in its initial state.
*/
void
reinitialize
();
private:
static
void
lock
(
ClipWorkflow
*
clipWorkflow
,
void
**
pp_ret
);
static
void
unlock
(
ClipWorkflow
*
clipWorkflow
);
void
setVmem
();
void
setState
(
State
state
);
/**
* Don't ever call this method from anywhere else than the unlock() method
*/
void
checkStateChange
();
private:
Clip
*
m_clip
;
unsigned
char
*
m_buffer
;
unsigned
char
*
m_backBuffer
;
/**
* This allow the render procedure to know in which buffer it should render.
* If true, then the render occurs in the back buffer, which means the
* returned buffer much be the "front" buffer.
* In other term :
* - When m_usingBackBuffer == false, lock() will return m_buffer, and getOutput() m_backBuffer
* - When m_usingBackBuffer == true, lock() will return m_backBuffer, and getOutput() m_buffer
*/
bool
m_usingBackBuffer
;
QReadWriteLock
*
m_backBufferLock
;
LibVLCpp
::
MediaPlayer
*
m_mediaPlayer
;
QMutex
*
m_renderMutex
;
QMutex
*
m_condMutex
;
QWaitCondition
*
m_waitCond
;
LibVLCpp
::
MediaPlayer
*
m_mediaPlayer
;
State
m_state
;
QReadWriteLock
*
m_stateLock
;
State
m_requiredState
;
...
...
src/Workflow/MainWorkflow.cpp
View file @
2cf157ac
...
...
@@ -50,7 +50,6 @@ void MainWorkflow::startRender()
m_currentFrame
=
0
;
emit
frameChanged
(
0
);
m_length
=
m_tracks
[
0
]
->
getLength
();
m_tracks
[
0
]
->
startRender
();
}
unsigned
char
*
MainWorkflow
::
getOutput
()
...
...
@@ -67,7 +66,6 @@ void MainWorkflow::setPosition( float pos )
if
(
m_renderStarted
==
false
)
return
;
qint64
frame
=
(
float
)
m_length
*
pos
;
m_tracks
[
0
]
->
requirePositionChanged
(
pos
);
m_currentFrame
=
frame
;
emit
frameChanged
(
frame
);
//Do not emit a signal for the RenderWidget, since it's the one that triggered that call...
...
...
src/Workflow/TrackWorkflow.cpp
View file @
2cf157ac
...
...
@@ -26,13 +26,9 @@
unsigned
char
*
TrackWorkflow
::
blackOutput
=
NULL
;
TrackWorkflow
::
TrackWorkflow
()
:
m_requiredPosition
(
-
1.0
f
)
TrackWorkflow
::
TrackWorkflow
()
{
m_condMutex
=
new
QMutex
;
m_waitCondition
=
new
QWaitCondition
;
m_mediaPlayer
=
new
LibVLCpp
::
MediaPlayer
();
m_renderMutex
=
new
QMutex
;
m_requiredPositionLock
=
new
QMutex
;
if
(
TrackWorkflow
::
blackOutput
==
NULL
)
{
//TODO: this ain't free !
...
...
@@ -43,38 +39,17 @@ TrackWorkflow::TrackWorkflow() : m_requiredPosition( -1.0f )
TrackWorkflow
::~
TrackWorkflow
()
{
delete
m_condMutex
;
delete
m_waitCondition
;
delete
m_mediaPlayer
;
delete
m_renderMutex
;
}
void
TrackWorkflow
::
addClip
(
Clip
*
clip
,
qint64
start
)
{
qDebug
()
<<
"Inserting clip at frame nb"
<<
start
;
ClipWorkflow
*
cw
=
new
ClipWorkflow
(
clip
,
m_renderMutex
,
m_condMutex
,
m_waitCondition
);
ClipWorkflow
*
cw
=
new
ClipWorkflow
(
clip
);
m_clips
.
insert
(
start
,
cw
);
computeLength
();
}
void
TrackWorkflow
::
startRender
()
{
m_current
=
m_clips
.
end
();
if
(
m_clips
.
size
()
<=
0
)
return
;
//If the first frame is to be render soon, we should play it now.
if
(
m_clips
.
begin
().
key
()
<
TrackWorkflow
::
nbFrameBeforePreload
)
{
m_clips
.
begin
().
value
()
->
initialize
(
m_mediaPlayer
);
if
(
m_current
.
key
()
==
0
)
{
m_current
=
m_clips
.
begin
();
m_current
.
value
()
->
startRender
();
}
}
}
void
TrackWorkflow
::
computeLength
()
{
if
(
m_clips
.
count
()
==
0
)
...
...
@@ -88,227 +63,158 @@ qint64 TrackWorkflow::getLength() const
return
m_length
;
}
bool
TrackWorkflow
::
checkNextClip
(
qint64
currentFrame
)
unsigned
char
*
TrackWorkflow
::
renderClip
(
ClipWorkflow
*
cw
,
bool
needRepositioning
,
float
pos
)
{
QMap
<
qint64
,
ClipWorkflow
*>::
iterator
next
;
const
QMap
<
qint64
,
ClipWorkflow
*>::
const_iterator
end
=
m_clips
.
end
();
unsigned
char
*
ret
=
TrackWorkflow
::
blackOutput
;
//Picking next clip :
if
(
m_current
==
end
)
{
//Checking if there is a clip in the first place...
if
(
m_clips
.
count
()
==
0
)
return
false
;
next
=
m_clips
.
begin
();
}
else
{
next
=
m_clips
.
begin
()
+
1
;
if
(
next
==
end
)
return
false
;
}
cw
->
getStateLock
()
->
lockForRead
();
//If it's about to be used, initialize it
if
(
next
.
key
()
==
currentFrame
+
TrackWorkflow
::
nbFrameBeforePreload
)
{
//Don't do anything if the current media player is still in use
//But for it to be in use, we should have a current media :
if
(
m_current
!=
end
&&
m_current
.
value
()
->
isRendering
()
==
false
)
qDebug
()
<<
"Preloading media"
;
next
.
value
()
->
initialize
(
m_mediaPlayer
);
}
//This ClipWorkflow must start at this frame :
else
if
(
next
.
key
()
==
currentFrame
)
if
(
cw
->
getState
()
==
ClipWorkflow
::
Rendering
)
{
qDebug
()
<<
"Starting rendering"
;
m_current
=
next
;
m_current
.
value
()
->
startRender
();
//The rendering state meens... whell it means that the frame is
//beeing rendered, so we wait.
cw
->
getStateLock
()
->
unlock
();
while
(
cw
->
isRendering
()
==
true
)
{
// qDebug() << "Waiting for complete render. State == " << cw->getState();
usleep
(
100
);
}
cw
->
getStateLock
()
->
lockForRead
();
//This way we can trigger the appropriate if just below.
}
return
true
;
}
unsigned
char
*
TrackWorkflow
::
getOutput
(
qint64
currentFrame
)
{
unsigned
char
*
ret
=
TrackWorkflow
::
blackOutput
;
bool
clipsRemaining
;
QMutexLocker
lock
(
m_requiredPositionLock
);
if
(
m_requiredPosition
>=
0.0
f
)
//If frame has been rendered :
if
(
cw
->
getState
()
==
ClipWorkflow
::
Sleeping
)
{
setPosition
(
m_requiredPosition
);
m_requiredPosition
=
-
1.0
f
;
cw
->
getStateLock
()
->
unlock
();
ret
=
cw
->
getOutput
();
if
(
needRepositioning
==
true
)
{
cw
->
setPosition
(
pos
);
}
cw
->
wake
();
}
checkStop
();
// qDebug() << "Frame nb" << currentFrame;
clipsRemaining
=
checkNextClip
(
currentFrame
);
//This is true only before the first render.
if
(
m_current
==
m_clips
.
end
()
)
else
if
(
cw
->
getState
()
==
ClipWorkflow
::
Stopped
)
{
// qDebug() << "m_current == m_clips.end()";
//If the track was empty, then its end is reached
if
(
clipsRemaining
==
false
)
emit
endReached
();
//Else, we return a black screen.
return
TrackWorkflow
::
blackOutput
;
cw
->
getStateLock
()
->
unlock
();
cw
->
initialize
(
m_mediaPlayer
);
cw
->
startRender
();
qDebug
()
<<
"Render started for clip"
<<
cw
->
debugId
;
}
//We proceed to the render only if the ClipWorkflow is in rendering mode.
if
(
m_current
.
value
()
->
isRendering
()
==
true
)
else
if
(
cw
->
getState
()
==
ClipWorkflow
::
Ready
||
cw
->
getState
()
==
ClipWorkflow
::
Initializing
)
{
m_waitCondition
->
wakeAll
();
// qDebug() << "Is rendering == true";
ret
=
m_current
.
value
()
->
getOutput
();
return
ret
;
//If the state is Initializing, then the workflow will wait.
//Otherwise, it will start directly.
cw
->
getStateLock
()
->
unlock
();
cw
->
startRender
();
qDebug
()
<<
"Started render for clip"
<<
cw
->
debugId
;
}
else
if
(
m_current
.
value
()
->
getState
()
==
ClipWorkflow
::
EndReached
||
m_current
.
value
()
->
getState
()
==
ClipWorkflow
::
StopRequired
)
else
{
//First, we stop the current ClipWorkflow so that it won't
//enter the lock/unlock cycle anymore.
qDebug
()
<<
"Stopping"
;
m_current
.
value
()
->
stop
();
//Then, if there's no remaining clip, end of track is reached.
if
(
clipsRemaining
==
false
)
emit
endReached
();
qDebug
()
<<
"Unexpected ClipWorkflow::State when rendering:"
<<
cw
->
getState
();
cw
->
getStateLock
()
->
unlock
();
}
// else
// qDebug() << "Uncoherent state : " << m_current.value()->getState();
return
ret
;
}
void
TrackWorkflow
::
initializeClipWorkflow
(
ClipWorkflow
*
cw
)
void
TrackWorkflow
::
preloadClip
(
ClipWorkflow
*
cw
)
{
//>Launching the initialization
cw
->
initialize
(
m_mediaPlayer
);
cw
->
startRender
();
}
cw
->
getStateLock
()
->
lockForRead
();
void
TrackWorkflow
::
stopClipWorkflow
(
ClipWorkflow
*
cw
)
{
if
(
cw
->
getState
()
!=
ClipWorkflow
::
Stopped
&&
cw
->
getState
()
!=
ClipWorkflow
::
StopRequired
)
if
(
cw
->
getState
()
==
ClipWorkflow
::
Stopped
)
{
cw
->
queryStateChange
(
ClipWorkflow
::
StopRequired
);
//Since state change won't be immediate, we add the clip workflow to a lookup list
m_toStop
.
enqueue
(
cw
)
;
cw
->
getStateLock
()
->
unlock
(
);
cw
->
initialize
(
m_mediaPlayer
);
return
;
}
cw
->
getStateLock
()
->
unlock
();
}
void
TrackWorkflow
::
setPosition
(
float
pos
)
void
TrackWorkflow
::
stopClipWorkflow
(
ClipWorkflow
*
cw
)
{
qDebug
()
<<
"Setting 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
=
end
;
cw
->
getStateLock
()
->
lockForRead
();
if
(
frame
>
m_length
)
if
(
cw
->
getState
()
==
ClipWorkflow
::
Stopped
)
{
if
(
m_current
!=
end
)
{
stopClipWorkflow
(
m_current
.
value
()
);
m_current
=
end
;
qDebug
()
<<
"After end of current track"
;
return
;
}
cw
->
getStateLock
()
->
unlock
();
return
;
}
//Locate the new clip workflow
while
(
it
!=
en
d
)
if
(
cw
->
getState
()
==
ClipWorkflow
::
Sleeping
||
cw
->
getState
()
==
ClipWorkflow
::
Ready
||
cw
->
getState
()
==
ClipWorkflow
::
EndReache
d
)
{
if
(
it
.
key
()
<=
frame
&&
(
it
.
key
()
+
it
.
value
()
->
getClip
()
->
getLength
()
)
>
frame
)
{
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
()
)
{
next
=
next
-
1
;
//Since the iterator must point to the previous video
}
else
{
next
=
end
;
}
// in order to checkNextClip() to work.
it
=
end
;
break
;
}
++
it
;
qDebug
()
<<
"Stopping from sleeping / ready / endreached state for clip "
<<
cw
->
debugId
;
cw
->
getStateLock
()
->
unlock
();
cw
->
queryStateChange
(
ClipWorkflow
::
Stopping
);
cw
->
wake
();
cw
->
stop
();
}
//No clip was found, just adjusing the current clip. (Render will be black though)
if
(
it
==
end
)
else
if
(
cw
->
getState
()
==
ClipWorkflow
::
Rendering
)
{
qDebug
()
<<
"In black zone"
;
//We should use the next clip, however, we use the clip just before
//the next.
//We also stop the current clip if it was started.
if
(
m_current
!=
end
)
{
stopClipWorkflow
(
m_current
.
value
()
);
}
//TODO: it seems that m_current may be equal to next... check if that could be a problem...
m_current
=
next
;
qDebug
()
<<
"Stopping from rendering state for clip"
<<
cw
->
debugId
;
cw
->
getStateLock
()
->
unlock
();
while
(
cw
->
isRendering
()
==
true
)
usleep
(
100
);
qDebug
()
<<
"Rendering completed"
<<
cw
->
debugId
;
cw
->
queryStateChange
(
ClipWorkflow
::
Stopping
);
cw
->
wake
();
cw
->
stop
();
qDebug
()
<<
"Mediaplayer Stop asked for clip"
<<
cw
->
debugId
;
}
// If the clip found is the current, we just change the position of the
// media player
else
if
(
it
==
m_current
)
else
if
(
cw
->
getState
()
==
ClipWorkflow
::
Initializing
)
{
qDebug
()
<<
"Using current clip with new position"
;
qDebug
()
<<
it
.
value
()
->
getState
();
//The clip may have been stoped (if we reached end but came back at it)
if
(
it
.
value
()
->
isStopped
()
)
{
initializeClipWorkflow
(
it
.
value
()
);
}
it
.
value
()
->
setPosition
(
(
float
)(
frame
-
it
.
key
()
)
/
(
float
)(
it
.
value
()
->
getClip
()
->
getLength
())
);
//Awaking renderers to avoid them to be stuck inside of the lock...
m_waitCondition
->
wakeAll
();
qDebug
()
<<
"Stopping from initializing state for clip"
<<
cw
->
debugId
;
cw
->
getStateLock
()
->
unlock
();
while
(
cw
->
isReady
()
==
false
)
usleep
(
20
);
cw
->
stop
();
}
// Else, we found a clip that is not the current one.
else
{
qDebug
()
<<
"Using other clip"
;
//First, we stop the current workflow.
if
(
m_current
!=
end
)
{
stopClipWorkflow
(
m_current
.
value
()
);
}
//We initialize the new workflow
initializeClipWorkflow
(
it
.
value
()
);
//And this is now our current clip
m_current
=
it
;
//TODO: we doesn't take the new position in count :/
qDebug
()
<<
"Unexpected ClipWorkflow::State when stopping :"
<<
cw
->
getState
();
cw
->
getStateLock
()
->
unlock
();
}
}
void
TrackWorkflow
::
requirePositionChanged
(
float
pos
)
unsigned
char
*
TrackWorkflow
::
getOutput
(
qint64
currentFrame
)
{
QMutexLocker
lock
(
m_requiredPositionLock
);
m_requiredPosition
=
pos
;
}
unsigned
char
*
ret
=
TrackWorkflow
::
blackOutput
;
QMap
<
qint64
,
ClipWorkflow
*>::
iterator
it
=
m_clips
.
begin
();
QMap
<
qint64
,
ClipWorkflow
*>::
iterator
end
=
m_clips
.
end
();
static
qint64
lastFrame
=
0
;
bool
needRepositioning
;
void
TrackWorkflow
::
checkStop
()
{
while
(
m_toStop
.
isEmpty
()
==
false
)
needRepositioning
=
(
abs
(
currentFrame
-
lastFrame
)
>
3
)
?
true
:
false
;
while
(
it
!=
end
)
{
ClipWorkflow
*
cw
=
m_toStop
.
head
();
if
(
cw
->
getState
()
==
ClipWorkflow
::
StopRequired
)
qint64
start
=
it
.
key
();
ClipWorkflow
*
cw
=
it
.
value
();
//Is the clip supposed to render now ?
if
(
start
<=
currentFrame
&&
currentFrame
<=
start
+
cw
->
getClip
()
->
getLength
()
)
{
qDebug
()
<<
"Stopping from queue"
;
cw
->
stop
();