divxdec and divxenc ported to 0.10
authorEdgard Lima <edgard.lima@indt.org.br>
Mon, 19 Dec 2005 14:40:22 +0000 (14:40 +0000)
committerEdgard Lima <edgard.lima@indt.org.br>
Mon, 19 Dec 2005 14:40:22 +0000 (14:40 +0000)
Original commit message from CVS:
divxdec and divxenc ported to 0.10

ChangeLog
configure.ac
ext/Makefile.am
ext/divx/Makefile.am
ext/divx/gstdivxdec.c
ext/divx/gstdivxdec.h
ext/divx/gstdivxenc.c
ext/divx/gstdivxenc.h

index 09cdb8817d434c737b7243f70f1b3366fad4bc6c..26e265621dd7343c8b066facb855ac194eb08272 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2005-12-19  Edgard Lima <edgard.lima@indt.org.br>
+
+       * configure.ac:
+       * ext/Makefile.am:
+       * ext/divx/Makefile.am:
+       * ext/divx/gstdivxdec.c:
+       * ext/divx/gstdivxdec.h:
+       * ext/divx/gstdivxenc.c:
+       * ext/divx/gstdivxenc.h:
+       divxdec and divxenc ported to 0.10
+       
 2005-12-18  Julien MOUTTE  <julien@moutte.net>
 
        * docs/plugins/gst-plugins-bad-plugins-decl.txt:
index 492bedd4ffdb2c3d18bfeca4cc1ac3617ab64558..631d5cf9a259ac80241b4cd230c7e1760b330222 100644 (file)
@@ -399,6 +399,64 @@ GST_CHECK_FEATURE(DTS, [dts library], dtsdec, [
   AC_SUBST(DTS_LIBS)
 ])
 
