mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
winks: Fix RGB frame flipping and postprocessing
Uncompressed RGB frames can be (usually are) bottom-up layout in DirectShow, and the code to flip them wasn't properly ported from 0.10. Fix it. Fix post-processing of RGB buffers. We need a writable buffer, but the requests pool is holding an extra ref. This could use more fixing to use a buffer pool
This commit is contained in:
parent
b4a51e7835
commit
08311c51be
5 changed files with 32 additions and 14 deletions
|
@ -796,7 +796,7 @@ gst_ks_video_device_set_caps (GstKsVideoDevice * self, GstCaps * caps)
|
||||||
priv->fps_n = fps_n;
|
priv->fps_n = fps_n;
|
||||||
priv->fps_d = fps_d;
|
priv->fps_d = fps_d;
|
||||||
|
|
||||||
if (gst_structure_has_name (s, "video/x-raw-rgb"))
|
if (media_type->is_rgb)
|
||||||
priv->rgb_swap_buf = g_malloc (media_type->sample_size / priv->height);
|
priv->rgb_swap_buf = g_malloc (media_type->sample_size / priv->height);
|
||||||
else
|
else
|
||||||
priv->rgb_swap_buf = NULL;
|
priv->rgb_swap_buf = NULL;
|
||||||
|
@ -1176,9 +1176,10 @@ error_get_result:
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_ks_video_device_postprocess_frame (GstKsVideoDevice * self, GstBuffer * buf)
|
gst_ks_video_device_postprocess_frame (GstKsVideoDevice * self, GstBuffer ** bufptr)
|
||||||
{
|
{
|
||||||
GstKsVideoDevicePrivate *priv = GST_KS_VIDEO_DEVICE_GET_PRIVATE (self);
|
GstKsVideoDevicePrivate *priv = GST_KS_VIDEO_DEVICE_GET_PRIVATE (self);
|
||||||
|
GstBuffer *buf = *bufptr;
|
||||||
|
|
||||||
/* If it's RGB we need to flip the image */
|
/* If it's RGB we need to flip the image */
|
||||||
if (priv->rgb_swap_buf != NULL) {
|
if (priv->rgb_swap_buf != NULL) {
|
||||||
|
@ -1186,6 +1187,10 @@ gst_ks_video_device_postprocess_frame (GstKsVideoDevice * self, GstBuffer * buf)
|
||||||
gint stride, line;
|
gint stride, line;
|
||||||
guint8 *dst, *src;
|
guint8 *dst, *src;
|
||||||
|
|
||||||
|
/* Need to make the buffer writable because
|
||||||
|
* the pseudo-bufferpool of requests keeps a ref */
|
||||||
|
buf = gst_buffer_make_writable (buf);
|
||||||
|
|
||||||
if (!gst_buffer_map (buf, &info, GST_MAP_READWRITE))
|
if (!gst_buffer_map (buf, &info, GST_MAP_READWRITE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -1205,6 +1210,7 @@ gst_ks_video_device_postprocess_frame (GstKsVideoDevice * self, GstBuffer * buf)
|
||||||
|
|
||||||
gst_buffer_unmap (buf, &info);
|
gst_buffer_unmap (buf, &info);
|
||||||
}
|
}
|
||||||
|
*bufptr = buf;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ GstClockTime gst_ks_video_device_get_duration (GstKsVideoDevice * self);
|
||||||
gboolean gst_ks_video_device_get_latency (GstKsVideoDevice * self, GstClockTime * min_latency, GstClockTime * max_latency);
|
gboolean gst_ks_video_device_get_latency (GstKsVideoDevice * self, GstClockTime * min_latency, GstClockTime * max_latency);
|
||||||
|
|
||||||
GstFlowReturn gst_ks_video_device_read_frame (GstKsVideoDevice * self, GstBuffer ** buf, GstClockTime * presentation_time, gulong * error_code, gchar ** error_str);
|
GstFlowReturn gst_ks_video_device_read_frame (GstKsVideoDevice * self, GstBuffer ** buf, GstClockTime * presentation_time, gulong * error_code, gchar ** error_str);
|
||||||
gboolean gst_ks_video_device_postprocess_frame (GstKsVideoDevice * self, GstBuffer *buf);
|
gboolean gst_ks_video_device_postprocess_frame (GstKsVideoDevice * self, GstBuffer **buf);
|
||||||
void gst_ks_video_device_cancel (GstKsVideoDevice * self);
|
void gst_ks_video_device_cancel (GstKsVideoDevice * self);
|
||||||
void gst_ks_video_device_cancel_stop (GstKsVideoDevice * self);
|
void gst_ks_video_device_cancel_stop (GstKsVideoDevice * self);
|
||||||
|
|
||||||
|
|
|
@ -927,7 +927,7 @@ 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);
|
||||||
|
|
||||||
if (!gst_ks_video_device_postprocess_frame (priv->device, *buf)) {
|
if (!gst_ks_video_device_postprocess_frame (priv->device, buf)) {
|
||||||
GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("Postprocessing failed"),
|
GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("Postprocessing failed"),
|
||||||
("Postprocessing failed"));
|
("Postprocessing failed"));
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
|
|
|
@ -125,10 +125,13 @@ ks_video_device_list_sort_cameras_first (GList * devices)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStructure *
|
static GstStructure *
|
||||||
ks_video_format_to_structure (GUID subtype_guid, GUID format_guid)
|
ks_video_format_to_structure (GUID subtype_guid, GUID format_guid,
|
||||||
|
gboolean * p_is_rgb)
|
||||||
{
|
{
|
||||||
GstStructure *structure = NULL;
|
GstStructure *structure = NULL;
|
||||||
const gchar *media_type = NULL, *format = NULL;
|
const gchar *media_type = NULL, *format = NULL;
|
||||||
|
/* RGB formats can be bottom-up (upside down) DIB */
|
||||||
|
gboolean is_rgb = FALSE;
|
||||||
|
|
||||||
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 */
|
||||||
|
@ -138,18 +141,23 @@ ks_video_format_to_structure (GUID subtype_guid, GUID format_guid)
|
||||||
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB555)) {
|
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB555)) {
|
||||||
media_type = "video/x-raw";
|
media_type = "video/x-raw";
|
||||||
format = "RGB15";
|
format = "RGB15";
|
||||||
|
is_rgb = TRUE;
|
||||||
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB565)) {
|
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB565)) {
|
||||||
media_type = "video/x-raw";
|
media_type = "video/x-raw";
|
||||||
format = "RGB16";
|
format = "RGB16";
|
||||||
|
is_rgb = TRUE;
|
||||||
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB24)) {
|
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB24)) {
|
||||||
format = "BGR";
|
|
||||||
media_type = "video/x-raw";
|
media_type = "video/x-raw";
|
||||||
|
format = "BGR";
|
||||||
|
is_rgb = TRUE;
|
||||||
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB32)) {
|
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB32)) {
|
||||||
media_type = "video/x-raw";
|
media_type = "video/x-raw";
|
||||||
format = "BGRx";
|
format = "BGRx";
|
||||||
|
is_rgb = TRUE;
|
||||||
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB32)) {
|
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB32)) {
|
||||||
media_type = "video/x-raw";
|
media_type = "video/x-raw";
|
||||||
format = "BGRA";
|
format = "BGRA";
|
||||||
|
is_rgb = TRUE;
|
||||||
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB1555)) {
|
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB1555)) {
|
||||||
GST_WARNING ("Unsupported video format ARGB15555");
|
GST_WARNING ("Unsupported video format ARGB15555");
|
||||||
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB4444)) {
|
} else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB4444)) {
|
||||||
|
@ -177,6 +185,9 @@ ks_video_format_to_structure (GUID subtype_guid, GUID format_guid)
|
||||||
if (format) {
|
if (format) {
|
||||||
gst_structure_set (structure, "format", G_TYPE_STRING, format, NULL);
|
gst_structure_set (structure, "format", G_TYPE_STRING, format, NULL);
|
||||||
}
|
}
|
||||||
|
if (p_is_rgb) {
|
||||||
|
*p_is_rgb = is_rgb;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!structure) {
|
if (!structure) {
|
||||||
|
@ -527,7 +538,7 @@ ks_video_probe_filter_for_caps (HANDLE filter_handle)
|
||||||
|
|
||||||
media_structure =
|
media_structure =
|
||||||
ks_video_format_to_structure (range->SubFormat,
|
ks_video_format_to_structure (range->SubFormat,
|
||||||
range->Specifier);
|
range->Specifier, &entry->is_rgb);
|
||||||
|
|
||||||
if (media_structure == NULL) {
|
if (media_structure == NULL) {
|
||||||
g_warning ("ks_video_format_to_structure returned NULL");
|
g_warning ("ks_video_format_to_structure returned NULL");
|
||||||
|
@ -678,22 +689,22 @@ ks_video_get_all_caps (void)
|
||||||
/* RGB formats */
|
/* RGB formats */
|
||||||
structure =
|
structure =
|
||||||
ks_video_append_var_video_fields (ks_video_format_to_structure
|
ks_video_append_var_video_fields (ks_video_format_to_structure
|
||||||
(MEDIASUBTYPE_RGB555, FORMAT_VideoInfo));
|
(MEDIASUBTYPE_RGB555, FORMAT_VideoInfo, NULL));
|
||||||
gst_caps_append_structure (caps, structure);
|
gst_caps_append_structure (caps, structure);
|
||||||
|
|
||||||
structure =
|
structure =
|
||||||
ks_video_append_var_video_fields (ks_video_format_to_structure
|
ks_video_append_var_video_fields (ks_video_format_to_structure
|
||||||
(MEDIASUBTYPE_RGB565, FORMAT_VideoInfo));
|
(MEDIASUBTYPE_RGB565, FORMAT_VideoInfo, NULL));
|
||||||
gst_caps_append_structure (caps, structure);
|
gst_caps_append_structure (caps, structure);
|
||||||
|
|
||||||
structure =
|
structure =
|
||||||
ks_video_append_var_video_fields (ks_video_format_to_structure
|
ks_video_append_var_video_fields (ks_video_format_to_structure
|
||||||
(MEDIASUBTYPE_RGB24, FORMAT_VideoInfo));
|
(MEDIASUBTYPE_RGB24, FORMAT_VideoInfo, NULL));
|
||||||
gst_caps_append_structure (caps, structure);
|
gst_caps_append_structure (caps, structure);
|
||||||
|
|
||||||
structure =
|
structure =
|
||||||
ks_video_append_var_video_fields (ks_video_format_to_structure
|
ks_video_append_var_video_fields (ks_video_format_to_structure
|
||||||
(MEDIASUBTYPE_RGB32, FORMAT_VideoInfo));
|
(MEDIASUBTYPE_RGB32, FORMAT_VideoInfo, NULL));
|
||||||
gst_caps_append_structure (caps, structure);
|
gst_caps_append_structure (caps, structure);
|
||||||
|
|
||||||
/* YUV formats */
|
/* YUV formats */
|
||||||
|
@ -705,16 +716,16 @@ ks_video_get_all_caps (void)
|
||||||
/* Other formats */
|
/* Other formats */
|
||||||
structure =
|
structure =
|
||||||
ks_video_append_var_video_fields (ks_video_format_to_structure
|
ks_video_append_var_video_fields (ks_video_format_to_structure
|
||||||
(MEDIASUBTYPE_MJPG, FORMAT_VideoInfo));
|
(MEDIASUBTYPE_MJPG, FORMAT_VideoInfo, NULL));
|
||||||
gst_caps_append_structure (caps, structure);
|
gst_caps_append_structure (caps, structure);
|
||||||
|
|
||||||
structure =
|
structure =
|
||||||
ks_video_append_var_video_fields (ks_video_format_to_structure
|
ks_video_append_var_video_fields (ks_video_format_to_structure
|
||||||
(MEDIASUBTYPE_dvsd, FORMAT_VideoInfo));
|
(MEDIASUBTYPE_dvsd, FORMAT_VideoInfo, NULL));
|
||||||
gst_caps_append_structure (caps, structure);
|
gst_caps_append_structure (caps, structure);
|
||||||
|
|
||||||
structure = /* no variable video fields (width, height, framerate) */
|
structure = /* no variable video fields (width, height, framerate) */
|
||||||
ks_video_format_to_structure (MEDIASUBTYPE_dvsd, FORMAT_DvInfo);
|
ks_video_format_to_structure (MEDIASUBTYPE_dvsd, FORMAT_DvInfo, NULL);
|
||||||
gst_caps_append_structure (caps, structure);
|
gst_caps_append_structure (caps, structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ struct _KsVideoMediaType
|
||||||
guint sample_size;
|
guint sample_size;
|
||||||
|
|
||||||
GstCaps * translated_caps;
|
GstCaps * translated_caps;
|
||||||
|
gboolean is_rgb;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct DVINFO {
|
typedef struct DVINFO {
|
||||||
|
|
Loading…
Reference in a new issue