[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