mpeg2enc: port to 0.11
This commit is contained in:
parent
12ee41829c
commit
5abef3c14b
@ -325,7 +325,7 @@ GST_PLUGINS_NONPORTED=" adpcmdec adpcmenc aiff asfmux \
|
|||||||
videomeasure videosignal vmnc \
|
videomeasure videosignal vmnc \
|
||||||
decklink fbdev linsys shm vcd \
|
decklink fbdev linsys shm vcd \
|
||||||
apexsink bz2 cdaudio celt cog curl dc1394 dirac directfb resindvd \
|
apexsink bz2 cdaudio celt cog curl dc1394 dirac directfb resindvd \
|
||||||
gsettings gsm jp2k ladspa modplug mpeg2enc mimic \
|
gsettings gsm jp2k ladspa modplug mimic \
|
||||||
musepack musicbrainz nas neon ofa openal opencv rsvg schro sdl smooth sndfile soundtouch spandsp timidity \
|
musepack musicbrainz nas neon ofa openal opencv rsvg schro sdl smooth sndfile soundtouch spandsp timidity \
|
||||||
wildmidi xvid apple_media lv2 teletextdec opus"
|
wildmidi xvid apple_media lv2 teletextdec opus"
|
||||||
AC_SUBST(GST_PLUGINS_NONPORTED)
|
AC_SUBST(GST_PLUGINS_NONPORTED)
|
||||||
|
@ -8,9 +8,11 @@ libgstmpeg2enc_la_SOURCES = \
|
|||||||
gstmpeg2encpicturereader.cc
|
gstmpeg2encpicturereader.cc
|
||||||
|
|
||||||
libgstmpeg2enc_la_CXXFLAGS = \
|
libgstmpeg2enc_la_CXXFLAGS = \
|
||||||
$(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) $(MPEG2ENC_CFLAGS)
|
$(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
|
||||||
|
$(GST_CXXFLAGS) $(MPEG2ENC_CFLAGS)
|
||||||
libgstmpeg2enc_la_LIBADD = \
|
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_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
libgstmpeg2enc_la_LIBTOOLFLAGS = --tag=disable-static
|
libgstmpeg2enc_la_LIBTOOLFLAGS = --tag=disable-static
|
||||||
|
|
||||||
|
@ -70,8 +70,8 @@ GST_DEBUG_CATEGORY (mpeg2enc_debug);
|
|||||||
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
|
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("video/x-raw-yuv, "
|
GST_STATIC_CAPS ("video/x-raw, "
|
||||||
"format = (fourcc) { I420 }, " COMMON_VIDEO_CAPS)
|
"format = (string) { I420 }, " COMMON_VIDEO_CAPS)
|
||||||
);
|
);
|
||||||
|
|
||||||
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
|
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_finalize (GObject * object);
|
||||||
static void gst_mpeg2enc_reset (GstMpeg2enc * enc);
|
static void gst_mpeg2enc_reset (GstMpeg2enc * enc);
|
||||||
static gboolean gst_mpeg2enc_setcaps (GstPad * pad, GstCaps * caps);
|
static gboolean gst_mpeg2enc_setcaps (GstMpeg2enc * enc, GstPad * pad,
|
||||||
static GstCaps *gst_mpeg2enc_getcaps (GstPad * pad);
|
GstCaps * caps);
|
||||||
static gboolean gst_mpeg2enc_sink_event (GstPad * pad, GstEvent * event);
|
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 void gst_mpeg2enc_loop (GstMpeg2enc * enc);
|
||||||
static GstFlowReturn gst_mpeg2enc_chain (GstPad * pad, GstBuffer * buffer);
|
static GstFlowReturn gst_mpeg2enc_chain (GstPad * pad, GstObject * parent,
|
||||||
static gboolean gst_mpeg2enc_src_activate_push (GstPad * pad, gboolean active);
|
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,
|
static GstStateChangeReturn gst_mpeg2enc_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
|
|
||||||
@ -99,38 +104,9 @@ static void gst_mpeg2enc_get_property (GObject * object,
|
|||||||
static void gst_mpeg2enc_set_property (GObject * object,
|
static void gst_mpeg2enc_set_property (GObject * object,
|
||||||
guint prop_id, const GValue * value, GParamSpec * pspec);
|
guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static void
|
#define gst_mpeg2enc_parent_class parent_class
|
||||||
_do_init (GType object_type)
|
G_DEFINE_TYPE_WITH_CODE (GstMpeg2enc, gst_mpeg2enc, GST_TYPE_ELEMENT,
|
||||||
{
|
G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_mpeg2enc_class_init (GstMpeg2encClass * klass)
|
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);
|
object_class->finalize = GST_DEBUG_FUNCPTR (gst_mpeg2enc_finalize);
|
||||||
|
|
||||||
element_class->change_state = GST_DEBUG_FUNCPTR (gst_mpeg2enc_change_state);
|
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
|
static void
|
||||||
@ -163,46 +150,37 @@ gst_mpeg2enc_finalize (GObject * object)
|
|||||||
}
|
}
|
||||||
delete enc->options;
|
delete enc->options;
|
||||||
|
|
||||||
g_mutex_free (enc->tlock);
|
|
||||||
g_cond_free (enc->cond);
|
|
||||||
g_queue_free (enc->time);
|
g_queue_free (enc->time);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_mpeg2enc_init (GstMpeg2enc * enc, GstMpeg2encClass * g_class)
|
gst_mpeg2enc_init (GstMpeg2enc * enc)
|
||||||
{
|
{
|
||||||
GstElement *element = GST_ELEMENT (enc);
|
GstElement *element = GST_ELEMENT (enc);
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
|
||||||
|
|
||||||
enc->sinkpad =
|
enc->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
|
||||||
gst_pad_new_from_template (gst_element_class_get_pad_template
|
gst_pad_set_query_function (enc->sinkpad,
|
||||||
(element_class, "sink"), "sink");
|
GST_DEBUG_FUNCPTR (gst_mpeg2enc_sink_query));
|
||||||
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));
|
|
||||||
gst_pad_set_event_function (enc->sinkpad,
|
gst_pad_set_event_function (enc->sinkpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_mpeg2enc_sink_event));
|
GST_DEBUG_FUNCPTR (gst_mpeg2enc_sink_event));
|
||||||
gst_pad_set_chain_function (enc->sinkpad,
|
gst_pad_set_chain_function (enc->sinkpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_mpeg2enc_chain));
|
GST_DEBUG_FUNCPTR (gst_mpeg2enc_chain));
|
||||||
gst_element_add_pad (element, enc->sinkpad);
|
gst_element_add_pad (element, enc->sinkpad);
|
||||||
|
|
||||||
enc->srcpad =
|
enc->srcpad = gst_pad_new_from_static_template (&src_template, "src");
|
||||||
gst_pad_new_from_template (gst_element_class_get_pad_template
|
|
||||||
(element_class, "src"), "src");
|
|
||||||
gst_pad_use_fixed_caps (enc->srcpad);
|
gst_pad_use_fixed_caps (enc->srcpad);
|
||||||
gst_pad_set_activatepush_function (enc->srcpad,
|
gst_pad_set_activatemode_function (enc->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_mpeg2enc_src_activate_push));
|
GST_DEBUG_FUNCPTR (gst_mpeg2enc_src_activate_mode));
|
||||||
gst_element_add_pad (element, enc->srcpad);
|
gst_element_add_pad (element, enc->srcpad);
|
||||||
|
|
||||||
enc->options = new GstMpeg2EncOptions ();
|
enc->options = new GstMpeg2EncOptions ();
|
||||||
enc->encoder = NULL;
|
enc->encoder = NULL;
|
||||||
|
|
||||||
enc->buffer = NULL;
|
enc->buffer = NULL;
|
||||||
enc->tlock = g_mutex_new ();
|
g_mutex_init (&enc->tlock);
|
||||||
enc->cond = g_cond_new ();
|
g_cond_init (&enc->cond);
|
||||||
enc->time = g_queue_new ();
|
enc->time = g_queue_new ();
|
||||||
|
|
||||||
gst_mpeg2enc_reset (enc);
|
gst_mpeg2enc_reset (enc);
|
||||||
@ -274,8 +252,8 @@ gst_mpeg2enc_structure_from_norm (GstMpeg2enc * enc, gint horiz,
|
|||||||
{
|
{
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
|
|
||||||
structure = gst_structure_new ("video/x-raw-yuv",
|
structure = gst_structure_new ("video/x-raw",
|
||||||
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'), NULL);
|
"format", G_TYPE_STRING, 'I420', NULL);
|
||||||
|
|
||||||
switch (enc->options->norm) {
|
switch (enc->options->norm) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -310,12 +288,11 @@ gst_mpeg2enc_structure_from_norm (GstMpeg2enc * enc, gint horiz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
gst_mpeg2enc_getcaps (GstPad * pad)
|
gst_mpeg2enc_getcaps (GstMpeg2enc * enc, GstPad * pad)
|
||||||
{
|
{
|
||||||
GstMpeg2enc *enc = GST_MPEG2ENC (GST_PAD_PARENT (pad));
|
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
|
||||||
caps = GST_PAD_CAPS (pad);
|
caps = gst_pad_get_current_caps (pad);
|
||||||
if (caps) {
|
if (caps) {
|
||||||
gst_caps_ref (caps);
|
gst_caps_ref (caps);
|
||||||
return caps;
|
return caps;
|
||||||
@ -364,24 +341,51 @@ gst_mpeg2enc_getcaps (GstPad * pad)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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));
|
GstMpeg2enc *enc;
|
||||||
GstCaps *othercaps = NULL, *mycaps;
|
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;
|
gboolean ret;
|
||||||
|
|
||||||
/* does not go well to restart stream mid-way */
|
/* does not go well to restart stream mid-way */
|
||||||
if (enc->encoder)
|
if (enc->encoder)
|
||||||
goto refuse_renegotiation;
|
goto refuse_renegotiation;
|
||||||
|
|
||||||
|
pad = enc->sinkpad;
|
||||||
|
|
||||||
/* since mpeg encoder does not really check, let's check caps */
|
/* since mpeg encoder does not really check, let's check caps */
|
||||||
mycaps = gst_pad_get_caps (pad);
|
if (!gst_video_info_from_caps (&enc->vinfo, caps))
|
||||||
othercaps = gst_caps_intersect (caps, mycaps);
|
goto refuse_caps;
|
||||||
gst_caps_unref (mycaps);
|
|
||||||
if (!othercaps || gst_caps_is_empty (othercaps))
|
if (GST_VIDEO_INFO_FORMAT (&enc->vinfo) != GST_VIDEO_FORMAT_I420)
|
||||||
goto refuse_caps;
|
goto refuse_caps;
|
||||||
gst_caps_unref (othercaps);
|
|
||||||
othercaps = NULL;
|
|
||||||
|
|
||||||
/* create new encoder with these settings */
|
/* create new encoder with these settings */
|
||||||
enc->encoder = new GstMpeg2Encoder (enc->options, GST_ELEMENT (enc), caps);
|
enc->encoder = new GstMpeg2Encoder (enc->options, GST_ELEMENT (enc), caps);
|
||||||
@ -428,12 +432,12 @@ refuse_renegotiation:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_mpeg2enc_sink_event (GstPad * pad, GstEvent * event)
|
gst_mpeg2enc_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
{
|
{
|
||||||
GstMpeg2enc *enc;
|
GstMpeg2enc *enc;
|
||||||
gboolean result = TRUE;
|
gboolean result = TRUE;
|
||||||
|
|
||||||
enc = GST_MPEG2ENC (GST_PAD_PARENT (pad));
|
enc = GST_MPEG2ENC (parent);
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_FLUSH_START:
|
case GST_EVENT_FLUSH_START:
|
||||||
@ -468,6 +472,16 @@ gst_mpeg2enc_sink_event (GstPad * pad, GstEvent * event)
|
|||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
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:
|
default:
|
||||||
/* for a serialized event, wait until an earlier buffer is gone,
|
/* 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 */
|
* though this is no guarantee as to when the encoder is done with it */
|
||||||
@ -541,11 +555,11 @@ ignore:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_mpeg2enc_chain (GstPad * pad, GstBuffer * buffer)
|
gst_mpeg2enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstMpeg2enc *enc;
|
GstMpeg2enc *enc;
|
||||||
|
|
||||||
enc = GST_MPEG2ENC (GST_PAD_PARENT (pad));
|
enc = GST_MPEG2ENC (parent);
|
||||||
|
|
||||||
if (G_UNLIKELY (!enc->encoder))
|
if (G_UNLIKELY (!enc->encoder))
|
||||||
goto not_negotiated;
|
goto not_negotiated;
|
||||||
@ -584,7 +598,7 @@ eos:
|
|||||||
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
||||||
|
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
return GST_FLOW_UNEXPECTED;
|
return GST_FLOW_EOS;
|
||||||
}
|
}
|
||||||
ignore:
|
ignore:
|
||||||
{
|
{
|
||||||
@ -615,12 +629,16 @@ gst_mpeg2enc_set_property (GObject * object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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;
|
gboolean result = TRUE;
|
||||||
GstMpeg2enc *enc;
|
GstMpeg2enc *enc;
|
||||||
|
|
||||||
enc = GST_MPEG2ENC (GST_PAD_PARENT (pad));
|
enc = GST_MPEG2ENC (parent);
|
||||||
|
|
||||||
|
if (mode != GST_PAD_MODE_PUSH)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
/* setcaps will start task once encoder is setup */
|
/* setcaps will start task once encoder is setup */
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#define __GST_MPEG2ENC_H__
|
#define __GST_MPEG2ENC_H__
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
#include "gstmpeg2encoptions.hh"
|
#include "gstmpeg2encoptions.hh"
|
||||||
#include "gstmpeg2encoder.hh"
|
#include "gstmpeg2encoder.hh"
|
||||||
|
|
||||||
@ -45,23 +47,23 @@ GST_DEBUG_CATEGORY_EXTERN (mpeg2enc_debug);
|
|||||||
|
|
||||||
#define GST_MPEG2ENC_MUTEX_LOCK(m) G_STMT_START { \
|
#define GST_MPEG2ENC_MUTEX_LOCK(m) G_STMT_START { \
|
||||||
GST_LOG_OBJECT (m, "locking tlock from thread %p", g_thread_self ()); \
|
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 ()); \
|
GST_LOG_OBJECT (m, "locked tlock from thread %p", g_thread_self ()); \
|
||||||
} G_STMT_END
|
} G_STMT_END
|
||||||
|
|
||||||
#define GST_MPEG2ENC_MUTEX_UNLOCK(m) G_STMT_START { \
|
#define GST_MPEG2ENC_MUTEX_UNLOCK(m) G_STMT_START { \
|
||||||
GST_LOG_OBJECT (m, "unlocking tlock from thread %p", g_thread_self ()); \
|
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
|
} G_STMT_END
|
||||||
|
|
||||||
#define GST_MPEG2ENC_WAIT(m) G_STMT_START { \
|
#define GST_MPEG2ENC_WAIT(m) G_STMT_START { \
|
||||||
GST_LOG_OBJECT (m, "thread %p waiting", g_thread_self ()); \
|
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
|
} G_STMT_END
|
||||||
|
|
||||||
#define GST_MPEG2ENC_SIGNAL(m) G_STMT_START { \
|
#define GST_MPEG2ENC_SIGNAL(m) G_STMT_START { \
|
||||||
GST_LOG_OBJECT (m, "signalling from thread %p", g_thread_self ()); \
|
GST_LOG_OBJECT (m, "signalling from thread %p", g_thread_self ()); \
|
||||||
g_cond_signal (m->cond); \
|
g_cond_signal (&m->cond); \
|
||||||
} G_STMT_END
|
} G_STMT_END
|
||||||
|
|
||||||
typedef struct _GstMpeg2enc {
|
typedef struct _GstMpeg2enc {
|
||||||
@ -70,6 +72,9 @@ typedef struct _GstMpeg2enc {
|
|||||||
/* pads */
|
/* pads */
|
||||||
GstPad *sinkpad, *srcpad;
|
GstPad *sinkpad, *srcpad;
|
||||||
|
|
||||||
|
/* video info for in caps */
|
||||||
|
GstVideoInfo vinfo;
|
||||||
|
|
||||||
/* options wrapper */
|
/* options wrapper */
|
||||||
GstMpeg2EncOptions *options;
|
GstMpeg2EncOptions *options;
|
||||||
|
|
||||||
@ -77,11 +82,11 @@ typedef struct _GstMpeg2enc {
|
|||||||
GstMpeg2Encoder *encoder;
|
GstMpeg2Encoder *encoder;
|
||||||
|
|
||||||
/* lock for syncing with encoding task */
|
/* lock for syncing with encoding task */
|
||||||
GMutex *tlock;
|
GMutex tlock;
|
||||||
/* with TLOCK */
|
/* with TLOCK */
|
||||||
/* signals counterpart thread that something changed;
|
/* signals counterpart thread that something changed;
|
||||||
* buffer ready for task or buffer has been processed */
|
* buffer ready for task or buffer has been processed */
|
||||||
GCond *cond;
|
GCond cond;
|
||||||
/* seen eos */
|
/* seen eos */
|
||||||
gboolean eos;
|
gboolean eos;
|
||||||
/* flowreturn obtained by encoding task */
|
/* flowreturn obtained by encoding task */
|
||||||
|
@ -113,9 +113,10 @@ bool
|
|||||||
#if GST_MJPEGTOOLS_API < 10900
|
#if GST_MJPEGTOOLS_API < 10900
|
||||||
gint n;
|
gint n;
|
||||||
#endif
|
#endif
|
||||||
gint i, x, y;
|
gint i, x, y, s;
|
||||||
guint8 *frame;
|
guint8 *frame;
|
||||||
GstMpeg2enc *enc;
|
GstMpeg2enc *enc;
|
||||||
|
GstVideoFrame vframe;
|
||||||
|
|
||||||
enc = GST_MPEG2ENC (element);
|
enc = GST_MPEG2ENC (element);
|
||||||
|
|
||||||
@ -131,10 +132,13 @@ bool
|
|||||||
GST_MPEG2ENC_WAIT (enc);
|
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
|
#if GST_MJPEGTOOLS_API < 10900
|
||||||
n = frames_read % input_imgs_buf_size;
|
n = frames_read % input_imgs_buf_size;
|
||||||
#endif
|
#endif
|
||||||
|
frame = GST_VIDEO_FRAME_COMP_DATA (&vframe, 0);
|
||||||
|
s = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 0);
|
||||||
x = encparams.horizontal_size;
|
x = encparams.horizontal_size;
|
||||||
y = encparams.vertical_size;
|
y = encparams.vertical_size;
|
||||||
|
|
||||||
@ -144,11 +148,13 @@ bool
|
|||||||
#else
|
#else
|
||||||
memcpy (input_imgs_buf[n][0] + i * encparams.phy_width, frame, x);
|
memcpy (input_imgs_buf[n][0] + i * encparams.phy_width, frame, x);
|
||||||
#endif
|
#endif
|
||||||
frame += x;
|
frame += s;
|
||||||
}
|
}
|
||||||
#if GST_MJPEGTOOLS_API < 10900
|
#if GST_MJPEGTOOLS_API < 10900
|
||||||
lum_mean[n] = LumMean (input_imgs_buf[n][0]);
|
lum_mean[n] = LumMean (input_imgs_buf[n][0]);
|
||||||
#endif
|
#endif
|
||||||
|
frame = GST_VIDEO_FRAME_COMP_DATA (&vframe, 1);
|
||||||
|
s = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 1);
|
||||||
x >>= 1;
|
x >>= 1;
|
||||||
y >>= 1;
|
y >>= 1;
|
||||||
for (i = 0; i < y; i++) {
|
for (i = 0; i < y; i++) {
|
||||||
@ -157,16 +163,19 @@ bool
|
|||||||
#else
|
#else
|
||||||
memcpy (input_imgs_buf[n][1] + i * encparams.phy_chrom_width, frame, x);
|
memcpy (input_imgs_buf[n][1] + i * encparams.phy_chrom_width, frame, x);
|
||||||
#endif
|
#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++) {
|
for (i = 0; i < y; i++) {
|
||||||
#if GST_MJPEGTOOLS_API >= 10900
|
#if GST_MJPEGTOOLS_API >= 10900
|
||||||
memcpy (image.Plane (2) + i * encparams.phy_chrom_width, frame, x);
|
memcpy (image.Plane (2) + i * encparams.phy_chrom_width, frame, x);
|
||||||
#else
|
#else
|
||||||
memcpy (input_imgs_buf[n][2] + i * encparams.phy_chrom_width, frame, x);
|
memcpy (input_imgs_buf[n][2] + i * encparams.phy_chrom_width, frame, x);
|
||||||
#endif
|
#endif
|
||||||
frame += x;
|
frame += s;
|
||||||
}
|
}
|
||||||
|
gst_video_frame_unmap (&vframe);
|
||||||
gst_buffer_unref (enc->buffer);
|
gst_buffer_unref (enc->buffer);
|
||||||
enc->buffer = NULL;
|
enc->buffer = NULL;
|
||||||
|
|
||||||
|
@ -55,8 +55,7 @@ GstMpeg2EncStreamWriter::WriteOutBufferUpto (const guint8 * buffer,
|
|||||||
GstMpeg2enc *enc = GST_MPEG2ENC (GST_PAD_PARENT (pad));
|
GstMpeg2enc *enc = GST_MPEG2ENC (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
buf = gst_buffer_new_and_alloc (flush_upto);
|
buf = gst_buffer_new_and_alloc (flush_upto);
|
||||||
|
gst_buffer_fill (buf, 0, buffer, flush_upto);
|
||||||
memcpy (GST_BUFFER_DATA (buf), buffer, flush_upto);
|
|
||||||
flushed += flush_upto;
|
flushed += flush_upto;
|
||||||
|
|
||||||
/* this should not block anything else (e.g. chain), but if it does,
|
/* 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_DURATION (buf) = GST_BUFFER_DURATION (inbuf);
|
||||||
gst_buffer_unref (inbuf);
|
gst_buffer_unref (inbuf);
|
||||||
}
|
}
|
||||||
gst_buffer_set_caps (buf, GST_PAD_CAPS (pad));
|
|
||||||
enc->srcresult = gst_pad_push (pad, buf);
|
enc->srcresult = gst_pad_push (pad, buf);
|
||||||
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
GST_MPEG2ENC_MUTEX_UNLOCK (enc);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user