summaryrefslogtreecommitdiff
path: root/ext/mpeg2enc
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2012-01-25 18:25:01 +0100
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2012-01-25 18:50:40 +0100
commit5abef3c14b593e02dea46fad45fe15d59cdb1add (patch)
treed4eb85999fec7a3f2dc1e9e6613bc93d132a64c5 /ext/mpeg2enc
parent12ee41829c4e1d350adeb898c721724550620260 (diff)
downloadgstreamer-plugins-bad-5abef3c14b593e02dea46fad45fe15d59cdb1add.tar.gz
mpeg2enc: port to 0.11
Diffstat (limited to 'ext/mpeg2enc')
-rw-r--r--ext/mpeg2enc/Makefile.am6
-rw-r--r--ext/mpeg2enc/gstmpeg2enc.cc176
-rw-r--r--ext/mpeg2enc/gstmpeg2enc.hh17
-rw-r--r--ext/mpeg2enc/gstmpeg2encpicturereader.cc19
-rw-r--r--ext/mpeg2enc/gstmpeg2encstreamwriter.cc4
5 files changed, 127 insertions, 95 deletions
diff --git a/ext/mpeg2enc/Makefile.am b/ext/mpeg2enc/Makefile.am
index 1e3d94403..719a161b7 100644
--- a/ext/mpeg2enc/Makefile.am
+++ b/ext/mpeg2enc/Makefile.am
@@ -8,9 +8,11 @@ libgstmpeg2enc_la_SOURCES = \
gstmpeg2encpicturereader.cc
libgstmpeg2enc_la_CXXFLAGS = \
- $(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) $(MPEG2ENC_CFLAGS)
+ $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
+ $(GST_CXXFLAGS) $(MPEG2ENC_CFLAGS)
libgstmpeg2enc_la_LIBADD = \
- $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) $(MPEG2ENC_LIBS)
+ $(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_MAJORMINOR@ \
+ $(GST_LIBS) $(MPEG2ENC_LIBS)
libgstmpeg2enc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstmpeg2enc_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/ext/mpeg2enc/gstmpeg2enc.cc b/ext/mpeg2enc/gstmpeg2enc.cc
index 5c0b426e9..9249f4d89 100644
--- a/ext/mpeg2enc/gstmpeg2enc.cc
+++ b/ext/mpeg2enc/gstmpeg2enc.cc
@@ -70,8 +70,8 @@ GST_DEBUG_CATEGORY (mpeg2enc_debug);
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw-yuv, "
- "format = (fourcc) { I420 }, " COMMON_VIDEO_CAPS)
+ GST_STATIC_CAPS ("video/x-raw, "
+ "format = (string) { I420 }, " COMMON_VIDEO_CAPS)
);
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
@@ -85,12 +85,17 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
static void gst_mpeg2enc_finalize (GObject * object);
static void gst_mpeg2enc_reset (GstMpeg2enc * enc);
-static gboolean gst_mpeg2enc_setcaps (GstPad * pad, GstCaps * caps);
-static GstCaps *gst_mpeg2enc_getcaps (GstPad * pad);
-static gboolean gst_mpeg2enc_sink_event (GstPad * pad, GstEvent * event);
+static gboolean gst_mpeg2enc_setcaps (GstMpeg2enc * enc, GstPad * pad,
+ GstCaps * caps);
+static gboolean gst_mpeg2enc_sink_query (GstPad * pad, GstObject * parent,
+ GstQuery * query);
+static gboolean gst_mpeg2enc_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event);
static void gst_mpeg2enc_loop (GstMpeg2enc * enc);
-static GstFlowReturn gst_mpeg2enc_chain (GstPad * pad, GstBuffer * buffer);
-static gboolean gst_mpeg2enc_src_activate_push (GstPad * pad, gboolean active);
+static GstFlowReturn gst_mpeg2enc_chain (GstPad * pad, GstObject * parent,
+ GstBuffer * buffer);
+static gboolean gst_mpeg2enc_src_activate_mode (GstPad * pad, GstObject * parent,
+ GstPadMode mode, gboolean active);
static GstStateChangeReturn gst_mpeg2enc_change_state (GstElement * element,
GstStateChange transition);
@@ -99,38 +104,9 @@ static void gst_mpeg2enc_get_property (GObject * object,
static void gst_mpeg2enc_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
-static void
-_do_init (GType object_type)
-{
- const GInterfaceInfo preset_interface_info = {
- NULL, /* interface_init */
- NULL, /* interface_finalize */
- NULL /* interface_data */
- };
-
- g_type_add_interface_static (object_type, GST_TYPE_PRESET,
- &preset_interface_info);
-}
-
-GST_BOILERPLATE_FULL (GstMpeg2enc, gst_mpeg2enc, GstElement, GST_TYPE_ELEMENT,
- _do_init);
-
-static void
-gst_mpeg2enc_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_set_details_simple (element_class,
- "mpeg2enc video encoder", "Codec/Encoder/Video",
- "High-quality MPEG-1/2 video encoder",
- "Andrew Stevens <andrew.stevens@nexgo.de>\n"
- "Ronald Bultje <rbultje@ronald.bitfreak.net>");
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_template));
-}
+#define gst_mpeg2enc_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstMpeg2enc, gst_mpeg2enc, GST_TYPE_ELEMENT,
+ G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
static void
gst_mpeg2enc_class_init (GstMpeg2encClass * klass)
@@ -149,6 +125,17 @@ gst_mpeg2enc_class_init (GstMpeg2encClass * klass)
object_class->finalize = GST_DEBUG_FUNCPTR (gst_mpeg2enc_finalize);
element_class->change_state = GST_DEBUG_FUNCPTR (gst_mpeg2enc_change_state);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&src_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&sink_template));
+
+ gst_element_class_set_details_simple (element_class,
+ "mpeg2enc video encoder", "Codec/Encoder/Video",
+ "High-quality MPEG-1/2 video encoder",
+ "Andrew Stevens <andrew.stevens@nexgo.de>\n"
+ "Ronald Bultje <rbultje@ronald.bitfreak.net>");
}
static void
@@ -163,46 +150,37 @@ gst_mpeg2enc_finalize (GObject * object)
}
delete enc->options;
- g_mutex_free (enc->tlock);
- g_cond_free (enc->cond);
g_queue_free (enc->time);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-gst_mpeg2enc_init (GstMpeg2enc * enc, GstMpeg2encClass * g_class)
+gst_mpeg2enc_init (GstMpeg2enc * enc)
{
GstElement *element = GST_ELEMENT (enc);
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- enc->sinkpad =
- gst_pad_new_from_template (gst_element_class_get_pad_template
- (element_class, "sink"), "sink");
- gst_pad_set_setcaps_function (enc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_mpeg2enc_setcaps));
- gst_pad_set_getcaps_function (enc->sinkpad,
- GST_DEBUG_FUNCPTR (gst_mpeg2enc_getcaps));
+
+ enc->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
+ gst_pad_set_query_function (enc->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_mpeg2enc_sink_query));
gst_pad_set_event_function (enc->sinkpad,
GST_DEBUG_FUNCPTR (gst_mpeg2enc_sink_event));
gst_pad_set_chain_function (enc->sinkpad,
GST_DEBUG_FUNCPTR (gst_mpeg2enc_chain));
gst_element_add_pad (element, enc->sinkpad);
- enc->srcpad =
- gst_pad_new_from_template (gst_element_class_get_pad_template
- (element_class, "src"), "src");
+ enc->srcpad = gst_pad_new_from_static_template (&src_template, "src");
gst_pad_use_fixed_caps (enc->srcpad);
- gst_pad_set_activatepush_function (enc->srcpad,
- GST_DEBUG_FUNCPTR (gst_mpeg2enc_src_activate_push));
+ gst_pad_set_activatemode_function (enc->srcpad,
+ GST_DEBUG_FUNCPTR (gst_mpeg2enc_src_activate_mode));
gst_element_add_pad (element, enc->srcpad);
enc->options = new GstMpeg2EncOptions ();
enc->encoder = NULL;
enc->buffer = NULL;
- enc->tlock = g_mutex_new ();
- enc->cond = g_cond_new ();
+ g_mutex_init (&enc->tlock);
+ g_cond_init (&enc->cond);
enc->time = g_queue_new ();
gst_mpeg2enc_reset (enc);
@@ -274,8 +252,8 @@ gst_mpeg2enc_structure_from_norm (GstMpeg2enc * enc, gint horiz,
{
GstStructure *structure;
- structure = gst_structure_new ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'), NULL);
+ structure = gst_structure_new ("video/x-raw",
+ "format", G_TYPE_STRING, 'I420', NULL);
switch (enc->options->norm) {
case 0:
@@ -310,12 +288,11 @@ gst_mpeg2enc_structure_from_norm (GstMpeg2enc * enc, gint horiz,
}
static GstCaps *
-gst_mpeg2enc_getcaps (GstPad * pad)
+gst_mpeg2enc_getcaps (GstMpeg2enc * enc, GstPad * pad)
{
- GstMpeg2enc *enc = GST_MPEG2ENC (GST_PAD_PARENT (pad));
GstCaps *caps;
- caps = GST_PAD_CAPS (pad);
+ caps = gst_pad_get_current_caps (pad);
if (caps) {
gst_caps_ref (caps);
return caps;
@@ -364,24 +341,51 @@ gst_mpeg2enc_getcaps (GstPad * pad)
}
static gboolean
-gst_mpeg2enc_setcaps (GstPad * pad, GstCaps * caps)
+gst_mpeg2enc_sink_query (GstPad * pad, GstObject * parent,
+ GstQuery * query)
{
- GstMpeg2enc *enc = GST_MPEG2ENC (GST_PAD_PARENT (pad));
- GstCaps *othercaps = NULL, *mycaps;
+ GstMpeg2enc *enc;
+ gboolean res = FALSE;
+
+ enc = GST_MPEG2ENC (parent);
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_CAPS:
+ {
+ GstCaps *filter, *caps;
+
+ gst_query_parse_caps (query, &filter);
+ caps = gst_mpeg2enc_getcaps (enc, pad);
+ gst_query_set_caps_result (query, caps);
+ gst_caps_unref (caps);
+ res = TRUE;
+ }
+ default:
+ res = gst_pad_query_default (pad, parent, query);
+ break;
+ }
+
+ return res;
+}
+
+static gboolean
+gst_mpeg2enc_setcaps (GstMpeg2enc * enc, GstPad * pad, GstCaps * caps)
+{
+ GstCaps *othercaps = NULL;
gboolean ret;
/* does not go well to restart stream mid-way */
if (enc->encoder)
goto refuse_renegotiation;
+ pad = enc->sinkpad;
+
/* since mpeg encoder does not really check, let's check caps */
- mycaps = gst_pad_get_caps (pad);
- othercaps = gst_caps_intersect (caps, mycaps);
- gst_caps_unref (mycaps);
- if (!othercaps || gst_caps_is_empty (othercaps))
+ if (!gst_video_info_from_caps (&enc->vinfo, caps))
+ goto refuse_caps;
+
+ if (GST_VIDEO_INFO_FORMAT (&enc->vinfo) != GST_VIDEO_FORMAT_I420)
goto refuse_caps;
- gst_caps_unref (othercaps);
- othercaps = NULL;
/* create new encoder with these settings */
enc->encoder = new GstMpeg2Encoder (enc->options, GST_ELEMENT (enc), caps);
@@ -428,12 +432,12 @@ refuse_renegotiation:
}
static gboolean
-gst_mpeg2enc_sink_event (GstPad * pad, GstEvent * event)
+gst_mpeg2enc_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
GstMpeg2enc *enc;
gboolean result = TRUE;
- enc = GST_MPEG2ENC (GST_PAD_PARENT (pad));
+ enc = GST_MPEG2ENC (parent);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
@@ -468,6 +472,16 @@ gst_mpeg2enc_sink_event (GstPad * pad, GstEvent * event)
gst_event_unref (event);
goto done;
break;
+ case GST_EVENT_CAPS:
+ {
+ GstCaps *caps;
+
+ gst_event_parse_caps (event, &caps);
+ result = gst_mpeg2enc_setcaps (enc, pad, caps);
+ gst_event_unref (event);
+ goto done;
+ break;
+ }
default:
/* for a serialized event, wait until an earlier buffer is gone,
* though this is no guarantee as to when the encoder is done with it */
@@ -541,11 +555,11 @@ ignore:
}
static GstFlowReturn
-gst_mpeg2enc_chain (GstPad * pad, GstBuffer * buffer)
+gst_mpeg2enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
GstMpeg2enc *enc;
- enc = GST_MPEG2ENC (GST_PAD_PARENT (pad));
+ enc = GST_MPEG2ENC (parent);
if (G_UNLIKELY (!enc->encoder))
goto not_negotiated;
@@ -584,7 +598,7 @@ eos:
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
gst_buffer_unref (buffer);
- return GST_FLOW_UNEXPECTED;
+ return GST_FLOW_EOS;
}
ignore:
{
@@ -615,12 +629,16 @@ gst_mpeg2enc_set_property (GObject * object,
}
static gboolean
-gst_mpeg2enc_src_activate_push (GstPad * pad, gboolean active)
+gst_mpeg2enc_src_activate_mode (GstPad * pad, GstObject * parent,
+ GstPadMode mode, gboolean active)
{
gboolean result = TRUE;
GstMpeg2enc *enc;
- enc = GST_MPEG2ENC (GST_PAD_PARENT (pad));
+ enc = GST_MPEG2ENC (parent);
+
+ if (mode != GST_PAD_MODE_PUSH)
+ return FALSE;
if (active) {
/* setcaps will start task once encoder is setup */
diff --git a/ext/mpeg2enc/gstmpeg2enc.hh b/ext/mpeg2enc/gstmpeg2enc.hh
index 413e51e4f..31f678191 100644
--- a/ext/mpeg2enc/gstmpeg2enc.hh
+++ b/ext/mpeg2enc/gstmpeg2enc.hh
@@ -24,6 +24,8 @@
#define __GST_MPEG2ENC_H__
#include <gst/gst.h>
+#include <gst/video/video.h>
+
#include "gstmpeg2encoptions.hh"
#include "gstmpeg2encoder.hh"
@@ -45,23 +47,23 @@ GST_DEBUG_CATEGORY_EXTERN (mpeg2enc_debug);
#define GST_MPEG2ENC_MUTEX_LOCK(m) G_STMT_START { \
GST_LOG_OBJECT (m, "locking tlock from thread %p", g_thread_self ()); \
- g_mutex_lock (m->tlock); \
+ g_mutex_lock (&m->tlock); \
GST_LOG_OBJECT (m, "locked tlock from thread %p", g_thread_self ()); \
} G_STMT_END
#define GST_MPEG2ENC_MUTEX_UNLOCK(m) G_STMT_START { \
GST_LOG_OBJECT (m, "unlocking tlock from thread %p", g_thread_self ()); \
- g_mutex_unlock (m->tlock); \
+ g_mutex_unlock (&m->tlock); \
} G_STMT_END
#define GST_MPEG2ENC_WAIT(m) G_STMT_START { \
GST_LOG_OBJECT (m, "thread %p waiting", g_thread_self ()); \
- g_cond_wait (m->cond, m->tlock); \
+ g_cond_wait (&m->cond, &m->tlock); \
} G_STMT_END
#define GST_MPEG2ENC_SIGNAL(m) G_STMT_START { \
GST_LOG_OBJECT (m, "signalling from thread %p", g_thread_self ()); \
- g_cond_signal (m->cond); \
+ g_cond_signal (&m->cond); \
} G_STMT_END
typedef struct _GstMpeg2enc {
@@ -70,6 +72,9 @@ typedef struct _GstMpeg2enc {
/* pads */
GstPad *sinkpad, *srcpad;
+ /* video info for in caps */
+ GstVideoInfo vinfo;
+
/* options wrapper */
GstMpeg2EncOptions *options;
@@ -77,11 +82,11 @@ typedef struct _GstMpeg2enc {
GstMpeg2Encoder *encoder;
/* lock for syncing with encoding task */
- GMutex *tlock;
+ GMutex tlock;
/* with TLOCK */
/* signals counterpart thread that something changed;
* buffer ready for task or buffer has been processed */
- GCond *cond;
+ GCond cond;
/* seen eos */
gboolean eos;
/* flowreturn obtained by encoding task */
diff --git a/ext/mpeg2enc/gstmpeg2encpicturereader.cc b/ext/mpeg2enc/gstmpeg2encpicturereader.cc
index 77e38440a..18a0fda5a 100644
--- a/ext/mpeg2enc/gstmpeg2encpicturereader.cc
+++ b/ext/mpeg2enc/gstmpeg2encpicturereader.cc
@@ -113,9 +113,10 @@ bool
#if GST_MJPEGTOOLS_API < 10900
gint n;
#endif
- gint i, x, y;
+ gint i, x, y, s;
guint8 *frame;
GstMpeg2enc *enc;
+ GstVideoFrame vframe;
enc = GST_MPEG2ENC (element);
@@ -131,10 +132,13 @@ bool
GST_MPEG2ENC_WAIT (enc);
}
- frame = GST_BUFFER_DATA (enc->buffer);
+ gst_video_frame_map (&vframe, &enc->vinfo, enc->buffer, GST_MAP_READ);
+// frame = GST_BUFFER_DATA (enc->buffer);
#if GST_MJPEGTOOLS_API < 10900
n = frames_read % input_imgs_buf_size;
#endif
+ frame = GST_VIDEO_FRAME_COMP_DATA (&vframe, 0);
+ s = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 0);
x = encparams.horizontal_size;
y = encparams.vertical_size;
@@ -144,11 +148,13 @@ bool
#else
memcpy (input_imgs_buf[n][0] + i * encparams.phy_width, frame, x);
#endif
- frame += x;
+ frame += s;
}
#if GST_MJPEGTOOLS_API < 10900
lum_mean[n] = LumMean (input_imgs_buf[n][0]);
#endif
+ frame = GST_VIDEO_FRAME_COMP_DATA (&vframe, 1);
+ s = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 1);
x >>= 1;
y >>= 1;
for (i = 0; i < y; i++) {
@@ -157,16 +163,19 @@ bool
#else
memcpy (input_imgs_buf[n][1] + i * encparams.phy_chrom_width, frame, x);
#endif
- frame += x;
+ frame += s;
}
+ frame = GST_VIDEO_FRAME_COMP_DATA (&vframe, 2);
+ s = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 2);
for (i = 0; i < y; i++) {
#if GST_MJPEGTOOLS_API >= 10900
memcpy (image.Plane (2) + i * encparams.phy_chrom_width, frame, x);
#else
memcpy (input_imgs_buf[n][2] + i * encparams.phy_chrom_width, frame, x);
#endif
- frame += x;
+ frame += s;
}
+ gst_video_frame_unmap (&vframe);
gst_buffer_unref (enc->buffer);
enc->buffer = NULL;
diff --git a/ext/mpeg2enc/gstmpeg2encstreamwriter.cc b/ext/mpeg2enc/gstmpeg2encstreamwriter.cc
index a17e82dd3..18507c314 100644
--- a/ext/mpeg2enc/gstmpeg2encstreamwriter.cc
+++ b/ext/mpeg2enc/gstmpeg2encstreamwriter.cc
@@ -55,8 +55,7 @@ GstMpeg2EncStreamWriter::WriteOutBufferUpto (const guint8 * buffer,
GstMpeg2enc *enc = GST_MPEG2ENC (GST_PAD_PARENT (pad));
buf = gst_buffer_new_and_alloc (flush_upto);
-
- memcpy (GST_BUFFER_DATA (buf), buffer, flush_upto);
+ gst_buffer_fill (buf, 0, buffer, flush_upto);
flushed += flush_upto;
/* this should not block anything else (e.g. chain), but if it does,
@@ -70,7 +69,6 @@ GstMpeg2EncStreamWriter::WriteOutBufferUpto (const guint8 * buffer,
GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (inbuf);
gst_buffer_unref (inbuf);
}
- gst_buffer_set_caps (buf, GST_PAD_CAPS (pad));
enc->srcresult = gst_pad_push (pad, buf);
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
}