+dnl *** DIVX ***
+translit(dnm, m, l) AM_CONDITIONAL(USE_DIVX, true)
+GST_CHECK_FEATURE(DIVX, [divx plugins], divx, [
+  HAVE_DIVX=yes
+  AC_CHECK_HEADER(encore2.h, ,
+                  [ AC_MSG_WARN([Divx4linux encore headers not found]) &&
+                    HAVE_DIVX=no ] )
+  if [ test x$HAVE_DIVX = xyes ]; then
+    AC_MSG_CHECKING([Checking for valid divx4linux encore version])
+    AC_TRY_COMPILE([
+#include <encore2.h>
+#if ENCORE_VERSION != 20021024
+#error Wrong version of divx encore libraries
+#endif
+    ], [
+return 0;
+    ], [ HAVE_DIVX=yes && AC_MSG_RESULT(yes)],
+       [ HAVE_DIVX=no  && AC_MSG_RESULT(no) &&
+         AC_MSG_WARN([Wrong version of divx4linux installed]) ])
+  fi
+  if [ test x$HAVE_DIVX = xyes ]; then
+    AC_CHECK_HEADER(decore.h, ,
+                    [ AC_MSG_WARN([Divx4linux decoder headers not found]) &&
+                      HAVE_DIVX=no ] )
+  fi
+  if [ test x$HAVE_DIVX = xyes ]; then
+    AC_MSG_CHECKING([Checking for valid divx4linux decore version])
+    AC_TRY_COMPILE([
+#include <decore.h>
+#if DECORE_VERSION != 20021112
+#error Wrong version of divx decore libraries
+#endif
+    ], [
+return 0;
+    ], [ HAVE_DIVX=yes && AC_MSG_RESULT(yes)],
+       [ HAVE_DIVX=no  && AC_MSG_RESULT(no) &&
+         AC_MSG_WARN([Wrong version of divx4linux installed]) ])
+  fi
+  LIBS="-lm"
+  if test x$HAVE_DIVX = xyes; then
+    AC_CHECK_LIB(divxencore, encore, ,
+                 [ AC_MSG_WARN([Divx4linux encore libs not found]) &&
+                   HAVE_DIVX=no ] )
+  fi
+  if test x$HAVE_DIVX = xyes; then
+    AC_CHECK_LIB(divxdecore, decore, ,
+                 [ AC_MSG_WARN([Divx4linux decore libs not found]) &&
+                   HAVE_DIVX=no ] )
+  fi
+  if test x$HAVE_DIVX = xyes; then
+    DIVXENC_LIBS="-ldivxencore -lm"
+    DIVXDEC_LIBS="-ldivxdecore -lm"
+    AC_SUBST(DIVXENC_LIBS)
+    AC_SUBST(DIVXDEC_LIBS)
+  fi
+])
+
+
 dnl *** musepack ***
 translit(dnm, m, l) AM_CONDITIONAL(USE_MUSEPACK, true)
 GST_CHECK_FEATURE(MUSEPACK, [musepackdec], musepack, [
@@ -579,6 +637,7 @@ ext/ivorbis/Makefile
 ext/gsm/Makefile
 ext/libmms/Makefile
 ext/dts/Makefile
+ext/divx/Makefile
 ext/musepack/Makefile
 ext/sdl/Makefile
 ext/xvid/Makefile
index 58c96f38b06570580365cb796e918fecc5102bd0..c1f06a9b659db32e9b1fe086712b8b8e9d59d5d3 100644 (file)
@@ -40,11 +40,11 @@ else
 DIRECTFB_DIR=
 endif
 
-#if USE_DIVX
-#DIVX_DIR=divx
-#else
+if USE_DIVX
+DIVX_DIR=divx
+else
 DIVX_DIR=
-#endif
+endif
 
 if USE_DTS
 DTS_DIR=dts
@@ -239,6 +239,7 @@ DIST_SUBDIRS= \
        ivorbis \
        libmms \
        dts \
+       divx \
        musepack \
        sdl \
        swfdec \
index e5323e11ac039de7c164f837565a35d9649909e5..8eee5b86b2f65a799aeb28b517328b0e39990e7b 100644 (file)
@@ -1,14 +1,15 @@
 
-plugin_LTLIBRARIES = libgstdivxenc.la libgstdivxdec.la
+plugin_LTLIBRARIES = libgstdivxdec.la 
 
+plugin_LTLIBRARIES = libgstdivxenc.la
 libgstdivxenc_la_SOURCES = gstdivxenc.c
-libgstdivxenc_la_CFLAGS = $(GST_CFLAGS) $(DIVX_CFLAGS)
-libgstdivxenc_la_LIBADD = $(DIVXENC_LIBS)
+libgstdivxenc_la_CFLAGS = $(GST_CFLAGS) $(DIVX_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
+libgstdivxenc_la_LIBADD = $(DIVXENC_LIBS) $(GST_PLUGINS_BASE_LIBS)
 libgstdivxenc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
 libgstdivxdec_la_SOURCES = gstdivxdec.c
-libgstdivxdec_la_CFLAGS = $(GST_CFLAGS) $(DIVX_CFLAGS)
-libgstdivxdec_la_LIBADD = $(DIVXDEC_LIBS)
+libgstdivxdec_la_CFLAGS = $(GST_CFLAGS) $(DIVX_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
+libgstdivxdec_la_LIBADD = $(DIVXDEC_LIBS) $(GST_PLUGINS_BASE_LIBS)
 libgstdivxdec_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
 noinst_HEADERS = gstdivxenc.h gstdivxdec.h
index 543bff3f9bd5cadb8eda3b535d91b4f19708d035..29b838e2180bed299ce3e42f3160dbf6f3ead2ff 100644 (file)
@@ -39,7 +39,7 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_STATIC_CAPS ("video/x-divx, "
         "divxversion = (int) [ 3, 5 ], "
         "width = (int) [ 16, 4096 ], "
-        "height = (int) [ 16, 4096 ], " "framerate = (double) [ 0, MAX ]")
+        "height = (int) [ 16, 4096 ], " "framerate = (fraction) [0/1, MAX]")
     );
 
 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
@@ -69,11 +69,11 @@ static void gst_divxdec_base_init (GstDivxDecClass * klass);
 static void gst_divxdec_class_init (GstDivxDecClass * klass);
 static void gst_divxdec_init (GstDivxDec * divxdec);
 static void gst_divxdec_dispose (GObject * object);
-static void gst_divxdec_chain (GstPad * pad, GstData * data);
-static GstPadLinkReturn gst_divxdec_connect (GstPad * pad,
-    const GstCaps * vscapslist);
-static GstPadLinkReturn gst_divxdec_negotiate (GstDivxDec * divxdec);
-
+static GstFlowReturn gst_divxdec_chain (GstPad * pad, GstBuffer * buf);
+static gboolean gst_divxdec_connect (GstPad * pad, GstCaps * vscapslist);
+static gboolean gst_divxdec_negotiate (GstDivxDec * divxdec);
+static GstStateChangeReturn
+gst_divxdec_change_state (GstElement * element, GstStateChange transition);
 static GstElementClass *parent_class = NULL;
 
 /* static guint gst_divxdec_signals[LAST_SIGNAL] = { 0 }; */
@@ -150,10 +150,12 @@ gst_divxdec_base_init (GstDivxDecClass * klass)
 static void
 gst_divxdec_class_init (GstDivxDecClass * klass)
 {
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
   GObjectClass *gobject_class = (GObjectClass *) klass;
 
   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
 
+  gstelement_class->change_state = gst_divxdec_change_state;
   gobject_class->dispose = gst_divxdec_dispose;
 }
 
@@ -167,14 +169,14 @@ gst_divxdec_init (GstDivxDec * divxdec)
       "sink");
   gst_element_add_pad (GST_ELEMENT (divxdec), divxdec->sinkpad);
   gst_pad_set_chain_function (divxdec->sinkpad, gst_divxdec_chain);
-  gst_pad_set_link_function (divxdec->sinkpad, gst_divxdec_connect);
+  gst_pad_set_setcaps_function (divxdec->sinkpad, gst_divxdec_connect);
 
   /* create the src pad */
   divxdec->srcpad =
       gst_pad_new_from_template (gst_static_pad_template_get (&src_template),
       "src");
   gst_element_add_pad (GST_ELEMENT (divxdec), divxdec->srcpad);
-  gst_pad_use_explicit_caps (divxdec->srcpad);
+  gst_pad_use_fixed_caps (divxdec->srcpad);
 
   /* bitrate, etc. */
   divxdec->width = divxdec->height = divxdec->csp = divxdec->bitcnt = -1;
@@ -244,11 +246,9 @@ gst_divxdec_setup (GstDivxDec * divxdec)
     gst_divxdec_unset (divxdec);
     return FALSE;
   }
