diff options
Diffstat (limited to 'ext/libfame')
-rw-r--r-- | ext/libfame/gstlibfame.c | 293 | ||||
-rw-r--r-- | ext/libfame/gstlibfame.h | 69 |
2 files changed, 185 insertions, 177 deletions
diff --git a/ext/libfame/gstlibfame.c b/ext/libfame/gstlibfame.c index c68ff36b..43e0e487 100644 --- a/ext/libfame/gstlibfame.c +++ b/ext/libfame/gstlibfame.c @@ -27,7 +27,7 @@ #include "gstlibfame.h" #include <gst/video/video.h> -#define FAMEENC_BUFFER_SIZE (300 * 1024) +#define FAMEENC_BUFFER_SIZE (300 * 1024) /* elementfactory information */ static GstElementDetails gst_fameenc_details = { @@ -41,12 +41,14 @@ static GQuark fame_object_name; /* FameEnc signals and args */ -enum { +enum +{ /* FILL ME */ LAST_SIGNAL }; -enum { +enum +{ ARG_0, ARG_VERSION, ARG_BITRATE, @@ -57,39 +59,31 @@ enum { ARG_FRAMES_PER_SEQUENCE, /* dynamically generated properties start here */ ARG_FAME_PROPS_START - /* FILL ME */ + /* FILL ME */ }; -static GstStaticPadTemplate sink_template = -GST_STATIC_PAD_TEMPLATE ( - "sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ( - "video/x-raw-yuv, " - "format = (fourcc) I420, " - "width = (int) [ 16, 4096 ], " - "height = (int) [ 16, 4096 ], " - "framerate = (double) { 23.976024, 24.0, 25.0, 29.970030, 30.0, " - " 50.0, 59.940060, 60.0 }" - ) -); - -static GstStaticPadTemplate src_template = -GST_STATIC_PAD_TEMPLATE ( - "src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ( - "video/mpeg, " - "mpegversion = (int) { 1, 4 }, " - "systemstream = (boolean) FALSE, " - "width = (int) [ 16, 4096 ], " - "height = (int) [ 16, 4096 ], " - "framerate = (double) { 23.976024, 24.0, 25.0, 29.970030, 30.0, " - " 50.0, 59.940060, 60.0 }" - ) -); +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-yuv, " + "format = (fourcc) I420, " + "width = (int) [ 16, 4096 ], " + "height = (int) [ 16, 4096 ], " + "framerate = (double) { 23.976024, 24.0, 25.0, 29.970030, 30.0, " + " 50.0, 59.940060, 60.0 }") + ); + +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/mpeg, " + "mpegversion = (int) { 1, 4 }, " + "systemstream = (boolean) FALSE, " + "width = (int) [ 16, 4096 ], " + "height = (int) [ 16, 4096 ], " + "framerate = (double) { 23.976024, 24.0, 25.0, 29.970030, 30.0, " + " 50.0, 59.940060, 60.0 }") + ); #define MAX_FRAME_RATES 9 typedef struct @@ -98,17 +92,16 @@ typedef struct gint den; } frame_rate_entry; -static const frame_rate_entry frame_rates[] = -{ - { 0, 0 }, - { 24000, 1001 }, - { 24, 1 }, - { 25, 1 }, - { 30000, 1001 }, - { 30, 1 }, - { 50, 1 }, - { 60000, 1001 }, - { 60, 1 }, +static const frame_rate_entry frame_rates[] = { + {0, 0}, + {24000, 1001}, + {24, 1}, + {25, 1}, + {30000, 1001}, + {30, 1}, + {50, 1}, + {60000, 1001}, + {60, 1}, }; static gint @@ -116,18 +109,18 @@ framerate_to_index (gfloat fps) { gint i; gint idx = -1; - + for (i = 1; i < MAX_FRAME_RATES; i++) { if (idx == -1) { idx = i; } else { - gfloat old_diff = fabs((1. * frame_rates[idx].num / - frame_rates[idx].den) - fps), - new_diff = fabs((1. * frame_rates[i].num / - frame_rates[i].den) - fps); + gfloat old_diff = fabs ((1. * frame_rates[idx].num / + frame_rates[idx].den) - fps), + new_diff = fabs ((1. * frame_rates[i].num / + frame_rates[i].den) - fps); if (new_diff < old_diff) { - idx = i; + idx = i; } } } @@ -135,19 +128,20 @@ framerate_to_index (gfloat fps) return idx; } -static void gst_fameenc_class_init (GstFameEncClass *klass); -static void gst_fameenc_base_init (GstFameEncClass *klass); -static void gst_fameenc_init (GstFameEnc *fameenc); -static void gst_fameenc_dispose (GObject *object); +static void gst_fameenc_class_init (GstFameEncClass * klass); +static void gst_fameenc_base_init (GstFameEncClass * klass); +static void gst_fameenc_init (GstFameEnc * fameenc); +static void gst_fameenc_dispose (GObject * object); -static void gst_fameenc_set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec); -static void gst_fameenc_get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec); +static void gst_fameenc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_fameenc_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); -static void gst_fameenc_chain (GstPad *pad, GstData *_data); +static void gst_fameenc_chain (GstPad * pad, GstData * _data); static GstElementClass *parent_class = NULL; + /*static guint gst_fameenc_signals[LAST_SIGNAL] = { 0 };*/ GType @@ -157,7 +151,7 @@ gst_fameenc_get_type (void) if (!fameenc_type) { static const GTypeInfo fameenc_info = { - sizeof (GstFameEncClass), + sizeof (GstFameEncClass), (GBaseInitFunc) gst_fameenc_base_init, NULL, (GClassInitFunc) gst_fameenc_class_init, @@ -167,33 +161,33 @@ gst_fameenc_get_type (void) 0, (GInstanceInitFunc) gst_fameenc_init, }; - fameenc_type = g_type_register_static (GST_TYPE_ELEMENT, - "GstFameEnc", &fameenc_info, 0); + fameenc_type = g_type_register_static (GST_TYPE_ELEMENT, + "GstFameEnc", &fameenc_info, 0); } return fameenc_type; } static int -gst_fameenc_item_compare (fame_list_t *item1, fame_list_t *item2) +gst_fameenc_item_compare (fame_list_t * item1, fame_list_t * item2) { return strcmp (item1->type, item2->type); } static void -gst_fameenc_base_init (GstFameEncClass *klass) +gst_fameenc_base_init (GstFameEncClass * klass) { GstElementClass *element_class = GST_ELEMENT_CLASS (klass); gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); + gst_static_pad_template_get (&sink_template)); gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); + gst_static_pad_template_get (&src_template)); gst_element_class_set_details (element_class, &gst_fameenc_details); } static void -gst_fameenc_class_init (GstFameEncClass *klass) +gst_fameenc_class_init (GstFameEncClass * klass) { GObjectClass *gobject_class = NULL; GstElementClass *gstelement_class = NULL; @@ -202,8 +196,8 @@ gst_fameenc_class_init (GstFameEncClass *klass) GList *props = NULL, *props_walk; gint current_prop = ARG_FAME_PROPS_START; - gobject_class = (GObjectClass*) klass; - gstelement_class = (GstElementClass*) klass; + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; parent_class = g_type_class_ref (GST_TYPE_ELEMENT); @@ -219,7 +213,9 @@ gst_fameenc_class_init (GstFameEncClass *klass) /* first sort the list */ walk = context->type_list; while (walk) { - props = g_list_insert_sorted (props, walk, (GCompareFunc)gst_fameenc_item_compare); + props = + g_list_insert_sorted (props, walk, + (GCompareFunc) gst_fameenc_item_compare); walk = walk->next; } @@ -232,7 +228,7 @@ gst_fameenc_class_init (GstFameEncClass *klass) fame_object_t *current_default; gint default_index; - walk = (fame_list_t *)props_walk->data; + walk = (fame_list_t *) props_walk->data; array = g_array_new (TRUE, FALSE, sizeof (GEnumValue)); current_type = walk->type; @@ -245,60 +241,68 @@ gst_fameenc_class_init (GstFameEncClass *klass) if (strstr (walk->type, "/")) { GEnumValue value; - if (current_default == walk->item) - default_index = current_value; + if (current_default == walk->item) + default_index = current_value; value.value = current_value++; value.value_name = g_strdup (walk->type); value.value_nick = g_strdup (walk->item->name); - + g_array_append_val (array, value); } props_walk = g_list_next (props_walk); if (props_walk) - walk = (fame_list_t *)props_walk->data; + walk = (fame_list_t *) props_walk->data; } while (props_walk && !strncmp (walk->type, current_type, current_len)); if (array->len > 0) { GType type; GParamSpec *pspec; - - type = g_enum_register_static (g_strdup_printf ("GstFameEnc_%s", current_type), (GEnumValue *)array->data); - pspec = g_param_spec_enum (current_type, current_type, g_strdup_printf ("The FAME \"%s\" object", current_type), - type, default_index, G_PARAM_READWRITE); + type = + g_enum_register_static (g_strdup_printf ("GstFameEnc_%s", + current_type), (GEnumValue *) array->data); + + pspec = + g_param_spec_enum (current_type, current_type, + g_strdup_printf ("The FAME \"%s\" object", current_type), type, + default_index, G_PARAM_READWRITE); g_param_spec_set_qdata (pspec, fame_object_name, (gpointer) current_type); - - g_object_class_install_property (G_OBJECT_CLASS (klass), current_prop++, pspec); + + g_object_class_install_property (G_OBJECT_CLASS (klass), current_prop++, + pspec); } } g_object_class_install_property (gobject_class, ARG_BITRATE, - g_param_spec_int ("bitrate", "Bitrate", "Target bitrate (0 = VBR)", - 0, 5000000, 0, G_PARAM_READWRITE)); + g_param_spec_int ("bitrate", "Bitrate", "Target bitrate (0 = VBR)", + 0, 5000000, 0, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, ARG_QUALITY, - g_param_spec_int ("quality", "Quality", "Percentage of quality of compression (versus size)", - 0, 100, 75, G_PARAM_READWRITE)); + g_param_spec_int ("quality", "Quality", + "Percentage of quality of compression (versus size)", 0, 100, 75, + G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, ARG_PATTERN, - g_param_spec_string ("pattern", "Pattern", "Encoding pattern of I, P, and B frames", - "IPPPPPPPPPPP", G_PARAM_READWRITE)); + g_param_spec_string ("pattern", "Pattern", + "Encoding pattern of I, P, and B frames", "IPPPPPPPPPPP", + G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, ARG_FRAMES_PER_SEQUENCE, - g_param_spec_int ("frames_per_sequence", "Frames Per Sequence", - "The number of frames in one sequence", - 1, G_MAXINT, 12, G_PARAM_READWRITE)); + g_param_spec_int ("frames_per_sequence", "Frames Per Sequence", + "The number of frames in one sequence", 1, G_MAXINT, 12, + G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, ARG_FAME_VERBOSE, - g_param_spec_boolean ("fame_verbose", "Fame Verbose", "Make FAME produce verbose output", - FALSE, G_PARAM_READWRITE)); + g_param_spec_boolean ("fame_verbose", "Fame Verbose", + "Make FAME produce verbose output", FALSE, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, ARG_BUFFER_SIZE, - g_param_spec_int ("buffer_size", "Buffer Size", "Set the decoding output buffer size", - 0, 1024*1024, FAMEENC_BUFFER_SIZE, G_PARAM_READWRITE)); + g_param_spec_int ("buffer_size", "Buffer Size", + "Set the decoding output buffer size", 0, 1024 * 1024, + FAMEENC_BUFFER_SIZE, G_PARAM_READWRITE)); } static GstPadLinkReturn -gst_fameenc_sink_link (GstPad *pad, const GstCaps *caps) +gst_fameenc_sink_link (GstPad * pad, const GstCaps * caps) { gint width, height, fps_idx; gdouble fps; @@ -316,7 +320,7 @@ gst_fameenc_sink_link (GstPad *pad, const GstCaps *caps) gst_structure_get_int (structure, "width", &width); gst_structure_get_int (structure, "height", &height); gst_structure_get_double (structure, "framerate", &fps); - + /* fameenc requires width and height to be multiples of 16 */ if (width % 16 != 0 || height % 16 != 0) return GST_PAD_LINK_REFUSED; @@ -343,12 +347,12 @@ gst_fameenc_sink_link (GstPad *pad, const GstCaps *caps) fameenc->initialized = TRUE; fameenc->time_interval = 0; - + return GST_PAD_LINK_OK; } static void -gst_fameenc_init (GstFameEnc *fameenc) +gst_fameenc_init (GstFameEnc * fameenc) { g_assert (fameenc != NULL); g_assert (GST_IS_FAMEENC (fameenc)); @@ -358,14 +362,16 @@ gst_fameenc_init (GstFameEnc *fameenc) g_assert (fameenc->fc != NULL); /* create the sink and src pads */ - fameenc->sinkpad = gst_pad_new_from_template ( - gst_static_pad_template_get (&sink_template), "sink"); + fameenc->sinkpad = + gst_pad_new_from_template (gst_static_pad_template_get (&sink_template), + "sink"); gst_element_add_pad (GST_ELEMENT (fameenc), fameenc->sinkpad); gst_pad_set_chain_function (fameenc->sinkpad, gst_fameenc_chain); gst_pad_set_link_function (fameenc->sinkpad, gst_fameenc_sink_link); - fameenc->srcpad = gst_pad_new_from_template ( - gst_static_pad_template_get (&src_template), "src"); + fameenc->srcpad = + gst_pad_new_from_template (gst_static_pad_template_get (&src_template), + "src"); gst_element_add_pad (GST_ELEMENT (fameenc), fameenc->srcpad); /* FIXME: set some more handler functions here */ @@ -380,21 +386,21 @@ gst_fameenc_init (GstFameEnc *fameenc) fameenc->fp.bitrate = 0; fameenc->fp.quality = 75; fameenc->fp.frame_rate_num = 25; - fameenc->fp.frame_rate_den = 1; /* avoid floating point exceptions */ - fameenc->fp.frames_per_sequence = 12; + fameenc->fp.frame_rate_den = 1; /* avoid floating point exceptions */ + fameenc->fp.frames_per_sequence = 12; fameenc->pattern = g_strdup ("IPPPPPPPPPP"); /* allocate space for the buffer */ - fameenc->buffer_size = FAMEENC_BUFFER_SIZE; /* FIXME */ + fameenc->buffer_size = FAMEENC_BUFFER_SIZE; /* FIXME */ fameenc->buffer = (unsigned char *) g_malloc (fameenc->buffer_size); - - fameenc->next_time = 0; + + fameenc->next_time = 0; fameenc->time_interval = 0; } static void -gst_fameenc_dispose (GObject *object) +gst_fameenc_dispose (GObject * object) { GstFameEnc *fameenc = GST_FAMEENC (object); @@ -404,7 +410,7 @@ gst_fameenc_dispose (GObject *object) } static void -gst_fameenc_chain (GstPad *pad, GstData *_data) +gst_fameenc_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstFameEnc *fameenc; @@ -423,8 +429,8 @@ gst_fameenc_chain (GstPad *pad, GstData *_data) data = (guchar *) GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); - GST_DEBUG ("gst_fameenc_chain: got buffer of %ld bytes in '%s'", - size, GST_OBJECT_NAME (fameenc)); + GST_DEBUG ("gst_fameenc_chain: got buffer of %ld bytes in '%s'", + size, GST_OBJECT_NAME (fameenc)); /* the data contains the three planes side by side, with size w * h, w * h /4, * w * h / 4 */ @@ -433,7 +439,7 @@ gst_fameenc_chain (GstPad *pad, GstData *_data) frame_size = fameenc->fp.width * fameenc->fp.height; - fameenc->fy.p = 0; + fameenc->fy.p = 0; fameenc->fy.y = data; fameenc->fy.u = data + frame_size; fameenc->fy.v = fameenc->fy.u + (frame_size >> 2); @@ -447,10 +453,13 @@ gst_fameenc_chain (GstPad *pad, GstData *_data) /* FIXME: safeguard, remove me when a better way is found */ if (length > FAMEENC_BUFFER_SIZE) - g_warning ("FAMEENC_BUFFER_SIZE is defined too low, encoded slice has size %d !\n", length); + g_warning + ("FAMEENC_BUFFER_SIZE is defined too low, encoded slice has size %d !\n", + length); if (!fameenc->time_interval) { - fameenc->time_interval = GST_SECOND * fameenc->fp.frame_rate_den / fameenc->fp.frame_rate_num; + fameenc->time_interval = + GST_SECOND * fameenc->fp.frame_rate_den / fameenc->fp.frame_rate_num; } fameenc->next_time += fameenc->time_interval; @@ -458,23 +467,23 @@ gst_fameenc_chain (GstPad *pad, GstData *_data) GST_BUFFER_SIZE (outbuf) = length; GST_BUFFER_TIMESTAMP (outbuf) = fameenc->next_time; GST_BUFFER_DATA (outbuf) = g_malloc (length); - memcpy (GST_BUFFER_DATA(outbuf), fameenc->buffer, length); + memcpy (GST_BUFFER_DATA (outbuf), fameenc->buffer, length); GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf); GST_DEBUG ("gst_fameenc_chain: pushing buffer of size %d", - GST_BUFFER_SIZE(outbuf)); + GST_BUFFER_SIZE (outbuf)); gst_pad_push (fameenc->srcpad, GST_DATA (outbuf)); } - fame_end_frame (fameenc->fc, NULL); + fame_end_frame (fameenc->fc, NULL); - gst_buffer_unref(buf); + gst_buffer_unref (buf); } static void -gst_fameenc_set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +gst_fameenc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) { GstFameEnc *fameenc; @@ -482,7 +491,8 @@ gst_fameenc_set_property (GObject *object, guint prop_id, fameenc = GST_FAMEENC (object); if (fameenc->initialized) { - GST_DEBUG ("error: fameenc encoder already initialized, cannot set properties !"); + GST_DEBUG + ("error: fameenc encoder already initialized, cannot set properties !"); return; } @@ -514,18 +524,18 @@ gst_fameenc_set_property (GObject *object, guint prop_id, values = G_ENUM_CLASS (g_type_class_ref (pspec->value_type))->values; name = (gchar *) g_param_spec_get_qdata (pspec, fame_object_name); - - fame_register (fameenc->fc, name, fame_get_object (fameenc->fc, values[index].value_name)); - } - else - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + + fame_register (fameenc->fc, name, fame_get_object (fameenc->fc, + values[index].value_name)); + } else + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void -gst_fameenc_get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +gst_fameenc_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) { GstFameEnc *fameenc; @@ -560,12 +570,12 @@ gst_fameenc_get_property (GObject *object, guint prop_id, values = G_ENUM_CLASS (g_type_class_ref (pspec->value_type))->values; name = (gchar *) g_param_spec_get_qdata (pspec, fame_object_name); - + f_object = fame_get_object (fameenc->fc, name); while (values[index].value_name) { if (!strcmp (values[index].value_nick, f_object->name)) { - g_value_set_enum (value, index); + g_value_set_enum (value, index); return; } index++; @@ -577,20 +587,15 @@ gst_fameenc_get_property (GObject *object, guint prop_id, } static gboolean -plugin_init (GstPlugin *plugin) +plugin_init (GstPlugin * plugin) { return gst_element_register (plugin, "fameenc", - GST_RANK_NONE, GST_TYPE_FAMEENC); + GST_RANK_NONE, GST_TYPE_FAMEENC); } -GST_PLUGIN_DEFINE ( - GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "fameenc", - "Fast Assembly MPEG Encoder", - plugin_init, - LIBFAME_VERSION, - "LGPL", - "libfame", - "http://fame.sourceforge.net/" -) +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "fameenc", + "Fast Assembly MPEG Encoder", + plugin_init, + LIBFAME_VERSION, "LGPL", "libfame", "http://fame.sourceforge.net/") diff --git a/ext/libfame/gstlibfame.h b/ext/libfame/gstlibfame.h index 15affdaf..74726bb6 100644 --- a/ext/libfame/gstlibfame.h +++ b/ext/libfame/gstlibfame.h @@ -25,8 +25,9 @@ #include <fame.h> #ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +extern "C" +{ +#endif /* __cplusplus */ #define GST_TYPE_FAMEENC \ @@ -40,48 +41,50 @@ extern "C" { #define GST_IS_FAMEENC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FAMEENC)) -typedef struct _GstFameEnc GstFameEnc; -typedef struct _GstFameEncClass GstFameEncClass; + typedef struct _GstFameEnc GstFameEnc; + typedef struct _GstFameEncClass GstFameEncClass; -struct _GstFameEnc { - GstElement element; + struct _GstFameEnc + { + GstElement element; - /* pads */ - GstPad *sinkpad, *srcpad; + /* pads */ + GstPad *sinkpad, *srcpad; - /* the timestamp of the next frame */ - guint64 next_time; - /* the interval between frames */ - guint64 time_interval; + /* the timestamp of the next frame */ + guint64 next_time; + /* the interval between frames */ + guint64 time_interval; - /* video state */ - gint format; - /* the size of the output buffer */ - gint outsize; + /* video state */ + gint format; + /* the size of the output buffer */ + gint outsize; - /* encoding pattern string */ - gchar *pattern; + /* encoding pattern string */ + gchar *pattern; - /* fameenc stuff */ - gboolean verbose; - fame_context_t *fc; - fame_parameters_t fp; - fame_yuv_t fy; - gulong buffer_size; - unsigned char *buffer; - gboolean initialized; -}; + /* fameenc stuff */ + gboolean verbose; + fame_context_t *fc; + fame_parameters_t fp; + fame_yuv_t fy; + gulong buffer_size; + unsigned char *buffer; + gboolean initialized; + }; -struct _GstFameEncClass { - GstElementClass parent_class; -}; + struct _GstFameEncClass + { + GstElementClass parent_class; + }; -GType gst_fameenc_get_type (void); + GType gst_fameenc_get_type (void); #ifdef __cplusplus } -#endif /* __cplusplus */ +#endif /* __cplusplus */ -#endif /* __GST_FAMEENC_H__ */ +#endif /* __GST_FAMEENC_H__ */ |