winks: port to 1.0

https://bugzilla.gnome.org/show_bug.cgi?id=702041
This commit is contained in:
Andoni Morales Alastruey 2014-03-14 18:23:51 +01:00
parent b6cd7c41e4
commit 86e96cfdc6
8 changed files with 181 additions and 293 deletions

View file

@ -347,7 +347,7 @@ GST_PLUGINS_NONPORTED=" cdxaparse \
apexsink dc1394 \ apexsink dc1394 \
gsettings \ gsettings \
musepack nas sdl timidity \ musepack nas sdl timidity \
directdraw acm wininet winks \ directdraw acm wininet \
xvid lv2 teletextdec sndio osx_video quicktime" xvid lv2 teletextdec sndio osx_video quicktime"
AC_SUBST(GST_PLUGINS_NONPORTED) AC_SUBST(GST_PLUGINS_NONPORTED)

View file

@ -6,10 +6,10 @@ libgstwinks_la_SOURCES = gstksclock.c \
kshelpers.c kshelpers.h \ kshelpers.c kshelpers.h \
ksvideohelpers.c ksvideohelpers.c
libgstwinks_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \ libgstwinks_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \
$(GST_PLUGINS_BASE_CFLAGS) $(DIRECTX_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(DIRECTX_CFLAGS) -Wno-error=missing-braces
libgstwinks_la_LIBADD = \ libgstwinks_la_LIBADD = \
$(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) \ $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_API_VERSION) \
-lgstinterfaces-$(GST_MAJORMINOR) $(DIRECTX_LDFLAGS) $(WINKS_LIBS) $(DIRECTX_LDFLAGS) $(WINKS_LIBS)
libgstwinks_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstwinks_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstwinks_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) libgstwinks_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)

View file

@ -26,9 +26,9 @@ GST_DEBUG_CATEGORY_EXTERN (gst_ks_debug);
struct _GstKsClockPrivate struct _GstKsClockPrivate
{ {
GMutex *mutex; GMutex mutex;
GCond *client_cond; GCond client_cond;
GCond *worker_cond; GCond worker_cond;
HANDLE clock_handle; HANDLE clock_handle;
@ -45,24 +45,24 @@ struct _GstKsClockPrivate
#define GST_KS_CLOCK_GET_PRIVATE(o) ((o)->priv) #define GST_KS_CLOCK_GET_PRIVATE(o) ((o)->priv)
#define GST_KS_CLOCK_LOCK() g_mutex_lock (priv->mutex) #define GST_KS_CLOCK_LOCK() g_mutex_lock (&priv->mutex)
#define GST_KS_CLOCK_UNLOCK() g_mutex_unlock (priv->mutex) #define GST_KS_CLOCK_UNLOCK() g_mutex_unlock (&priv->mutex)
static void gst_ks_clock_dispose (GObject * object); static void gst_ks_clock_dispose (GObject * object);
static void gst_ks_clock_finalize (GObject * object); static void gst_ks_clock_finalize (GObject * object);
GST_BOILERPLATE (GstKsClock, gst_ks_clock, GObject, G_TYPE_OBJECT); G_DEFINE_TYPE (GstKsClock, gst_ks_clock, G_TYPE_OBJECT);
static GstKsClockClass *parent_class = NULL;
static void
gst_ks_clock_base_init (gpointer gclass)
{
}
static void static void
gst_ks_clock_class_init (GstKsClockClass * klass) gst_ks_clock_class_init (GstKsClockClass * klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
g_type_class_add_private (klass, sizeof (GstKsClockPrivate)); g_type_class_add_private (klass, sizeof (GstKsClockPrivate));
gobject_class->dispose = gst_ks_clock_dispose; gobject_class->dispose = gst_ks_clock_dispose;
@ -70,7 +70,7 @@ gst_ks_clock_class_init (GstKsClockClass * klass)
} }
static void static void
gst_ks_clock_init (GstKsClock * self, GstKsClockClass * gclass) gst_ks_clock_init (GstKsClock * self)
{ {
GstKsClockPrivate *priv; GstKsClockPrivate *priv;
@ -79,9 +79,9 @@ gst_ks_clock_init (GstKsClock * self, GstKsClockClass * gclass)
priv = GST_KS_CLOCK_GET_PRIVATE (self); priv = GST_KS_CLOCK_GET_PRIVATE (self);
priv->mutex = g_mutex_new (); g_mutex_init (&priv->mutex);
priv->client_cond = g_cond_new (); g_cond_init (&priv->client_cond);
priv->worker_cond = g_cond_new (); g_cond_init (&priv->worker_cond);
priv->clock_handle = INVALID_HANDLE_VALUE; priv->clock_handle = INVALID_HANDLE_VALUE;
@ -110,9 +110,9 @@ gst_ks_clock_finalize (GObject * object)
GstKsClock *self = GST_KS_CLOCK (object); GstKsClock *self = GST_KS_CLOCK (object);
GstKsClockPrivate *priv = GST_KS_CLOCK_GET_PRIVATE (self); GstKsClockPrivate *priv = GST_KS_CLOCK_GET_PRIVATE (self);
g_cond_free (priv->worker_cond); g_cond_clear (&priv->worker_cond);
g_cond_free (priv->client_cond); g_cond_clear (&priv->client_cond);
g_mutex_free (priv->mutex); g_mutex_clear (&priv->mutex);
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
@ -218,7 +218,7 @@ gst_ks_clock_close_unlocked (GstKsClock * self)
if (priv->worker_thread != NULL) { if (priv->worker_thread != NULL) {
priv->worker_running = FALSE; priv->worker_running = FALSE;
g_cond_signal (priv->worker_cond); g_cond_signal (&priv->worker_cond);
GST_KS_CLOCK_UNLOCK (); GST_KS_CLOCK_UNLOCK ();
g_thread_join (priv->worker_thread); g_thread_join (priv->worker_thread);
@ -305,10 +305,10 @@ gst_ks_clock_worker_thread_func (gpointer data)
if (!priv->worker_initialized) { if (!priv->worker_initialized) {
priv->worker_initialized = TRUE; priv->worker_initialized = TRUE;
g_cond_signal (priv->client_cond); g_cond_signal (&priv->client_cond);
} }
g_cond_wait (priv->worker_cond, priv->mutex); g_cond_wait (&priv->worker_cond, &priv->mutex);
} }
priv->worker_initialized = FALSE; priv->worker_initialized = FALSE;
@ -329,11 +329,11 @@ gst_ks_clock_start (GstKsClock * self)
priv->worker_initialized = FALSE; priv->worker_initialized = FALSE;
priv->worker_thread = priv->worker_thread =
g_thread_create (gst_ks_clock_worker_thread_func, self, TRUE, NULL); g_thread_new ("ks-worker", gst_ks_clock_worker_thread_func, self);
} }
while (!priv->worker_initialized) while (!priv->worker_initialized)
g_cond_wait (priv->client_cond, priv->mutex); g_cond_wait (&priv->client_cond, &priv->mutex);
GST_KS_CLOCK_UNLOCK (); GST_KS_CLOCK_UNLOCK ();
} }
@ -349,7 +349,7 @@ gst_ks_clock_provide_master_clock (GstKsClock * self, GstClock * master_clock)
if (priv->master_clock != NULL) if (priv->master_clock != NULL)
gst_object_unref (priv->master_clock); gst_object_unref (priv->master_clock);
priv->master_clock = master_clock; priv->master_clock = master_clock;
g_cond_signal (priv->worker_cond); g_cond_signal (&priv->worker_cond);
GST_KS_CLOCK_UNLOCK (); GST_KS_CLOCK_UNLOCK ();
} }

