Skip to content

Commit cfefa1e

Browse files
made reading videos async
1 parent 0e9ebc3 commit cfefa1e

3 files changed

Lines changed: 107 additions & 74 deletions

File tree

es-core/src/components/VideoComponent.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,6 @@ void VideoComponent::handleStartDelay()
239239
}
240240
// Completed
241241
mStartDelayed = false;
242-
// Clear the playing flag so startVideo works
243-
mIsPlaying = false;
244242
startVideo();
245243
}
246244
}
@@ -251,8 +249,8 @@ void VideoComponent::handleLooping()
251249

252250
void VideoComponent::startVideoWithDelay()
253251
{
254-
// If not playing then either start the video or initiate the delay
255-
if (!mIsPlaying)
252+
// If not playing and not already preparing to play, start the process
253+
if (!mIsPlaying && mPlayingVideoPath.empty())
256254
{
257255
// Set the video that we are going to be playing so we don't attempt to restart it
258256
mPlayingVideoPath = mVideoPath;
@@ -270,7 +268,6 @@ void VideoComponent::startVideoWithDelay()
270268
mFadeIn = 0.0f;
271269
mStartTime = SDL_GetTicks() + mConfig.startDelay;
272270
}
273-
mIsPlaying = true;
274271
}
275272
}
276273

@@ -313,8 +310,8 @@ void VideoComponent::manageState()
313310
// is not active and the component is visible
314311
bool show = mShowing && !mScreensaverActive && !mDisable && mVisible;
315312