-
   return TRUE;
 }
 
-
 static void
 gst_divxdec_dispose (GObject * object)
 {
@@ -258,28 +258,19 @@ gst_divxdec_dispose (GObject * object)
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
-
-static void
-gst_divxdec_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_divxdec_chain (GstPad * pad, GstBuffer * buf)
 {
-  GstBuffer *buf = GST_BUFFER (_data);
   GstDivxDec *divxdec;
   GstBuffer *outbuf;
   DEC_FRAME xframe;
-  int ret;
-
-  g_return_if_fail (pad != NULL);
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (buf != NULL);
-
-  divxdec = GST_DIVXDEC (GST_OBJECT_PARENT (pad));
+  int res;
+  GstFlowReturn ret;
 
+  divxdec = GST_DIVXDEC (gst_pad_get_parent (pad));
   if (!divxdec->handle) {
     if (gst_divxdec_negotiate (divxdec) <= 0) {
-      GST_ELEMENT_ERROR (divxdec, CORE, TOO_LAZY, (NULL),
-          ("No format set - aborting"));
-      gst_buffer_unref (buf);
-      return;
+      goto not_negotiated;
     }
   }
 
@@ -296,15 +287,37 @@ gst_divxdec_chain (GstPad * pad, GstData * _data)
   xframe.stride = 0;
   xframe.render_flag = 1;
 
-  if ((ret = decore (divxdec->handle, DEC_OPT_FRAME, &xframe, NULL))) {
+  if ((res = decore (divxdec->handle, DEC_OPT_FRAME, &xframe, NULL))) {
+    goto not_decoding;
+  }
+
+  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (divxdec->srcpad));
+  ret = gst_pad_push (divxdec->srcpad, outbuf);
+  goto cleanup;
+
+not_negotiated:
+  {
+    GST_ELEMENT_ERROR (divxdec, CORE, TOO_LAZY, (NULL),
+        ("No format set - aborting"));
+    ret = GST_FLOW_NOT_NEGOTIATED;
+    goto cleanup;
+  }
+
+not_decoding:
+  {
     GST_ELEMENT_ERROR (divxdec, STREAM, DECODE, (NULL),
-        ("Error decoding divx frame: %s (%d)", gst_divxdec_error (ret), ret));
-    gst_buffer_unref (buf);
-    return;
+        ("Error decoding divx frame: %s (%d)", gst_divxdec_error (res), res));
+    gst_buffer_unref (outbuf);
+    ret = GST_FLOW_ERROR;
+    goto cleanup;
   }
 
-  gst_pad_push (divxdec->srcpad, GST_DATA (outbuf));
+cleanup:
+
   gst_buffer_unref (buf);
+  gst_object_unref (divxdec);
+  return ret;
+
 }
 
 
