From aa9969dbcfca36106b6c9a37554221ecd621afd0 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 11 Dec 2003 21:07:25 +0000 Subject: This is a first attempt at a wrapper for the lib'ified mpeg2enc of mjpegtools. Currently, there's a few release candi... Original commit message from CVS: This is a first attempt at a wrapper for the lib'ified mpeg2enc of mjpegtools. Currently, there's a few release candidates for mjpegtools-1.6.2 available, but no stable version yet. I've made 4 small subclasses to wrap input, output, options and generic encoding model. The last .cc file is the GStreamer plugin element. Note that it doesn't actually work yet, I'm doing something wrong with header parsing and Andrew asked me to commit so he could help debugging that. Apart from that, we should soon be able to make top-quality MPEG encodes! :). mpeg2enc licensing is tricky, btw, I don't even want to start discussing that... --- ext/mpeg2enc/Makefile.am | 18 + ext/mpeg2enc/gstmpeg2enc.cc | 319 ++++++++++++++ ext/mpeg2enc/gstmpeg2enc.hh | 63 +++ ext/mpeg2enc/gstmpeg2encoder.cc | 95 +++++ ext/mpeg2enc/gstmpeg2encoder.hh | 44 ++ ext/mpeg2enc/gstmpeg2encoptions.cc | 703 +++++++++++++++++++++++++++++++ ext/mpeg2enc/gstmpeg2encoptions.hh | 42 ++ ext/mpeg2enc/gstmpeg2encpicturereader.cc | 129 ++++++ ext/mpeg2enc/gstmpeg2encpicturereader.hh | 49 +++ ext/mpeg2enc/gstmpeg2encstreamwriter.cc | 94 +++++ ext/mpeg2enc/gstmpeg2encstreamwriter.hh | 45 ++ 11 files changed, 1601 insertions(+) create mode 100644 ext/mpeg2enc/Makefile.am create mode 100644 ext/mpeg2enc/gstmpeg2enc.cc create mode 100644 ext/mpeg2enc/gstmpeg2enc.hh create mode 100644 ext/mpeg2enc/gstmpeg2encoder.cc create mode 100644 ext/mpeg2enc/gstmpeg2encoder.hh create mode 100644 ext/mpeg2enc/gstmpeg2encoptions.cc create mode 100644 ext/mpeg2enc/gstmpeg2encoptions.hh create mode 100644 ext/mpeg2enc/gstmpeg2encpicturereader.cc create mode 100644 ext/mpeg2enc/gstmpeg2encpicturereader.hh create mode 100644 ext/mpeg2enc/gstmpeg2encstreamwriter.cc create mode 100644 ext/mpeg2enc/gstmpeg2encstreamwriter.hh (limited to 'ext/mpeg2enc') 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 + * + * 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 ", + }; + 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 + * + * 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 +#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 + * + * 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 +#include +#include +#include +#include + +#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 + * + * 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 +#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 + * + * 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 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 + * + * 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 +#include + +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 + * + * 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 + +#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 + * + * 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 + +#include +#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 + * + * 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 + * + * 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 + +#include + +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__ */ -- cgit v1.2.1