316-
// See if we're already playing
317-
if (mIsPlaying)
313+
// See if we're already playing (or mid-parse preparing to play)
314+
if (mIsPlaying || mPlayingVideoPath.length() > 0)
318315
{
319316
// If we are not on display then stop the video from playing
320317
if (!show)
@@ -332,7 +329,7 @@ void VideoComponent::manageState()
332329
}
333330
}
334331
// Need to recheck variable rather than 'else' because it may be modified above
335-
if (!mIsPlaying)
332+
if (!mIsPlaying && mPlayingVideoPath.empty())
336333
{
337334
// If we are on display then see if we should start the video
338335
if (show && !mVideoPath.empty())

es-core/src/components/VideoVlcComponent.cpp

Lines changed: 95 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ static void display(void* /*data*/, void* /*id*/) {
4040

4141
VideoVlcComponent::VideoVlcComponent(Window* window, std::string subtitles) :
4242
VideoComponent(window),
43-
mMediaPlayer(nullptr)
43+
mMediaPlayer(nullptr),
44+
mMediaParsing(false)
4445
{
4546
memset(&mContext, 0, sizeof(mContext));
4647

@@ -137,6 +138,9 @@ void VideoVlcComponent::render(const Transform4x4f& parentTrans)
137138
if (!isVisible())
138139
return;
139140

141+
// Poll for async media parsing completion each frame
142+
handleParsing();
143+
140144
VideoComponent::render(parentTrans);
141145
Transform4x4f trans = parentTrans * getTransform();
142146
GuiComponent::renderChildren(trans);
@@ -233,7 +237,7 @@ void VideoVlcComponent::handleLooping()
233237

234238
void VideoVlcComponent::startVideo()
235239
{
236-
if (!mIsPlaying) {
240+
if (!mIsPlaying && !mMediaParsing) {
237241
mVideoWidth = 0;
238242
mVideoHeight = 0;
239243

@@ -252,83 +256,108 @@ void VideoVlcComponent::startVideo()
252256
mMedia = libvlc_media_new_path(mVLC, path.c_str());
253257
if (mMedia)
254258
{
255-
unsigned track_count;
256-
// Get the media metadata so we can find the aspect ratio
259+
// Start async parse — we will poll for completion in handleParsing()
257260
libvlc_media_parse_with_options(mMedia, libvlc_media_fetch_local, -1);
258-
while (libvlc_media_get_parsed_status(mMedia) == 0)
259-
;
260-
libvlc_media_track_t** tracks;
261-
track_count = libvlc_media_tracks_get(mMedia, &tracks);
262-
for (unsigned track = 0; track < track_count; ++track)
263-
{
264-
if (tracks[track]->i_type == libvlc_track_video)
265-
{
266-
mVideoWidth = tracks[track]->video->i_width;
267-
mVideoHeight = tracks[track]->video->i_height;
268-
break;
269-
}
270-
}
271-
libvlc_media_tracks_release(tracks, track_count);
261+
mMediaParsing = true;
262+
}
263+
}
264+
}
265+
}
266+
267+
void VideoVlcComponent::handleParsing()
268+
{
269+
if (!mMediaParsing || !mMedia)
270+
return;
271+
272+
// Poll — not yet parsed, come back next frame
273+
if (libvlc_media_get_parsed_status(mMedia) == 0)
274+
return;
275+
276+
mMediaParsing = false;
277+
onMediaParsed();
278+
}
279+
280+
void VideoVlcComponent::onMediaParsed()
281+
{
282+
unsigned track_count;
283+
libvlc_media_track_t** tracks;
284+
track_count = libvlc_media_tracks_get(mMedia, &tracks);
285+
for (unsigned track = 0; track < track_count; ++track)
286+
{
287+
if (tracks[track]->i_type == libvlc_track_video)
288+
{
289+
mVideoWidth = tracks[track]->video->i_width;
290+
mVideoHeight = tracks[track]->video->i_height;
291+
break;
292+
}
293+
}
294+
libvlc_media_tracks_release(tracks, track_count);
272295

273-
// Make sure we found a valid video track
274-
if ((mVideoWidth > 0) && (mVideoHeight > 0))
296+
// Make sure we found a valid video track
297+
if ((mVideoWidth > 0) && (mVideoHeight > 0))
298+
{
299+
if (mScreensaverMode)
300+
{
301+
std::string resolution = Settings::getInstance()->getString("VlcScreenSaverResolution");
302+
if(resolution != "original") {
303+
float scale = 1;
304+
if (resolution == "low")
305+
// 25% of screen resolution
306+
scale = 0.25;
307+
if (resolution == "medium")
308+
// 50% of screen resolution
309+
scale = 0.5;
310+
if (resolution == "high")
311+
// 75% of screen resolution
312+
scale = 0.75;
313+
314+
Vector2f resizeScale((Renderer::getScreenWidth() / (float)mVideoWidth) * scale, (Renderer::getScreenHeight() / (float)mVideoHeight) * scale);
315+
316+
if(resizeScale.x() < resizeScale.y())
275317
{
276-
if (mScreensaverMode)
277-
{
278-
std::string resolution = Settings::getInstance()->getString("VlcScreenSaverResolution");
279-
if(resolution != "original") {
280-
float scale = 1;
281-
if (resolution == "low")
282-
// 25% of screen resolution
283-
scale = 0.25;
284-
if (resolution == "medium")
285-
// 50% of screen resolution
286-
scale = 0.5;
287-
if (resolution == "high")
288-
// 75% of screen resolution
289-
scale = 0.75;
290-
291-
Vector2f resizeScale((Renderer::getScreenWidth() / (float)mVideoWidth) * scale, (Renderer::getScreenHeight() / (float)mVideoHeight) * scale);
292-
293-
if(resizeScale.x() < resizeScale.y())
294-
{
295-
mVideoWidth = (unsigned int) (mVideoWidth * resizeScale.x());
296-
mVideoHeight = (unsigned int) (mVideoHeight * resizeScale.x());
297-
}else{
298-
mVideoWidth = (unsigned int) (mVideoWidth * resizeScale.y());
299-
mVideoHeight = (unsigned int) (mVideoHeight * resizeScale.y());
300-
}
301-
}
302-
}
303-
else
304-
{
305-
remove(getTitlePath().c_str());
306-
}
307-
PowerSaver::pause();
308-
setupContext();
309-
310-
// Setup the media player
311-
mMediaPlayer = libvlc_media_player_new_from_media(mMedia);
312-
313-
setMuteMode();
314-
315-
libvlc_media_player_play(mMediaPlayer);
316-
libvlc_video_set_callbacks(mMediaPlayer, lock, unlock, display, (void*)&mContext);
317-
libvlc_video_set_format(mMediaPlayer, "RGBA", (int)mVideoWidth, (int)mVideoHeight, (int)mVideoWidth * 4);
318-
319-
// Update the playing state
320-
mIsPlaying = true;
321-
mFadeIn = 0.0f;
318+
mVideoWidth = (unsigned int) (mVideoWidth * resizeScale.x());
319+
mVideoHeight = (unsigned int) (mVideoHeight * resizeScale.x());
320+
}else{
321+
mVideoWidth = (unsigned int) (mVideoWidth * resizeScale.y());
322+
mVideoHeight = (unsigned int) (mVideoHeight * resizeScale.y());
322323
}
323324
}
324325
}
326+
else
327+
{
328+
remove(getTitlePath().c_str());
329+
}
330+
PowerSaver::pause();
331+
setupContext();
332+
333+
// Setup the media player
334+
mMediaPlayer = libvlc_media_player_new_from_media(mMedia);
335+
336+
setMuteMode();
337+
338+
libvlc_media_player_play(mMediaPlayer);
339+
libvlc_video_set_callbacks(mMediaPlayer, lock, unlock, display, (void*)&mContext);
340+
libvlc_video_set_format(mMediaPlayer, "RGBA", (int)mVideoWidth, (int)mVideoHeight, (int)mVideoWidth * 4);
341+
342+
// Update the playing state
343+
mIsPlaying = true;
344+
mFadeIn = 0.0f;
325345
}
326346
}
327347

328348
void VideoVlcComponent::stopVideo()
329349
{
330350
mIsPlaying = false;
331351
mStartDelayed = false;
352+
mPlayingVideoPath = "";
353+
// If we were mid-parse with no player yet, cancel the parse and release the media
354+
if (mMediaParsing && mMedia)
355+
{
356+
libvlc_media_parse_stop(mMedia);
357+
libvlc_media_release(mMedia);
358+
mMedia = nullptr;
359+
}
360+
mMediaParsing = false;
332361
// Release the media player so it stops calling back to us
333362
if (mMediaPlayer)
334363
{

es-core/src/components/VideoVlcComponent.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,19 @@ class VideoVlcComponent : public VideoComponent
6262
void setupContext();
6363
void freeContext();
6464

65+
// Called each frame to check if async media parsing has completed;
66+
// once done, extracts track info and starts playback.
67+
void handleParsing();
68+
// Second half of startVideo — runs after parsing finishes.
69+
void onMediaParsed();
70+
6571
private:
6672
static libvlc_instance_t* mVLC;
6773
libvlc_media_t* mMedia;
6874
libvlc_media_player_t* mMediaPlayer;
6975
VideoContext mContext;
7076
std::shared_ptr<TextureResource> mTexture;
77+
bool mMediaParsing;
7178
};
7279

7380
#endif // ES_CORE_COMPONENTS_VIDEO_VLC_COMPONENT_H

0 commit comments

Comments
 (0)