diff options
author | Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk> | 2012-01-25 18:25:01 +0100 |
---|---|---|
committer | Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk> | 2012-01-25 18:50:40 +0100 |
commit | 5abef3c14b593e02dea46fad45fe15d59cdb1add (patch) | |
tree | d4eb85999fec7a3f2dc1e9e6613bc93d132a64c5 /ext/mpeg2enc | |
parent | 12ee41829c4e1d350adeb898c721724550620260 (diff) | |
download | gstreamer-plugins-bad-5abef3c14b593e02dea46fad45fe15d59cdb1add.tar.gz |
mpeg2enc: port to 0.11
Diffstat (limited to 'ext/mpeg2enc')
-rw-r--r-- | ext/mpeg2enc/Makefile.am | 6 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2enc.cc | 176 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2enc.hh | 17 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2encpicturereader.cc | 19 | ||||
-rw-r--r-- | ext/mpeg2enc/gstmpeg2encstreamwriter.cc | 4 |
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); } |