configure.ac: Clean up detection of different mjpegtoolsAPI versions.

Original commit message from CVS:
Patch by: Mark Nauwelaerts <manauw at skynet dot be>
* configure.ac:
Clean up detection of different mjpegtoolsAPI versions.
* ext/mpeg2enc/gstmpeg2enc.cc:
* ext/mpeg2enc/gstmpeg2enc.hh:
* ext/mpeg2enc/gstmpeg2encoder.cc:
* ext/mpeg2enc/gstmpeg2encoptions.cc:
* ext/mpeg2enc/gstmpeg2encpicturereader.cc:
* ext/mpeg2enc/gstmpeg2encpicturereader.hh:
* ext/mpeg2enc/gstmpeg2encstreamwriter.cc:
* ext/mpeg2enc/gstmpeg2encstreamwriter.hh:
Streamline conditional code for evolving mjpegtools API,
optimize and fix/prevent crash in log handling, use
names/nicks for enums in the usual way andm inor updates
in code and properties/settings. Partially fixes bug #520329.
This commit is contained in:
Mark Nauwelaerts 2008-03-05 05:38:06 +00:00 committed by Sebastian Dröge
parent 15ac9f5a13
commit 646ac4cdf2
10 changed files with 179 additions and 131 deletions

View file

@ -1,3 +1,23 @@
2008-03-05 Sebastian Dröge <slomo@circular-chaos.org>
Patch by: Mark Nauwelaerts <manauw at skynet dot be>
* configure.ac:
Clean up detection of different mjpegtoolsAPI versions.
* ext/mpeg2enc/gstmpeg2enc.cc:
* ext/mpeg2enc/gstmpeg2enc.hh:
* ext/mpeg2enc/gstmpeg2encoder.cc:
* ext/mpeg2enc/gstmpeg2encoptions.cc:
* ext/mpeg2enc/gstmpeg2encpicturereader.cc:
* ext/mpeg2enc/gstmpeg2encpicturereader.hh:
* ext/mpeg2enc/gstmpeg2encstreamwriter.cc:
* ext/mpeg2enc/gstmpeg2encstreamwriter.hh:
Streamline conditional code for evolving mjpegtools API,
optimize and fix/prevent crash in log handling, use
names/nicks for enums in the usual way andm inor updates
in code and properties/settings. Partially fixes bug #520329.
2008-03-04 Zaheer Abbas Merali <zaheerabbas at merali dot org> 2008-03-04 Zaheer Abbas Merali <zaheerabbas at merali dot org>
* gst/mpegtsparse/gstmpegdesc.h: * gst/mpegtsparse/gstmpegdesc.h:

View file

