[gst-devel] mpeg->divx status

Joshua N Pritikin vishnu at pobox.com
Fri May 9 07:39:14 CEST 2003


On Fri, May 09, 2003 at 08:40:43AM +0200, Ronald Bultje wrote:
> On Fri, 2003-05-09 at 07:29, Joshua N Pritikin wrote:
> > mplayer can play it if i use the -fps option.  However,
> > the audio has lots of clicks and pops.  The audio is about
> > 1-2s ahead of the video too.  i'm going to work on fixing
> > the AVI header and see if things improve.  At least, FPS
> > looks easy to fix.
> 
> I've got a local semi-fix for the audio problem. I know the problem, but
> fixing it is hard, since you basically need to know the number of
> samples written in how many bytes at which samplerate. Normally, this
> bytes-per-second value can be calculated using audio_size/time, but time
> (last_timestamp-first_timestamp) is inaccurate, it misses the time being
> spent in the last buffer, and this can't be calculated in any correct
> way, since we don't know the length of the last buffer (in time). In
> short, mp3-audio is currently broken in avimux, and I'm not sure yet how
> to fix it. WAV audio should work.

Yah, tested.  Audio sounds fine with WAV.  However, need a more
compact format than raw PCM!

How about something like:

  mpegdemux ! mad ! lame enable_special_timestamps=1 ! avimux

?

> For FPS, we simply request the FPS from the video sink pad, so if that
> doesn't work, likely something is broken somewhere in how the elements
> interoperate. It'd help if you could send the AVI header (first 1 kB or
> so) of the file to me, or via bugzilla.

i have a fix in the attached patch.  However, it looks like the AVI
header is never written because the pipeline doesn't complete the
transition to EOS.  (i get "audio_q: waiting for the app to restart
source pad elements" instead of EOS.)

Another problem is A/V is off, audio gets way ahead.  i speculate
that the problem is due to wildly inaccurate bitrate calculations.

One more strange problem: i am able to convert VCD MPEG1, but i
had problems with AlienSong -- the video get scrambled.  i don't
really care about AlienSong, per se, but i wonder why it doesn't
work.

-- 
Victory to the Divine Mother!!         after all,
  http://sahajayoga.org                  http://why-compete.org
-------------- next part --------------
Index: gstxvidenc.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/xvid/gstxvidenc.c,v
retrieving revision 1.2
diff -u -r1.2 gstxvidenc.c
--- gstxvidenc.c	22 Apr 2003 14:55:12 -0000	1.2
+++ gstxvidenc.c	9 May 2003 14:23:28 -0000
@@ -128,6 +128,73 @@
 }
 
 
+static const GstFormat*
+get_src_formats (GstPad *pad)
+{
+  static const GstFormat formats[] = {
+    GST_FORMAT_BYTES,
+    GST_FORMAT_TIME,
+    GST_FORMAT_UNITS,
+    0
+  };
+  return formats;
+}
+
+static gboolean
+convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
+	     GstFormat *dest_format, gint64 *dest_value)
+{
+  GstXvidEnc *xvidenc;
+
+  xvidenc = GST_XVIDENC(GST_OBJECT_PARENT(pad));
+	      
+  if (xvidenc->handle == NULL) {
+    g_warning ("xvidenc: attempt to do conversion before media is sampled (ignored)");
+    return FALSE;
+  }
+
+  switch (src_format) {
+    case GST_FORMAT_BYTES:
+      switch (*dest_format) {
+        case GST_FORMAT_DEFAULT:
+          *dest_format = GST_FORMAT_TIME;
+        case GST_FORMAT_TIME:
+	  *dest_value = (GST_SECOND * 8 * src_value) / xvidenc->bitrate;
+	  return TRUE;
+        default: break;
+      }
+      break;
+    case GST_FORMAT_TIME:
+      switch (*dest_format) {
+        case GST_FORMAT_DEFAULT:
+          *dest_format = GST_FORMAT_BYTES;
+        case GST_FORMAT_BYTES:
+	  *dest_format = src_value * xvidenc->bitrate / (GST_SECOND * 8);
+	  return TRUE;
+        case GST_FORMAT_UNITS:
+	  *dest_value = src_value * xvidenc->fps / GST_SECOND;
+	  return TRUE;
+        default: break;
+      }
+      break;
+    case GST_FORMAT_UNITS:
+      switch (*dest_format) {
+        case GST_FORMAT_DEFAULT:
+          *dest_format = GST_FORMAT_TIME;
+        case GST_FORMAT_TIME:
+          *dest_value = src_value * GST_SECOND / xvidenc->fps;
+	  return TRUE;
+        case GST_FORMAT_BYTES:
+	  *dest_value = xvidenc->bitrate * src_value / (8 * xvidenc->fps);
+	  return TRUE;
+        default: break;
+      }
+      break;
+    default: break;
+  }
+  return FALSE;
+}
+
 static void
 gst_xvidenc_class_init (GstXvidEncClass *klass)
 {
@@ -195,6 +262,10 @@
                       GST_PAD_TEMPLATE_GET(src_template),
                       "src");
   gst_element_add_pad(GST_ELEMENT(xvidenc), xvidenc->srcpad);
+  gst_pad_set_formats_function (xvidenc->srcpad,
+				GST_DEBUG_FUNCPTR (get_src_formats));
+  gst_pad_set_convert_function (xvidenc->srcpad,
+				GST_DEBUG_FUNCPTR (convert_src));
 
   /* bitrate, etc. */
   xvidenc->width = xvidenc->height = xvidenc->csp = -1;
@@ -211,17 +282,16 @@
 gst_xvidenc_setup (GstXvidEnc *xvidenc)
 {
   XVID_ENC_PARAM xenc;
-  gdouble fps;
   int ret;
 
-  fps = gst_video_frame_rate(GST_PAD_PEER(xvidenc->sinkpad));
+  xvidenc->fps = gst_video_frame_rate(GST_PAD_PEER(xvidenc->sinkpad));
 
   /* set up xvid codec parameters - grab docs from
    * xvid.org for more info */
   memset(&xenc, 0, sizeof(XVID_ENC_PARAM));
   xenc.width = xvidenc->width;
   xenc.height = xvidenc->height;
-  xenc.fincr = (int)(fps * 1000);
+  xenc.fincr = (int)(xvidenc->fps * 1000);
   xenc.fbase = 1000;
   xenc.rc_bitrate = xvidenc->bitrate;
   xenc.rc_reaction_delay_factor = -1;
@@ -327,8 +397,9 @@
   }
 
   /* we are not going to act on variable caps */
-  if (!GST_CAPS_IS_FIXED(vscaps))
+  if (!GST_CAPS_IS_FIXED(vscaps)) {
     return GST_PAD_LINK_DELAYED;
+  }
 
   for (caps = vscaps; caps != NULL; caps = caps->next)
   {
Index: gstxvidenc.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/xvid/gstxvidenc.h,v
retrieving revision 1.2
diff -u -r1.2 gstxvidenc.h
--- gstxvidenc.h	22 Apr 2003 14:55:12 -0000	1.2
+++ gstxvidenc.h	9 May 2003 14:23:28 -0000
@@ -60,6 +60,7 @@
   void *handle;
   int csp;
   int width, height;
+  double fps;
 };
 
 struct _GstXvidEncClass {


More information about the gstreamer-devel mailing list