diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/Makefile.am | 8 | ||||
-rw-r--r-- | ext/mpeg2enc/Makefile.am | 18 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2enc.cc | 319 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2enc.hh | 63 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2encoder.cc | 95 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2encoder.hh | 44 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2encoptions.cc | 703 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2encoptions.hh | 42 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2encpicturereader.cc | 129 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2encpicturereader.hh | 49 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2encstreamwriter.cc | 94 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2encstreamwriter.hh | 45 |
12 files changed, 1609 insertions, 0 deletions
diff --git a/ext/Makefile.am b/ext/Makefile.am index a26660d7..cdcfefe7 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -190,6 +190,12 @@ else MPEG2DEC_DIR= endif +if USE_MPEG2ENC +MPEG2ENC_DIR=mpeg2enc +else +MPEG2ENC_DIR= +endif + if USE_MPLEX MPLEX_DIR=mplex else @@ -318,6 +324,7 @@ SUBDIRS=\ $(MAS_DIR) \ $(MIKMOD_DIR) \ $(MPEG2DEC_DIR) \ + $(MPEG2ENC_DIR) \ $(MPLEX_DIR) \ $(OGG_DIR) \ $(PANGO_DIR) \ @@ -367,6 +374,7 @@ DIST_SUBDIRS=\ mad \ mikmod \ mpeg2dec \ + mpeg2enc \ mplex \ ogg \ pango \ diff --git a/ext/mpeg2enc/Makefile.am b/ext/mpeg2enc/Makefile.am new file mode 100644 index 00000000..da5d01d1 --- /dev/null +++ b/ext/mpeg2enc/Makefile.am @@ -0,0 +1,18 @@ +plugin_LTLIBRARIES = libgstmpeg2enc.la + +libgstmpeg2enc_la_SOURCES = \ + gstmpeg2enc.cc \ + gstmpeg2encoptions.cc \ + gstmpeg2encoder.cc \ + gstmpeg2encstreamwriter.cc \ + gstmpeg2encpicturereader.cc +libgstmpeg2enc_la_CXXFLAGS = $(MPEG2ENC_CFLAGS) $(GST_CFLAGS) +libgstmpeg2enc_la_LIBADD = $(MPEG2ENC_LIBS) +libgstmpeg2enc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) + +noinst_HEADERS = \ + gstmpeg2enc.hh \ + gstmpeg2encoder.hh \ + gstmpeg2encoptions.hh \ + gstmpeg2encstreamwriter.hh \ + gstmpeg2encpicturereader.hh diff --git a/ext/mpeg2enc/gstmpeg2enc.cc b/ext/mpeg2enc/gstmpeg2enc.cc new file mode 100644 index 00000000..5e5e028d --- /dev/null +++ b/ext/mpeg2enc/gstmpeg2enc.cc @@ -0,0 +1,319 @@ +/* GStreamer mpeg2enc (mjpegtools) wrapper + * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstmpeg2enc.cc: gstreamer wrapping + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstmpeg2enc.hh" + +GST_PAD_TEMPLATE_FACTORY (sink_templ, + "sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_CAPS_NEW ( + "mpeg2enc_sink", + "video/x-raw-yuv", + "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096), + "framerate", GST_PROPS_LIST ( + GST_PROPS_FLOAT (24/1.001), + GST_PROPS_FLOAT (24.), + GST_PROPS_FLOAT (25.), + GST_PROPS_FLOAT (30/1.001), + GST_PROPS_FLOAT (30.), + GST_PROPS_FLOAT (50.), + GST_PROPS_FLOAT (60/1.001), + GST_PROPS_FLOAT (60.) + ) + ) +) + +GST_PAD_TEMPLATE_FACTORY (src_templ, + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_CAPS_NEW ( + "mpeg2enc_src", + "video/mpeg", + "systemstream", GST_PROPS_BOOLEAN (FALSE), + "mpegversion", GST_PROPS_INT_RANGE (1, 2), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096), + "framerate", GST_PROPS_LIST ( + GST_PROPS_FLOAT (24/1.001), + GST_PROPS_FLOAT (24.), + GST_PROPS_FLOAT (25.), + GST_PROPS_FLOAT (30/1.001), + GST_PROPS_FLOAT (30.), + GST_PROPS_FLOAT (50.), + GST_PROPS_FLOAT (60/1.001), + GST_PROPS_FLOAT (60.) + ) + ) +) + +static void gst_mpeg2enc_base_init (GstMpeg2encClass *klass); +static void gst_mpeg2enc_class_init (GstMpeg2encClass *klass); +static void gst_mpeg2enc_init (GstMpeg2enc *enc); +static void gst_mpeg2enc_dispose (GObject *object); + +static void gst_mpeg2enc_loop (GstElement *element); + +static GstPadLinkReturn + gst_mpeg2enc_sink_link (GstPad *pad, + GstCaps *caps); +static GstCaps * + gst_mpeg2enc_src_getcaps (GstPad *pad, + GstCaps *caps); + +static GstElementStateReturn + gst_mpeg2enc_change_state (GstElement *element); + +static void gst_mpeg2enc_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void gst_mpeg2enc_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +static GstElementClass *parent_class = NULL; + +GType +gst_mpeg2enc_get_type (void) +{ + static GType gst_mpeg2enc_type = 0; + + if (!gst_mpeg2enc_type) { + static const GTypeInfo gst_mpeg2enc_info = { + sizeof (GstMpeg2encClass), + (GBaseInitFunc) gst_mpeg2enc_base_init, + NULL, + (GClassInitFunc) gst_mpeg2enc_class_init, + NULL, + NULL, + sizeof (GstMpeg2enc), + 0, + (GInstanceInitFunc) gst_mpeg2enc_init, + }; + + gst_mpeg2enc_type = + g_type_register_static (GST_TYPE_ELEMENT, + "GstMpeg2enc", + &gst_mpeg2enc_info, + (GTypeFlags) 0); + } + + return gst_mpeg2enc_type; +} + +static void +gst_mpeg2enc_base_init (GstMpeg2encClass *klass) +{ + static GstElementDetails gst_mpeg2enc_details = { + "mpeg2enc video encoder", + "Codec/Video/Encoder", + "High-quality MPEG-1/2 video encoder", + "Ronald Bultje <rbultje@ronald.bitfreak.net>", + }; + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_add_pad_template (element_class, + GST_PAD_TEMPLATE_GET (src_templ)); + gst_element_class_add_pad_template (element_class, + GST_PAD_TEMPLATE_GET (sink_templ)); + gst_element_class_set_details (element_class, + &gst_mpeg2enc_details); +} + +static void +gst_mpeg2enc_class_init (GstMpeg2encClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + parent_class = GST_ELEMENT_CLASS (g_type_class_ref (GST_TYPE_ELEMENT)); + + /* register arguments */ + mjpeg_default_handler_verbosity (0); + GstMpeg2EncOptions::initProperties (object_class); + + object_class->set_property = gst_mpeg2enc_set_property; + object_class->get_property = gst_mpeg2enc_get_property; + + object_class->dispose = gst_mpeg2enc_dispose; + + element_class->change_state = gst_mpeg2enc_change_state; +} + +static void +gst_mpeg2enc_dispose (GObject *object) +{ + GstMpeg2enc *enc = GST_MPEG2ENC (object); + + if (enc->encoder) { + delete enc->encoder; + enc->encoder = NULL; + } + delete enc->options; +} + +static void +gst_mpeg2enc_init (GstMpeg2enc *enc) +{ + GstElement *element = GST_ELEMENT (enc); + + enc->sinkpad = gst_pad_new_from_template ( + gst_element_get_pad_template (element, "sink"), "sink"); + gst_pad_set_link_function (enc->sinkpad, gst_mpeg2enc_sink_link); + gst_element_add_pad (element, enc->sinkpad); + + enc->srcpad = gst_pad_new_from_template ( + gst_element_get_pad_template (element, "src"), "src"); + gst_pad_set_getcaps_function (enc->srcpad, gst_mpeg2enc_src_getcaps); + gst_element_add_pad (element, enc->srcpad); + + enc->options = new GstMpeg2EncOptions (); + + gst_element_set_loop_function (element, gst_mpeg2enc_loop); + + enc->encoder = NULL; +} + +static void +gst_mpeg2enc_loop (GstElement *element) +{ + GstMpeg2enc *enc = GST_MPEG2ENC (element); + + if (!enc->encoder) { + GstCaps *caps; + + /* create new encoder with these settings */ + enc->encoder = new GstMpeg2Encoder (enc->options, + enc->sinkpad, + GST_PAD_CAPS (enc->sinkpad), + enc->srcpad); + + /* and set caps on other side */ + caps = enc->encoder->getFormat (); + if (gst_pad_try_set_caps (enc->srcpad, caps) <= 0) { + gst_element_error (element, + "Failed to set up encoder properly"); + delete enc->encoder; + enc->encoder = NULL; + return; + } + } + + enc->encoder->encodePicture (); +} + +static GstPadLinkReturn +gst_mpeg2enc_sink_link (GstPad *pad, + GstCaps *caps) +{ + GstMpeg2enc *enc = GST_MPEG2ENC (gst_pad_get_parent (pad)); + + if (!GST_CAPS_IS_FIXED (caps)) + return GST_PAD_LINK_DELAYED; + + if (enc->encoder) { + delete enc->encoder; + enc->encoder = NULL; + } + + return GST_PAD_LINK_OK; +} + +static GstCaps * +gst_mpeg2enc_src_getcaps (GstPad *pad, + GstCaps *caps) +{ + GstMpeg2enc *enc = GST_MPEG2ENC (gst_pad_get_parent (pad)); + + if (enc->encoder) { + return enc->encoder->getFormat (); + } + + return gst_caps_ref (gst_pad_template_get_caps ( + gst_element_get_pad_template (gst_pad_get_parent (pad), "src"))); +} + +static void +gst_mpeg2enc_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GST_MPEG2ENC (object)->options->getProperty (prop_id, value); +} + +static void +gst_mpeg2enc_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GST_MPEG2ENC (object)->options->setProperty (prop_id, value); +} + +static GstElementStateReturn +gst_mpeg2enc_change_state (GstElement *element) +{ + GstMpeg2enc *enc = GST_MPEG2ENC (element); + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_PAUSED_TO_READY: + delete enc->encoder; + enc->encoder = NULL; + break; + default: + break; + } + + if (parent_class->change_state) + return parent_class->change_state (element); + + return GST_STATE_SUCCESS; +} + +static gboolean +plugin_init (GstPlugin *plugin) +{ + return gst_element_register (plugin, "mpeg2enc", + GST_RANK_NONE, + GST_TYPE_MPEG2ENC); +} + +GST_PLUGIN_DEFINE ( + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "mpeg2enc", + "High-quality MPEG-1/2 video encoder", + plugin_init, + VERSION, + "GPL", + GST_PACKAGE, + GST_ORIGIN +) diff --git a/ext/mpeg2enc/gstmpeg2enc.hh b/ext/mpeg2enc/gstmpeg2enc.hh new file mode 100644 index 00000000..25c61e61 --- /dev/null +++ b/ext/mpeg2enc/gstmpeg2enc.hh @@ -0,0 +1,63 @@ +/* GStreamer mpeg2enc (mjpegtools) wrapper + * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstmpeg2enc.hh: object definition + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_MPEG2ENC_H__ +#define __GST_MPEG2ENC_H__ + +#include <gst/gst.h> +#include "gstmpeg2encoptions.hh" +#include "gstmpeg2encoder.hh" + +G_BEGIN_DECLS + +#define GST_TYPE_MPEG2ENC \ + (gst_mpeg2enc_get_type ()) +#define GST_MPEG2ENC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPEG2ENC, GstMpeg2enc)) +#define GST_MPEG2ENC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPEG2ENC, GstMpeg2enc)) +#define GST_IS_MPEG2ENC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPEG2ENC)) +#define GST_IS_MPEG2ENC_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPEG2ENC)) + +typedef struct _GstMpeg2enc { + GstElement parent; + + /* pads */ + GstPad *sinkpad, *srcpad; + + /* options wrapper */ + GstMpeg2EncOptions *options; + + /* general encoding object (contains rest) */ + GstMpeg2Encoder *encoder; +} GstMpeg2enc; + +typedef struct _GstMpeg2encClass { + GstElementClass parent; +} GstMpeg2encClass; + +GType gst_mpeg2enc_get_type (void); + +G_END_DECLS + +#endif /* __GST_MPEG2ENC_H__ */ diff --git a/ext/mpeg2enc/gstmpeg2encoder.cc b/ext/mpeg2enc/gstmpeg2encoder.cc new file mode 100644 index 00000000..e0952db1 --- /dev/null +++ b/ext/mpeg2enc/gstmpeg2encoder.cc @@ -0,0 +1,95 @@ +/* GStreamer mpeg2enc (mjpegtools) wrapper + * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstmpeg2encoder.cc: gstreamer/mpeg2enc encoder class + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <mpegconsts.h> +#include <quantize.hh> +#include <ratectl.hh> +#include <seqencoder.hh> +#include <mpeg2coder.hh> + +#include "gstmpeg2encoder.hh" + +/* + * Class init stuff. + */ + +GstMpeg2Encoder::GstMpeg2Encoder (GstMpeg2EncOptions *options, + GstPad *sinkpad, + GstCaps *caps, + GstPad *srcpad) : + MPEG2Encoder (*options) +{ + MPEG2EncInVidParams strm; + + /* I/O */ + reader = new GstMpeg2EncPictureReader (sinkpad, caps, &parms); + reader->StreamPictureParams (strm); + if (options->SetFormatPresets (strm)) { + g_warning ("Eek! Format presets failed. This is really bad!"); + } + writer = new GstMpeg2EncStreamWriter (srcpad, &parms); + + /* encoding internals */ + quantizer = new Quantizer (parms); + coder = new MPEG2Coder (parms, *writer); + bitrate_controller = new OnTheFlyRateCtl (parms); + + /* sequencer */ + seqencoder = new SeqEncoder (parms, *reader, *quantizer, + *writer, *coder, *bitrate_controller); + + parms.Init (*options); + reader->Init (); + quantizer->Init (); +} + +/* + * One image. + */ + +void +GstMpeg2Encoder::encodePicture () +{ + /* hm, this is all... eek! */ + seqencoder->Encode (); +} + +/* + * Get current output format. + */ + +GstCaps * +GstMpeg2Encoder::getFormat () +{ + gdouble fps = Y4M_RATIO_DBL (mpeg_framerate (options.frame_rate)); + + return GST_CAPS_NEW ("mpeg2enc_src", + "video/mpeg", + "systemstream", GST_PROPS_BOOLEAN (FALSE), + "mpegversion", GST_PROPS_INT (options.mpeg), + "width", GST_PROPS_INT (options.in_img_width), + "height", GST_PROPS_INT (options.in_img_height), + "framerate", GST_PROPS_FLOAT (fps)); +} diff --git a/ext/mpeg2enc/gstmpeg2encoder.hh b/ext/mpeg2enc/gstmpeg2encoder.hh new file mode 100644 index 00000000..ebe29692 --- /dev/null +++ b/ext/mpeg2enc/gstmpeg2encoder.hh @@ -0,0 +1,44 @@ +/* GStreamer mpeg2enc (mjpegtools) wrapper + * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstmpeg2encoder.hh: gstreamer/mpeg2enc encoder class + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_MPEG2ENCODER_H__ +#define __GST_MPEG2ENCODER_H__ + +#include <mpeg2encoder.hh> +#include "gstmpeg2encoptions.hh" +#include "gstmpeg2encpicturereader.hh" +#include "gstmpeg2encstreamwriter.hh" + +class GstMpeg2Encoder : public MPEG2Encoder { +public: + GstMpeg2Encoder (GstMpeg2EncOptions *options, + GstPad *sinkpad, + GstCaps *caps, + GstPad *srcpad); + + /* one image */ + void encodePicture (); + + /* get current output format */ + GstCaps *getFormat (); +}; + +#endif /* __GST_MPEG2ENCODER_H__ */ diff --git a/ext/mpeg2enc/gstmpeg2encoptions.cc b/ext/mpeg2enc/gstmpeg2encoptions.cc new file mode 100644 index 00000000..5dbf9ac7 --- /dev/null +++ b/ext/mpeg2enc/gstmpeg2encoptions.cc @@ -0,0 +1,703 @@ +/* GStreamer mpeg2enc (mjpegtools) wrapper + * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstmpeg2encoptions.cc: gobject/mpeg2enc option wrapping class + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstmpeg2encoptions.hh" + +/* + * Property enumeration. + */ + +enum { + ARG_0, + ARG_FORMAT, + ARG_FRAMERATE, + ARG_ASPECT, + ARG_INTERLACE_MODE, + ARG_BITRATE, + ARG_NONVIDEO_BITRATE, + ARG_QUANTISATION, + ARG_VCD_STILL_SIZE, + ARG_MOTION_SEARCH_RADIUS, + ARG_REDUCTION_4_4, + ARG_REDUCTION_2_2, + ARG_UNIT_COEFF_ELIM, + ARG_MIN_GOP_SIZE, + ARG_MAX_GOP_SIZE, + ARG_CLOSED_GOP, + ARG_FORCE_B_B_P, + ARG_B_PER_REFFRAME, + ARG_QUANTISATION_REDUCTION, + ARG_QUANT_REDUCTION_MAX_VAR, + ARG_INTRA_DC_PRECISION, + ARG_REDUCE_HF, + ARG_KEEP_HF, + ARG_QUANTISATION_MATRIX, + ARG_BUFSIZE, + ARG_VIDEO_NORM, + ARG_SEQUENCE_LENGTH, + ARG_3_2_PULLDOWN, + ARG_SEQUENCE_HEADER_EVERY_GOP, + ARG_PLAYBACK_FIELD_ORDER, + ARG_DUMMY_SVCD_SOF, + ARG_CORRECT_SVCD_HDS, + ARG_ALTSCAN_MPEG2, + ARG_CONSTRAINTS + /* FILL ME */ +}; + +/* + * Property enumeration types. + */ + +#define GST_TYPE_MPEG2ENC_FORMAT \ + (gst_mpeg2enc_format_get_type ()) + +static GType +gst_mpeg2enc_format_get_type (void) +{ + static GType mpeg2enc_format_type = 0; + + if (!mpeg2enc_format_type) { + static const GEnumValue mpeg2enc_formats[] = { + { 0, "0", "Generic MPEG-1" }, + { 1, "1", "Standard VCD" }, + { 2, "2", "User VCD" }, + { 3, "3", "Generic MPEG-2" }, + { 4, "4", "Standard SVCD" }, + { 5, "5", "User SVCD" }, + { 6, "6", "VCD Stills sequences" }, + { 7, "7", "SVCD Stills sequences" }, + { 8, "8", "DVD MPEG-2 for dvdauthor" }, + { 9, "9", "DVD MPEG-2" }, + { 0, NULL, NULL }, + }; + + mpeg2enc_format_type = + g_enum_register_static ("GstMpeg2encFormat", + mpeg2enc_formats); + } + + return mpeg2enc_format_type; +} + +#define GST_TYPE_MPEG2ENC_FRAMERATE \ + (gst_mpeg2enc_framerate_get_type ()) + +static GType +gst_mpeg2enc_framerate_get_type (void) +{ + static GType mpeg2enc_framerate_type = 0; + + if (!mpeg2enc_framerate_type) { + static const GEnumValue mpeg2enc_framerates[] = { + { 0, "0", "Same as input" }, + { 1, "1", "24/1.001 (NTSC 3:2 pulldown converted film)" }, + { 2, "2", "24 (native film)" }, + { 3, "3", "25 (PAL/SECAM video)" }, + { 4, "4", "30/1.001 (NTSC video)" }, + { 5, "5", "30" }, + { 6, "6", "50 (PAL/SECAM fields)" }, + { 7, "7", "60/1.001 (NTSC fields)" }, + { 8, "8", "60" }, + { 0, NULL, NULL }, + }; + + mpeg2enc_framerate_type = + g_enum_register_static ("GstMpeg2encFramerate", + mpeg2enc_framerates); + } + + return mpeg2enc_framerate_type; +} + +#define GST_TYPE_MPEG2ENC_ASPECT \ + (gst_mpeg2enc_aspect_get_type ()) + +static GType +gst_mpeg2enc_aspect_get_type (void) +{ + static GType mpeg2enc_aspect_type = 0; + + if (!mpeg2enc_aspect_type) { + static const GEnumValue mpeg2enc_aspects[] = { + { 0, "0", "Deduce from input" }, + { 1, "1", "1:1" }, + { 2, "2", "4:3" }, + { 3, "3", "16:9" }, + { 4, "4", "2.21:1" }, + { 0, NULL, NULL }, + }; + + mpeg2enc_aspect_type = + g_enum_register_static ("GstMpeg2encAspect", + mpeg2enc_aspects); + } + + return mpeg2enc_aspect_type; +} + +#define GST_TYPE_MPEG2ENC_INTERLACE_MODE \ + (gst_mpeg2enc_interlace_mode_get_type ()) + +static GType +gst_mpeg2enc_interlace_mode_get_type (void) +{ + static GType mpeg2enc_interlace_mode_type = 0; + + if (!mpeg2enc_interlace_mode_type) { + static const GEnumValue mpeg2enc_interlace_modes[] = { + { -1, "-1", "Format default mode" }, + { 0, "0", "Progressive" }, + { 1, "1", "Interlaced, per-frame encoding" }, + { 2, "2", "Interlaced, per-field-encoding" }, + { 0, NULL, NULL }, + }; + + mpeg2enc_interlace_mode_type = + g_enum_register_static ("GstMpeg2encInterlaceMode", + mpeg2enc_interlace_modes); + } + + return mpeg2enc_interlace_mode_type; +} + +#define GST_TYPE_MPEG2ENC_QUANTISATION_MATRIX \ + (gst_mpeg2enc_quantisation_matrix_get_type ()) + +#define GST_MPEG2ENC_QUANTISATION_MATRIX_DEFAULT 0 +#define GST_MPEG2ENC_QUANTISATION_MATRIX_HI_RES 1 +#define GST_MPEG2ENC_QUANTISATION_MATRIX_KVCD 2 +#define GST_MPEG2ENC_QUANTISATION_MATRIX_TMPGENC 3 + +static GType +gst_mpeg2enc_quantisation_matrix_get_type (void) +{ + static GType mpeg2enc_quantisation_matrix_type = 0; + + if (!mpeg2enc_quantisation_matrix_type) { + static const GEnumValue mpeg2enc_quantisation_matrixes[] = { + { GST_MPEG2ENC_QUANTISATION_MATRIX_DEFAULT, + "0", "Default" }, + { GST_MPEG2ENC_QUANTISATION_MATRIX_HI_RES, + "1", "High resolution" }, + { GST_MPEG2ENC_QUANTISATION_MATRIX_KVCD, + "2", "KVCD" }, + { GST_MPEG2ENC_QUANTISATION_MATRIX_TMPGENC, + "3", "TMPGEnc" }, + { 0, NULL, NULL }, + }; + + mpeg2enc_quantisation_matrix_type = + g_enum_register_static ("GstMpeg2encQuantisationMatrix", + mpeg2enc_quantisation_matrixes); + } + + return mpeg2enc_quantisation_matrix_type; +} + +#define GST_TYPE_MPEG2ENC_VIDEO_NORM \ + (gst_mpeg2enc_video_norm_get_type ()) + +static GType +gst_mpeg2enc_video_norm_get_type (void) +{ + static GType mpeg2enc_video_norm_type = 0; + + if (!mpeg2enc_video_norm_type) { + static const GEnumValue mpeg2enc_video_norms[] = { + { 0, "0", "Unspecified" }, + { 'p', "p", "PAL" }, + { 'n', "n", "NTSC" }, + { 's', "s", "SECAM" }, + { 0, NULL, NULL }, + }; + + mpeg2enc_video_norm_type = + g_enum_register_static ("GstMpeg2encVideoNorm", + mpeg2enc_video_norms); + } + + return mpeg2enc_video_norm_type; +} + +#define GST_TYPE_MPEG2ENC_PLAYBACK_FIELD_ORDER \ + (gst_mpeg2enc_playback_field_order_get_type ()) + +static GType +gst_mpeg2enc_playback_field_order_get_type (void) +{ + static GType mpeg2enc_playback_field_order_type = 0; + + if (!mpeg2enc_playback_field_order_type) { + static const GEnumValue mpeg2enc_playback_field_orders[] = { + { Y4M_UNKNOWN, "0", "Unspecified" }, + { Y4M_ILACE_TOP_FIRST, "1", "Top-field first" }, + { Y4M_ILACE_BOTTOM_FIRST, "2", "Bottom-field first" }, + { 0, NULL, NULL }, + }; + + mpeg2enc_playback_field_order_type = + g_enum_register_static ("GstMpeg2encPlaybackFieldOrders", + mpeg2enc_playback_field_orders); + } + + return mpeg2enc_playback_field_order_type; +} + +/* + * Class init stuff. + */ + +GstMpeg2EncOptions::GstMpeg2EncOptions () : + MPEG2EncOptions () +{ + /* autodetect number of CPUs */ + num_cpus = sysconf (_SC_NPROCESSORS_ONLN); + if (num_cpus < 0) + num_cpus = 1; + if (num_cpus > 32) + num_cpus = 32; +} + +/* + * Init properties (call once). + */ + +void +GstMpeg2EncOptions::initProperties (GObjectClass *klass) +{ + /* encoding profile */ + g_object_class_install_property (klass, ARG_FORMAT, + g_param_spec_enum ("format", "Format", "Encoding profile format", + GST_TYPE_MPEG2ENC_FORMAT, 0, + (GParamFlags) G_PARAM_READWRITE)); + + /* input/output stream overrides */ + g_object_class_install_property (klass, ARG_FRAMERATE, + g_param_spec_enum ("framerate", "Framerate", "Output framerate", + GST_TYPE_MPEG2ENC_FRAMERATE, 0, + (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_ASPECT, + g_param_spec_enum ("aspect", "Aspect", "Display aspect ratio", + GST_TYPE_MPEG2ENC_ASPECT, 0, + (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_INTERLACE_MODE, + g_param_spec_enum ("interlace-mode", "Interlace mode", + "MPEG-2 motion estimation and encoding modes", + GST_TYPE_MPEG2ENC_INTERLACE_MODE, 0, + (GParamFlags) G_PARAM_READWRITE)); + + /* general encoding stream options */ + g_object_class_install_property (klass, ARG_BITRATE, + g_param_spec_int ("bitrate", "Bitrate", "Compressed video bitrate (kbps)", + 0, 10*1024, 1125, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_NONVIDEO_BITRATE, + g_param_spec_int ("non-video-bitrate", "Non-video bitrate", + "Assumed bitrate of non-video for sequence splitting (kbps)", + 0, 10*1024, 0, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_QUANTISATION, + g_param_spec_int ("quantisation", "Quantisation", + "Quantisation factor (0=default, 1=best, 31=worst)", + 0, 31, 0, (GParamFlags) G_PARAM_READWRITE)); + + /* stills options */ + g_object_class_install_property (klass, ARG_VCD_STILL_SIZE, + g_param_spec_int ("vcd-still-size", "VCD stills size", + "Size of VCD stills (in kB)", + 0, 512, 0, (GParamFlags) G_PARAM_READWRITE)); + + /* motion estimation options */ + g_object_class_install_property (klass, ARG_MOTION_SEARCH_RADIUS, + g_param_spec_int ("motion-search-radius", "Motion search radius", + "Motion compensation search radius", + 0, 32, 16, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_REDUCTION_4_4, + g_param_spec_int ("reduction-4x4", "4x4 reduction", + "Reduction factor for 4x4 subsampled candidate motion estimates" + " (1=max. quality, 4=max. speed)", + 1, 4, 2, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_REDUCTION_2_2, + g_param_spec_int ("reduction-2x2", "2x2 reduction", + "Reduction factor for 2x2 subsampled candidate motion estimates" + " (1=max. quality, 4=max. speed)", + 1, 4, 3, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_UNIT_COEFF_ELIM, + g_param_spec_int ("unit-coeff-elim", "Unit coefficience elimination", + "How agressively small-unit picture blocks should be skipped", + -40, 40, 0, (GParamFlags) G_PARAM_READWRITE)); + + /* GOP options */ + g_object_class_install_property (klass, ARG_MIN_GOP_SIZE, + g_param_spec_int ("min-gop-size", "Min. GOP size", + "Minimal size per Group-of-Pictures (-1=default)", + -1, 250, 0, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_MAX_GOP_SIZE, + g_param_spec_int ("max-gop-size", "Max. GOP size", + "Maximal size per Group-of-Pictures (-1=default)", + -1, 250, 0, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_CLOSED_GOP, + g_param_spec_boolean ("closed-gop", "Closed GOP", + "All Group-of-Pictures are closed (for multi-angle DVDs)", + FALSE, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_FORCE_B_B_P, + g_param_spec_boolean ("force-b-b-p", "Force B-B-P", + "Force two B frames between I/P frames when closing GOP boundaries", + FALSE, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_B_PER_REFFRAME, + g_param_spec_int ("b-per-refframe", "B per ref. frame", + "Number of B frames between each I/P frame", + 0, 2, 2, (GParamFlags) G_PARAM_READWRITE)); + + /* quantisation options */ + g_object_class_install_property (klass, ARG_QUANTISATION_REDUCTION, + g_param_spec_float ("quantisation-reduction", "Quantisation reduction", + "Max. quantisation reduction for highly active blocks", + -4., 10., 0., (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_QUANT_REDUCTION_MAX_VAR, + g_param_spec_float ("quant-reduction-max-var", "Max. quant. reduction variance", + "Maximal luma variance below which quantisation boost is used", + 0., 2500., 0., (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_INTRA_DC_PRECISION, + g_param_spec_int ("intra-dc-prec", "Intra. DC precision", + "Number of bits precision for DC (base colour) in MPEG-2 blocks", + 8, 11, 9, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_REDUCE_HF, + g_param_spec_float ("reduce-hf", "Reduce HF", + "How much to reduce high-frequency resolution (by increasing quantisation)", + 0., 2., 0., (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_KEEP_HF, + g_param_spec_boolean ("keep-hf", "Keep HF", + "Maximize high-frequency resolution (for high-quality sources)", + FALSE, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_QUANTISATION_MATRIX, + g_param_spec_enum ("quant-matrix", "Quant. matrix", + "Quantisation matrix to use for encoding", + GST_TYPE_MPEG2ENC_QUANTISATION_MATRIX, 0, + (GParamFlags) G_PARAM_READWRITE)); + + /* general options */ + g_object_class_install_property (klass, ARG_BUFSIZE, + g_param_spec_int ("bufsize", "Decoder buf. size", + "Target decoders video buffer size (kB)", + 20, 4000, 46, (GParamFlags) G_PARAM_READWRITE)); + + /* header flag settings */ + g_object_class_install_property (klass, ARG_VIDEO_NORM, + g_param_spec_enum ("norm", "Norm", + "Tag output for specific video norm", + GST_TYPE_MPEG2ENC_VIDEO_NORM, 0, + (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_SEQUENCE_LENGTH, + g_param_spec_int ("sequence-length", "Sequence length", + "Place a sequence boundary after each <num> MB (0=disable)", + 0, 10*1024, 0, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_3_2_PULLDOWN, + g_param_spec_boolean ("pulldown-3-2", "3-2 pull down", + "Generate header flags for 3-2 pull down 24fps movies", + FALSE, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_SEQUENCE_HEADER_EVERY_GOP, + g_param_spec_boolean ("sequence-header-every-gop", + "Sequence hdr. every GOP", + "Include a sequence header in every GOP", + FALSE, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_DUMMY_SVCD_SOF, + g_param_spec_boolean ("dummy-svcd-sof", "Dummy SVCD SOF", + "Generate dummy SVCD scan-data (for vcdimager)", + TRUE, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_PLAYBACK_FIELD_ORDER, + g_param_spec_enum ("playback-field-order", "Playback field order", + "Force specific playback field order", + GST_TYPE_MPEG2ENC_PLAYBACK_FIELD_ORDER, Y4M_UNKNOWN, + (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_CORRECT_SVCD_HDS, + g_param_spec_boolean ("correct-svcd-hds", "Correct SVCD hor. size", + "Force SVCD width to 480 instead of 540/720", + FALSE, (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property (klass, ARG_ALTSCAN_MPEG2, + g_param_spec_boolean ("altscan-mpeg2", "Alt. MPEG-2 scan", + "Alternate MPEG-2 block scanning. Disabling this might " + "make buggy players play SVCD streams", + TRUE, (GParamFlags) G_PARAM_READWRITE)); +#if 0 +"--dxr2-hack" +#endif + + /* dangerous/experimental stuff */ + g_object_class_install_property (klass, ARG_CONSTRAINTS, + g_param_spec_boolean ("constraints", "Constraints", + "Use strict video resolution and bitrate checks", + TRUE, (GParamFlags) G_PARAM_READWRITE)); +} + +/* + * GObject property foo, C++ style. + */ + +void +GstMpeg2EncOptions::getProperty (guint prop_id, + GValue *value) +{ + switch (prop_id) { + case ARG_FORMAT: + g_value_set_enum (value, format); + break; + case ARG_FRAMERATE: + g_value_set_enum (value, frame_rate); + break; + case ARG_ASPECT: + g_value_set_enum (value, aspect_ratio); + break; + case ARG_INTERLACE_MODE: + g_value_set_enum (value, fieldenc); + break; + case ARG_BITRATE: + g_value_set_int (value, bitrate/1024); + break; + case ARG_NONVIDEO_BITRATE: + g_value_set_int (value, nonvid_bitrate/1024); + break; + case ARG_QUANTISATION: + g_value_set_int (value, quant); + break; + case ARG_VCD_STILL_SIZE: + g_value_set_int (value, still_size / 1024); + break; + case ARG_MOTION_SEARCH_RADIUS: + g_value_set_int (value, searchrad); + break; + case ARG_REDUCTION_4_4: + g_value_set_int (value, me44_red); + break; + case ARG_REDUCTION_2_2: + g_value_set_int (value, me22_red); + break; + case ARG_UNIT_COEFF_ELIM: + g_value_set_int (value, unit_coeff_elim); + break; + case ARG_MIN_GOP_SIZE: + g_value_set_int (value, min_GOP_size); + break; + case ARG_MAX_GOP_SIZE: + g_value_set_int (value, max_GOP_size); + break; + case ARG_CLOSED_GOP: + g_value_set_boolean (value, closed_GOPs); + break; + case ARG_FORCE_B_B_P: + g_value_set_boolean (value, preserve_B); + break; + case ARG_B_PER_REFFRAME: + g_value_set_int (value, Bgrp_size - 1); + break; + case ARG_QUANTISATION_REDUCTION: + g_value_set_float (value, act_boost); + break; + case ARG_QUANT_REDUCTION_MAX_VAR: + g_value_set_float (value, boost_var_ceil); + break; + case ARG_INTRA_DC_PRECISION: + g_value_set_int (value, mpeg2_dc_prec - 8); + break; + case ARG_REDUCE_HF: + g_value_set_float (value, hf_q_boost); + break; + case ARG_KEEP_HF: + g_value_set_boolean (value, hf_quant == 2); + break; + case ARG_QUANTISATION_MATRIX: + switch (hf_quant) { + case 0: + g_value_set_enum (value, GST_MPEG2ENC_QUANTISATION_MATRIX_DEFAULT); + break; + case 2: + g_value_set_enum (value, GST_MPEG2ENC_QUANTISATION_MATRIX_HI_RES); + break; + case 3: + g_value_set_enum (value, GST_MPEG2ENC_QUANTISATION_MATRIX_KVCD); + break; + case 4: + g_value_set_enum (value, GST_MPEG2ENC_QUANTISATION_MATRIX_TMPGENC); + break; + } + break; + case ARG_BUFSIZE: + g_value_set_int (value, video_buffer_size); + break; + case ARG_VIDEO_NORM: + g_value_set_enum (value, norm); + break; + case ARG_SEQUENCE_LENGTH: + g_value_set_int (value, seq_length_limit); + break; + case ARG_3_2_PULLDOWN: + g_value_set_boolean (value, vid32_pulldown); + break; + case ARG_SEQUENCE_HEADER_EVERY_GOP: + g_value_set_boolean (value, seq_hdr_every_gop); + break; + case ARG_DUMMY_SVCD_SOF: + g_value_set_boolean (value, svcd_scan_data); + break; + case ARG_PLAYBACK_FIELD_ORDER: + g_value_set_enum (value, force_interlacing); + break; + case ARG_CORRECT_SVCD_HDS: + g_value_set_boolean (value, !hack_svcd_hds_bug); + break; + case ARG_ALTSCAN_MPEG2: + g_value_set_boolean (value, !hack_altscan_bug); + break; + case ARG_CONSTRAINTS: + g_value_set_boolean (value, !ignore_constraints); + break; + default: + break; + } +} + +void +GstMpeg2EncOptions::setProperty (guint prop_id, + const GValue *value) +{ + switch (prop_id) { + case ARG_FORMAT: + format = g_value_get_enum (value); + break; + case ARG_FRAMERATE: + frame_rate = g_value_get_enum (value); + break; + case ARG_ASPECT: + aspect_ratio = g_value_get_enum (value); + break; + case ARG_INTERLACE_MODE: + fieldenc = g_value_get_enum (value); + break; + case ARG_BITRATE: + bitrate = g_value_get_int (value) * 1024; + break; + case ARG_NONVIDEO_BITRATE: + nonvid_bitrate = g_value_get_int (value) * 1024; + break; + case ARG_QUANTISATION: + quant = g_value_get_int (value); + break; + case ARG_VCD_STILL_SIZE: + still_size = g_value_get_int (value) * 1024; + break; + case ARG_MOTION_SEARCH_RADIUS: + searchrad = g_value_get_int (value); + break; + case ARG_REDUCTION_4_4: + me44_red = g_value_get_int (value); + break; + case ARG_REDUCTION_2_2: + me22_red = g_value_get_int (value); + break; + case ARG_UNIT_COEFF_ELIM: + unit_coeff_elim = g_value_get_int (value); + break; + case ARG_MIN_GOP_SIZE: + min_GOP_size = g_value_get_int (value); + break; + case ARG_MAX_GOP_SIZE: + max_GOP_size = g_value_get_int (value); + break; + case ARG_CLOSED_GOP: + closed_GOPs = g_value_get_boolean (value); + break; + case ARG_FORCE_B_B_P: + preserve_B = g_value_get_boolean (value); + break; + case ARG_B_PER_REFFRAME: + Bgrp_size = g_value_get_int (value) + 1; + break; + case ARG_QUANTISATION_REDUCTION: + act_boost = g_value_get_float (value); + break; + case ARG_QUANT_REDUCTION_MAX_VAR: + boost_var_ceil = g_value_get_float (value); + break; + case ARG_INTRA_DC_PRECISION: + mpeg2_dc_prec = g_value_get_int (value) + 8; + break; + case ARG_REDUCE_HF: + hf_q_boost = g_value_get_float (value); + if (hf_quant == 0 && hf_q_boost != 0.) + hf_quant = 1; + break; + case ARG_KEEP_HF: + hf_quant = g_value_get_boolean (value) ? 2 : 0; + break; + case ARG_QUANTISATION_MATRIX: + switch (g_value_get_enum (value)) { + case GST_MPEG2ENC_QUANTISATION_MATRIX_DEFAULT: + hf_quant = 0; + hf_q_boost = 0; + break; + case GST_MPEG2ENC_QUANTISATION_MATRIX_HI_RES: + hf_quant = 2; + break; + case GST_MPEG2ENC_QUANTISATION_MATRIX_KVCD: + hf_quant = 3; + break; + case GST_MPEG2ENC_QUANTISATION_MATRIX_TMPGENC: + hf_quant = 4; + break; + } + break; + case ARG_BUFSIZE: + video_buffer_size = g_value_get_int (value); + break; + case ARG_VIDEO_NORM: + norm = g_value_get_enum (value); + break; + case ARG_SEQUENCE_LENGTH: + seq_length_limit = g_value_get_int (value); + break; + case ARG_3_2_PULLDOWN: + vid32_pulldown = g_value_get_boolean (value); + break; + case ARG_SEQUENCE_HEADER_EVERY_GOP: + seq_hdr_every_gop = g_value_get_boolean (value); + break; + case ARG_DUMMY_SVCD_SOF: + svcd_scan_data = g_value_get_boolean (value); + break; + case ARG_PLAYBACK_FIELD_ORDER: + force_interlacing = g_value_get_enum (value); + break; + case ARG_CORRECT_SVCD_HDS: + hack_svcd_hds_bug = !g_value_get_boolean (value); + break; + case ARG_ALTSCAN_MPEG2: + hack_altscan_bug = !g_value_get_boolean (value); + break; + case ARG_CONSTRAINTS: + ignore_constraints = !g_value_get_boolean (value); + break; + default: + break; + } +} diff --git a/ext/mpeg2enc/gstmpeg2encoptions.hh b/ext/mpeg2enc/gstmpeg2encoptions.hh new file mode 100644 index 00000000..ccacd951 --- /dev/null +++ b/ext/mpeg2enc/gstmpeg2encoptions.hh @@ -0,0 +1,42 @@ +/* GStreamer mpeg2enc (mjpegtools) wrapper + * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstmpeg2encoptions.hh: gobject/mpeg2enc option wrapping class + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_MPEG2ENCOPTIONS_H__ +#define __GST_MPEG2ENCOPTIONS_H__ + +#include <glib-object.h> +#include <mpeg2encoptions.hh> + +class GstMpeg2EncOptions : public MPEG2EncOptions { +public: + GstMpeg2EncOptions (); + + /* Init properties (call once) */ + static void initProperties (GObjectClass *klass); + + /* GObject property foo, C++ style */ + void getProperty (guint prop_id, + GValue *value); + void setProperty (guint prop_id, + const GValue *value); +}; + +#endif /* __GST_MPEG2ENCOPTIONS_H__ */ diff --git a/ext/mpeg2enc/gstmpeg2encpicturereader.cc b/ext/mpeg2enc/gstmpeg2encpicturereader.cc new file mode 100644 index 00000000..226acc8d --- /dev/null +++ b/ext/mpeg2enc/gstmpeg2encpicturereader.cc @@ -0,0 +1,129 @@ +/* GStreamer mpeg2enc (mjpegtools) wrapper + * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstmpeg2encpicturereader.cc: GStreamer/mpeg2enc input wrapper + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <encoderparams.hh> + +#include "gstmpeg2encpicturereader.hh" + +/* + * Class init stuff. + */ + +GstMpeg2EncPictureReader::GstMpeg2EncPictureReader (GstPad *in_pad, + GstCaps *in_caps, + EncoderParams *params) : + PictureReader (*params) +{ + pad = in_pad; + caps = gst_caps_copy (in_caps); +} + +GstMpeg2EncPictureReader::~GstMpeg2EncPictureReader () +{ + gst_caps_unref (caps); +} + +/* + * Get input picture parameters (width/height etc.). + */ + +void +GstMpeg2EncPictureReader::StreamPictureParams (MPEG2EncInVidParams &strm) +{ + gint width, height; + gfloat fps; + + gst_caps_get (caps, "width", &width, + "height", &height, + "framerate", &fps, NULL); + + strm.horizontal_size = width; + strm.vertical_size = height; + strm.frame_rate_code = mpeg_framerate_code (mpeg_conform_framerate (fps)); + strm.interlacing_code = Y4M_ILACE_NONE; + strm.aspect_ratio_code = mpeg_guess_mpeg_aspect_code (2, y4m_sar_SQUARE, + strm.horizontal_size, + strm.vertical_size); + + /* FIXME: + * strm.interlacing_code = y4m_si_get_interlace(&si); + * sar = y4m_si_get_sampleaspect(&si); + * strm.aspect_ratio_code = + * mpeg_guess_mpeg_aspect_code(2, sar, + * strm.horizontal_size, + * strm.vertical_size); + */ +} + +/* + * Read a frame. + */ + +bool +GstMpeg2EncPictureReader::LoadFrame () +{ + GstData *data; + GstBuffer *buf = NULL; + gint i, x, y, n; + guint8 *frame; + + do { + if (!(data = gst_pad_pull (pad))) { + return true; + } else if (GST_IS_EVENT (data)) { + if (GST_EVENT_TYPE (data) == GST_EVENT_EOS) { + gst_pad_event_default (pad, GST_EVENT (data)); + return true; + } + gst_pad_event_default (pad, GST_EVENT (data)); + } else { + buf = GST_BUFFER (data); + } + } while (!buf); + + frame = GST_BUFFER_DATA (buf); + n = frames_read % input_imgs_buf_size; + x = encparams.horizontal_size; + y = encparams.vertical_size; + + for (i = 0; i < y; i++) { + memcpy (input_imgs_buf[n][0]+i*encparams.phy_width, frame, x); + frame += x; + } + lum_mean[n] = LumMean (input_imgs_buf[n][0]); + x >>= 1; + y >>= 1; + for (i = 0; i < y; i++) { + memcpy (input_imgs_buf[n][1]+i*encparams.phy_chrom_width, frame, x); + frame += x; + } + for (i = 0; i < y; i++) { + memcpy (input_imgs_buf[n][2]+i*encparams.phy_chrom_width, frame, x); + frame += x; + } + gst_buffer_unref (buf); + + return false; +} diff --git a/ext/mpeg2enc/gstmpeg2encpicturereader.hh b/ext/mpeg2enc/gstmpeg2encpicturereader.hh new file mode 100644 index 00000000..93ed8bdc --- /dev/null +++ b/ext/mpeg2enc/gstmpeg2encpicturereader.hh @@ -0,0 +1,49 @@ +/* GStreamer mpeg2enc (mjpegtools) wrapper + * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstmpeg2encpicturereader.hh: GStreamer/mpeg2enc input wrapper + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_MPEG2ENCPICTUREREADER_H__ +#define __GST_MPEG2ENCPICTUREREADER_H__ + +#include <gst/gst.h> + +#include <picturereader.hh> +#include "gstmpeg2encoptions.hh" + +class GstMpeg2EncPictureReader : public PictureReader { +public: + GstMpeg2EncPictureReader (GstPad *pad, + GstCaps *caps, + EncoderParams *params); + ~GstMpeg2EncPictureReader (); + + /* get input picture parameters (width/height etc.) */ + void StreamPictureParams (MPEG2EncInVidParams &strm); + +protected: + /* read a frame */ + bool LoadFrame (); + +private: + GstPad *pad; + GstCaps *caps; +}; + +#endif /* __GST_MPEG2ENCPICTUREREADER_H__ */ diff --git a/ext/mpeg2enc/gstmpeg2encstreamwriter.cc b/ext/mpeg2enc/gstmpeg2encstreamwriter.cc new file mode 100644 index 00000000..50c70cdf --- /dev/null +++ b/ext/mpeg2enc/gstmpeg2encstreamwriter.cc @@ -0,0 +1,94 @@ +/* GStreamer mpeg2enc (mjpegtools) wrapper + * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstmpeg2encstreamwriter.cc: GStreamer/mpeg2enc output wrapper + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstmpeg2encstreamwriter.hh" + +#define BUFSIZE (128*1024) + +/* + * Class init stuff. + */ + +GstMpeg2EncStreamWriter::GstMpeg2EncStreamWriter (GstPad *in_pad, + EncoderParams *params) : + ElemStrmWriter (*params) +{ + pad = in_pad; + buf = NULL; +} + +/* + * Output functions. + */ + +void +GstMpeg2EncStreamWriter::PutBits (guint32 val, + gint n) +{ + /* only relevant bits */ + val &= ~(0xffffffffU << n); + + /* write data */ + while (n >= outcnt) { + if (!buf) { + buf = gst_buffer_new_and_alloc (BUFSIZE); + GST_BUFFER_SIZE (buf) = 0; + } + + outbfr = (outbfr << outcnt ) | (val >> (n - outcnt)); + GST_BUFFER_DATA (buf)[GST_BUFFER_SIZE (buf)++] = outbfr; + n -= outcnt; + outcnt = 8; + bytecnt++; + + if (GST_BUFFER_SIZE (buf) >= GST_BUFFER_MAXSIZE (buf)) + FrameFlush (); + } + + /* cache remaining bits */ + if (n != 0) { + outbfr = (outbfr << n) | val; + outcnt -= n; + } +} + +void +GstMpeg2EncStreamWriter::FrameBegin () +{ +} + +void +GstMpeg2EncStreamWriter::FrameFlush () +{ + if (buf) { + gst_pad_push (pad, GST_DATA (buf)); + buf = NULL; + } +} + +void +GstMpeg2EncStreamWriter::FrameDiscard () +{ +} diff --git a/ext/mpeg2enc/gstmpeg2encstreamwriter.hh b/ext/mpeg2enc/gstmpeg2encstreamwriter.hh new file mode 100644 index 00000000..708b942e --- /dev/null +++ b/ext/mpeg2enc/gstmpeg2encstreamwriter.hh @@ -0,0 +1,45 @@ +/* GStreamer mpeg2enc (mjpegtools) wrapper + * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> + * + * gstmpeg2encstreamwriter.hh: GStreamer/mpeg2enc output wrapper + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_MPEG2ENCSTREAMWRITER_H__ +#define __GST_MPEG2ENCSTREAMWRITER_H__ + +#include <gst/gst.h> + +#include <elemstrmwriter.hh> + +class GstMpeg2EncStreamWriter : public ElemStrmWriter { +public: + GstMpeg2EncStreamWriter (GstPad *pad, + EncoderParams *params); + + /* output functions */ + void PutBits (guint32 val, gint n); + void FrameBegin (); + void FrameFlush (); + void FrameDiscard (); + +private: + GstPad *pad; + GstBuffer *buf; +}; + +#endif /* __GST_MPEG2ENCSTREAMWRITER_H__ */ |