@ -608,18 +608,34 @@ AC_SUBST(LIBMMS_LIBS)
dnl *** mjpegtools version info *** dnl *** mjpegtools version info ***
dnl some may prefer older version (given quirks above) dnl some may prefer older version (given quirks above)
dnl hm, no version info seems available within mjpegtools headers dnl hm, no version info seems available within mjpegtools headers
dnl and API really moves along
PKG_CHECK_EXISTS(mjpegtools >= 1.9.0 mjpegtools < 1.10.0, [ echo
AC_DEFINE(GST_MJPEGTOOLS_19x, 1, [mjpegtools >= 1.9.0 is used]) PKG_CHECK_EXISTS(mjpegtools >= 1.6.1.93 mjpegtools < 1.8.0, [
have_mpjegtools_19x=yes mjpegtools_api=10601
], [
PKG_CHECK_EXISTS(mjpegtools >= 1.8.0 mjpegtools < 1.9.0, [
mjpegtools_api=10800
], [ ], [
have_mpjegtools_19x=no]) PKG_CHECK_MODULES(MJPEG, mjpegtools >= 1.9.0, [
dnl logging API changed in release candidates
PKG_CHECK_EXISTS(mjpegtools >= 1.8.0, [ OLD_CFLAGS="$CFLAGS"
AC_DEFINE(GST_MJPEGTOOLS_18x, 1, [mjpegtools >= 1.8.0 is used]) OLD_LIBS="$LIBS"
have_mpjegtools_18x=yes CFLAGS="$MJPEG_CFLAGS"
], [ LIBS="$LIBS $MJPEG_LIBS -lmjpegutils -lm -lpthread"
have_mpjegtools_18x=no]) AC_CHECK_FUNC(mjpeg_loglev_t, [
mjpegtools_api=10903
], [
mjpegtools_api=10900
])
CFLAGS="$OLD_CFLAGS"
LIBS="$OLD_LIBS"
], [
mjpegtools_api=0
])
])
])
AC_DEFINE_UNQUOTED(GST_MJPEGTOOLS_API, $mjpegtools_api,
[mjpegtools API evolution])
dnl *** mpeg2enc *** dnl *** mpeg2enc ***
translit(dnm, m, l) AM_CONDITIONAL(USE_MPEG2ENC, true) translit(dnm, m, l) AM_CONDITIONAL(USE_MPEG2ENC, true)
@ -665,21 +681,15 @@ AG_GST_CHECK_FEATURE(MPEG2ENC, [mpeg2enc], mpeg2enc, [
dnl mpeg2syntaxcodes.h header by default, and a new release dnl mpeg2syntaxcodes.h header by default, and a new release
dnl is not in sight, so check for this oversight in case dnl is not in sight, so check for this oversight in case
dnl distros or folks have fixed this themselves dnl distros or folks have fixed this themselves
if test "x$have_mpjegtools_18x" = "xyes"; then if test "$mjpegtools_api" -ge "10800"; then
AC_CHECK_HEADER([mpeg2syntaxcodes.h], [ AC_CHECK_HEADER([mpeg2syntaxcodes.h], [
mpeg2enc_headers_ok=yes mpeg2enc_headers_ok=yes
], [ ], [
mpeg2enc_headers_ok=no mpeg2enc_headers_ok=no
]) ])
else else
mpeg2enc_headers_ok=yes mpeg2enc_headers_ok=yes
fi fi
if test "x$have_mpjegtools_19x" = "xyes"; then
AG_GST_CHECK_LIBHEADER(MJPEGTOOLS_19rc3, mpeg2encpp, mjpeg_loglev_t, $MPEG2ENC_LIBS, mjpeg_logging.h,
AC_DEFINE(GST_MJPEGTOOLS_19rc3, 1, [mjpegtools >= 1.9.3rc3 is used]))
fi
if test "x$mpeg2enc_headers_ok" = "xyes"; then if test "x$mpeg2enc_headers_ok" = "xyes"; then
HAVE_MPEG2ENC="yes" HAVE_MPEG2ENC="yes"
fi fi

View file

@ -90,6 +90,7 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
"mpegversion = (int) { 1, 2 }, " COMMON_VIDEO_CAPS) "mpegversion = (int) { 1, 2 }, " COMMON_VIDEO_CAPS)
); );
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 (GstPad * pad, GstCaps * caps);
@ -158,6 +159,7 @@ gst_mpeg2enc_finalize (GObject * object)
g_mutex_free (enc->tlock); g_mutex_free (enc->tlock);
g_cond_free (enc->cond); g_cond_free (enc->cond);
g_queue_free (enc->time);
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
@ -195,6 +197,7 @@ gst_mpeg2enc_init (GstMpeg2enc * enc, GstMpeg2encClass * g_class)
enc->buffer = NULL; enc->buffer = NULL;
enc->tlock = g_mutex_new (); enc->tlock = g_mutex_new ();
enc->cond = g_cond_new (); enc->cond = g_cond_new ();
enc->time = g_queue_new ();
gst_mpeg2enc_reset (enc); gst_mpeg2enc_reset (enc);
} }
@ -202,6 +205,8 @@ gst_mpeg2enc_init (GstMpeg2enc * enc, GstMpeg2encClass * g_class)
static void static void
gst_mpeg2enc_reset (GstMpeg2enc * enc) gst_mpeg2enc_reset (GstMpeg2enc * enc)
{ {
GstBuffer *buf;
enc->eos = FALSE; enc->eos = FALSE;
enc->srcresult = GST_FLOW_OK; enc->srcresult = GST_FLOW_OK;
@ -209,6 +214,8 @@ gst_mpeg2enc_reset (GstMpeg2enc * enc)
if (enc->buffer) if (enc->buffer)
gst_buffer_unref (enc->buffer); gst_buffer_unref (enc->buffer);
enc->buffer = NULL; enc->buffer = NULL;
while ((buf = (GstBuffer *) g_queue_pop_head (enc->time)))
gst_buffer_unref (buf);
if (enc->encoder) { if (enc->encoder) {
delete enc->encoder; delete enc->encoder;
@ -548,6 +555,7 @@ gst_mpeg2enc_chain (GstPad * pad, GstBuffer * buffer)
while (enc->buffer) while (enc->buffer)
GST_MPEG2ENC_WAIT (enc); GST_MPEG2ENC_WAIT (enc);
enc->buffer = buffer; enc->buffer = buffer;
g_queue_push_tail (enc->time, gst_buffer_ref (buffer));
GST_MPEG2ENC_SIGNAL (enc); GST_MPEG2ENC_SIGNAL (enc);
GST_MPEG2ENC_MUTEX_UNLOCK (enc); GST_MPEG2ENC_MUTEX_UNLOCK (enc);
@ -573,13 +581,15 @@ eos:
} }
ignore: ignore:
{ {
GstFlowReturn ret = enc->srcresult;
GST_DEBUG_OBJECT (enc, GST_DEBUG_OBJECT (enc,
"ignoring buffer because encoding task encountered %s", "ignoring buffer because encoding task encountered %s",
gst_flow_get_name (enc->srcresult)); gst_flow_get_name (enc->srcresult));
GST_MPEG2ENC_MUTEX_UNLOCK (enc); GST_MPEG2ENC_MUTEX_UNLOCK (enc);
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
return enc->srcresult; return ret;
} }
} }
@ -649,44 +659,37 @@ done:
static mjpeg_log_handler_t old_handler = NULL; static mjpeg_log_handler_t old_handler = NULL;
/* note that this will affect all mjpegtools elements/threads */ /* note that this will affect all mjpegtools elements/threads */
static void static void
gst_mpeg2enc_log_callback (log_level_t level, const char *message) gst_mpeg2enc_log_callback (log_level_t level, const char *message)
{ {
GstDebugLevel gst_level; GstDebugLevel gst_level;
#ifndef GST_MJPEGTOOLS_19rc3 #if GST_MJPEGTOOLS_API >= 10903
switch (level) { static const gint mjpeg_log_error = mjpeg_loglev_t ("error");
case LOG_NONE: static const gint mjpeg_log_warn = mjpeg_loglev_t ("warn");
gst_level = GST_LEVEL_NONE; static const gint mjpeg_log_info = mjpeg_loglev_t ("info");
break; static const gint mjpeg_log_debug = mjpeg_loglev_t ("debug");
case LOG_ERROR:
gst_level = GST_LEVEL_ERROR;
break;
case LOG_INFO:
gst_level = GST_LEVEL_INFO;
break;
case LOG_DEBUG:
gst_level = GST_LEVEL_DEBUG;
break;
default:
gst_level = GST_LEVEL_INFO;
break;
}
#else #else
if (level == mjpeg_loglev_t ("debug")) static const gint mjpeg_log_error = LOG_ERROR;
gst_level = GST_LEVEL_DEBUG; static const gint mjpeg_log_warn = LOG_WARN;
else if (level == mjpeg_loglev_t ("info")) static const gint mjpeg_log_info = LOG_INFO;
gst_level = GST_LEVEL_INFO; static const gint mjpeg_log_debug = LOG_DEBUG;
else if (level == mjpeg_loglev_t ("warn"))
gst_level = GST_LEVEL_WARNING;
else if (level == mjpeg_loglev_t ("error"))
gst_level = GST_LEVEL_ERROR;
else
gst_level = GST_LEVEL_INFO;
#endif #endif
gst_debug_log (mpeg2enc_debug, gst_level, "", "", 0, NULL, message); if (level == mjpeg_log_error) {
gst_level = GST_LEVEL_ERROR;
} else if (level == mjpeg_log_warn) {
gst_level = GST_LEVEL_WARNING;
} else if (level == mjpeg_log_info) {
gst_level = GST_LEVEL_INFO;
} else if (level == mjpeg_log_debug) {
gst_level = GST_LEVEL_DEBUG;
} else {
gst_level = GST_LEVEL_INFO;
}
/* message could have a % in it, do not segfault in such case */
gst_debug_log (mpeg2enc_debug, gst_level, "", "", 0, NULL, "%s", message);
/* chain up to the old handler; /* chain up to the old handler;
* this could actually be a handler from another mjpegtools based * this could actually be a handler from another mjpegtools based

View file

@ -88,6 +88,8 @@ typedef struct _GstMpeg2enc {
GstFlowReturn srcresult; GstFlowReturn srcresult;
/* buffer for encoding task */ /* buffer for encoding task */
GstBuffer *buffer; GstBuffer *buffer;
/* timestamps for output */
GQueue *time;
} GstMpeg2enc; } GstMpeg2enc;

