freeimagedec: Move utility functions to gstfreeimageutils.c/.h and other minor cleanup
Also removed static pad templates, changed elements to have underscore rather than hyphen in their name, and fix caps handling (BGR/RGB)
This commit is contained in:
parent
4fc7cd5ec8
commit
992d159add
@ -27,11 +27,11 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gstfreeimagedec.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <gst/video/video.h>
|
|
||||||
|
#include "gstfreeimagedec.h"
|
||||||
|
#include "gstfreeimageutils.h"
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_EXTERN (freeimagedec_debug);
|
GST_DEBUG_CATEGORY_EXTERN (freeimagedec_debug);
|
||||||
#define GST_CAT_DEFAULT freeimagedec_debug
|
#define GST_CAT_DEFAULT freeimagedec_debug
|
||||||
@ -41,21 +41,6 @@ typedef struct
|
|||||||
FREE_IMAGE_FORMAT fif;
|
FREE_IMAGE_FORMAT fif;
|
||||||
} GstFreeImageDecClassData;
|
} GstFreeImageDecClassData;
|
||||||
|
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_freeimagedec_src_pad_template =
|
|
||||||
GST_STATIC_PAD_TEMPLATE ("src",
|
|
||||||
GST_PAD_SRC,
|
|
||||||
GST_PAD_ALWAYS,
|
|
||||||
GST_STATIC_CAPS ("ANY")
|
|
||||||
);
|
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_freeimagedec_sink_pad_template =
|
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
|
||||||
GST_PAD_SINK,
|
|
||||||
GST_PAD_ALWAYS,
|
|
||||||
GST_STATIC_CAPS ("ANY")
|
|
||||||
);
|
|
||||||
|
|
||||||
static void gst_freeimagedec_class_init (GstFreeImageDecClass * klass,
|
static void gst_freeimagedec_class_init (GstFreeImageDecClass * klass,
|
||||||
GstFreeImageDecClassData * class_data);
|
GstFreeImageDecClassData * class_data);
|
||||||
static void gst_freeimagedec_init (GstFreeImageDec * freeimagedec);
|
static void gst_freeimagedec_init (GstFreeImageDec * freeimagedec);
|
||||||
@ -78,18 +63,17 @@ static gboolean gst_freeimagedec_freeimage_init (GstFreeImageDec * freeimagedec)
|
|||||||
static gboolean gst_freeimagedec_freeimage_clear (GstFreeImageDec * freeimagedec);
|
static gboolean gst_freeimagedec_freeimage_clear (GstFreeImageDec * freeimagedec);
|
||||||
static GstFlowReturn gst_freeimagedec_caps_create_and_set (GstFreeImageDec * freeimagedec);
|
static GstFlowReturn gst_freeimagedec_caps_create_and_set (GstFreeImageDec * freeimagedec);
|
||||||
static GstFlowReturn gst_freeimagedec_push_dib (GstFreeImageDec * freeimagedec);
|
static GstFlowReturn gst_freeimagedec_push_dib (GstFreeImageDec * freeimagedec);
|
||||||
static GstCaps * gst_freeimagedec_caps_from_freeimage_format (FREE_IMAGE_FORMAT fif);
|
|
||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
|
|
||||||
void DLL_CALLCONV
|
void DLL_CALLCONV
|
||||||
user_error (FREE_IMAGE_FORMAT fif, const char *message)
|
gst_freeimagedec_user_error (FREE_IMAGE_FORMAT fif, const char *message)
|
||||||
{
|
{
|
||||||
GST_ERROR ("%s", message);
|
GST_ERROR ("%s", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DLL_CALLCONV
|
static int DLL_CALLCONV
|
||||||
user_seek (fi_handle handle, long offset, int origin)
|
gst_freeimagedec_user_seek (fi_handle handle, long offset, int origin)
|
||||||
{
|
{
|
||||||
GstFreeImageDec *freeimagedec = GST_FREEIMAGEDEC (handle);
|
GstFreeImageDec *freeimagedec = GST_FREEIMAGEDEC (handle);
|
||||||
|
|
||||||
@ -108,7 +92,7 @@ user_seek (fi_handle handle, long offset, int origin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static long DLL_CALLCONV
|
static long DLL_CALLCONV
|
||||||
user_tell (fi_handle handle)
|
gst_freeimagedec_user_tell (fi_handle handle)
|
||||||
{
|
{
|
||||||
GstFreeImageDec *freeimagedec = GST_FREEIMAGEDEC (handle);
|
GstFreeImageDec *freeimagedec = GST_FREEIMAGEDEC (handle);
|
||||||
|
|
||||||
@ -205,7 +189,7 @@ gst_freeimagedec_class_init (GstFreeImageDecClass * klass,
|
|||||||
gst_element_class_add_pad_template (gstelement_class, templ);
|
gst_element_class_add_pad_template (gstelement_class, templ);
|
||||||
|
|
||||||
/* add src pad template */
|
/* add src pad template */
|
||||||
caps = gst_freeimagedec_caps_from_freeimage_format (klass->fif);
|
caps = gst_freeimageutils_caps_from_freeimage_format (klass->fif);
|
||||||
templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps);
|
templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps);
|
||||||
gst_element_class_add_pad_template (gstelement_class, templ);
|
gst_element_class_add_pad_template (gstelement_class, templ);
|
||||||
|
|
||||||
@ -226,8 +210,11 @@ gst_freeimagedec_class_init (GstFreeImageDecClass * klass,
|
|||||||
static void
|
static void
|
||||||
gst_freeimagedec_init (GstFreeImageDec * freeimagedec)
|
gst_freeimagedec_init (GstFreeImageDec * freeimagedec)
|
||||||
{
|
{
|
||||||
freeimagedec->sinkpad =
|
GstElementClass * klass = GST_ELEMENT_GET_CLASS (freeimagedec);
|
||||||
gst_pad_new_from_static_template (&gst_freeimagedec_sink_pad_template, "sink");
|
|
||||||
|
freeimagedec->sinkpad = gst_pad_new_from_template (
|
||||||
|
gst_element_class_get_pad_template (klass, "sink"), "sink");
|
||||||
|
|
||||||
gst_pad_set_activate_function (freeimagedec->sinkpad, gst_freeimagedec_sink_activate);
|
gst_pad_set_activate_function (freeimagedec->sinkpad, gst_freeimagedec_sink_activate);
|
||||||
gst_pad_set_activatepull_function (freeimagedec->sinkpad,
|
gst_pad_set_activatepull_function (freeimagedec->sinkpad,
|
||||||
gst_freeimagedec_sink_activate_pull);
|
gst_freeimagedec_sink_activate_pull);
|
||||||
@ -238,8 +225,8 @@ gst_freeimagedec_init (GstFreeImageDec * freeimagedec)
|
|||||||
gst_pad_set_setcaps_function (freeimagedec->sinkpad, gst_freeimagedec_sink_setcaps);
|
gst_pad_set_setcaps_function (freeimagedec->sinkpad, gst_freeimagedec_sink_setcaps);
|
||||||
gst_element_add_pad (GST_ELEMENT (freeimagedec), freeimagedec->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (freeimagedec), freeimagedec->sinkpad);
|
||||||
|
|
||||||
freeimagedec->srcpad =
|
freeimagedec->srcpad = gst_pad_new_from_template (
|
||||||
gst_pad_new_from_static_template (&gst_freeimagedec_src_pad_template, "src");
|
gst_element_class_get_pad_template (klass, "src"), "src");
|
||||||
gst_pad_use_fixed_caps (freeimagedec->srcpad);
|
gst_pad_use_fixed_caps (freeimagedec->srcpad);
|
||||||
gst_element_add_pad (GST_ELEMENT (freeimagedec), freeimagedec->srcpad);
|
gst_element_add_pad (GST_ELEMENT (freeimagedec), freeimagedec->srcpad);
|
||||||
|
|
||||||
@ -249,9 +236,6 @@ gst_freeimagedec_init (GstFreeImageDec * freeimagedec)
|
|||||||
freeimagedec->in_timestamp = GST_CLOCK_TIME_NONE;
|
freeimagedec->in_timestamp = GST_CLOCK_TIME_NONE;
|
||||||
freeimagedec->in_duration = GST_CLOCK_TIME_NONE;
|
freeimagedec->in_duration = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
freeimagedec->width = -1;
|
|
||||||
freeimagedec->height = -1;
|
|
||||||
freeimagedec->bpp = -1;
|
|
||||||
freeimagedec->fps_n = 0;
|
freeimagedec->fps_n = 0;
|
||||||
freeimagedec->fps_d = 1;
|
freeimagedec->fps_d = 1;
|
||||||
|
|
||||||
@ -260,8 +244,8 @@ gst_freeimagedec_init (GstFreeImageDec * freeimagedec)
|
|||||||
/* Set user IO functions to FreeImageIO struct */
|
/* Set user IO functions to FreeImageIO struct */
|
||||||
freeimagedec->fiio.read_proc = user_read;
|
freeimagedec->fiio.read_proc = user_read;
|
||||||
freeimagedec->fiio.write_proc = NULL;
|
freeimagedec->fiio.write_proc = NULL;
|
||||||
freeimagedec->fiio.seek_proc = user_seek;
|
freeimagedec->fiio.seek_proc = gst_freeimagedec_user_seek;
|
||||||
freeimagedec->fiio.tell_proc = user_tell;
|
freeimagedec->fiio.tell_proc = gst_freeimagedec_user_tell;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
@ -270,114 +254,48 @@ gst_freeimagedec_caps_create_and_set (GstFreeImageDec * freeimagedec)
|
|||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GstCaps *caps = NULL, *res = NULL;
|
GstCaps *caps = NULL, *res = NULL;
|
||||||
GstPadTemplate *templ = NULL;
|
GstPadTemplate *templ = NULL;
|
||||||
gint image_type, video_format = -1, endianness;
|
|
||||||
|
|
||||||
/* Get bits per channel */
|
caps = gst_freeimageutils_caps_from_dib (freeimagedec->dib,
|
||||||
freeimagedec->bpp = FreeImage_GetBPP (freeimagedec->dib);
|
freeimagedec->fps_n, freeimagedec->fps_d);
|
||||||
|
|
||||||
/* Get image type */
|
if (caps == NULL) {
|
||||||
image_type = FreeImage_GetImageType (freeimagedec->dib);
|
/* we have an unsupported type, we'll try converting to RGB/RGBA */
|
||||||
|
|
||||||
/* Get width and height */
|
|
||||||
freeimagedec->width = FreeImage_GetWidth (freeimagedec->dib);
|
|
||||||
freeimagedec->height = FreeImage_GetHeight (freeimagedec->dib);
|
|
||||||
|
|
||||||
GST_LOG ("Image_type=%d, %dx%dx%d", image_type, freeimagedec->width, freeimagedec->height, freeimagedec->bpp);
|
|
||||||
|
|
||||||
switch (image_type) {
|
|
||||||
case FIT_BITMAP:
|
|
||||||
if (freeimagedec->bpp < 16) {
|
|
||||||
FIBITMAP * dib;
|
FIBITMAP * dib;
|
||||||
if (FreeImage_IsTransparent (freeimagedec->dib)) {
|
if (FreeImage_IsTransparent (freeimagedec->dib)) {
|
||||||
GST_DEBUG ("Image is palletised with transparency, convert to 32-bit RGB");
|
GST_DEBUG ("Image is non-standard format with transparency, convert to 32-bit RGB");
|
||||||
dib = FreeImage_ConvertTo32Bits (freeimagedec->dib);
|
dib = FreeImage_ConvertTo32Bits (freeimagedec->dib);
|
||||||
video_format = GST_VIDEO_FORMAT_RGBA;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GST_DEBUG ("Image is palletised, convert to 24-bit RGB");
|
GST_DEBUG ("Image is non-standard format, convert to 24-bit RGB");
|
||||||
dib = FreeImage_ConvertTo24Bits (freeimagedec->dib);
|
dib = FreeImage_ConvertTo24Bits (freeimagedec->dib);
|
||||||
video_format = GST_VIDEO_FORMAT_RGB;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
caps = gst_freeimageutils_caps_from_dib (freeimagedec->dib,
|
||||||
|
freeimagedec->fps_n, freeimagedec->fps_d);
|
||||||
|
if (caps == NULL) {
|
||||||
|
GST_DEBUG ("Image could not be converted to RGB/RGBA, try grayscale");
|
||||||
|
if (dib)
|
||||||
|
FreeImage_Unload (dib);
|
||||||
|
dib = FreeImage_ConvertToStandardType (freeimagedec->dib, TRUE);
|
||||||
|
|
||||||
|
caps = gst_freeimageutils_caps_from_dib (freeimagedec->dib,
|
||||||
|
freeimagedec->fps_n, freeimagedec->fps_d);
|
||||||
|
|
||||||
|
if (caps == NULL) {
|
||||||
|
GST_WARNING ("Failed to convert image");
|
||||||
|
if (dib)
|
||||||
|
FreeImage_Unload (dib);
|
||||||
|
ret = GST_FLOW_NOT_SUPPORTED;
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the converted dib as our new dib */
|
||||||
FreeImage_Unload (freeimagedec->dib);
|
FreeImage_Unload (freeimagedec->dib);
|
||||||
freeimagedec->dib = dib;
|
freeimagedec->dib = dib;
|
||||||
}
|
}
|
||||||
else if (freeimagedec->bpp == 24) {
|
|
||||||
if (FreeImage_GetRedMask (freeimagedec->dib) == GST_VIDEO_BYTE1_MASK_24_INT &&
|
|
||||||
FreeImage_GetGreenMask (freeimagedec->dib) == GST_VIDEO_BYTE2_MASK_24_INT &&
|
|
||||||
FreeImage_GetBlueMask (freeimagedec->dib) == GST_VIDEO_BYTE3_MASK_24_INT) {
|
|
||||||
video_format = GST_VIDEO_FORMAT_RGB;
|
|
||||||
}
|
|
||||||
else if (FreeImage_GetRedMask (freeimagedec->dib) == GST_VIDEO_BYTE3_MASK_24_INT &&
|
|
||||||
FreeImage_GetGreenMask (freeimagedec->dib) == GST_VIDEO_BYTE2_MASK_24_INT &&
|
|
||||||
FreeImage_GetBlueMask (freeimagedec->dib) == GST_VIDEO_BYTE1_MASK_24_INT) {
|
|
||||||
video_format = GST_VIDEO_FORMAT_BGR;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GST_ELEMENT_ERROR (freeimagedec, STREAM, NOT_IMPLEMENTED, (NULL),
|
|
||||||
("freeimagedec only supports RGB or BGR 24-bit bitmaps"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (freeimagedec->bpp == 32) {
|
|
||||||
if (FreeImage_GetRedMask (freeimagedec->dib) == GST_VIDEO_BYTE1_MASK_32_INT &&
|
|
||||||
FreeImage_GetGreenMask (freeimagedec->dib) == GST_VIDEO_BYTE2_MASK_32_INT &&
|
|
||||||
FreeImage_GetBlueMask (freeimagedec->dib) == GST_VIDEO_BYTE3_MASK_32_INT) {
|
|
||||||
video_format = GST_VIDEO_FORMAT_RGBA;
|
|
||||||
}
|
|
||||||
else if (FreeImage_GetRedMask (freeimagedec->dib) == GST_VIDEO_BYTE3_MASK_32_INT &&
|
|
||||||
FreeImage_GetGreenMask (freeimagedec->dib) == GST_VIDEO_BYTE2_MASK_32_INT &&
|
|
||||||
FreeImage_GetBlueMask (freeimagedec->dib) == GST_VIDEO_BYTE1_MASK_32_INT) {
|
|
||||||
video_format = GST_VIDEO_FORMAT_BGRA;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GST_ELEMENT_ERROR (freeimagedec, STREAM, NOT_IMPLEMENTED, (NULL),
|
|
||||||
("freeimagedec only supports RGBA or BGRA 32-bit bitmaps"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GST_ELEMENT_ERROR (freeimagedec, STREAM, NOT_IMPLEMENTED, (NULL),
|
|
||||||
("freeimagedec does not support this image type"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We could not find a supported format */
|
GST_DEBUG_OBJECT (caps, "are the caps");
|
||||||
if (video_format == -1) {
|
|
||||||
ret = GST_FLOW_NOT_SUPPORTED;
|
|
||||||
goto beach;
|
|
||||||
}
|
|
||||||
|
|
||||||
caps = gst_video_format_new_caps (video_format, freeimagedec->width,
|
|
||||||
freeimagedec->height, freeimagedec->fps_n, freeimagedec->fps_d, 1, 1);
|
|
||||||
break;
|
|
||||||
case FIT_UINT16:
|
|
||||||
endianness = G_BYTE_ORDER;
|
|
||||||
|
|
||||||
caps = gst_caps_new_simple ("video/x-raw-gray",
|
|
||||||
"width", G_TYPE_INT, freeimagedec->width,
|
|
||||||
"height", G_TYPE_INT, freeimagedec->height,
|
|
||||||
"bpp", G_TYPE_INT, 16,
|
|
||||||
"depth", G_TYPE_INT, 16,
|
|
||||||
"endianness", G_TYPE_INT, endianness,
|
|
||||||
"framerate", GST_TYPE_FRACTION, freeimagedec->fps_n, freeimagedec->fps_d,
|
|
||||||
NULL);
|
|
||||||
break;
|
|
||||||
case FIT_INT16:
|
|
||||||
endianness = G_BYTE_ORDER;
|
|
||||||
|
|
||||||
caps = gst_caps_new_simple ("video/x-raw-gray",
|
|
||||||
"width", G_TYPE_INT, freeimagedec->width,
|
|
||||||
"height", G_TYPE_INT, freeimagedec->height,
|
|
||||||
"bpp", G_TYPE_INT, 16,
|
|
||||||
"depth", G_TYPE_INT, 16,
|
|
||||||
"endianness", G_TYPE_INT, endianness,
|
|
||||||
"framerate", GST_TYPE_FRACTION, freeimagedec->fps_n, freeimagedec->fps_d,
|
|
||||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
|
||||||
NULL);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
GST_ELEMENT_ERROR (freeimagedec, STREAM, NOT_IMPLEMENTED, (NULL),
|
|
||||||
("freeimagedec does not support this image type"));
|
|
||||||
ret = GST_FLOW_NOT_SUPPORTED;
|
|
||||||
goto beach;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gst_pad_set_caps (freeimagedec->srcpad, caps))
|
if (!gst_pad_set_caps (freeimagedec->srcpad, caps))
|
||||||
ret = GST_FLOW_NOT_NEGOTIATED;
|
ret = GST_FLOW_NOT_NEGOTIATED;
|
||||||
@ -407,7 +325,7 @@ gst_freeimagedec_task (GstPad * pad)
|
|||||||
|
|
||||||
GST_LOG_OBJECT (freeimagedec, "read frame");
|
GST_LOG_OBJECT (freeimagedec, "read frame");
|
||||||
|
|
||||||
/* Query length of file for use by user_seek (SEEK_END) */
|
/* Query length of file for use by gst_freeimagedec_user_seek (SEEK_END) */
|
||||||
format = GST_FORMAT_BYTES;
|
format = GST_FORMAT_BYTES;
|
||||||
gst_pad_query_peer_duration (pad, &format, &freeimagedec->length);
|
gst_pad_query_peer_duration (pad, &format, &freeimagedec->length);
|
||||||
|
|
||||||
@ -611,8 +529,6 @@ gst_freeimagedec_freeimage_clear (GstFreeImageDec * freeimagedec)
|
|||||||
freeimagedec->in_timestamp = GST_CLOCK_TIME_NONE;
|
freeimagedec->in_timestamp = GST_CLOCK_TIME_NONE;
|
||||||
freeimagedec->in_duration = GST_CLOCK_TIME_NONE;
|
freeimagedec->in_duration = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
freeimagedec->bpp = freeimagedec->height = freeimagedec->width = -1;
|
|
||||||
|
|
||||||
freeimagedec->setup = FALSE;
|
freeimagedec->setup = FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -714,7 +630,7 @@ gst_freeimagedec_push_dib (GstFreeImageDec * freeimagedec)
|
|||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstBuffer *buffer = NULL;
|
GstBuffer *buffer = NULL;
|
||||||
size_t buffer_size = 0;
|
size_t buffer_size = 0;
|
||||||
guint pitch;
|
guint pitch, height;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
if (freeimagedec->dib == NULL)
|
if (freeimagedec->dib == NULL)
|
||||||
@ -727,8 +643,9 @@ gst_freeimagedec_push_dib (GstFreeImageDec * freeimagedec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate output buffer */
|
/* Allocate output buffer */
|
||||||
|
height = FreeImage_GetHeight (freeimagedec->dib);
|
||||||
pitch = FreeImage_GetPitch (freeimagedec->dib);
|
pitch = FreeImage_GetPitch (freeimagedec->dib);
|
||||||
buffer_size = pitch * freeimagedec->height;
|
buffer_size = pitch * height;
|
||||||
|
|
||||||
GST_LOG ("Buffer size must be %d", buffer_size);
|
GST_LOG ("Buffer size must be %d", buffer_size);
|
||||||
|
|
||||||
@ -739,9 +656,9 @@ gst_freeimagedec_push_dib (GstFreeImageDec * freeimagedec)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* flip image and copy to buffer */
|
/* flip image and copy to buffer */
|
||||||
for (i = 0; i < freeimagedec->height; i++) {
|
for (i = 0; i < height; i++) {
|
||||||
memcpy (GST_BUFFER_DATA (buffer) + i * pitch,
|
memcpy (GST_BUFFER_DATA (buffer) + i * pitch,
|
||||||
FreeImage_GetBits (freeimagedec->dib) + (freeimagedec->height - i - 1) * pitch, pitch);
|
FreeImage_GetBits (freeimagedec->dib) + (height - i - 1) * pitch, pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -756,111 +673,6 @@ gst_freeimagedec_push_dib (GstFreeImageDec * freeimagedec)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GST_VIDEO_CAPS_FLOAT
|
|
||||||
#define GST_VIDEO_CAPS_FLOAT \
|
|
||||||
"video/x-raw-gray-float, " \
|
|
||||||
"bpp = (int) 32, " \
|
|
||||||
"depth = (int) 32, " \
|
|
||||||
"endianness = (int) BYTE_ORDER, " \
|
|
||||||
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
|
||||||
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
|
||||||
"framerate = " GST_VIDEO_FPS_RANGE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GST_VIDEO_CAPS_RGBF
|
|
||||||
#define GST_VIDEO_CAPS_RGBF \
|
|
||||||
"video/x-raw-rgb-float, " \
|
|
||||||
"bpp = (int) 96, " \
|
|
||||||
"depth = (int) 96, " \
|
|
||||||
"endianness = (int) BYTE_ORDER, " \
|
|
||||||
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
|
||||||
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
|
||||||
"framerate = " GST_VIDEO_FPS_RANGE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GST_VIDEO_CAPS_RGBAF
|
|
||||||
#define GST_VIDEO_CAPS_RGBAF \
|
|
||||||
"video/x-raw-rgba-float, " \
|
|
||||||
"bpp = (int) 96, " \
|
|
||||||
"depth = (int) 96, " \
|
|
||||||
"endianness = (int) BYTE_ORDER, " \
|
|
||||||
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
|
||||||
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
|
||||||
"framerate = " GST_VIDEO_FPS_RANGE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GST_VIDEO_CAPS_GRAY8
|
|
||||||
#define GST_VIDEO_CAPS_GRAY8 \
|
|
||||||
"video/x-raw-gray, " \
|
|
||||||
"bpp = (int) 8, " \
|
|
||||||
"depth = (int) 8, " \
|
|
||||||
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
|
||||||
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
|
||||||
"framerate = " GST_VIDEO_FPS_RANGE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static GstCaps *
|
|
||||||
gst_freeimagedec_caps_from_freeimage_format (FREE_IMAGE_FORMAT fif)
|
|
||||||
{
|
|
||||||
GstCaps * caps = gst_caps_new_empty ();
|
|
||||||
|
|
||||||
if (FreeImage_FIFSupportsExportType (fif, FIT_BITMAP)) {
|
|
||||||
if (FreeImage_FIFSupportsExportBPP (fif, 1) ||
|
|
||||||
FreeImage_FIFSupportsExportBPP (fif, 4) ||
|
|
||||||
FreeImage_FIFSupportsExportBPP (fif, 8) ||
|
|
||||||
FreeImage_FIFSupportsExportBPP (fif, 24)) {
|
|
||||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB));
|
|
||||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_BGR));
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportBPP (fif, 16)) {
|
|
||||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB_15));
|
|
||||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB_16));
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportBPP (fif, 32)) {
|
|
||||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGBA));
|
|
||||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_BGRA));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportType (fif, FIT_UINT16)) {
|
|
||||||
if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
|
||||||
gst_caps_append (caps, gst_caps_from_string (
|
|
||||||
GST_VIDEO_CAPS_GRAY16 ("BIG_ENDIAN")));
|
|
||||||
else
|
|
||||||
gst_caps_append (caps, gst_caps_from_string (
|
|
||||||
GST_VIDEO_CAPS_GRAY16 ("LITTLE_ENDIAN")));
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportType (fif, FIT_INT16)) {
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportType (fif, FIT_UINT32)) {
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportType (fif, FIT_INT32)) {
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportType (fif, FIT_FLOAT)) {
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportType (fif, FIT_DOUBLE)) {
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportType (fif, FIT_COMPLEX)) {
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportType (fif, FIT_RGB16)) {
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportType (fif, FIT_RGBA16)) {
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportType (fif, FIT_RGBF)) {
|
|
||||||
}
|
|
||||||
if (FreeImage_FIFSupportsExportType (fif, FIT_RGBAF)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/* non-standard format, we'll convert to RGB */
|
|
||||||
if (gst_caps_get_size (caps) == 0) {
|
|
||||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB));
|
|
||||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGBA));
|
|
||||||
}
|
|
||||||
|
|
||||||
return caps;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_freeimagedec_register_plugin (GstPlugin * plugin, FREE_IMAGE_FORMAT fif)
|
gst_freeimagedec_register_plugin (GstPlugin * plugin, FREE_IMAGE_FORMAT fif)
|
||||||
{
|
{
|
||||||
@ -889,7 +701,7 @@ gst_freeimagedec_register_plugin (GstPlugin * plugin, FREE_IMAGE_FORMAT fif)
|
|||||||
tmp = g_strdup_printf ("fidec_%s", format);
|
tmp = g_strdup_printf ("fidec_%s", format);
|
||||||
type_name = g_ascii_strdown (tmp, -1);
|
type_name = g_ascii_strdown (tmp, -1);
|
||||||
g_free (tmp);
|
g_free (tmp);
|
||||||
g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-+", '-');
|
g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-+_", '-');
|
||||||
|
|
||||||
GST_LOG ("Trying to use name %s", type_name);
|
GST_LOG ("Trying to use name %s", type_name);
|
||||||
|
|
||||||
|
|||||||
@ -60,9 +60,6 @@ struct _GstFreeImageDec
|
|||||||
|
|
||||||
gboolean setup;
|
gboolean setup;
|
||||||
|
|
||||||
gint width;
|
|
||||||
gint height;
|
|
||||||
gint bpp;
|
|
||||||
gint fps_n;
|
gint fps_n;
|
||||||
gint fps_d;
|
gint fps_d;
|
||||||
|
|
||||||
|
|||||||
216
ext/freeimage/gstfreeimageutils.c
Normal file
216
ext/freeimage/gstfreeimageutils.c
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
|
#include "gstfreeimageutils.h"
|
||||||
|
|
||||||
|
GstCaps *
|
||||||
|
gst_freeimageutils_caps_from_dib (FIBITMAP * dib, gint fps_n, gint fps_d)
|
||||||
|
{
|
||||||
|
FREE_IMAGE_TYPE image_type;
|
||||||
|
guint width, height, bpp;
|
||||||
|
gint video_format = -1;
|
||||||
|
GstCaps * caps = NULL;
|
||||||
|
gint endianness;
|
||||||
|
|
||||||
|
if (dib == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Get bits per channel */
|
||||||
|
bpp = FreeImage_GetBPP (dib);
|
||||||
|
|
||||||
|
/* Get image type */
|
||||||
|
image_type = FreeImage_GetImageType (dib);
|
||||||
|
|
||||||
|
/* Get width and height */
|
||||||
|
width = FreeImage_GetWidth (dib);
|
||||||
|
height = FreeImage_GetHeight (dib);
|
||||||
|
|
||||||
|
GST_LOG ("Image_type=%d, %dx%dx%d", image_type, width, height, bpp);
|
||||||
|
|
||||||
|
switch (image_type) {
|
||||||
|
case FIT_BITMAP:
|
||||||
|
if (bpp == 24) {
|
||||||
|
if (FreeImage_GetRedMask (dib) == GST_VIDEO_BYTE1_MASK_24_INT &&
|
||||||
|
FreeImage_GetGreenMask (dib) == GST_VIDEO_BYTE2_MASK_24_INT &&
|
||||||
|
FreeImage_GetBlueMask (dib) == GST_VIDEO_BYTE3_MASK_24_INT) {
|
||||||
|
video_format = GST_VIDEO_FORMAT_RGB;
|
||||||
|
}
|
||||||
|
else if (FreeImage_GetRedMask (dib) == GST_VIDEO_BYTE3_MASK_24_INT &&
|
||||||
|
FreeImage_GetGreenMask (dib) == GST_VIDEO_BYTE2_MASK_24_INT &&
|
||||||
|
FreeImage_GetBlueMask (dib) == GST_VIDEO_BYTE1_MASK_24_INT) {
|
||||||
|
video_format = GST_VIDEO_FORMAT_BGR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (bpp == 32) {
|
||||||
|
if (FreeImage_GetRedMask (dib) == GST_VIDEO_BYTE1_MASK_32_INT &&
|
||||||
|
FreeImage_GetGreenMask (dib) == GST_VIDEO_BYTE2_MASK_32_INT &&
|
||||||
|
FreeImage_GetBlueMask (dib) == GST_VIDEO_BYTE3_MASK_32_INT) {
|
||||||
|
video_format = GST_VIDEO_FORMAT_RGBA;
|
||||||
|
}
|
||||||
|
else if (FreeImage_GetRedMask (dib) == GST_VIDEO_BYTE3_MASK_32_INT &&
|
||||||
|
FreeImage_GetGreenMask (dib) == GST_VIDEO_BYTE2_MASK_32_INT &&
|
||||||
|
FreeImage_GetBlueMask (dib) == GST_VIDEO_BYTE1_MASK_32_INT) {
|
||||||
|
video_format = GST_VIDEO_FORMAT_BGRA;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We could not find a supported format */
|
||||||
|
if (video_format == -1) {
|
||||||
|
caps = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
caps = gst_video_format_new_caps (video_format, width, height,
|
||||||
|
fps_n, fps_d, 1, 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FIT_UINT16:
|
||||||
|
endianness = G_BYTE_ORDER;
|
||||||
|
|
||||||
|
caps = gst_caps_new_simple ("video/x-raw-gray",
|
||||||
|
"width", G_TYPE_INT, width,
|
||||||
|
"height", G_TYPE_INT, height,
|
||||||
|
"bpp", G_TYPE_INT, 16,
|
||||||
|
"depth", G_TYPE_INT, 16,
|
||||||
|
"endianness", G_TYPE_INT, endianness,
|
||||||
|
"framerate", GST_TYPE_FRACTION, fps_n, fps_d,
|
||||||
|
NULL);
|
||||||
|
break;
|
||||||
|
case FIT_INT16:
|
||||||
|
endianness = G_BYTE_ORDER;
|
||||||
|
|
||||||
|
caps = gst_caps_new_simple ("video/x-raw-gray",
|
||||||
|
"width", G_TYPE_INT, width,
|
||||||
|
"height", G_TYPE_INT, height,
|
||||||
|
"bpp", G_TYPE_INT, 16,
|
||||||
|
"depth", G_TYPE_INT, 16,
|
||||||
|
"endianness", G_TYPE_INT, endianness,
|
||||||
|
"framerate", GST_TYPE_FRACTION, fps_n, fps_d,
|
||||||
|
"signed", G_TYPE_BOOLEAN, TRUE,
|
||||||
|
NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
caps = NULL;
|
||||||
|
}
|
||||||
|
return caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstCaps *
|
||||||
|
gst_freeimageutils_caps_from_freeimage_format (FREE_IMAGE_FORMAT fif)
|
||||||
|
{
|
||||||
|
GstCaps * caps = gst_caps_new_empty ();
|
||||||
|
|
||||||
|
if (FreeImage_FIFSupportsExportType (fif, FIT_BITMAP)) {
|
||||||
|
if (FreeImage_FIFSupportsExportBPP (fif, 1) ||
|
||||||
|
FreeImage_FIFSupportsExportBPP (fif, 4) ||
|
||||||
|
FreeImage_FIFSupportsExportBPP (fif, 8) ||
|
||||||
|
FreeImage_FIFSupportsExportBPP (fif, 24)) {
|
||||||
|
if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
|
||||||
|
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_BGR));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportBPP (fif, 16)) {
|
||||||
|
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB_15));
|
||||||
|
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB_16));
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportBPP (fif, 32)) {
|
||||||
|
if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
|
||||||
|
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_BGRA));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGBA));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportType (fif, FIT_UINT16)) {
|
||||||
|
if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
||||||
|
gst_caps_append (caps, gst_caps_from_string (
|
||||||
|
GST_VIDEO_CAPS_GRAY16 ("BIG_ENDIAN")));
|
||||||
|
else
|
||||||
|
gst_caps_append (caps, gst_caps_from_string (
|
||||||
|
GST_VIDEO_CAPS_GRAY16 ("LITTLE_ENDIAN")));
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportType (fif, FIT_INT16)) {
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportType (fif, FIT_UINT32)) {
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportType (fif, FIT_INT32)) {
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportType (fif, FIT_FLOAT)) {
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportType (fif, FIT_DOUBLE)) {
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportType (fif, FIT_COMPLEX)) {
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportType (fif, FIT_RGB16)) {
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportType (fif, FIT_RGBA16)) {
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportType (fif, FIT_RGBF)) {
|
||||||
|
}
|
||||||
|
if (FreeImage_FIFSupportsExportType (fif, FIT_RGBAF)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* non-standard format, we'll try and convert to RGB */
|
||||||
|
if (gst_caps_get_size (caps) == 0) {
|
||||||
|
if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
|
||||||
|
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_BGR));
|
||||||
|
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_BGRA));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB));
|
||||||
|
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGBA));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_freeimageutils_parse_caps (const GstCaps * caps, FREE_IMAGE_TYPE * type,
|
||||||
|
gint * width, gint * height, gint * bpp, guint32 * red_mask,
|
||||||
|
guint32 * green_mask, guint32 * blue_mask)
|
||||||
|
{
|
||||||
|
GstStructure * s;
|
||||||
|
|
||||||
|
s = gst_caps_get_structure (caps, 0);
|
||||||
|
|
||||||
|
gst_structure_get_int (s, "width", width);
|
||||||
|
gst_structure_get_int (s, "height", height);
|
||||||
|
gst_structure_get_int (s, "bpp", bpp);
|
||||||
|
|
||||||
|
if (g_strcmp0 (gst_structure_get_name (s), "video/x-raw-rgb") == 0) {
|
||||||
|
*type = FIT_BITMAP;
|
||||||
|
gst_structure_get_int (s, "red_mask", red_mask);
|
||||||
|
gst_structure_get_int (s, "green_mask", green_mask);
|
||||||
|
gst_structure_get_int (s, "blue_mask", blue_mask);
|
||||||
|
}
|
||||||
|
else if (g_strcmp0 (gst_structure_get_name (s), "video/x-raw-gray") == 0) {
|
||||||
|
gboolean is_signed;
|
||||||
|
if (!gst_structure_get_boolean (s, "signed", &is_signed))
|
||||||
|
is_signed = FALSE;
|
||||||
|
|
||||||
|
if (*bpp == 8)
|
||||||
|
*type = FIT_BITMAP; /* need to create palette for this later */
|
||||||
|
else if (*bpp == 16 && is_signed == FALSE)
|
||||||
|
*type = FIT_UINT16;
|
||||||
|
else if (*bpp == 16 && is_signed == TRUE)
|
||||||
|
*type = FIT_INT16;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
16
ext/freeimage/gstfreeimageutils.h
Normal file
16
ext/freeimage/gstfreeimageutils.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef __GST_FREEIMAGEUTILS_H__
|
||||||
|
#define __GST_FREEIMAGEUTILS_H__
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
#include <FreeImage.h>
|
||||||
|
|
||||||
|
GstCaps * gst_freeimageutils_caps_from_dib (FIBITMAP * dib,
|
||||||
|
gint fps_n, gint fps_d);
|
||||||
|
GstCaps * gst_freeimageutils_caps_from_freeimage_format (
|
||||||
|
FREE_IMAGE_FORMAT fif);
|
||||||
|
|
||||||
|
gboolean gst_freeimageutils_parse_caps (const GstCaps * caps,
|
||||||
|
FREE_IMAGE_TYPE * type, gint * width, gint * height, gint * bpp,
|
||||||
|
unsigned * red_mask, unsigned * green_mask, unsigned * blue_mask);
|
||||||
|
|
||||||
|
#endif // __GST_FREEIMAGEUTILS_H__
|
||||||
Loading…
x
Reference in New Issue
Block a user