View file

@ -105,18 +105,17 @@ static void gst_ks_video_device_set_property (GObject * object, guint prop_id,
static void gst_ks_video_device_reset_caps (GstKsVideoDevice * self); static void gst_ks_video_device_reset_caps (GstKsVideoDevice * self);
static guint gst_ks_video_device_get_frame_size (GstKsVideoDevice * self); static guint gst_ks_video_device_get_frame_size (GstKsVideoDevice * self);
GST_BOILERPLATE (GstKsVideoDevice, gst_ks_video_device, GObject, G_TYPE_OBJECT); G_DEFINE_TYPE (GstKsVideoDevice, gst_ks_video_device, G_TYPE_OBJECT);
static void static GstKsVideoDeviceClass *parent_class = NULL;
gst_ks_video_device_base_init (gpointer gclass)
{
}
static void static void
gst_ks_video_device_class_init (GstKsVideoDeviceClass * klass) gst_ks_video_device_class_init (GstKsVideoDeviceClass * klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
g_type_class_add_private (klass, sizeof (GstKsVideoDevicePrivate)); g_type_class_add_private (klass, sizeof (GstKsVideoDevicePrivate));
gobject_class->dispose = gst_ks_video_device_dispose; gobject_class->dispose = gst_ks_video_device_dispose;
@ -135,8 +134,7 @@ gst_ks_video_device_class_init (GstKsVideoDeviceClass * klass)
} }
static void static void
gst_ks_video_device_init (GstKsVideoDevice * self, gst_ks_video_device_init (GstKsVideoDevice * self)
GstKsVideoDeviceClass * gclass)
{ {
GstKsVideoDevicePrivate *priv; GstKsVideoDevicePrivate *priv;
@ -313,7 +311,8 @@ gst_ks_video_device_prepare_buffers (GstKsVideoDevice * self)
} }
for (i = 0; i < priv->num_requests; i++) { for (i = 0; i < priv->num_requests; i++) {
ReadRequest req = { 0, }; ReadRequest req;
memset (&req, '0', sizeof (ReadRequest));
req.buf = self->allocfunc (frame_size, KS_BUFFER_ALIGNMENT, req.buf = self->allocfunc (frame_size, KS_BUFFER_ALIGNMENT,
self->allocfunc_data); self->allocfunc_data);
@ -568,7 +567,8 @@ gst_ks_video_device_create_pin (GstKsVideoDevice * self,
alignment = 0; alignment = 0;
if (ks_object_get_property (pin_handle, KSPROPSETID_Connection, if (ks_object_get_property (pin_handle, KSPROPSETID_Connection,
KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, &framing_ex, NULL, NULL)) { KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, (void *) &framing_ex, NULL,
NULL)) {
if (framing_ex->CountItems >= 1) { if (framing_ex->CountItems >= 1) {
*num_outstanding = framing_ex->FramingItem[0].Frames; *num_outstanding = framing_ex->FramingItem[0].Frames;
alignment = framing_ex->FramingItem[0].FileAlignment; alignment = framing_ex->FramingItem[0].FileAlignment;
@ -580,8 +580,8 @@ gst_ks_video_device_create_pin (GstKsVideoDevice * self,
"ALLOCATORFRAMING"); "ALLOCATORFRAMING");
if (ks_object_get_property (pin_handle, KSPROPSETID_Connection, if (ks_object_get_property (pin_handle, KSPROPSETID_Connection,
KSPROPERTY_CONNECTION_ALLOCATORFRAMING, &framing, &framing_size, KSPROPERTY_CONNECTION_ALLOCATORFRAMING, (void *) &framing,
NULL)) { &framing_size, NULL)) {
*num_outstanding = framing->Frames; *num_outstanding = framing->Frames;
alignment = framing->FileAlignment; alignment = framing->FileAlignment;
} else { } else {
@ -590,7 +590,7 @@ gst_ks_video_device_create_pin (GstKsVideoDevice * self,
} }
GST_DEBUG ("num_outstanding: %lu alignment: 0x%08x", *num_outstanding, GST_DEBUG ("num_outstanding: %lu alignment: 0x%08x", *num_outstanding,
alignment); (guint) alignment);
if (*num_outstanding == 0 || *num_outstanding > MAX_OUTSTANDING_FRAMES) { if (*num_outstanding == 0 || *num_outstanding > MAX_OUTSTANDING_FRAMES) {
GST_DEBUG ("setting number of allowable outstanding frames to 1"); GST_DEBUG ("setting number of allowable outstanding frames to 1");
@ -627,7 +627,8 @@ gst_ks_video_device_create_pin (GstKsVideoDevice * self,
if (ks_object_get_property (pin_handle, KSPROPSETID_Stream, if (ks_object_get_property (pin_handle, KSPROPSETID_Stream,
KSPROPERTY_STREAM_MASTERCLOCK, (gpointer *) & cur_clock_handle, KSPROPERTY_STREAM_MASTERCLOCK, (gpointer *) & cur_clock_handle,
&cur_clock_handle_size, NULL)) { &cur_clock_handle_size, NULL)) {
GST_DEBUG ("current master clock handle: 0x%08x", *cur_clock_handle); GST_DEBUG ("current master clock handle: 0x%08x",
(guint) * cur_clock_handle);
CloseHandle (*cur_clock_handle); CloseHandle (*cur_clock_handle);
g_free (cur_clock_handle); g_free (cur_clock_handle);
} else { } else {
@ -948,6 +949,7 @@ gst_ks_video_device_request_frame (GstKsVideoDevice * self, ReadRequest * req,
KSSTREAM_READ_PARAMS *params; KSSTREAM_READ_PARAMS *params;
BOOL success; BOOL success;
DWORD bytes_returned = 0; DWORD bytes_returned = 0;
GstMapInfo info;
if (!gst_ks_read_request_pick_buffer (self, req)) if (!gst_ks_read_request_pick_buffer (self, req))
goto error_pick_buffer; goto error_pick_buffer;
@ -961,15 +963,17 @@ gst_ks_video_device_request_frame (GstKsVideoDevice * self, ReadRequest * req,
params = &req->params; params = &req->params;
memset (params, 0, sizeof (KSSTREAM_READ_PARAMS)); memset (params, 0, sizeof (KSSTREAM_READ_PARAMS));
gst_buffer_map (req->buf, &info, GST_MAP_READ);
params->header.Size = sizeof (KSSTREAM_HEADER) + sizeof (KS_FRAME_INFO); params->header.Size = sizeof (KSSTREAM_HEADER) + sizeof (KS_FRAME_INFO);
params->header.PresentationTime.Numerator = 1; params->header.PresentationTime.Numerator = 1;
params->header.PresentationTime.Denominator = 1; params->header.PresentationTime.Denominator = 1;
params->header.FrameExtent = gst_ks_video_device_get_frame_size (self); params->header.FrameExtent = gst_ks_video_device_get_frame_size (self);
params->header.Data = GST_BUFFER_DATA (req->buf); params->header.Data = info.data;
params->frame_info.ExtendedHeaderSize = sizeof (KS_FRAME_INFO); params->frame_info.ExtendedHeaderSize = sizeof (KS_FRAME_INFO);
success = DeviceIoControl (priv->pin_handle, IOCTL_KS_READ_STREAM, NULL, 0, success = DeviceIoControl (priv->pin_handle, IOCTL_KS_READ_STREAM, NULL, 0,
params, params->header.Size, &bytes_returned, &req->overlapped); params, params->header.Size, &bytes_returned, &req->overlapped);
gst_buffer_unmap (req->buf, &info);
if (!success && GetLastError () != ERROR_IO_PENDING) if (!success && GetLastError () != ERROR_IO_PENDING)
goto error_ioctl; goto error_ioctl;
@ -1067,7 +1071,7 @@ gst_ks_video_device_read_frame (GstKsVideoDevice * self, GstBuffer ** buf,
if (G_LIKELY (hdr->DataUsed != 0)) { if (G_LIKELY (hdr->DataUsed != 0)) {
/* Assume it's a good frame */ /* Assume it's a good frame */
GST_BUFFER_SIZE (req->buf) = hdr->DataUsed; gst_buffer_set_size (req->buf, hdr->DataUsed);
*buf = gst_buffer_ref (req->buf); *buf = gst_buffer_ref (req->buf);
} }
@ -1130,7 +1134,7 @@ error_timeout:
if (error_str != NULL) if (error_str != NULL)
*error_str = NULL; *error_str = NULL;
return GST_FLOW_UNEXPECTED; return GST_FLOW_CUSTOM_ERROR;
} }
error_wait: error_wait:
{ {

View file

@ -66,15 +66,15 @@ enum
GST_DEBUG_CATEGORY (gst_ks_debug); GST_DEBUG_CATEGORY (gst_ks_debug);
#define GST_CAT_DEFAULT gst_ks_debug #define GST_CAT_DEFAULT gst_ks_debug
#define KS_WORKER_LOCK(priv) g_mutex_lock (priv->worker_lock) #define KS_WORKER_LOCK(priv) g_mutex_lock (&priv->worker_lock)
#define KS_WORKER_UNLOCK(priv) g_mutex_unlock (priv->worker_lock) #define KS_WORKER_UNLOCK(priv) g_mutex_unlock (&priv->worker_lock)
#define KS_WORKER_WAIT(priv) \ #define KS_WORKER_WAIT(priv) \
g_cond_wait (priv->worker_notify_cond, priv->worker_lock) g_cond_wait (&priv->worker_notify_cond, &priv->worker_lock)
#define KS_WORKER_NOTIFY(priv) g_cond_signal (priv->worker_notify_cond) #define KS_WORKER_NOTIFY(priv) g_cond_signal (&priv->worker_notify_cond)
#define KS_WORKER_WAIT_FOR_RESULT(priv) \ #define KS_WORKER_WAIT_FOR_RESULT(priv) \
g_cond_wait (priv->worker_result_cond, priv->worker_lock) g_cond_wait (&priv->worker_result_cond, &priv->worker_lock)
#define KS_WORKER_NOTIFY_RESULT(priv) \ #define KS_WORKER_NOTIFY_RESULT(priv) \
g_cond_signal (priv->worker_result_cond) g_cond_signal (&priv->worker_result_cond)
typedef enum typedef enum
{ {
@ -103,9 +103,9 @@ struct _GstKsVideoSrcPrivate
/* Worker thread */ /* Worker thread */
GThread *worker_thread; GThread *worker_thread;
GMutex *worker_lock; GMutex worker_lock;
GCond *worker_notify_cond; GCond worker_notify_cond;
GCond *worker_result_cond; GCond worker_result_cond;
KsWorkerState worker_state; KsWorkerState worker_state;
GstCaps *worker_pending_caps; GstCaps *worker_pending_caps;
@ -124,22 +124,14 @@ struct _GstKsVideoSrcPrivate
#define GST_KS_VIDEO_SRC_GET_PRIVATE(o) ((o)->priv) #define GST_KS_VIDEO_SRC_GET_PRIVATE(o) ((o)->priv)
static void gst_ks_video_src_init_interfaces (GType type);
static void gst_ks_video_src_finalize (GObject * object); static void gst_ks_video_src_finalize (GObject * object);
static void gst_ks_video_src_get_property (GObject * object, guint prop_id, static void gst_ks_video_src_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static void gst_ks_video_src_set_property (GObject * object, guint prop_id, static void gst_ks_video_src_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_ks_video_src_probe_interface_init (GstPropertyProbeInterface * G_GNUC_UNUSED static GArray
iface); * gst_ks_video_src_get_device_name_values (GstKsVideoSrc * self);
static const GList *gst_ks_video_src_probe_get_properties (GstPropertyProbe *
probe);
static GValueArray *gst_ks_video_src_probe_get_values (GstPropertyProbe * probe,
guint prop_id, const GParamSpec * pspec);
static GValueArray *gst_ks_video_src_get_device_name_values (GstKsVideoSrc *
self);
static void gst_ks_video_src_reset (GstKsVideoSrc * self); static void gst_ks_video_src_reset (GstKsVideoSrc * self);
static GstStateChangeReturn gst_ks_video_src_change_state (GstElement * element, static GstStateChangeReturn gst_ks_video_src_change_state (GstElement * element,
@ -147,10 +139,11 @@ static GstStateChangeReturn gst_ks_video_src_change_state (GstElement * element,
static gboolean gst_ks_video_src_set_clock (GstElement * element, static gboolean gst_ks_video_src_set_clock (GstElement * element,
GstClock * clock); GstClock * clock);
static GstCaps *gst_ks_video_src_get_caps (GstBaseSrc * basesrc); static GstCaps *gst_ks_video_src_get_caps (GstBaseSrc * basesrc,
GstCaps * filter);
static gboolean gst_ks_video_src_set_caps (GstBaseSrc * basesrc, static gboolean gst_ks_video_src_set_caps (GstBaseSrc * basesrc,
GstCaps * caps); GstCaps * caps);
static void gst_ks_video_src_fixate (GstBaseSrc * basesrc, GstCaps * caps); static GstCaps *gst_ks_video_src_fixate (GstBaseSrc * basesrc, GstCaps * caps);
static gboolean gst_ks_video_src_query (GstBaseSrc * basesrc, GstQuery * query); static gboolean gst_ks_video_src_query (GstBaseSrc * basesrc, GstQuery * query);
static gboolean gst_ks_video_src_unlock (GstBaseSrc * basesrc); static gboolean gst_ks_video_src_unlock (GstBaseSrc * basesrc);
static gboolean gst_ks_video_src_unlock_stop (GstBaseSrc * basesrc); static gboolean gst_ks_video_src_unlock_stop (GstBaseSrc * basesrc);
@ -160,25 +153,9 @@ static GstFlowReturn gst_ks_video_src_create (GstPushSrc * pushsrc,
static GstBuffer *gst_ks_video_src_alloc_buffer (guint size, guint alignment, static GstBuffer *gst_ks_video_src_alloc_buffer (guint size, guint alignment,
gpointer user_data); gpointer user_data);
GST_BOILERPLATE_FULL (GstKsVideoSrc, gst_ks_video_src, GstPushSrc, G_DEFINE_TYPE (GstKsVideoSrc, gst_ks_video_src, GST_TYPE_PUSH_SRC);
GST_TYPE_PUSH_SRC, gst_ks_video_src_init_interfaces);
static void static GstKsVideoSrcClass *parent_class = NULL;
gst_ks_video_src_base_init (gpointer gclass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
gst_element_class_set_static_metadata (element_class, "KsVideoSrc",
"Source/Video",
"Stream data from a video capture device through Windows kernel streaming",
"Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.com>\n"
"Haakon Sporsheim <hakon.sporsheim@tandberg.com>\n"
"Andres Colubri <andres.colubri@gmail.com>");
gst_element_class_add_pad_template (element_class,
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
ks_video_get_all_caps ()));
}
static void static void
gst_ks_video_src_class_init (GstKsVideoSrcClass * klass) gst_ks_video_src_class_init (GstKsVideoSrcClass * klass)
@ -190,6 +167,19 @@ gst_ks_video_src_class_init (GstKsVideoSrcClass * klass)
g_type_class_add_private (klass, sizeof (GstKsVideoSrcPrivate)); g_type_class_add_private (klass, sizeof (GstKsVideoSrcPrivate));
parent_class = g_type_class_peek_parent (klass);
gst_element_class_set_static_metadata (gstelement_class, "KsVideoSrc",
"Source/Video",
"Stream data from a video capture device through Windows kernel streaming",
"Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.com>\n"
"Haakon Sporsheim <hakon.sporsheim@tandberg.com>\n"
"Andres Colubri <andres.colubri@gmail.com>");
gst_element_class_add_pad_template (gstelement_class,
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
ks_video_get_all_caps ()));
gobject_class->finalize = gst_ks_video_src_finalize; gobject_class->finalize = gst_ks_video_src_finalize;
gobject_class->get_property = gst_ks_video_src_get_property; gobject_class->get_property = gst_ks_video_src_get_property;
gobject_class->set_property = gst_ks_video_src_set_property; gobject_class->set_property = gst_ks_video_src_set_property;
@ -238,7 +228,7 @@ gst_ks_video_src_class_init (GstKsVideoSrcClass * klass)
} }
static void static void
gst_ks_video_src_init (GstKsVideoSrc * self, GstKsVideoSrcClass * gclass) gst_ks_video_src_init (GstKsVideoSrc * self)
{ {
GstBaseSrc *basesrc = GST_BASE_SRC (self); GstBaseSrc *basesrc = GST_BASE_SRC (self);
GstKsVideoSrcPrivate *priv; GstKsVideoSrcPrivate *priv;
@ -397,65 +387,12 @@ gst_ks_video_src_apply_driver_quirks (GstKsVideoSrc * self)
} }
} }
static void /*FIXME: when we have a devices API replacement */
gst_ks_video_src_init_interfaces (GType type) G_GNUC_UNUSED static GArray *
{
static const GInterfaceInfo ksvideosrc_info = {
(GInterfaceInitFunc) gst_ks_video_src_probe_interface_init,
NULL,
NULL,
};
g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE, &ksvideosrc_info);
}
static void
gst_ks_video_src_probe_interface_init (GstPropertyProbeInterface * iface)
{
iface->get_properties = gst_ks_video_src_probe_get_properties;
iface->get_values = gst_ks_video_src_probe_get_values;
}
static const GList *
gst_ks_video_src_probe_get_properties (GstPropertyProbe * probe)
{
GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
static GList *props = NULL;
if (!props) {
GParamSpec *pspec;
pspec = g_object_class_find_property (klass, "device-name");
props = g_list_append (props, pspec);
}
return props;
}
static GValueArray *
gst_ks_video_src_probe_get_values (GstPropertyProbe * probe, guint prop_id,
const GParamSpec * pspec)
{
GstKsVideoSrc *src = GST_KS_VIDEO_SRC (probe);
GValueArray *array = NULL;
switch (prop_id) {
case PROP_DEVICE_NAME:
array = gst_ks_video_src_get_device_name_values (src);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
break;
}
return array;
}
static GValueArray *
gst_ks_video_src_get_device_name_values (GstKsVideoSrc * self) gst_ks_video_src_get_device_name_values (GstKsVideoSrc * self)
{ {
GList *devices, *cur; GList *devices, *cur;
GValueArray *array = g_value_array_new (0); GArray *array = g_array_new (TRUE, TRUE, sizeof (GValue));
devices = ks_enumerate_devices (&KSCATEGORY_VIDEO); devices = ks_enumerate_devices (&KSCATEGORY_VIDEO);
if (devices == NULL) if (devices == NULL)
@ -469,7 +406,7 @@ gst_ks_video_src_get_device_name_values (GstKsVideoSrc * self)
g_value_init (&value, G_TYPE_STRING); g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, entry->name); g_value_set_string (&value, entry->name);
g_value_array_append (array, &value); g_array_append_val (array, value);
g_value_unset (&value); g_value_unset (&value);
ks_device_entry_free (entry); ks_device_entry_free (entry);
@ -506,9 +443,9 @@ gst_ks_video_src_open_device (GstKsVideoSrc * self)
gboolean match; gboolean match;
if (priv->device_path != NULL) { if (priv->device_path != NULL) {
match = g_strcasecmp (entry->path, priv->device_path) == 0; match = g_ascii_strcasecmp (entry->path, priv->device_path) == 0;
} else if (priv->device_name != NULL) { } else if (priv->device_name != NULL) {
match = g_strcasecmp (entry->name, priv->device_name) == 0; match = g_ascii_strcasecmp (entry->name, priv->device_name) == 0;
} else if (priv->device_index >= 0) { } else if (priv->device_index >= 0) {
match = entry->index == priv->device_index; match = entry->index == priv->device_index;
} else { } else {
@ -666,16 +603,16 @@ gst_ks_video_src_start_worker (GstKsVideoSrc * self)
GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self); GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self);
gboolean result; gboolean result;
priv->worker_lock = g_mutex_new (); g_mutex_init (&priv->worker_lock);
priv->worker_notify_cond = g_cond_new (); g_cond_init (&priv->worker_notify_cond);
priv->worker_result_cond = g_cond_new (); g_cond_init (&priv->worker_result_cond);
priv->worker_pending_caps = NULL; priv->worker_pending_caps = NULL;
priv->worker_pending_run = FALSE; priv->worker_pending_run = FALSE;
priv->worker_state = KS_WORKER_STATE_STARTING; priv->worker_state = KS_WORKER_STATE_STARTING;
priv->worker_thread = priv->worker_thread =
g_thread_create (gst_ks_video_src_worker_func, self, TRUE, NULL); g_thread_new ("ks-worker", gst_ks_video_src_worker_func, self);
KS_WORKER_LOCK (priv); KS_WORKER_LOCK (priv);
while (priv->worker_state < KS_WORKER_STATE_READY) while (priv->worker_state < KS_WORKER_STATE_READY)
@ -699,12 +636,9 @@ gst_ks_video_src_stop_worker (GstKsVideoSrc * self)
g_thread_join (priv->worker_thread); g_thread_join (priv->worker_thread);
priv->worker_thread = NULL; priv->worker_thread = NULL;
g_cond_free (priv->worker_result_cond); g_cond_clear (&priv->worker_result_cond);
priv->worker_result_cond = NULL; g_cond_clear (&priv->worker_notify_cond);
g_cond_free (priv->worker_notify_cond); g_mutex_clear (&priv->worker_lock);
priv->worker_notify_cond = NULL;
g_mutex_free (priv->worker_lock);
priv->worker_lock = NULL;
} }
static GstStateChangeReturn static GstStateChangeReturn
@ -756,11 +690,11 @@ gst_ks_video_src_set_clock (GstElement * element, GstClock * clock)
gst_ks_clock_provide_master_clock (priv->ksclock, clock); gst_ks_clock_provide_master_clock (priv->ksclock, clock);
GST_OBJECT_UNLOCK (element); GST_OBJECT_UNLOCK (element);
return GST_ELEMENT_CLASS (element)->set_clock (element, clock); return GST_ELEMENT_CLASS (parent_class)->set_clock (element, clock);
} }
static GstCaps * static GstCaps *
gst_ks_video_src_get_caps (GstBaseSrc * basesrc) gst_ks_video_src_get_caps (GstBaseSrc * basesrc, GstCaps * filter)
{ {
GstKsVideoSrc *self = GST_KS_VIDEO_SRC (basesrc); GstKsVideoSrc *self = GST_KS_VIDEO_SRC (basesrc);
GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self); GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self);
@ -787,18 +721,28 @@ gst_ks_video_src_set_caps (GstBaseSrc * basesrc, GstCaps * caps)
KS_WORKER_WAIT_FOR_RESULT (priv); KS_WORKER_WAIT_FOR_RESULT (priv);
KS_WORKER_UNLOCK (priv); KS_WORKER_UNLOCK (priv);
GST_DEBUG ("Result is %d", priv->worker_setcaps_result);
return priv->worker_setcaps_result; return priv->worker_setcaps_result;
} }
static void static GstCaps *
gst_ks_video_src_fixate (GstBaseSrc * basesrc, GstCaps * caps) gst_ks_video_src_fixate (GstBaseSrc * basesrc, GstCaps * caps)
{ {
GstStructure *structure = gst_caps_get_structure (caps, 0); GstStructure *structure;
GstCaps *fixated_caps;
gint i;
gst_structure_fixate_field_nearest_int (structure, "width", G_MAXINT); fixated_caps = gst_caps_make_writable (caps);
gst_structure_fixate_field_nearest_int (structure, "height", G_MAXINT);
gst_structure_fixate_field_nearest_fraction (structure, "framerate", for (i = 0; i < gst_caps_get_size (fixated_caps); ++i) {
G_MAXINT, 1); structure = gst_caps_get_structure (fixated_caps, i);
gst_structure_fixate_field_nearest_int (structure, "width", G_MAXINT);
gst_structure_fixate_field_nearest_int (structure, "height", G_MAXINT);
gst_structure_fixate_field_nearest_fraction (structure, "framerate",
G_MAXINT, 1);
}
return gst_caps_fixate (fixated_caps);
} }
static gboolean static gboolean
@ -1006,6 +950,7 @@ gst_ks_video_src_create (GstPushSrc * pushsrc, GstBuffer ** buf)
GstClockTime presentation_time; GstClockTime presentation_time;
gulong error_code; gulong error_code;
gchar *error_str; gchar *error_str;
GstMapInfo info;
g_assert (priv->device != NULL); g_assert (priv->device != NULL);
@ -1042,8 +987,9 @@ gst_ks_video_src_create (GstPushSrc * pushsrc, GstBuffer ** buf)
if (G_UNLIKELY (priv->do_stats)) if (G_UNLIKELY (priv->do_stats))
gst_ks_video_src_update_statistics (self); gst_ks_video_src_update_statistics (self);
gst_ks_video_device_postprocess_frame (priv->device, gst_buffer_map (*buf, &info, GST_MAP_WRITE);
GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf)); gst_ks_video_device_postprocess_frame (priv->device, info.data, info.size);
gst_buffer_unmap (*buf, &info);
return GST_FLOW_OK; return GST_FLOW_OK;
@ -1062,15 +1008,17 @@ error_start_capture:
switch (error_code) { switch (error_code) {
case ERROR_FILE_NOT_FOUND: case ERROR_FILE_NOT_FOUND:
GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND, GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
("failed to start capture (device unplugged)"), (debug_str)); ("failed to start capture (device unplugged)"), ("%s", debug_str));
break; break;
case ERROR_NO_SYSTEM_RESOURCES: case ERROR_NO_SYSTEM_RESOURCES:
GST_ELEMENT_ERROR (self, RESOURCE, BUSY, GST_ELEMENT_ERROR (self, RESOURCE, BUSY,
("failed to start capture (device already in use)"), (debug_str)); ("failed to start capture (device already in use)"), ("%s",
debug_str));
break; break;
default: default:
GST_ELEMENT_ERROR (self, RESOURCE, FAILED, GST_ELEMENT_ERROR (self, RESOURCE, FAILED,
("failed to start capture (0x%08x)", error_code), (debug_str)); ("failed to start capture (0x%08x)", (guint) error_code), ("%s",
debug_str));
break; break;
} }
@ -1081,10 +1029,10 @@ error_read_frame:
if (result == GST_FLOW_ERROR) { if (result == GST_FLOW_ERROR) {
if (error_str != NULL) { if (error_str != NULL) {
GST_ELEMENT_ERROR (self, RESOURCE, READ, GST_ELEMENT_ERROR (self, RESOURCE, READ,
("read failed: %s [0x%08x]", error_str, error_code), ("read failed: %s [0x%08x]", error_str, (guint) error_code),
("gst_ks_video_device_read_frame failed")); ("gst_ks_video_device_read_frame failed"));
} }
} else if (result == GST_FLOW_UNEXPECTED) { } else if (result == GST_FLOW_CUSTOM_ERROR) {
GST_ELEMENT_ERROR (self, RESOURCE, READ, GST_ELEMENT_ERROR (self, RESOURCE, READ,
("read failed"), ("gst_ks_video_device_read_frame failed")); ("read failed"), ("gst_ks_video_device_read_frame failed"));
} }
@ -1100,32 +1048,14 @@ gst_ks_video_src_alloc_buffer (guint size, guint alignment, gpointer user_data)
{ {
GstKsVideoSrc *self = GST_KS_VIDEO_SRC (user_data); GstKsVideoSrc *self = GST_KS_VIDEO_SRC (user_data);
GstBuffer *buf; GstBuffer *buf;
GstCaps *caps; GstAllocationParams params = { 0, alignment - 1, 0, 0, };
GstFlowReturn flow_ret;
caps = gst_pad_get_negotiated_caps (GST_BASE_SRC_PAD (self)); buf = gst_buffer_new_allocate (NULL, size, &params);
if (caps == NULL) if (buf == NULL)
goto error_no_caps;
flow_ret = gst_pad_alloc_buffer (GST_BASE_SRC_PAD (self), 0,
size + (alignment - 1), caps, &buf);
gst_caps_unref (caps);
if (G_UNLIKELY (flow_ret != GST_FLOW_OK))
goto error_alloc_buffer; goto error_alloc_buffer;
GST_BUFFER_DATA (buf) =
GSIZE_TO_POINTER ((GPOINTER_TO_SIZE (GST_BUFFER_DATA (buf)) + (alignment -
1)) & ~(alignment - 1));
GST_BUFFER_SIZE (buf) = size;
return buf; return buf;
error_no_caps:
{
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("not negotiated"), ("maybe setcaps failed?"));
return NULL;
}
error_alloc_buffer: error_alloc_buffer:
{ {
GST_ELEMENT_ERROR (self, CORE, PAD, ("alloc_buffer failed"), (NULL)); GST_ELEMENT_ERROR (self, CORE, PAD, ("alloc_buffer failed"), (NULL));

View file

@ -21,7 +21,6 @@
#define __GST_KS_VIDEO_SRC_H__ #define __GST_KS_VIDEO_SRC_H__
#include <gst/base/gstpushsrc.h> #include <gst/base/gstpushsrc.h>
#include <gst/interfaces/propertyprobe.h>
G_BEGIN_DECLS G_BEGIN_DECLS

View file

@ -21,6 +21,7 @@
#include <ksmedia.h> #include <ksmedia.h>
#include <setupapi.h> #include <setupapi.h>
#include <gst/gst.h>
GST_DEBUG_CATEGORY_EXTERN (gst_ks_debug); GST_DEBUG_CATEGORY_EXTERN (gst_ks_debug);
#define GST_CAT_DEFAULT gst_ks_debug #define GST_CAT_DEFAULT gst_ks_debug
@ -28,7 +29,8 @@ GST_DEBUG_CATEGORY_EXTERN (gst_ks_debug);
#ifndef STATIC_KSPROPSETID_Wave_Queued #ifndef STATIC_KSPROPSETID_Wave_Queued
#define STATIC_KSPROPSETID_Wave_Queued \ #define STATIC_KSPROPSETID_Wave_Queued \
0x16a15b10L,0x16f0,0x11d0,0xa1,0x95,0x00,0x20,0xaf,0xd1,0x56,0xe4 0x16a15b10L,0x16f0,0x11d0,0xa1,0x95,0x00,0x20,0xaf,0xd1,0x56,0xe4
DEFINE_GUIDSTRUCT("16a15b10-16f0-11d0-a195-0020afd156e4", KSPROPSETID_Wave_Queued); DEFINE_GUIDSTRUCT ("16a15b10-16f0-11d0-a195-0020afd156e4",
KSPROPSETID_Wave_Queued);
#endif #endif
gboolean gboolean
@ -165,9 +167,11 @@ ks_filter_get_pin_property (HANDLE filter_handle, gulong pin_id,
GUID prop_set, gulong prop_id, gpointer value, gulong value_size, GUID prop_set, gulong prop_id, gpointer value, gulong value_size,
gulong * error) gulong * error)
{ {
KSP_PIN prop = { 0, }; KSP_PIN prop;
DWORD bytes_returned = 0; DWORD bytes_returned = 0;
memset (&prop, 0, sizeof (KSP_PIN));
prop.PinId = pin_id; prop.PinId = pin_id;
prop.Property.Set = prop_set; prop.Property.Set = prop_set;
prop.Property.Id = prop_id; prop.Property.Id = prop_id;
@ -181,11 +185,12 @@ gboolean
ks_filter_get_pin_property_multi (HANDLE filter_handle, gulong pin_id, ks_filter_get_pin_property_multi (HANDLE filter_handle, gulong pin_id,
GUID prop_set, gulong prop_id, KSMULTIPLE_ITEM ** items, gulong * error) GUID prop_set, gulong prop_id, KSMULTIPLE_ITEM ** items, gulong * error)
{ {
KSP_PIN prop = { 0, }; KSP_PIN prop;
DWORD items_size = 0, bytes_written = 0; DWORD items_size = 0, bytes_written = 0;
gulong err; gulong err;
gboolean ret; gboolean ret;
memset (&prop, 0, sizeof (KSP_PIN));
*items = NULL; *items = NULL;
prop.PinId = pin_id; prop.PinId = pin_id;
@ -221,11 +226,12 @@ gboolean
ks_object_query_property (HANDLE handle, GUID prop_set, gulong prop_id, ks_object_query_property (HANDLE handle, GUID prop_set, gulong prop_id,
gulong prop_flags, gpointer * value, gulong * value_size, gulong * error) gulong prop_flags, gpointer * value, gulong * value_size, gulong * error)
{ {
KSPROPERTY prop = { 0, }; KSPROPERTY prop;
DWORD req_value_size = 0, bytes_written = 0; DWORD req_value_size = 0, bytes_written = 0;
gulong err; gulong err;
gboolean ret; gboolean ret;
memset (&prop, 0, sizeof (KSPROPERTY));
*value = NULL; *value = NULL;
prop.Set = prop_set; prop.Set = prop_set;
@ -278,9 +284,10 @@ gboolean
ks_object_set_property (HANDLE handle, GUID prop_set, gulong prop_id, ks_object_set_property (HANDLE handle, GUID prop_set, gulong prop_id,
gpointer value, gulong value_size, gulong * error) gpointer value, gulong value_size, gulong * error)
{ {
KSPROPERTY prop = { 0, }; KSPROPERTY prop;
DWORD bytes_returned; DWORD bytes_returned;
memset (&prop, 0, sizeof (KSPROPERTY));
prop.Set = prop_set; prop.Set = prop_set;
prop.Id = prop_id; prop.Id = prop_id;
prop.Flags = KSPROPERTY_TYPE_SET; prop.Flags = KSPROPERTY_TYPE_SET;
@ -300,7 +307,7 @@ ks_object_get_supported_property_sets (HANDLE handle, GUID ** propsets,
*len = 0; *len = 0;
if (ks_object_query_property (handle, GUID_NULL, 0, if (ks_object_query_property (handle, GUID_NULL, 0,
KSPROPERTY_TYPE_SETSUPPORT, propsets, &size, &error)) { KSPROPERTY_TYPE_SETSUPPORT, (void *) propsets, &size, &error)) {
if (size % sizeof (GUID) == 0) { if (size % sizeof (GUID) == 0) {
*len = size / sizeof (GUID); *len = size / sizeof (GUID);
return TRUE; return TRUE;
@ -324,9 +331,10 @@ gchar *
ks_guid_to_string (const GUID * guid) ks_guid_to_string (const GUID * guid)
{ {
return g_strdup_printf ("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", return g_strdup_printf ("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
guid->Data1, guid->Data, guid->Data3, guid->Data4[0], guid->Data4[1], (guint) guid->Data1, (guint) guid->Data2, (guint) guid->Data3,
guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], (guint) guid->Data4[0], (guint) guid->Data4[1], (guint) guid->Data4[2],
guid->Data4[6], guid->Data4[7]); (guint) guid->Data4[3], (guint) guid->Data4[4], (guint) guid->Data4[5],
(guint) guid->Data4[6], (guint) guid->Data4[7]);
} }
const gchar * const gchar *
@ -379,7 +387,7 @@ ks_options_flags_to_string (gulong flags)
CHECK_OPTIONS_FLAG (LOOPEDDATA); CHECK_OPTIONS_FLAG (LOOPEDDATA);
if (flags != 0) if (flags != 0)
g_string_append_printf (str, "|0x%08x", flags); g_string_append_printf (str, "|0x%08x", (guint) flags);
ret = str->str; ret = str->str;
g_string_free (str, FALSE); g_string_free (str, FALSE);

View file

@ -128,92 +128,39 @@ static GstStructure *
ks_video_format_to_structure (GUID subtype_guid, GUID format_guid) ks_video_format_to_structure (GUID subtype_guid, GUID format_guid)
{ {
GstStructure *structure = NULL; GstStructure *structure = NULL;
const gchar *media_type = NULL, *format = NULL;
if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_MJPG) || IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_TVMJ) || /* FIXME: NOT tested */ if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_MJPG) || IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_TVMJ) || /* FIXME: NOT tested */
IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_WAKE) || /* FIXME: NOT tested */ IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_WAKE) || /* FIXME: NOT tested */
IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_CFCC) || /* FIXME: NOT tested */ IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_CFCC) || /* FIXME: NOT tested */
IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_IJPG)) { /* FIXME: NOT tested */ IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_IJPG)) { /* FIXME: NOT tested */
structure = gst_structure_new ("image/jpeg", NULL); media_type = "image/jpeg";
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB555) || /* FIXME: NOT tested */ } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB555)) {
IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB565) || /* FIXME: NOT tested */ media_type = "video/x-raw";
IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB24) || IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB32) || /* FIXME: NOT tested */ format = "RGB15";
IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB1555) || /* FIXME: NOT tested */ } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB565)) {
IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB32) || /* FIXME: NOT tested */ media_type = "video/x-raw";
IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB4444)) { /* FIXME: NOT tested */ format = "RGB16";
guint depth = 0, bpp = 0; } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB24)) {
gint endianness = 0; media_type = "video/x-raw";
guint32 r_mask = 0, b_mask = 0, g_mask = 0; format = "RGBx";
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB32)) {
if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB555)) { media_type = "video/x-raw";
bpp = 16; format = "RGB";
depth = 15; } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB32)) {
endianness = G_BIG_ENDIAN; media_type = "video/x-raw";
r_mask = 0x7c00; format = "ARGB";
g_mask = 0x03e0; } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB1555)) {
b_mask = 0x001f; GST_WARNING ("Unsupported video format ARGB15555");
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB565)) { } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB4444)) {
bpp = depth = 16; GST_WARNING ("Unsupported video format ARGB4444");
endianness = G_BIG_ENDIAN; } else if (memcmp (&subtype_guid.Data2, &MEDIASUBTYPE_FOURCC.Data2,
r_mask = 0xf800; sizeof (subtype_guid) - sizeof (subtype_guid.Data1)) == 0) {
g_mask = 0x07e0; guint8 *p = (guint8 *) & subtype_guid.Data1;
b_mask = 0x001f; gchar *format = g_strdup_printf ("%c%c%c%c", p[0], p[1], p[2], p[3]);
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB24)) { structure = gst_structure_new ("video/x-raw", "format",
bpp = depth = 24; G_TYPE_STRING, format, NULL);
endianness = G_BIG_ENDIAN; g_free (format);
r_mask = 0x0000ff;
g_mask = 0x00ff00;
b_mask = 0xff0000;
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB32)) {
bpp = 32;
depth = 24;
endianness = G_BIG_ENDIAN;
r_mask = 0x000000ff;
g_mask = 0x0000ff00;
b_mask = 0x00ff0000;
/* FIXME: check
*r_mask = 0xff000000;
*g_mask = 0x00ff0000;
*b_mask = 0x0000ff00;
*/
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB1555)) {
bpp = 16;
depth = 15;
endianness = G_BIG_ENDIAN;
r_mask = 0x7c00;
g_mask = 0x03e0;
b_mask = 0x001f;
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB32)) {
bpp = depth = 32;
endianness = G_BIG_ENDIAN;
r_mask = 0x000000ff;
g_mask = 0x0000ff00;
b_mask = 0x00ff0000;
/* FIXME: check
*r_mask = 0xff000000;
*g_mask = 0x00ff0000;
*b_mask = 0x0000ff00;
*/
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB4444)) {
bpp = 16;
depth = 12;
endianness = G_BIG_ENDIAN;
r_mask = 0x0f00;
g_mask = 0x00f0;
b_mask = 0x000f;
//r_mask = 0x000f;
//g_mask = 0x00f0;
//b_mask = 0x0f00;
} else {
g_assert_not_reached ();
}
structure = gst_structure_new ("video/x-raw-rgb",
"bpp", G_TYPE_INT, bpp,
"depth", G_TYPE_INT, depth,
"red_mask", G_TYPE_INT, r_mask,
"green_mask", G_TYPE_INT, g_mask,
"blue_mask", G_TYPE_INT, b_mask,
"endianness", G_TYPE_INT, endianness, NULL);
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_dvsd)) { } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_dvsd)) {
if (IsEqualGUID (&format_guid, &FORMAT_DvInfo)) { if (IsEqualGUID (&format_guid, &FORMAT_DvInfo)) {
structure = gst_structure_new ("video/x-dv", structure = gst_structure_new ("video/x-dv",
@ -221,23 +168,23 @@ ks_video_format_to_structure (GUID subtype_guid, GUID format_guid)
} else if (IsEqualGUID (&format_guid, &FORMAT_VideoInfo)) { } else if (IsEqualGUID (&format_guid, &FORMAT_VideoInfo)) {
structure = gst_structure_new ("video/x-dv", structure = gst_structure_new ("video/x-dv",
"systemstream", G_TYPE_BOOLEAN, FALSE, "systemstream", G_TYPE_BOOLEAN, FALSE,
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('d', 'v', 's', 'd'), "format", G_TYPE_STRING, "dvsd", NULL);
NULL);
} }
} else if (memcmp (&subtype_guid.Data, &MEDIASUBTYPE_FOURCC.Data, }
sizeof (subtype_guid) - sizeof (subtype_guid.Data1)) == 0) {
guint8 *p = (guint8 *) & subtype_guid.Data1;
structure = gst_structure_new ("video/x-raw-yuv", if (media_type) {
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC (p[0], p[1], p[2], p[3]), structure = gst_structure_new_empty (media_type);
NULL); if (format) {
gst_structure_set (structure, "format", G_TYPE_STRING, format, NULL);
}
} }
if (!structure) { if (!structure) {
GST_DEBUG ("Unknown DirectShow Video GUID %08x-%04x-%04x-%04x-%08x%04x", GST_DEBUG ("Unknown DirectShow Video GUID %08x-%04x-%04x-%04x-%08x%04x",
subtype_guid.Data1, subtype_guid.Data, subtype_guid.Data3, (guint) subtype_guid.Data1, (guint) subtype_guid.Data2,
*(WORD *) subtype_guid.Data4, *(DWORD *) & subtype_guid.Data4[2], (guint) subtype_guid.Data3,
*(WORD *) & subtype_guid.Data4[6]); (guint) subtype_guid.Data4, (guint) & subtype_guid.Data4[2],
(guint) & subtype_guid.Data4[6]);
} }
return structure; return structure;
@ -736,8 +683,8 @@ ks_video_get_all_caps (void)
/* YUV formats */ /* YUV formats */
structure = structure =
ks_video_append_var_video_fields (gst_structure_new ("video/x-raw-yuv", ks_video_append_var_video_fields (gst_structure_new_empty
NULL)); ("video/x-raw"));
gst_caps_append_structure (caps, structure); gst_caps_append_structure (caps, structure);
/* Other formats */ /* Other formats */