/* thread to keep track of synced frames */
gint8 *isqueued_queued_frames; /* 1 = queued, 0 = unqueued, -1 = error */
- pthread_t thread_queued_frames;
- pthread_mutex_t mutex_queued_frames;
- pthread_cond_t *cond_queued_frames;
+ GThread *thread_queued_frames;
+ GMutex *mutex_queued_frames;
+ GCond **cond_queued_frames;
gint current_frame;
/* something to get our buffers from */
gint8 *frame_queued;
guint buffer_size;
- /* a seperate pthread for the sync() thread (improves correctness of timestamps) */
+ /* a seperate GThread for the sync() thread (improves correctness of timestamps) */
gint8 *isready_soft_sync; /* 1 = ok, 0 = waiting, -1 = error */
struct timeval *timestamp_soft_sync;
- pthread_t thread_soft_sync;
- pthread_mutex_t mutex_soft_sync;
- pthread_cond_t *cond_soft_sync;
+ GThread * thread_soft_sync;
+ GMutex * mutex_soft_sync;
+ GCond ** cond_soft_sync;
- /* num of queued frames and some pthread stuff to wait if there's not enough */
+ /* num of queued frames and some GThread stuff to wait if there's not enough */
guint16 num_queued_frames;
- pthread_mutex_t mutex_queued_frames;
- pthread_cond_t cond_queued_frames;
+ GMutex * mutex_queued_frames;
+ GCond * cond_queued_frames;
/* first timestamp */
guint64 first_timestamp;
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
-#include <pthread.h>
#include "v4lmjpegsink_calls.h"
/* On some systems MAP_FAILED seems to be missing */
DEBUG("starting sync thread");
+#if 0
/* Allow easy shutting down by other processes... */
pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );
pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
+#endif
while (1)
{
- pthread_mutex_lock(&(v4lmjpegsink->mutex_queued_frames));
+ g_mutex_lock(v4lmjpegsink->mutex_queued_frames);
if (!v4lmjpegsink->isqueued_queued_frames[frame])
{
- pthread_cond_wait(&(v4lmjpegsink->cond_queued_frames[frame]),
- &(v4lmjpegsink->mutex_queued_frames));
+ g_cond_wait(v4lmjpegsink->cond_queued_frames[frame],
+ v4lmjpegsink->mutex_queued_frames);
}
if (v4lmjpegsink->isqueued_queued_frames[frame] != 1)
{
- pthread_mutex_unlock(&(v4lmjpegsink->mutex_queued_frames));
+ g_mutex_unlock(v4lmjpegsink->mutex_queued_frames);
goto end;
}
- pthread_mutex_unlock(&(v4lmjpegsink->mutex_queued_frames));
+ g_mutex_unlock(v4lmjpegsink->mutex_queued_frames);
DEBUG("thread-syncing on next frame");
if (ioctl(GST_V4LELEMENT(v4lmjpegsink)->video_fd, MJPIOC_SYNC,
gst_element_error(GST_ELEMENT(v4lmjpegsink),
"Failed to sync on frame %d: %s",
frame, g_strerror(errno));
- pthread_mutex_lock(&(v4lmjpegsink->mutex_queued_frames));
+ g_mutex_lock(v4lmjpegsink->mutex_queued_frames);
v4lmjpegsink->isqueued_queued_frames[frame] = -1;
- pthread_cond_broadcast(&(v4lmjpegsink->cond_queued_frames[frame]));
- pthread_mutex_unlock(&(v4lmjpegsink->mutex_queued_frames));
+ g_cond_broadcast(v4lmjpegsink->cond_queued_frames[frame]);
+ g_mutex_unlock(v4lmjpegsink->mutex_queued_frames);
goto end;
}
else
"Internal error: frame number confusion");
goto end;
}
- pthread_mutex_lock(&(v4lmjpegsink->mutex_queued_frames));
+ g_mutex_lock(v4lmjpegsink->mutex_queued_frames);
v4lmjpegsink->isqueued_queued_frames[frame] = 0;
- pthread_cond_broadcast(&(v4lmjpegsink->cond_queued_frames[frame]));
- pthread_mutex_unlock(&(v4lmjpegsink->mutex_queued_frames));
+ g_cond_broadcast(v4lmjpegsink->cond_queued_frames[frame]);
+ g_mutex_unlock(v4lmjpegsink->mutex_queued_frames);
}
frame = (frame+1)%v4lmjpegsink->breq.count;
end:
DEBUG("Sync thread got signalled to exit");
- pthread_exit(NULL);
+ g_thread_exit(NULL);
+ return NULL;
}
return FALSE;
}
- pthread_mutex_lock(&(v4lmjpegsink->mutex_queued_frames));
+ g_mutex_lock(v4lmjpegsink->mutex_queued_frames);
v4lmjpegsink->isqueued_queued_frames[num] = 1;
- pthread_cond_broadcast(&(v4lmjpegsink->cond_queued_frames[num]));
- pthread_mutex_unlock(&(v4lmjpegsink->mutex_queued_frames));
+ g_cond_broadcast(v4lmjpegsink->cond_queued_frames[num]);
+ g_mutex_unlock(v4lmjpegsink->mutex_queued_frames);
return TRUE;
}
v4lmjpegsink->current_frame = (v4lmjpegsink->current_frame+1)%v4lmjpegsink->breq.count;
*num = v4lmjpegsink->current_frame;
- pthread_mutex_lock(&(v4lmjpegsink->mutex_queued_frames));
+ g_mutex_lock(v4lmjpegsink->mutex_queued_frames);
if (v4lmjpegsink->isqueued_queued_frames[*num] == 1)
{
- pthread_cond_wait(&(v4lmjpegsink->cond_queued_frames[*num]),
- &(v4lmjpegsink->mutex_queued_frames));
+ g_cond_wait(v4lmjpegsink->cond_queued_frames[*num],
+ v4lmjpegsink->mutex_queued_frames);
}
if (v4lmjpegsink->isqueued_queued_frames[*num] != 0)
{
- pthread_mutex_unlock(&(v4lmjpegsink->mutex_queued_frames));
+ g_mutex_unlock(v4lmjpegsink->mutex_queued_frames);
return FALSE;
}
else
- pthread_mutex_unlock(&(v4lmjpegsink->mutex_queued_frames));
+ g_mutex_unlock(v4lmjpegsink->mutex_queued_frames);
return TRUE;
}
return FALSE;
}
- /* allocate/init the pthread thingies */
- pthread_mutex_init(&(v4lmjpegsink->mutex_queued_frames), NULL);
+ /* allocate/init the GThread thingies */
+ v4lmjpegsink->mutex_queued_frames = g_mutex_new();
v4lmjpegsink->isqueued_queued_frames = (gint8 *)
malloc(sizeof(gint8) * v4lmjpegsink->breq.count);
if (!v4lmjpegsink->isqueued_queued_frames)
g_strerror(errno));
return FALSE;
}
- v4lmjpegsink->cond_queued_frames = (pthread_cond_t *)
- malloc(sizeof(pthread_cond_t) * v4lmjpegsink->breq.count);
+ v4lmjpegsink->cond_queued_frames = (GCond **)
+ malloc(sizeof(GCond *) * v4lmjpegsink->breq.count);
if (!v4lmjpegsink->cond_queued_frames)
{
gst_element_error(GST_ELEMENT(v4lmjpegsink),
return FALSE;
}
for (n=0;n<v4lmjpegsink->breq.count;n++)
- pthread_cond_init(&(v4lmjpegsink->cond_queued_frames[n]), NULL);
+ v4lmjpegsink->cond_queued_frames[n] = g_cond_new();
return TRUE;
}
gboolean
gst_v4lmjpegsink_playback_start (GstV4lMjpegSink *v4lmjpegsink)
{
+ GError *error;
gint n;
DEBUG("starting playback");
v4lmjpegsink->current_frame = -1;
/* create sync() thread */
- if (pthread_create(&(v4lmjpegsink->thread_queued_frames), NULL,
- gst_v4lmjpegsink_sync_thread, (void *) v4lmjpegsink))
+ v4lmjpegsink->thread_queued_frames = g_thread_create(
+ gst_v4lmjpegsink_sync_thread, (void *) v4lmjpegsink, TRUE, &error);
+ if(!v4lmjpegsink->thread_queued_frames)
{
gst_element_error(GST_ELEMENT(v4lmjpegsink),
- "Failed to create sync thread: %s",
- g_strerror(errno));
+ "Failed to create sync thread: %s", error->message);
return FALSE;
}
}
/* .. and wait for all buffers to be queued on */
- pthread_join(v4lmjpegsink->thread_queued_frames, NULL);
+ g_thread_join(v4lmjpegsink->thread_queued_frames);
return TRUE;
}
gboolean
gst_v4lmjpegsink_playback_deinit (GstV4lMjpegSink *v4lmjpegsink)
{
+ int n;
+
DEBUG("quitting playback subsystem");
GST_V4L_CHECK_OPEN(GST_V4LELEMENT(v4lmjpegsink));
GST_V4L_CHECK_ACTIVE(GST_V4LELEMENT(v4lmjpegsink));
- /* free pthread thingies */
+ /* free GThread thingies */
+ g_mutex_free(v4lmjpegsink->mutex_queued_frames);
+ for (n=0;n<v4lmjpegsink->breq.count;n++)
+ g_cond_free(v4lmjpegsink->cond_queued_frames[n]);
free(v4lmjpegsink->cond_queued_frames);
free(v4lmjpegsink->isqueued_queued_frames);
#include <errno.h>
#include "v4lsrc_calls.h"
#include <sys/time.h>
-#include <pthread.h>
/* number of buffers to be queued *at least* before syncing */
#define MIN_BUFFERS_QUEUED 2
v4lsrc->frame_queued[num] = 1;
- pthread_mutex_lock(&(v4lsrc->mutex_queued_frames));
+ g_mutex_lock(v4lsrc->mutex_queued_frames);
v4lsrc->num_queued_frames++;
- pthread_cond_broadcast(&(v4lsrc->cond_queued_frames));
- pthread_mutex_unlock(&(v4lsrc->mutex_queued_frames));
+ g_cond_broadcast(v4lsrc->cond_queued_frames);
+ g_mutex_unlock(v4lsrc->mutex_queued_frames);
return TRUE;
}
DEBUG("starting software sync thread");
+#if 0
/* Allow easy shutting down by other processes... */
pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );
pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
+#endif
while (1)
{
/* are there queued frames left? */
- pthread_mutex_lock(&(v4lsrc->mutex_queued_frames));
+ g_mutex_lock(v4lsrc->mutex_queued_frames);
if (v4lsrc->num_queued_frames < MIN_BUFFERS_QUEUED)
{
if (v4lsrc->frame_queued[frame] < 0)
DEBUG("Waiting for new frames to be queued (%d < %d)",
v4lsrc->num_queued_frames, MIN_BUFFERS_QUEUED);
- pthread_cond_wait(&(v4lsrc->cond_queued_frames),
- &(v4lsrc->mutex_queued_frames));
+ g_cond_wait(v4lsrc->cond_queued_frames, v4lsrc->mutex_queued_frames);
}
- pthread_mutex_unlock(&(v4lsrc->mutex_queued_frames));
+ g_mutex_unlock(v4lsrc->mutex_queued_frames);
if (!v4lsrc->num_queued_frames)
{
gst_element_error(GST_ELEMENT(v4lsrc),
"Error syncing on a buffer (%d): %s",
frame, g_strerror(errno));
- pthread_mutex_lock(&(v4lsrc->mutex_soft_sync));
+ g_mutex_lock(v4lsrc->mutex_soft_sync);
v4lsrc->isready_soft_sync[frame] = -1;
- pthread_cond_broadcast(&(v4lsrc->cond_soft_sync[frame]));
- pthread_mutex_unlock(&(v4lsrc->mutex_soft_sync));
+ g_cond_broadcast(v4lsrc->cond_soft_sync[frame]);
+ g_mutex_unlock(v4lsrc->mutex_soft_sync);
goto end;
}
else
{
- pthread_mutex_lock(&(v4lsrc->mutex_soft_sync));
+ g_mutex_lock(v4lsrc->mutex_soft_sync);
gettimeofday(&(v4lsrc->timestamp_soft_sync[frame]), NULL);
v4lsrc->isready_soft_sync[frame] = 1;
- pthread_cond_broadcast(&(v4lsrc->cond_soft_sync[frame]));
- pthread_mutex_unlock(&(v4lsrc->mutex_soft_sync));
+ g_cond_broadcast(v4lsrc->cond_soft_sync[frame]);
+ g_mutex_unlock(v4lsrc->mutex_soft_sync);
}
- pthread_mutex_lock(&(v4lsrc->mutex_queued_frames));
+ g_mutex_lock(v4lsrc->mutex_queued_frames);
v4lsrc->num_queued_frames--;
v4lsrc->frame_queued[frame] = 0;
- pthread_mutex_unlock(&(v4lsrc->mutex_queued_frames));
+ g_mutex_unlock(v4lsrc->mutex_queued_frames);
frame = (frame+1)%v4lsrc->mbuf.frames;
}
end:
DEBUG("Software sync thread got signalled to exit");
- pthread_exit(NULL);
+ g_thread_exit(NULL);
+ return NULL;
}
DEBUG("syncing on next frame (%d)", *num);
/* "software sync()" on the frame */
- pthread_mutex_lock(&(v4lsrc->mutex_soft_sync));
+ g_mutex_lock(v4lsrc->mutex_soft_sync);
if (v4lsrc->isready_soft_sync[*num] == 0)
{
DEBUG("Waiting for frame %d to be synced on", *num);
- pthread_cond_wait(&(v4lsrc->cond_soft_sync[*num]),
- &(v4lsrc->mutex_soft_sync));
+ g_cond_wait(v4lsrc->cond_soft_sync[*num], v4lsrc->mutex_soft_sync);
}
if (v4lsrc->isready_soft_sync[*num] < 0)
return FALSE;
v4lsrc->isready_soft_sync[*num] = 0;
- pthread_mutex_unlock(&(v4lsrc->mutex_soft_sync));
+ g_mutex_unlock(v4lsrc->mutex_soft_sync);
return TRUE;
}
for (n=0;n<v4lsrc->mbuf.frames;n++)
v4lsrc->frame_queued[n] = 0;
- /* init the pthread stuff */
- pthread_mutex_init(&(v4lsrc->mutex_soft_sync), NULL);
+ /* init the GThread stuff */
+ v4lsrc->mutex_soft_sync = g_mutex_new();
v4lsrc->isready_soft_sync = (gint8 *) malloc(sizeof(gint8) * v4lsrc->mbuf.frames);
if (!v4lsrc->isready_soft_sync)
{
g_strerror(errno));
return FALSE;
}
- v4lsrc->cond_soft_sync = (pthread_cond_t *)
- malloc(sizeof(pthread_cond_t) * v4lsrc->mbuf.frames);
+ v4lsrc->cond_soft_sync = (GCond **) malloc( sizeof(GCond *) * v4lsrc->mbuf.frames);
if (!v4lsrc->cond_soft_sync)
{
gst_element_error(GST_ELEMENT(v4lsrc),
return FALSE;
}
for (n=0;n<v4lsrc->mbuf.frames;n++)
- pthread_cond_init(&(v4lsrc->cond_soft_sync[n]), NULL);
+ v4lsrc->cond_soft_sync[n] = g_cond_new();
- pthread_mutex_init(&(v4lsrc->mutex_queued_frames), NULL);
- pthread_cond_init(&(v4lsrc->cond_queued_frames), NULL);
+ v4lsrc->mutex_queued_frames = g_mutex_new();
+ v4lsrc->cond_queued_frames = g_cond_new();
/* Map the buffers */
GST_V4LELEMENT(v4lsrc)->buffer = mmap(0, v4lsrc->mbuf.size,
gboolean
gst_v4lsrc_capture_start (GstV4lSrc *v4lsrc)
{
+ GError *error = NULL;
int n;
DEBUG("starting capture");
v4lsrc->sync_frame = -1;
/* start the sync() thread (correct timestamps) */
- if ( pthread_create( &(v4lsrc->thread_soft_sync), NULL,
- gst_v4lsrc_soft_sync_thread, (void *) v4lsrc ) )
+ v4lsrc->thread_soft_sync = g_thread_create(gst_v4lsrc_soft_sync_thread,
+ (void *) v4lsrc, TRUE, &error);
+ if (!v4lsrc->thread_soft_sync)
{
gst_element_error(GST_ELEMENT(v4lsrc),
- "Failed to create software sync thread: %s",
- g_strerror(errno));
+ "Failed to create software sync thread: %s",error->message);
return FALSE;
}
for (n=0;n<v4lsrc->mbuf.frames;n++)
v4lsrc->frame_queued[n] = -1;
- pthread_join(v4lsrc->thread_soft_sync, NULL);
+ g_thread_join(v4lsrc->thread_soft_sync);
return TRUE;
}
gboolean
gst_v4lsrc_capture_deinit (GstV4lSrc *v4lsrc)
{
+ int n;
+
DEBUG("quitting capture subsystem");
GST_V4L_CHECK_OPEN(GST_V4LELEMENT(v4lsrc));
GST_V4L_CHECK_ACTIVE(GST_V4LELEMENT(v4lsrc));
/* free buffer tracker */
+ g_mutex_free(v4lsrc->mutex_queued_frames);
+ for (n=0;n<v4lsrc->mbuf.frames;n++)
+ g_cond_free(v4lsrc->cond_soft_sync[n]);
free(v4lsrc->frame_queued);
free(v4lsrc->cond_soft_sync);
free(v4lsrc->isready_soft_sync);