summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.net>2013-01-23 10:16:51 +0000
committerTim-Philipp Müller <tim.muller@collabora.co.uk>2013-02-07 13:37:44 +0000
commite765deb01b781354cac2cbaf930cbea5e7d9d9f1 (patch)
treea996aebb1e9042b2d7fb6307a15cccfc4722727b
parent7ffb57d8a1a2c662de85b7d127638a9827f147ed (diff)
x264enc: detect supported bit depth and pixel formats at runtime
http://bugs.debian.org/667573 https://bugzilla.gnome.org/show_bug.cgi?id=691935
-rw-r--r--ext/x264/gstx264enc.c154
1 files changed, 100 insertions, 54 deletions
diff --git a/ext/x264/gstx264enc.c b/ext/x264/gstx264enc.c
index f657d840..b32aaa00 100644
--- a/ext/x264/gstx264enc.c
+++ b/ext/x264/gstx264enc.c
@@ -389,57 +389,6 @@ gst_x264_enc_build_tunings_string (GstX264Enc * x264enc)
x264enc->tunings->str);
}
-#if X264_BIT_DEPTH == 8
-# if X264_CHROMA_FORMAT == 0
-# define COLOR_FORMATS "I420, YV12, Y42B, Y444, NV12"
-# elif X264_CHROMA_FORMAT == X264_CSP_I420
-# define COLOR_FORMATS "I420, YV12, NV12"
-# elif X264_CHROMA_FORMAT == X264_CSP_I422
-# define COLOR_FORMATS "Y42B"
-# elif X264_CHROMA_FORMAT == X264_CSP_I444
-# define COLOR_FORMATS "Y444"
-# else
-# error "Unsupported chroma format"
-# endif
-#elif X264_BIT_DEPTH == 10
-# if G_BYTE_ORDER == G_LITTLE_ENDIAN
-# if X264_CHROMA_FORMAT == 0
-# define COLOR_FORMATS "I420_10LE, I422_10LE, Y444_10LE"
-# elif X264_CHROMA_FORMAT == X264_CSP_I420
-# define COLOR_FORMATS "I420_10LE"
-# elif X264_CHROMA_FORMAT == X264_CSP_I422
-# define COLOR_FORMATS "I422_10LE"
-# elif X264_CHROMA_FORMAT == X264_CSP_I444
-# define COLOR_FORMATS "Y444_10LE"
-# else
-# error "Unsupported chroma format"
-# endif
-# else
-# if X264_CHROMA_FORMAT == 0
-# define COLOR_FORMATS "I420_10BE, I422_10BE, Y444_10BE"
-# elif X264_CHROMA_FORMAT == X264_CSP_I420
-# define COLOR_FORMATS "I420_10BE"
-# elif X264_CHROMA_FORMAT == X264_CSP_I422
-# define COLOR_FORMATS "I422_10BE"
-# elif X264_CHROMA_FORMAT == X264_CSP_I444
-# define COLOR_FORMATS "Y444_10BE"
-# else
-# error "Unsupported chroma format"
-# endif
-# endif
-#else
-# error "Only 8-bit and 10-bit supported"
-#endif
-
-static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw, "
- "format = (string) { " COLOR_FORMATS " }, "
- "framerate = (fraction) [0, MAX], "
- "width = (int) [ 16, MAX ], " "height = (int) [ 16, MAX ]")
- );
-
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
@@ -505,12 +454,108 @@ gst_x264_enc_build_partitions (gint analyse)
}
static void
+set_value (GValue * val, gint count, ...)
+{
+ const gchar *fmt = NULL;
+ GValue sval = G_VALUE_INIT;
+ va_list ap;
+ gint i;
+
+ g_value_init (&sval, G_TYPE_STRING);
+
+ if (count > 1)
+ g_value_init (val, GST_TYPE_LIST);
+
+ va_start (ap, count);
+ for (i = 0; i < count; i++) {
+ fmt = va_arg (ap, const gchar *);
+ g_value_set_string (&sval, fmt);
+ if (count > 1) {
+ gst_value_list_append_value (val, &sval);
+ }
+ }
+ va_end (ap);
+
+ if (count == 1)
+ *val = sval;
+ else
+ g_value_unset (&sval);
+}
+
+static GstCaps *
+gst_x264_enc_get_supported_input_caps (void)
+{
+ GValue fmt = G_VALUE_INIT;
+ GstCaps *caps;
+
+ caps = gst_caps_new_empty_simple ("video/x-raw");
+
+ if (x264_bit_depth == 8) {
+ GST_INFO ("This x264 build supports 8-bit depth");
+ if (x264_chroma_format == 0) {
+ set_value (&fmt, 5, "I420", "YV12", "Y42B", "Y444", "NV12");
+ } else if (x264_chroma_format == X264_CSP_I420) {
+ set_value (&fmt, 3, "I420", "YV12", "NV12");
+ } else if (x264_chroma_format == X264_CSP_I422) {
+ set_value (&fmt, 1, "Y42B");
+ } else if (x264_chroma_format == X264_CSP_I444) {
+ set_value (&fmt, 1, "Y444");
+ } else {
+ GST_ERROR ("Unsupported chroma format %d", x264_chroma_format);
+ }
+ } else if (x264_bit_depth == 10) {
+ GST_INFO ("This x264 build supports 10-bit depth");
+
+ if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
+ if (x264_chroma_format == 0) {
+ set_value (&fmt, 3, "I420_10LE", "I422_10LE", "Y444_10LE");
+ } else if (x264_chroma_format == X264_CSP_I420) {
+ set_value (&fmt, 1, "I420_10LE");
+ } else if (x264_chroma_format == X264_CSP_I422) {
+ set_value (&fmt, 1, "Y422_10LE");
+ } else if (x264_chroma_format == X264_CSP_I444) {
+ set_value (&fmt, 1, "Y444_10LE");
+ } else {
+ GST_ERROR ("Unsupported chroma format %d", x264_chroma_format);
+ }
+ } else {
+ if (x264_chroma_format == 0) {
+ set_value (&fmt, 3, "I420_10BE", "I422_10BE", "Y444_10BE");
+ } else if (x264_chroma_format == X264_CSP_I420) {
+ set_value (&fmt, 1, "I420_10BE");
+ } else if (x264_chroma_format == X264_CSP_I422) {
+ set_value (&fmt, 1, "Y422_10BE");
+ } else if (x264_chroma_format == X264_CSP_I444) {
+ set_value (&fmt, 1, "Y444_10BE");
+ } else {
+ GST_ERROR ("Unsupported chroma format %d", x264_chroma_format);
+ }
+ }
+ } else {
+ GST_ERROR ("Unsupported bit depth %d, we only support 8-bit and 10-bit",
+ x264_bit_depth);
+ }
+
+ if (G_VALUE_TYPE (&fmt) != G_TYPE_INVALID)
+ gst_structure_take_value (gst_caps_get_structure (caps, 0), "format", &fmt);
+
+ gst_caps_set_simple (caps,
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
+ "width", GST_TYPE_INT_RANGE, 16, G_MAXINT,
+ "height", GST_TYPE_INT_RANGE, 16, G_MAXINT, NULL);
+
+ return caps;
+}
+
+static void
gst_x264_enc_class_init (GstX264EncClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *element_class;
GstVideoEncoderClass *gstencoder_class;
+ GstPadTemplate *tmpl;
const gchar *partitions = NULL;
+ GstCaps *caps;
x264enc_defaults = g_string_new ("");
@@ -764,10 +809,11 @@ gst_x264_enc_class_init (GstX264EncClass * klass)
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_factory));
-
+ caps = gst_x264_enc_get_supported_input_caps ();
+ tmpl = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps);
+ gst_element_class_add_pad_template (element_class, tmpl);
+ gst_caps_unref (caps);
}
static void