Convert from pthreads to GThreads. Untested. BBB: feel free to revert this if it's horribly broken.

Original commit message from CVS:
Convert from pthreads to GThreads.  Untested.  BBB: feel free to revert
this if it's horribly broken.
This commit is contained in:
David Schleef 2002-11-02 21:29:10 +00:00
parent 00b21146ed
commit 048fd81203
4 changed files with 88 additions and 75 deletions

View file

@ -63,9 +63,9 @@ struct _GstV4lMjpegSink {
/* 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 */

View file

@ -56,17 +56,17 @@ struct _GstV4lSrc {
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;

View file

@ -25,7 +25,6 @@
#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 */
@ -52,24 +51,26 @@ gst_v4lmjpegsink_sync_thread (void *arg)
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,
@ -78,10 +79,10 @@ gst_v4lmjpegsink_sync_thread (void *arg)
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
@ -93,10 +94,10 @@ gst_v4lmjpegsink_sync_thread (void *arg)
"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;
@ -104,7 +105,8 @@ gst_v4lmjpegsink_sync_thread (void *arg)
end:
DEBUG("Sync thread got signalled to exit");
pthread_exit(NULL);
g_thread_exit(NULL);
return NULL;
}
@ -129,10 +131,10 @@ gst_v4lmjpegsink_queue_frame (GstV4lMjpegSink *v4lmjpegsink,
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;
}
@ -154,19 +156,19 @@ gst_v4lmjpegsink_sync_frame (GstV4lMjpegSink *v4lmjpegsink,
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;
}
@ -365,8 +367,8 @@ gst_v4lmjpegsink_playback_init (GstV4lMjpegSink *v4lmjpegsink)
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)
@ -376,8 +378,8 @@ gst_v4lmjpegsink_playback_init (GstV4lMjpegSink *v4lmjpegsink)
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),
@ -386,7 +388,7 @@ gst_v4lmjpegsink_playback_init (GstV4lMjpegSink *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;
}
@ -401,6 +403,7 @@ gst_v4lmjpegsink_playback_init (GstV4lMjpegSink *v4lmjpegsink)
gboolean
gst_v4lmjpegsink_playback_start (GstV4lMjpegSink *v4lmjpegsink)
{
GError *error;
gint n;
DEBUG("starting playback");
@ -414,12 +417,12 @@ gst_v4lmjpegsink_playback_start (GstV4lMjpegSink *v4lmjpegsink)
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;
}
@ -515,7 +518,7 @@ gst_v4lmjpegsink_playback_stop (GstV4lMjpegSink *v4lmjpegsink)
}
/* .. 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;
}
@ -530,11 +533,16 @@ gst_v4lmjpegsink_playback_stop (GstV4lMjpegSink *v4lmjpegsink)
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);

View file

@ -27,7 +27,6 @@
#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
@ -94,10 +93,10 @@ gst_v4lsrc_queue_frame (GstV4lSrc *v4lsrc,
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;
}
@ -117,14 +116,16 @@ gst_v4lsrc_soft_sync_thread (void *arg)
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)
@ -133,10 +134,9 @@ gst_v4lsrc_soft_sync_thread (void *arg)
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)
{
@ -155,32 +155,33 @@ retry:
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;
}
@ -199,18 +200,17 @@ gst_v4lsrc_sync_next_frame (GstV4lSrc *v4lsrc,
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;
}
@ -290,8 +290,8 @@ gst_v4lsrc_capture_init (GstV4lSrc *v4lsrc)
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)
{
@ -311,8 +311,7 @@ gst_v4lsrc_capture_init (GstV4lSrc *v4lsrc)
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),
@ -321,10 +320,10 @@ gst_v4lsrc_capture_init (GstV4lSrc *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,
@ -351,6 +350,7 @@ gst_v4lsrc_capture_init (GstV4lSrc *v4lsrc)
gboolean
gst_v4lsrc_capture_start (GstV4lSrc *v4lsrc)
{
GError *error = NULL;
int n;
DEBUG("starting capture");
@ -367,12 +367,12 @@ gst_v4lsrc_capture_start (GstV4lSrc *v4lsrc)
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;
}
@ -463,7 +463,7 @@ gst_v4lsrc_capture_stop (GstV4lSrc *v4lsrc)
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;
}
@ -478,11 +478,16 @@ gst_v4lsrc_capture_stop (GstV4lSrc *v4lsrc)
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);