@@ -312,85 +325,89 @@ gst_divxdec_chain (GstPad * pad, GstData * _data)
  * stays clear */
 
 /*
-{
+  {
   GST_MAKE_FOURCC ('R', 'G', 'B', ' '), 32, 32,
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
-GST_MAKE_FOURCC ('A', 'B', 'G', 'R'), 32}
+  #if (G_BYTE_ORDER == G_BIG_ENDIAN)
+  GST_MAKE_FOURCC ('A', 'B', 'G', 'R'), 32}
 
-,
-#else
-0, 32}
+  ,
+  #else
+  0, 32}
 
-,
-#endif
-{
+  ,
+  #endif
+  {
   GST_MAKE_FOURCC ('R', 'G', 'B', ' '), 24, 24,
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
-GST_MAKE_FOURCC ('A', 'B', 'G', 'R'), 24}
+  #if (G_BYTE_ORDER == G_BIG_ENDIAN)
+  GST_MAKE_FOURCC ('A', 'B', 'G', 'R'), 24}
 
-,
-#else
-0, 24}
+  ,
+  #else
+  0, 24}
 
-,
-#endif
-{
-GST_MAKE_FOURCC ('R', 'G', 'B', ' '), 16, 16, 3, 16}
+  ,
+  #endif
+  {
+  GST_MAKE_FOURCC ('R', 'G', 'B', ' '), 16, 16, 3, 16}
 
-, {
-GST_MAKE_FOURCC ('R', 'G', 'B', ' '), 15, 16, 0, 16}
+  , {
+  GST_MAKE_FOURCC ('R', 'G', 'B', ' '), 15, 16, 0, 16}
 
-,
-#endif
-    if (fmt_list[i].fourcc == GST_MAKE_FOURCC ('R', 'G', 'B', ' ')) {
+  ,
+  #endif
+  if (fmt_list[i].fourcc == GST_MAKE_FOURCC ('R', 'G', 'B', ' ')) {
   guint32 r_mask = 0, b_mask = 0, g_mask = 0;
   gint endianness = 0;
 
   switch (fmt_list[i].depth) {
-    case 15:
-      endianness = G_BYTE_ORDER;
-      r_mask = 0xf800;
-      g_mask = 0x07c0;
-      b_mask = 0x003e;
-      break;
-    case 16:
-      endianness = G_BYTE_ORDER;
-      r_mask = 0xf800;
-      g_mask = 0x07e0;
-      b_mask = 0x001f;
-      break;
-    case 24:
-      endianness = G_BIG_ENDIAN;
-      r_mask = GST_VIDEO_BYTE1_MASK_24_INT;
-      g_mask = GST_VIDEO_BYTE2_MASK_24_INT;
-      b_mask = GST_VIDEO_BYTE3_MASK_24_INT break;
-    case 32:
-      endianness = G_BIG_ENDIAN;
-      r_mask = GST_VIDEO_BYTE1_MASK_32_INT;
-      g_mask = GST_VIDEO_BYTE2_MASK_32_INT;
-      b_mask = GST_VIDEO_BYTE3_MASK_32_INT break;
+  case 15:
+  endianness = G_BYTE_ORDER;
+  r_mask = 0xf800;
+  g_mask = 0x07c0;
+  b_mask = 0x003e;
+  break;
+  case 16:
+  endianness = G_BYTE_ORDER;
+  r_mask = 0xf800;
+  g_mask = 0x07e0;
+  b_mask = 0x001f;
+  break;
+  case 24:
+  endianness = G_BIG_ENDIAN;
+  r_mask = GST_VIDEO_BYTE1_MASK_24_INT;
+  g_mask = GST_VIDEO_BYTE2_MASK_24_INT;
+  b_mask = GST_VIDEO_BYTE3_MASK_24_INT break;
+  case 32:
+  endianness = G_BIG_ENDIAN;
+  r_mask = GST_VIDEO_BYTE1_MASK_32_INT;
+  g_mask = GST_VIDEO_BYTE2_MASK_32_INT;
+  b_mask = GST_VIDEO_BYTE3_MASK_32_INT break;
   }
   caps = GST_CAPS_NEW ("divxdec_src_pad_rgb",
-      "video/x-raw-rgb",
-      "width", GST_PROPS_INT (divxdec->width),
-      "height", GST_PROPS_INT (divxdec->height),
-      "framerate", GST_PROPS_FLOAT (divxdec->fps),
-      "depth", GST_PROPS_INT (fmt_list[i].depth),
-      "bpp", GST_PROPS_INT (fmt_list[i].bpp),
-      "endianness", GST_PROPS_INT (endianness),
-      "red_mask", GST_PROPS_INT (r_mask),
-      "green_mask", GST_PROPS_INT (g_mask),
-      "blue_mask", GST_PROPS_INT (b_mask));
-} else {
-#endif
-
-#endif
+  "video/x-raw-rgb",
+  "width", GST_PROPS_INT (divxdec->width),
+  "height", GST_PROPS_INT (divxdec->height),
+  "framerate", GST_PROPS_FLOAT (divxdec->fps),
+  "depth", GST_PROPS_INT (fmt_list[i].depth),
+  "bpp", GST_PROPS_INT (fmt_list[i].bpp),
+  "endianness", GST_PROPS_INT (endianness),
+  "red_mask", GST_PROPS_INT (r_mask),
+  "green_mask", GST_PROPS_INT (g_mask),
+  "blue_mask", GST_PROPS_INT (b_mask));
+  } else {
+  #endif
+
+  #endif
 */
 
