Commit 317f0780 authored by Rafaël Carré's avatar Rafaël Carré

vlc-thumb: use pthread conditions

Also use a static boolean if the condition has been signaled
before we start waiting on it: libvlc_MediaPlayerSnapshotTaken event
is serialized with libvlc_video_take_snapshot() so when the function
returns the event already happened.
parent 7d049229
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
/* Copyright © 2007-2011 Rafaël Carré <funman@videolanorg> */ /* Copyright © 2007-2011 Rafaël Carré <funman@videolanorg> */
/* Works with : libvlc 1.2.0 /* Works with : libvlc 1.2.0
gcc -pedantic -Wall -Werror -Wextra `pkg-config --cflags --libs libvlc` gcc -pedantic -Wall -Werror -Wextra `pkg-config --cflags --libs libvlc` -lpthread
# to register the thumbnailer: # to register the thumbnailer:
list=`grep ^Mime vlc.desktop|cut -d= -f2-|sed -e s/";"/\\\n/g -e s,/,@,g` list=`grep ^Mime vlc.desktop|cut -d= -f2-|sed -e s/";"/\\\n/g -e s,/,@,g`
...@@ -22,6 +22,17 @@ ...@@ -22,6 +22,17 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <locale.h> #include <locale.h>
#include <pthread.h>
#include <errno.h>
#include <time.h>
#if !defined (_POSIX_CLOCK_SELECTION)
# define _POSIX_CLOCK_SELECTION (-1)
#endif
#if (_POSIX_CLOCK_SELECTION < 0)
# error Clock selection is not available!
#endif
#include <vlc/vlc.h> #include <vlc/vlc.h>
...@@ -96,67 +107,75 @@ static libvlc_instance_t *create_libvlc(void) ...@@ -96,67 +107,75 @@ static libvlc_instance_t *create_libvlc(void)
return libvlc_new(sizeof args / sizeof *args, args); return libvlc_new(sizeof args / sizeof *args, args);
} }
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t wait;
static bool done;
static void callback(const libvlc_event_t *ev, void *param) static void callback(const libvlc_event_t *ev, void *param)
{ {
float new_position = ev->u.media_player_position_changed.new_position; float new_position;
(void)param;
pthread_mutex_lock(&lock);
switch (ev->type) { switch (ev->type) {
case libvlc_MediaPlayerPositionChanged: case libvlc_MediaPlayerPositionChanged:
if (new_position >= VLC_THUMBNAIL_POSITION * .9) { /* 90% margin */ new_position = ev->u.media_player_position_changed.new_position;
*(int*)param = 1; if (new_position < VLC_THUMBNAIL_POSITION * .9 /* 90% margin */)
}
break; break;
case libvlc_MediaPlayerSnapshotTaken: case libvlc_MediaPlayerSnapshotTaken:
*(int*)param = 1; done = true;
pthread_cond_signal(&wait);
break; break;
default: default:
assert(0); assert(0);
} }
pthread_mutex_unlock(&lock);
} }
/* FIXME: should use pthread notification */ static void event_wait(const char *error)
static void event_wait(const char *error, int *f)
{ {
int ret;
struct timespec ts;
#define VLC_THUMBNAIL_TIMEOUT 5.0 /* 5 secs */ #define VLC_THUMBNAIL_TIMEOUT 5.0 /* 5 secs */
#define VLC_THUMBNAIL_LOOP_STEP 0.2 /* 200 ms */
float max = VLC_THUMBNAIL_TIMEOUT; clock_gettime(CLOCK_MONOTONIC, &ts);
while ((max -= VLC_THUMBNAIL_LOOP_STEP) > 0.) { ts.tv_sec += VLC_THUMBNAIL_TIMEOUT;
if (*f) pthread_mutex_lock(&lock);
return; ret = done ? 0 : pthread_cond_timedwait(&wait, &lock, &ts);
pthread_mutex_unlock(&lock);
usleep(VLC_THUMBNAIL_LOOP_STEP * 1000000); assert(!ret || ret == ETIMEDOUT);
}
if (ret) {
fprintf(stderr, fprintf(stderr,
"%s (timeout after %.2f secs!\n", error, VLC_THUMBNAIL_TIMEOUT); "%s (timeout after %.2f secs!\n", error, VLC_THUMBNAIL_TIMEOUT);
exit(1); exit(1);
}
} }
static void set_position(libvlc_media_player_t *mp) static void set_position(libvlc_media_player_t *mp)
{ {
int f = 0;
libvlc_event_manager_t *em = libvlc_media_player_event_manager(mp); libvlc_event_manager_t *em = libvlc_media_player_event_manager(mp);
assert(em); assert(em);
libvlc_event_attach(em, libvlc_MediaPlayerPositionChanged, callback, &f); libvlc_event_attach(em, libvlc_MediaPlayerPositionChanged, callback, NULL);
done = false;
libvlc_media_player_set_position(mp, VLC_THUMBNAIL_POSITION); libvlc_media_player_set_position(mp, VLC_THUMBNAIL_POSITION);
event_wait("Couldn't set position", &f); event_wait("Couldn't set position");
libvlc_event_detach(em, libvlc_MediaPlayerPositionChanged, callback, &f); libvlc_event_detach(em, libvlc_MediaPlayerPositionChanged, callback, NULL);
} }
static void snapshot(libvlc_media_player_t *mp, int width, char *out_with_ext) static void snapshot(libvlc_media_player_t *mp, int width, char *out_with_ext)
{ {
int f = 0;
libvlc_event_manager_t *em = libvlc_media_player_event_manager(mp); libvlc_event_manager_t *em = libvlc_media_player_event_manager(mp);
assert(em); assert(em);
libvlc_event_attach(em, libvlc_MediaPlayerSnapshotTaken, callback, &f); libvlc_event_attach(em, libvlc_MediaPlayerSnapshotTaken, callback, NULL);
done = false;
libvlc_video_take_snapshot(mp, 0, out_with_ext, width, 0); libvlc_video_take_snapshot(mp, 0, out_with_ext, width, 0);
event_wait("Snapshot has not been written", &f); event_wait("Snapshot has not been written");
libvlc_event_detach(em, libvlc_MediaPlayerSnapshotTaken, callback, &f); libvlc_event_detach(em, libvlc_MediaPlayerSnapshotTaken, callback, NULL);
} }
int main(int argc, const char **argv) int main(int argc, const char **argv)
...@@ -164,6 +183,7 @@ int main(int argc, const char **argv) ...@@ -164,6 +183,7 @@ int main(int argc, const char **argv)
const char *in; const char *in;
char *out, *out_with_ext; char *out, *out_with_ext;
int width; int width;
pthread_condattr_t attr;
libvlc_instance_t *libvlc; libvlc_instance_t *libvlc;
libvlc_media_player_t *mp; libvlc_media_player_t *mp;
libvlc_media_t *m; libvlc_media_t *m;
...@@ -173,6 +193,11 @@ int main(int argc, const char **argv) ...@@ -173,6 +193,11 @@ int main(int argc, const char **argv)
cmdline(argc, argv, &in, &out, &out_with_ext, &width); cmdline(argc, argv, &in, &out, &out_with_ext, &width);
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
pthread_cond_init(&wait, &attr);
pthread_condattr_destroy(&attr);
/* starts vlc */ /* starts vlc */
libvlc = create_libvlc(); libvlc = create_libvlc();
assert(libvlc); assert(libvlc);
...@@ -202,5 +227,7 @@ int main(int argc, const char **argv) ...@@ -202,5 +227,7 @@ int main(int argc, const char **argv)
libvlc_media_release(m); libvlc_media_release(m);
libvlc_release(libvlc); libvlc_release(libvlc);
pthread_cond_destroy(&wait);
return 0; return 0;
} }
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