View file

@ -26,8 +26,10 @@
#include <mpegconsts.h> #include <mpegconsts.h>
#include <quantize.hh> #include <quantize.hh>
#ifdef GST_MJPEGTOOLS_19x #if GST_MJPEGTOOLS_API >= 10900
#include <ontheflyratectl.hh> #include <ontheflyratectl.hh>
#include <pass1ratectl.hh>
#include <pass2ratectl.hh>
#else #else
#include <ratectl.hh> #include <ratectl.hh>
#endif #endif
@ -57,18 +59,19 @@ GstMpeg2Encoder::~GstMpeg2Encoder ()
gst_object_unref (element); gst_object_unref (element);
} }
gboolean gboolean GstMpeg2Encoder::setup ()
GstMpeg2Encoder::setup ()
{ {
MPEG2EncInVidParams strm; MPEG2EncInVidParams
GstMpeg2enc *enc; strm;
GstMpeg2enc *
enc;
enc = GST_MPEG2ENC (element); enc = GST_MPEG2ENC (element);
/* I/O */ /* I/O */
reader = new GstMpeg2EncPictureReader (element, caps, &parms); reader = new GstMpeg2EncPictureReader (element, caps, &parms);
reader->StreamPictureParams (strm); reader->StreamPictureParams (strm);
#if defined(GST_MJPEGTOOLS_18x) && !defined(GST_MJPEGTOOLS_19x) #if GST_MJPEGTOOLS_API == 10800
/* chain thread caters for reading, do not need another thread for this */ /* chain thread caters for reading, do not need another thread for this */
options.allow_parallel_read = FALSE; options.allow_parallel_read = FALSE;
#endif #endif
@ -79,22 +82,20 @@ GstMpeg2Encoder::setup ()
/* encoding internals */ /* encoding internals */
quantizer = new Quantizer (parms); quantizer = new Quantizer (parms);
#ifdef GST_MJPEGTOOLS_19x #if GST_MJPEGTOOLS_API < 10900
bitrate_controller = new OnTheFlyRateCtl (parms);
#else
pass1ratectl = new OnTheFlyPass1 (parms); pass1ratectl = new OnTheFlyPass1 (parms);
pass2ratectl = new OnTheFlyPass2 (parms); pass2ratectl = new OnTheFlyPass2 (parms);
#else
bitrate_controller = new OnTheFlyRateCtl (parms);
#endif #endif
#if GST_MJPEGTOOLS_API >= 10900
#ifdef GST_MJPEGTOOLS_18x
/* sequencer */ /* sequencer */
# ifdef GST_MJPEGTOOLS_19x
seqencoder = new SeqEncoder (parms, *reader, *quantizer, seqencoder = new SeqEncoder (parms, *reader, *quantizer,
*writer, *pass1ratectl, *pass2ratectl); *writer, *pass1ratectl, *pass2ratectl);
# else #elif GST_MJPEGTOOLS_API >= 10800
/* sequencer */
seqencoder = new SeqEncoder (parms, *reader, *quantizer, seqencoder = new SeqEncoder (parms, *reader, *quantizer,
*writer, *bitrate_controller); *writer, *bitrate_controller);
# endif
#else #else
coder = new MPEG2Coder (parms, *writer); coder = new MPEG2Coder (parms, *writer);
/* sequencer */ /* sequencer */
@ -112,7 +113,7 @@ GstMpeg2Encoder::init ()
parms.Init (options); parms.Init (options);
reader->Init (); reader->Init ();
quantizer->Init (); quantizer->Init ();
#ifdef GST_MJPEGTOOLS_18x #if GST_MJPEGTOOLS_API >= 10800
seqencoder->Init (); seqencoder->Init ();
#endif #endif
init_done = TRUE; init_done = TRUE;
@ -127,7 +128,7 @@ void
GstMpeg2Encoder::encode () GstMpeg2Encoder::encode ()
{ {
/* hm, this is all... eek! */ /* hm, this is all... eek! */
#ifdef GST_MJPEGTOOLS_18x #if GST_MJPEGTOOLS_API >= 10800
seqencoder->EncodeStream (); seqencoder->EncodeStream ();
#else #else
seqencoder->Encode (); seqencoder->Encode ();

View file

@ -88,16 +88,16 @@ gst_mpeg2enc_format_get_type (void)
if (!mpeg2enc_format_type) { if (!mpeg2enc_format_type) {
static const GEnumValue mpeg2enc_formats[] = { static const GEnumValue mpeg2enc_formats[] = {
{0, "0", "Generic MPEG-1"}, {0, "Generic MPEG-1", "0"},
{1, "1", "Standard VCD"}, {1, "Standard VCD", "1"},
{2, "2", "User VCD"}, {2, "User VCD", "2"},
{3, "3", "Generic MPEG-2"}, {3, "Generic MPEG-2", "3"},
{4, "4", "Standard SVCD"}, {4, "Standard SVCD", "4"},
{5, "5", "User SVCD"}, {5, "User SVCD", "5"},
{6, "6", "VCD Stills sequences"}, {6, "VCD Stills sequences", "6"},
{7, "7", "SVCD Stills sequences"}, {7, "SVCD Stills sequences", "7"},
{8, "8", "DVD MPEG-2 for dvdauthor"}, {8, "DVD MPEG-2 for dvdauthor", "8"},
{9, "9", "DVD MPEG-2"}, {9, "DVD MPEG-2", "9"},
{0, NULL, NULL}, {0, NULL, NULL},
}; };
@ -118,15 +118,15 @@ gst_mpeg2enc_framerate_get_type (void)
if (!mpeg2enc_framerate_type) { if (!mpeg2enc_framerate_type) {
static const GEnumValue mpeg2enc_framerates[] = { static const GEnumValue mpeg2enc_framerates[] = {
{0, "0", "Same as input"}, {0, "Same as input", "0"},
{1, "1", "24/1.001 (NTSC 3:2 pulldown converted film)"}, {1, "24/1.001 (NTSC 3:2 pulldown converted film)", "1"},
{2, "2", "24 (native film)"}, {2, "24 (native film)", "2"},
{3, "3", "25 (PAL/SECAM video)"}, {3, "25 (PAL/SECAM video)", "3"},
{4, "4", "30/1.001 (NTSC video)"}, {4, "30/1.001 (NTSC video)", "4"},
{5, "5", "30"}, {5, "30", "5"},
{6, "6", "50 (PAL/SECAM fields)"}, {6, "50 (PAL/SECAM fields)", "6"},
{7, "7", "60/1.001 (NTSC fields)"}, {7, "60/1.001 (NTSC fields)", "7"},
{8, "8", "60"}, {8, "60", "8"},
{0, NULL, NULL}, {0, NULL, NULL},
}; };
@ -147,11 +147,11 @@ gst_mpeg2enc_aspect_get_type (void)
if (!mpeg2enc_aspect_type) { if (!mpeg2enc_aspect_type) {
static const GEnumValue mpeg2enc_aspects[] = { static const GEnumValue mpeg2enc_aspects[] = {
{0, "0", "Deduce from input"}, {0, "Deduce from input", "0"},
{1, "1", "1:1"}, {1, "1:1", "1"},
{2, "2", "4:3"}, {2, "4:3", "2"},
{3, "3", "16:9"}, {3, "16:9", "3"},
{4, "4", "2.21:1"}, {4, "2.21:1", "4"},
{0, NULL, NULL}, {0, NULL, NULL},
}; };
@ -172,10 +172,10 @@ gst_mpeg2enc_interlace_mode_get_type (void)
if (!mpeg2enc_interlace_mode_type) { if (!mpeg2enc_interlace_mode_type) {
static const GEnumValue mpeg2enc_interlace_modes[] = { static const GEnumValue mpeg2enc_interlace_modes[] = {
{-1, "-1", "Format default mode"}, {-1, "Format default mode", "-1"},
{0, "0", "Progressive"}, {0, "Progressive", "0"},
{1, "1", "Interlaced, per-frame encoding"}, {1, "Interlaced, per-frame encoding", "1"},
{2, "2", "Interlaced, per-field-encoding"}, {2, "Interlaced, per-field-encoding", "2"},
{0, NULL, NULL}, {0, NULL, NULL},
}; };
@ -203,13 +203,13 @@ gst_mpeg2enc_quantisation_matrix_get_type (void)
if (!mpeg2enc_quantisation_matrix_type) { if (!mpeg2enc_quantisation_matrix_type) {
static const GEnumValue mpeg2enc_quantisation_matrixes[] = { static const GEnumValue mpeg2enc_quantisation_matrixes[] = {
{GST_MPEG2ENC_QUANTISATION_MATRIX_DEFAULT, {GST_MPEG2ENC_QUANTISATION_MATRIX_DEFAULT,
"0", "Default"}, "Default", "9"},
{GST_MPEG2ENC_QUANTISATION_MATRIX_HI_RES, {GST_MPEG2ENC_QUANTISATION_MATRIX_HI_RES,
"1", "High resolution"}, "High resolution", "1"},
{GST_MPEG2ENC_QUANTISATION_MATRIX_KVCD, {GST_MPEG2ENC_QUANTISATION_MATRIX_KVCD,
"2", "KVCD"}, "KVCD", "2"},
{GST_MPEG2ENC_QUANTISATION_MATRIX_TMPGENC, {GST_MPEG2ENC_QUANTISATION_MATRIX_TMPGENC,
"3", "TMPGEnc"}, "TMPGEnc", "3"},
{0, NULL, NULL}, {0, NULL, NULL},
}; };
@ -231,10 +231,10 @@ gst_mpeg2enc_video_norm_get_type (void)
if (!mpeg2enc_video_norm_type) { if (!mpeg2enc_video_norm_type) {
static const GEnumValue mpeg2enc_video_norms[] = { static const GEnumValue mpeg2enc_video_norms[] = {
{0, "0", "Unspecified"}, {0, "Unspecified", "0"},
{'p', "p", "PAL"}, {'p', "PAL", "p"},
{'n', "n", "NTSC"}, {'n', "NTSC", "n"},
{'s', "s", "SECAM"}, {'s', "SECAM", "s"},
{0, NULL, NULL}, {0, NULL, NULL},
}; };
@ -255,9 +255,9 @@ gst_mpeg2enc_playback_field_order_get_type (void)
if (!mpeg2enc_playback_field_order_type) { if (!mpeg2enc_playback_field_order_type) {
static const GEnumValue mpeg2enc_playback_field_orders[] = { static const GEnumValue mpeg2enc_playback_field_orders[] = {
{Y4M_UNKNOWN, "0", "Unspecified"}, {Y4M_UNKNOWN, "Unspecified", "0"},
{Y4M_ILACE_TOP_FIRST, "1", "Top-field first"}, {Y4M_ILACE_TOP_FIRST, "Top-field first", "1"},
{Y4M_ILACE_BOTTOM_FIRST, "2", "Bottom-field first"}, {Y4M_ILACE_BOTTOM_FIRST, "Bottom-field first", "2"},
{0, NULL, NULL}, {0, NULL, NULL},
}; };
@ -322,8 +322,8 @@ GstMpeg2EncOptions::initProperties (GObjectClass * klass)
0, 10 * 1024, 0, (GParamFlags) G_PARAM_READWRITE)); 0, 10 * 1024, 0, (GParamFlags) G_PARAM_READWRITE));
g_object_class_install_property (klass, ARG_QUANTISATION, g_object_class_install_property (klass, ARG_QUANTISATION,
g_param_spec_int ("quantisation", "Quantisation", g_param_spec_int ("quantisation", "Quantisation",
"Quantisation factor (0=default, 1=best, 31=worst)", "Quantisation factor (-1=cbr, 0=default, 1=best, 31=worst)",
0, 31, 0, (GParamFlags) G_PARAM_READWRITE)); -1, 31, 0, (GParamFlags) G_PARAM_READWRITE));
/* stills options */ /* stills options */
g_object_class_install_property (klass, ARG_VCD_STILL_SIZE, g_object_class_install_property (klass, ARG_VCD_STILL_SIZE,
@ -449,7 +449,7 @@ GstMpeg2EncOptions::initProperties (GObjectClass * klass)
g_param_spec_boolean ("constraints", "Constraints", g_param_spec_boolean ("constraints", "Constraints",
"Use strict video resolution and bitrate checks", "Use strict video resolution and bitrate checks",
TRUE, (GParamFlags) G_PARAM_READWRITE)); TRUE, (GParamFlags) G_PARAM_READWRITE));
#ifdef GST_MJPEGTOOLS_18x #if GST_MJPEGTOOLS_API >= 10800
g_object_class_install_property (klass, ARG_DUALPRIME_MPEG2, g_object_class_install_property (klass, ARG_DUALPRIME_MPEG2,
g_param_spec_boolean ("dualprime", "Dual Prime Motion Estimation", g_param_spec_boolean ("dualprime", "Dual Prime Motion Estimation",
"Dual Prime Motion Estimation Mode for MPEG-2 I/P-frame only " "Dual Prime Motion Estimation Mode for MPEG-2 I/P-frame only "
@ -485,7 +485,7 @@ GstMpeg2EncOptions::getProperty (guint prop_id, GValue * value)
g_value_set_int (value, nonvid_bitrate / 1024); g_value_set_int (value, nonvid_bitrate / 1024);
break; break;
case ARG_QUANTISATION: case ARG_QUANTISATION:
g_value_set_int (value, quant); g_value_set_int (value, force_cbr ? -1 : quant);
break; break;
case ARG_VCD_STILL_SIZE: case ARG_VCD_STILL_SIZE:
g_value_set_int (value, still_size / 1024); g_value_set_int (value, still_size / 1024);
@ -578,7 +578,7 @@ GstMpeg2EncOptions::getProperty (guint prop_id, GValue * value)
case ARG_CONSTRAINTS: case ARG_CONSTRAINTS:
g_value_set_boolean (value, !ignore_constraints); g_value_set_boolean (value, !ignore_constraints);
break; break;
#ifdef GST_MJPEGTOOLS_18x #if GST_MJPEGTOOLS_API >= 10800
case ARG_DUALPRIME_MPEG2: case ARG_DUALPRIME_MPEG2:
g_value_set_boolean (value, hack_dualprime); g_value_set_boolean (value, hack_dualprime);
break; break;
@ -612,6 +612,10 @@ GstMpeg2EncOptions::setProperty (guint prop_id, const GValue * value)
break; break;
case ARG_QUANTISATION: case ARG_QUANTISATION:
quant = g_value_get_int (value); quant = g_value_get_int (value);
if (quant < 0) {
force_cbr = 1;
quant = 0;
}
break; break;
case ARG_VCD_STILL_SIZE: case ARG_VCD_STILL_SIZE:
still_size = g_value_get_int (value) * 1024; still_size = g_value_get_int (value) * 1024;
@ -707,7 +711,7 @@ GstMpeg2EncOptions::setProperty (guint prop_id, const GValue * value)
case ARG_CONSTRAINTS: case ARG_CONSTRAINTS:
ignore_constraints = !g_value_get_boolean (value); ignore_constraints = !g_value_get_boolean (value);
break; break;
#ifdef GST_MJPEGTOOLS_18x #if GST_MJPEGTOOLS_API >= 10800
case ARG_DUALPRIME_MPEG2: case ARG_DUALPRIME_MPEG2:
hack_dualprime = g_value_get_boolean (value); hack_dualprime = g_value_get_boolean (value);
break; break;

View file

@ -25,10 +25,6 @@
#include <encoderparams.hh> #include <encoderparams.hh>
#ifdef GST_MJPEGTOOLS_19x
#include <imageplanes.hh>
#endif
#include "gstmpeg2enc.hh" #include "gstmpeg2enc.hh"
#include "gstmpeg2encpicturereader.hh" #include "gstmpeg2encpicturereader.hh"
@ -107,14 +103,13 @@ GstMpeg2EncPictureReader::StreamPictureParams (MPEG2EncInVidParams & strm)
*/ */
bool bool
#ifdef GST_MJPEGTOOLS_19x #if GST_MJPEGTOOLS_API >= 10900
GstMpeg2EncPictureReader::LoadFrame (ImagePlanes & image) GstMpeg2EncPictureReader::LoadFrame (ImagePlanes & image)
#else #else
GstMpeg2EncPictureReader::LoadFrame () GstMpeg2EncPictureReader::LoadFrame ()
#endif #endif
{ {
#if GST_MJPEGTOOLS_API < 10900
#ifndef GST_MJPEGTOOLS_19x
gint n; gint n;
#endif #endif
gint i, x, y; gint i, x, y;
@ -136,27 +131,27 @@ bool
} }
frame = GST_BUFFER_DATA (enc->buffer); frame = GST_BUFFER_DATA (enc->buffer);
#ifndef GST_MJPEGTOOLS_19x #if GST_MJPEGTOOLS_API < 10900
n = frames_read % input_imgs_buf_size; n = frames_read % input_imgs_buf_size;
#endif #endif
x = encparams.horizontal_size; x = encparams.horizontal_size;
y = encparams.vertical_size; y = encparams.vertical_size;
for (i = 0; i < y; i++) { for (i = 0; i < y; i++) {
#ifdef GST_MJPEGTOOLS_19x #if GST_MJPEGTOOLS_API >= 10900
memcpy (image.Plane (0) + i * encparams.phy_width, frame, x); memcpy (image.Plane (0) + i * encparams.phy_width, frame, x);
#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 += x;
} }
#ifndef GST_MJPEGTOOLS_19x #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
x >>= 1; x >>= 1;
y >>= 1; y >>= 1;
for (i = 0; i < y; i++) { for (i = 0; i < y; i++) {
#ifdef GST_MJPEGTOOLS_19x #if GST_MJPEGTOOLS_API >= 10900
memcpy (image.Plane (1) + i * encparams.phy_chrom_width, frame, x); memcpy (image.Plane (1) + i * encparams.phy_chrom_width, frame, x);
#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);
@ -164,7 +159,7 @@ bool
frame += x; frame += x;
} }
for (i = 0; i < y; i++) { for (i = 0; i < y; i++) {
#ifdef GST_MJPEGTOOLS_19x #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);

View file

@ -25,6 +25,10 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <picturereader.hh> #include <picturereader.hh>
#if GST_MJPEGTOOLS_API >= 10900
#include <imageplanes.hh>
#endif
class GstMpeg2EncPictureReader : public PictureReader { class GstMpeg2EncPictureReader : public PictureReader {
public: public:
@ -37,7 +41,7 @@ public:
protected: protected:
/* read a frame */ /* read a frame */
#ifdef GST_MJPEGTOOLS_19x #if GST_MJPEGTOOLS_API >= 10900
bool LoadFrame (ImagePlanes &image); bool LoadFrame (ImagePlanes &image);
#else #else
bool LoadFrame (); bool LoadFrame ();

View file

@ -28,7 +28,7 @@
#include "gstmpeg2encstreamwriter.hh" #include "gstmpeg2encstreamwriter.hh"
#include <string.h> #include <string.h>
#ifdef GST_MJPEGTOOLS_18x #if GST_MJPEGTOOLS_API >= 10800
/* /*
* Class init stuff. * Class init stuff.
@ -51,7 +51,7 @@ void
GstMpeg2EncStreamWriter::WriteOutBufferUpto (const guint8 * buffer, GstMpeg2EncStreamWriter::WriteOutBufferUpto (const guint8 * buffer,
const guint32 flush_upto) const guint32 flush_upto)
{ {
GstBuffer *buf; GstBuffer *buf, *inbuf;
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);
@ -62,12 +62,21 @@ GstMpeg2EncStreamWriter::WriteOutBufferUpto (const guint8 * buffer,
/* 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,
* it's ok as mpeg2enc is not really a loop-based element, but push-based */ * it's ok as mpeg2enc is not really a loop-based element, but push-based */
GST_MPEG2ENC_MUTEX_LOCK (enc); GST_MPEG2ENC_MUTEX_LOCK (enc);
/* best effort at giving output some meaningful time metadata
* no mpeg2enc specs on this though, but it might help getting the output
* into container formats that really do like timestamps (unlike mplex) */
if ((inbuf = (GstBuffer *) g_queue_pop_head (enc->time))) {
GST_BUFFER_TIMESTAMP (buf) = GST_BUFFER_TIMESTAMP (inbuf);
GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (inbuf);
gst_buffer_unref (inbuf);
}
gst_buffer_set_caps (buf, GST_PAD_CAPS (pad)); 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);
} }
guint64 GstMpeg2EncStreamWriter::BitCount () guint64
GstMpeg2EncStreamWriter::BitCount ()
{ {
return flushed * 8ll; return flushed * 8ll;
} }
@ -157,4 +166,4 @@ void
GstMpeg2EncStreamWriter::FrameDiscard () GstMpeg2EncStreamWriter::FrameDiscard ()
{ {
} }
#endif /* GST_MJPEGTOOLS_18x */ #endif /* GST_MJPEGTOOLS_API >= 10800 */

View file

@ -27,7 +27,7 @@
#include <elemstrmwriter.hh> #include <elemstrmwriter.hh>
#ifdef GST_MJPEGTOOLS_18x #if GST_MJPEGTOOLS_API >= 10800
class GstMpeg2EncStreamWriter : public ElemStrmWriter { class GstMpeg2EncStreamWriter : public ElemStrmWriter {
public: public:
@ -61,6 +61,6 @@ private:
GstPad *pad; GstPad *pad;
GstBuffer *buf; GstBuffer *buf;
}; };
#endif /* GST_MJPEGTOOLS_18x */ #endif /* GST_MJPEGTOOLS_API >= 10800 */
#endif /* __GST_MPEG2ENCSTREAMWRITER_H__ */ #endif /* __GST_MPEG2ENCSTREAMWRITER_H__ */