-static GstPadLinkReturn
+static gboolean
 gst_divxdec_negotiate (GstDivxDec * divxdec)
 {
-  GstCaps *caps;
+  GstCaps *caps = NULL;
+  gint i;
+  gint par_num, par_den;
+  gboolean ret = FALSE;
+
   struct
   {
     guint32 fourcc;
@@ -398,6 +415,7 @@ gst_divxdec_negotiate (GstDivxDec * divxdec)
     guint32 csp;
     gint bitcnt;
   }
+
   fmt_list[] = {
     {
     GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'), 16, 16,
@@ -414,7 +432,18 @@ gst_divxdec_negotiate (GstDivxDec * divxdec)
     , {
     0, 0, 0, 0, 0}
   };
-  gint i;
+
+  GST_DEBUG_OBJECT (divxdec, "fps %d/%d, PAR %d/%d",
+      divxdec->fps_n, divxdec->fps_d, divxdec->par_n, divxdec->par_d);
+
+  /* calculate par
+   * the info.aspect_* values reflect PAR;
+   * 0:0 is allowed and can be interpreted as 1:1, so correct for it */
+  par_num = divxdec->par_n;
+  par_den = divxdec->par_d;
+  if (par_num == 0 && par_den == 0) {
+    par_num = par_den = 1;
+  }
 
   for (i = 0; fmt_list[i].fourcc != 0; i++) {
     divxdec->csp = fmt_list[i].csp;
@@ -422,27 +451,48 @@ gst_divxdec_negotiate (GstDivxDec * divxdec)
     caps = gst_caps_new_simple ("video/x-raw-yuv",
         "width", G_TYPE_INT, divxdec->width,
         "height", G_TYPE_INT, divxdec->height,
-        "framerate", G_TYPE_DOUBLE, divxdec->fps,
+        "framerate", GST_TYPE_FRACTION, divxdec->fps_n, divxdec->fps_d,
+        "pixel-aspect-ratio", GST_TYPE_FRACTION, par_num, par_den,
         "format", GST_TYPE_FOURCC, fmt_list[i].fourcc, NULL);
 
-    if (gst_divxdec_setup (divxdec) &&
-        gst_pad_set_explicit_caps (divxdec->srcpad, caps)) {
-      divxdec->csp = fmt_list[i].csp;
-      divxdec->bpp = fmt_list[i].bpp;
-      divxdec->bitcnt = fmt_list[i].bitcnt;
-      return GST_PAD_LINK_OK;
+    if (caps) {
+
+      if (gst_divxdec_setup (divxdec) &&
+          gst_pad_set_caps (divxdec->srcpad, caps)) {
+        divxdec->csp = fmt_list[i].csp;
+        divxdec->bpp = fmt_list[i].bpp;
+        divxdec->bitcnt = fmt_list[i].bitcnt;
+        ret = TRUE;
+        goto done;
+      }
+
+      gst_caps_unref (caps);
+      caps = NULL;
+
     }
+
   }
 
   /* if we got here - it's not good */
-  return GST_PAD_LINK_REFUSED;
+
+done:
+
+  if (caps) {
+    gst_caps_unref (caps);
+  }
+
+  return ret;
 }
 
 
-static GstPadLinkReturn
-gst_divxdec_connect (GstPad * pad, const GstCaps * caps)
+static gboolean
+gst_divxdec_connect (GstPad * pad, GstCaps * caps)
 {
   GstDivxDec *divxdec;
+  const GValue *par;
+  const GValue *fps;
+  gboolean ret = FALSE;
+
   GstStructure *structure = gst_caps_get_structure (caps, 0);
 
   divxdec = GST_DIVXDEC (gst_pad_get_parent (pad));
@@ -452,18 +502,61 @@ gst_divxdec_connect (GstPad * pad, const GstCaps * caps)
     gst_divxdec_unset (divxdec);
   }
 
-  /* we are not going to act on variable caps */
-  if (!gst_caps_is_fixed (caps))
-    return GST_PAD_LINK_DELAYED;
-
   /* if we get here, we know the input is divx. we
    * only need to bother with the output colorspace */
   gst_structure_get_int (structure, "width", &divxdec->width);
   gst_structure_get_int (structure, "height", &divxdec->height);
-  gst_structure_get_double (structure, "framerate", &divxdec->fps);
   gst_structure_get_int (structure, "divxversion", &divxdec->version);
 
-  return gst_divxdec_negotiate (divxdec);
+  /* get pixel aspect ratio if it's set */
+  par = gst_structure_get_value (structure, "pixel-aspect-ratio");
+  if (par) {
+    divxdec->par_n = gst_value_get_fraction_numerator (par),
+        divxdec->par_d = gst_value_get_fraction_denominator (par);
+  }
+
+  fps = gst_structure_get_value (structure, "framerate");
+  if (fps != NULL) {
+    divxdec->fps_n = gst_value_get_fraction_numerator (fps);
+    divxdec->fps_d = gst_value_get_fraction_denominator (fps);
+  } else {
+    divxdec->fps_n = -1;
+  }
+
+  ret = gst_divxdec_negotiate (divxdec);
+  gst_object_unref (divxdec);
+
+  return ret;
+}
+
+static GstStateChangeReturn
+gst_divxdec_change_state (GstElement * element, GstStateChange transition)
+{
+  GstStateChangeReturn ret;
+
+  switch (transition) {
+    case GST_STATE_CHANGE_NULL_TO_READY:
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+      break;
+    default:
+      break;
+  }
+
+  ret = parent_class->change_state (element, transition);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      break;
+    case GST_STATE_CHANGE_READY_TO_NULL:
+      break;
+    default:
+      break;
+  }
+
+  return ret;
 }
 
 
