forked from Mirrors/wine-wine
winegstreamer: Move broad callback handling code to gst_cbs.
Signed-off-by: Derek Lesho <dlesho@codeweavers.com> Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>feature/deterministic
parent
168ec2c82a
commit
3ddf3a720f
|
@ -20,10 +20,76 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
#include "objbase.h"
|
||||||
|
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
|
|
||||||
#include "gst_cbs.h"
|
#include "gst_cbs.h"
|
||||||
|
|
||||||
|
static pthread_key_t wine_gst_key;
|
||||||
|
|
||||||
|
void mark_wine_thread(void)
|
||||||
|
{
|
||||||
|
/* set it to non-NULL to indicate that this is a Wine thread */
|
||||||
|
pthread_setspecific(wine_gst_key, &wine_gst_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL is_wine_thread(void)
|
||||||
|
{
|
||||||
|
return pthread_getspecific(wine_gst_key) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pthread_mutex_t cb_list_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
static pthread_cond_t cb_list_cond = PTHREAD_COND_INITIALIZER;
|
||||||
|
static struct list cb_list = LIST_INIT(cb_list);
|
||||||
|
|
||||||
|
static void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user)
|
||||||
|
{
|
||||||
|
struct cb_data *cbdata = user;
|
||||||
|
|
||||||
|
if (cbdata->type < GSTDEMUX_MAX)
|
||||||
|
perform_cb_gstdemux(cbdata);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&cbdata->lock);
|
||||||
|
cbdata->finished = 1;
|
||||||
|
pthread_cond_broadcast(&cbdata->cond);
|
||||||
|
pthread_mutex_unlock(&cbdata->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD WINAPI dispatch_thread(void *user)
|
||||||
|
{
|
||||||
|
struct cb_data *cbdata;
|
||||||
|
|
||||||
|
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&cb_list_lock);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
pthread_cond_wait(&cb_list_cond, &cb_list_lock);
|
||||||
|
|
||||||
|
while (!list_empty(&cb_list))
|
||||||
|
{
|
||||||
|
cbdata = LIST_ENTRY(list_head(&cb_list), struct cb_data, entry);
|
||||||
|
list_remove(&cbdata->entry);
|
||||||
|
|
||||||
|
TrySubmitThreadpoolCallback(&perform_cb, cbdata, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&cb_list_lock);
|
||||||
|
|
||||||
|
CoUninitialize();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_dispatch_thread(void)
|
||||||
|
{
|
||||||
|
pthread_key_create(&wine_gst_key, NULL);
|
||||||
|
CloseHandle(CreateThread(NULL, 0, &dispatch_thread, NULL, 0, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
/* gstreamer calls our callbacks from threads that Wine did not create. Some
|
/* gstreamer calls our callbacks from threads that Wine did not create. Some
|
||||||
* callbacks execute code which requires Wine to have created the thread
|
* callbacks execute code which requires Wine to have created the thread
|
||||||
* (critical sections, debug logging, dshow client code). Since gstreamer can't
|
* (critical sections, debug logging, dshow client code). Since gstreamer can't
|
||||||
|
@ -31,7 +97,7 @@
|
||||||
* callbacks in code which avoids the Wine thread requirement, and then
|
* callbacks in code which avoids the Wine thread requirement, and then
|
||||||
* dispatch those callbacks on a thread that is known to be created by Wine.
|
* dispatch those callbacks on a thread that is known to be created by Wine.
|
||||||
*
|
*
|
||||||
* This file must not contain any code that depends on the Wine TEB!
|
* This thread must not run any code that depends on the Wine TEB!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void call_cb(struct cb_data *cbdata)
|
static void call_cb(struct cb_data *cbdata)
|
||||||
|
|
|
@ -42,7 +42,8 @@ enum CB_TYPE {
|
||||||
REMOVED_DECODED_PAD,
|
REMOVED_DECODED_PAD,
|
||||||
AUTOPLUG_BLACKLIST,
|
AUTOPLUG_BLACKLIST,
|
||||||
UNKNOWN_TYPE,
|
UNKNOWN_TYPE,
|
||||||
QUERY_SINK
|
QUERY_SINK,
|
||||||
|
GSTDEMUX_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cb_data {
|
struct cb_data {
|
||||||
|
@ -135,12 +136,8 @@ struct cb_data {
|
||||||
struct list entry;
|
struct list entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern pthread_mutex_t cb_list_lock DECLSPEC_HIDDEN;
|
|
||||||
extern pthread_cond_t cb_list_cond DECLSPEC_HIDDEN;
|
|
||||||
extern struct list cb_list DECLSPEC_HIDDEN;
|
|
||||||
void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user) DECLSPEC_HIDDEN;
|
|
||||||
BOOL is_wine_thread(void) DECLSPEC_HIDDEN;
|
|
||||||
void mark_wine_thread(void) DECLSPEC_HIDDEN;
|
void mark_wine_thread(void) DECLSPEC_HIDDEN;
|
||||||
|
void perform_cb_gstdemux(struct cb_data *data) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
GstBusSyncReply watch_bus_wrapper(GstBus *bus, GstMessage *msg, gpointer user) DECLSPEC_HIDDEN;
|
GstBusSyncReply watch_bus_wrapper(GstBus *bus, GstMessage *msg, gpointer user) DECLSPEC_HIDDEN;
|
||||||
void existing_new_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN;
|
void existing_new_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -43,8 +43,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
|
||||||
|
|
||||||
static const GUID MEDIASUBTYPE_CVID = {mmioFOURCC('c','v','i','d'), 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
static const GUID MEDIASUBTYPE_CVID = {mmioFOURCC('c','v','i','d'), 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
||||||
|
|
||||||
static pthread_key_t wine_gst_key;
|
|
||||||
|
|
||||||
struct gstdemux
|
struct gstdemux
|
||||||
{
|
{
|
||||||
struct strmbase_filter filter;
|
struct strmbase_filter filter;
|
||||||
|
@ -100,17 +98,6 @@ static HRESULT WINAPI GST_ChangeCurrent(IMediaSeeking *iface);
|
||||||
static HRESULT WINAPI GST_ChangeStop(IMediaSeeking *iface);
|
static HRESULT WINAPI GST_ChangeStop(IMediaSeeking *iface);
|
||||||
static HRESULT WINAPI GST_ChangeRate(IMediaSeeking *iface);
|
static HRESULT WINAPI GST_ChangeRate(IMediaSeeking *iface);
|
||||||
|
|
||||||
void mark_wine_thread(void)
|
|
||||||
{
|
|
||||||
/* set it to non-NULL to indicate that this is a Wine thread */
|
|
||||||
pthread_setspecific(wine_gst_key, &wine_gst_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL is_wine_thread(void)
|
|
||||||
{
|
|
||||||
return pthread_getspecific(wine_gst_key) != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean amt_from_gst_caps_audio_raw(const GstCaps *caps, AM_MEDIA_TYPE *amt)
|
static gboolean amt_from_gst_caps_audio_raw(const GstCaps *caps, AM_MEDIA_TYPE *amt)
|
||||||
{
|
{
|
||||||
WAVEFORMATEXTENSIBLE *wfe;
|
WAVEFORMATEXTENSIBLE *wfe;
|
||||||
|
@ -2183,14 +2170,8 @@ static HRESULT GST_RemoveOutputPins(struct gstdemux *This)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_t cb_list_lock = PTHREAD_MUTEX_INITIALIZER;
|
void perform_cb_gstdemux(struct cb_data *cbdata)
|
||||||
pthread_cond_t cb_list_cond = PTHREAD_COND_INITIALIZER;
|
|
||||||
struct list cb_list = LIST_INIT(cb_list);
|
|
||||||
|
|
||||||
void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user)
|
|
||||||
{
|
{
|
||||||
struct cb_data *cbdata = user;
|
|
||||||
|
|
||||||
switch(cbdata->type)
|
switch(cbdata->type)
|
||||||
{
|
{
|
||||||
case WATCH_BUS:
|
case WATCH_BUS:
|
||||||
|
@ -2274,44 +2255,11 @@ void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user)
|
||||||
data->query);
|
data->query);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
default:
|
||||||
|
{
|
||||||
pthread_mutex_lock(&cbdata->lock);
|
assert(0);
|
||||||
cbdata->finished = 1;
|
|
||||||
pthread_cond_broadcast(&cbdata->cond);
|
|
||||||
pthread_mutex_unlock(&cbdata->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD WINAPI dispatch_thread(void *user)
|
|
||||||
{
|
|
||||||
struct cb_data *cbdata;
|
|
||||||
|
|
||||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
|
||||||
|
|
||||||
pthread_mutex_lock(&cb_list_lock);
|
|
||||||
|
|
||||||
while(1){
|
|
||||||
pthread_cond_wait(&cb_list_cond, &cb_list_lock);
|
|
||||||
|
|
||||||
while(!list_empty(&cb_list)){
|
|
||||||
cbdata = LIST_ENTRY(list_head(&cb_list), struct cb_data, entry);
|
|
||||||
list_remove(&cbdata->entry);
|
|
||||||
|
|
||||||
TrySubmitThreadpoolCallback(&perform_cb, cbdata, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&cb_list_lock);
|
|
||||||
|
|
||||||
CoUninitialize();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void start_dispatch_thread(void)
|
|
||||||
{
|
|
||||||
pthread_key_create(&wine_gst_key, NULL);
|
|
||||||
CloseHandle(CreateThread(NULL, 0, &dispatch_thread, NULL, 0, NULL));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b)
|
static BOOL compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b)
|
||||||
|
|
Loading…
Reference in New Issue