index 0468ff0a95062450b2507d31852285acc2dd7354..90c4703786c02ca701371711ca1aea10ac4f279a 100644 (file)
@@ -56,7 +56,9 @@ struct _GstDivxDec {
   int bitcnt, bpp;
   int version;
   int width, height;
-  gdouble fps;
+
+  gint fps_n, fps_d;
+  gint par_n, par_d;
 };
 
 struct _GstDivxDecClass {
index 591bb90ea529fbe1371ab7105fee0fafe405947b..5269e01eb46a1f31c0b9727de437759e7ad8b174 100644 (file)
@@ -48,7 +48,7 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS ("video/x-divx, "
         "divxversion = (int) 5, "
         "width = (int) [ 16, 4096 ], "
-        "height = (int) [ 16, 4096 ], " "framerate = (double) [ 0, MAX ]")
+        "height = (int) [ 16, 4096 ], " "framerate = (fraction) [0/1, MAX]")
     );
 
 
@@ -73,9 +73,8 @@ static void gst_divxenc_class_init (GstDivxEncClass * klass);
 static void gst_divxenc_base_init (GstDivxEncClass * klass);
 static void gst_divxenc_init (GstDivxEnc * divxenc);
 static void gst_divxenc_dispose (GObject * object);
-static void gst_divxenc_chain (GstPad * pad, GstData * data);
-static GstPadLinkReturn gst_divxenc_connect (GstPad * pad,
-    const GstCaps * vscapslist);
+static GstFlowReturn gst_divxenc_chain (GstPad * pad, GstBuffer * buf);
+static gboolean gst_divxenc_setcaps (GstPad * pad, GstCaps * caps);
 
 /* properties */
 static void gst_divxenc_set_property (GObject * object,
@@ -162,13 +161,12 @@ gst_divxenc_base_init (GstDivxEncClass * klass)
 static void
 gst_divxenc_class_init (GstDivxEncClass * klass)
 {
-  GstElementClass *gstelement_class;
-  GObjectClass *gobject_class;
+  GObjectClass *gobject_class = (GObjectClass *) klass;
 
-  gobject_class = (GObjectClass *) klass;
-  gstelement_class = (GstElementClass *) klass;
+  parent_class = g_type_class_peek_parent (klass);
 
-  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+  gobject_class->set_property = gst_divxenc_set_property;
+  gobject_class->get_property = gst_divxenc_get_property;
 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
       g_param_spec_ulong ("bitrate", "Bitrate",
@@ -187,9 +185,6 @@ gst_divxenc_class_init (GstDivxEncClass * klass)
       g_param_spec_int ("quality", "Quality",
           "Amount of Motion Estimation", 1, 5, 3, G_PARAM_READWRITE));
 
-  gobject_class->set_property = gst_divxenc_set_property;
-  gobject_class->get_property = gst_divxenc_get_property;
-
   gobject_class->dispose = gst_divxenc_dispose;
 
   gst_divxenc_signals[FRAME_ENCODED] =
@@ -210,13 +205,13 @@ gst_divxenc_init (GstDivxEnc * divxenc)
   gst_element_add_pad (GST_ELEMENT (divxenc), divxenc->sinkpad);
 
   gst_pad_set_chain_function (divxenc->sinkpad, gst_divxenc_chain);
-  gst_pad_set_link_function (divxenc->sinkpad, gst_divxenc_connect);
+  gst_pad_set_setcaps_function (divxenc->sinkpad, gst_divxenc_setcaps);
 
   /* create the src pad */
   divxenc->srcpad =
       gst_pad_new_from_template (gst_static_pad_template_get (&src_template),
       "src");
-  gst_pad_use_explicit_caps (divxenc->srcpad);
+  gst_pad_use_fixed_caps (divxenc->srcpad);
   gst_element_add_pad (GST_ELEMENT (divxenc), divxenc->srcpad);
 
   /* bitrate, etc. */
@@ -254,7 +249,7 @@ gst_divxenc_setup (GstDivxEnc * divxenc)
   output.use_bidirect = 1;
   output.input_clock = 0;
   output.input_frame_period = 1000000;
-  output.internal_timescale = divxenc->fps * 1000000;
+  output.internal_timescale = (divxenc->fps_n / divxenc->fps_d) * 1000000;      /* FIX? */
   output.max_key_interval = (divxenc->max_key_interval == -1) ?
       150 : divxenc->max_key_interval;
   output.key_frame_threshold = 50;
@@ -314,21 +309,17 @@ gst_divxenc_dispose (GObject * object)
 }
 
 
-static void
-gst_divxenc_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_divxenc_chain (GstPad * pad, GstBuffer * buf)
 {
-  GstBuffer *buf = GST_BUFFER (_data);
   GstDivxEnc *divxenc;
   GstBuffer *outbuf;
   ENC_FRAME xframe;
   ENC_RESULT xres;
-  int ret;
+  int res;
+  GstFlowReturn ret = GST_FLOW_OK;
 
-  g_return_if_fail (pad != NULL);
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (buf != NULL);
-
-  divxenc = GST_DIVXENC (GST_OBJECT_PARENT (pad));
+  divxenc = GST_DIVXENC (gst_pad_get_parent (pad));
 
   outbuf = gst_buffer_new_and_alloc (divxenc->buffer_size);
   GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
@@ -336,28 +327,38 @@ gst_divxenc_chain (GstPad * pad, GstData * _data)
   /* encode and so ... */
   xframe.image = GST_BUFFER_DATA (buf);
   xframe.bitstream = (void *) GST_BUFFER_DATA (outbuf);
-  xframe.length = GST_BUFFER_MAXSIZE (outbuf);
+  xframe.length = GST_BUFFER_SIZE (outbuf);     /* GST_BUFFER_MAXSIZE */
   xframe.produce_empty_frame = 0;
 
-  if ((ret = encore (divxenc->handle, ENC_OPT_ENCODE, &xframe, &xres))) {
-    GST_ELEMENT_ERROR (divxenc, LIBRARY, ENCODE, (NULL),
-        ("Error encoding divx frame: %s (%d)", gst_divxenc_error (ret), ret));
-    gst_buffer_unref (buf);
-    return;
+  if ((res = encore (divxenc->handle, ENC_OPT_ENCODE, &xframe, &xres))) {
+    goto not_encoding;
   }
 
   GST_BUFFER_SIZE (outbuf) = xframe.length;
-  if (xres.cType == 'I')
-    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_KEY_UNIT);
 
   /* go out, multiply! */
-  gst_pad_push (divxenc->srcpad, GST_DATA (outbuf));
+  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (divxenc->srcpad));
+  gst_pad_push (divxenc->srcpad, outbuf);
 
   /* proclaim destiny */
   g_signal_emit (G_OBJECT (divxenc), gst_divxenc_signals[FRAME_ENCODED], 0);
 
   /* until the final judgement */
+  goto done;
+
+not_encoding:
+
+  GST_ELEMENT_ERROR (divxenc, LIBRARY, ENCODE, (NULL),
+      ("Error encoding divx frame: %s (%d)", gst_divxenc_error (res), res));
+  ret = GST_FLOW_ERROR;
+  gst_buffer_unref (outbuf);
+  goto done;
+
+done:
   gst_buffer_unref (buf);
+  gst_object_unref (divxenc);
+  return ret;
+
 }
 
 /* FIXME: moving broken bits here for others to fix */
@@ -366,26 +367,27 @@ gst_divxenc_chain (GstPad * pad, GstData * _data)
     case GST_MAKE_FOURCC ('R', 'G', 'B', ' '):
       gst_caps_get_int (caps, "depth", &d);
       switch (d) {
-        case 24:
-          divx_cs = 0;
-          bitcnt = 24;
-          break;
-        case 32:
-          divx_cs = 0;
-          bitcnt = 32;
-          break;
+       case 24:
+         divx_cs = 0;
+         bitcnt = 24;
+         break;
+       case 32:
+         divx_cs = 0;
+         bitcnt = 32;
+         break;
 */
 
-static GstPadLinkReturn
-gst_divxenc_connect (GstPad * pad, const GstCaps * caps)
+static gboolean
+gst_divxenc_setcaps (GstPad * pad, GstCaps * caps)
 {
   GstDivxEnc *divxenc;
   GstStructure *structure = gst_caps_get_structure (caps, 0);
   gint w, h;
-  gdouble fps;
+  const GValue *fps;
   guint32 fourcc;
   guint32 divx_cs;
   gint bitcnt = 0;
+  gboolean ret = FALSE;
 
   divxenc = GST_DIVXENC (gst_pad_get_parent (pad));
 
@@ -394,9 +396,16 @@ gst_divxenc_connect (GstPad * pad, const GstCaps * caps)
 
   gst_structure_get_int (structure, "width", &w);
   gst_structure_get_int (structure, "height", &h);
-  gst_structure_get_double (structure, "framerate", &fps);
   gst_structure_get_fourcc (structure, "format", &fourcc);
 
+  fps = gst_structure_get_value (structure, "framerate");
+  if (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps)) {
+    divxenc->fps_n = gst_value_get_fraction_numerator (fps);
+    divxenc->fps_d = gst_value_get_fraction_denominator (fps);
+  } else {
+    divxenc->fps_n = -1;
+  }
+
   switch (fourcc) {
     case GST_MAKE_FOURCC ('I', '4', '2', '0'):
       divx_cs = GST_MAKE_FOURCC ('I', '4', '2', '0');
@@ -414,35 +423,47 @@ gst_divxenc_connect (GstPad * pad, const GstCaps * caps)
       divx_cs = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
       break;
     default:
-      return GST_PAD_LINK_REFUSED;
+      ret = FALSE;
+      goto done;
   }
 
   divxenc->csp = divx_cs;
   divxenc->bitcnt = bitcnt;
   divxenc->width = w;
   divxenc->height = h;
-  divxenc->fps = fps;
 
   /* try it */
   if (gst_divxenc_setup (divxenc)) {
-    GstPadLinkReturn ret;
-    GstCaps *new_caps;
+    GstCaps *new_caps = NULL;
 
     new_caps = gst_caps_new_simple ("video/x-divx",
         "divxversion", G_TYPE_INT, 5,
         "width", G_TYPE_INT, w,
-        "height", G_TYPE_INT, h, "framerate", G_TYPE_DOUBLE, fps, NULL);
+        "height", G_TYPE_INT, h,
+        "framerate", GST_TYPE_FRACTION, divxenc->fps_n, divxenc->fps_d, NULL);
+
+    if (new_caps) {
+
+      if (!gst_pad_set_caps (divxenc->srcpad, new_caps)) {
+        gst_divxenc_unset (divxenc);
+        ret = FALSE;
+        goto done;
+      }
+      gst_caps_unref (new_caps);
+      ret = TRUE;
+      goto done;
 
-    ret = gst_pad_set_explicit_caps (divxenc->srcpad, new_caps);
-    if (ret <= 0) {
-      gst_divxenc_unset (divxenc);
     }
 
-    return ret;
   }
 
   /* if we got here - it's not good */
-  return GST_PAD_LINK_REFUSED;
+
+  ret = FALSE;
+
+done:
+  gst_object_unref (divxenc);
+  return ret;
 }
 
 
@@ -450,10 +471,9 @@ static void
 gst_divxenc_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec)
 {
-  GstDivxEnc *divxenc;
+  GstDivxEnc *divxenc = GST_DIVXENC (object);
 
-  g_return_if_fail (GST_IS_DIVXENC (object));
-  divxenc = GST_DIVXENC (object);
+  GST_OBJECT_LOCK (divxenc);
 
   switch (prop_id) {
     case ARG_BITRATE:
@@ -469,6 +489,8 @@ gst_divxenc_set_property (GObject * object,
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
+
+  GST_OBJECT_UNLOCK (divxenc);
 }
 
 
@@ -476,10 +498,9 @@ static void
 gst_divxenc_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec)
 {
-  GstDivxEnc *divxenc;
+  GstDivxEnc *divxenc = GST_DIVXENC (object);
 
-  g_return_if_fail (GST_IS_DIVXENC (object));
-  divxenc = GST_DIVXENC (object);
+  GST_OBJECT_LOCK (divxenc);
 
   switch (prop_id) {
     case ARG_BITRATE:
@@ -498,8 +519,9 @@ gst_divxenc_get_property (GObject * object,
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
-}
 
+  GST_OBJECT_UNLOCK (divxenc);
+}
 
 static gboolean
 plugin_init (GstPlugin * plugin)
index 206659d32f2cb60ff30fefb14d632628f178f5b9..0d5cad05dfceeb58604044177fa4e080e2e3d4ad 100644 (file)
@@ -64,7 +64,7 @@ struct _GstDivxEnc {
   guint32 csp;
   gint bitcnt; 
   gint width, height;
-  gfloat fps;
+  gint fps_n, fps_d;
 };
 
 struct _GstDivxEncClass {