GNOME Bugzilla – Bug 628174
New gstvalue checks cause trouble in thoggen
Last modified: 2010-08-31 08:50:03 UTC
I tried to rip a DVD last night, and got an assertion in gst_value_set_fraction_range() at: g_return_if_fail (((gdouble) start->data[0].v_int) / ((gdouble) start->data[1].v_int) < ((gdouble) end->data[0].v_int) / ((gdouble) end->data[1].v_int)); This check was introduced in: commit 4d8320e4c66e4b58d78ddff97b63f3ece46327ce Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> Date: Mon Jun 14 15:30:08 2010 +0200 gstvalue: Add some more assertions and checks for valid input parameters I don't understand the failure. start has a strange value, but the result should still meet the check. I suspect the problem comes from the 'double' calculation calculating strangely because the values are right up at the int32 limits. In any case, doing double calcs in the fraction paths seems like a bad idea - so far, we've managed to largely avoid floating point operations except for the rate params. (gdb) print *start $1 = {g_type = 1601467239, data = {{v_int = 1970037110, v_uint = 1970037110, v_long = 1970037110, v_ulong = 1970037110, v_int64 = 7310291509518819702, v_uint64 = 7310291509518819702, v_float = 2.99648145e+32, v_double = 5.0241924449441303e+180, v_pointer = 0x756c6176}, {v_int = 1919311732, v_uint = 1919311732, v_long = 1919311732, v_ulong = 1919311732, v_int64 = 7598807741463158644, v_uint64 = 7598807741463158644, v_float = 4.56300467e+30, v_double = 9.7538516110743229e+199, v_pointer = 0x72665f74}}} (gdb) print *end $2 = {g_type = 224, data = {{v_int = 2147483647, v_uint = 2147483647, v_long = 2147483647, v_ulong = 2147483647, v_int64 = 2147483647, v_uint64 = 2147483647, v_float = nan(0x7fffff), v_double = 1.0609978949885705e-314, v_pointer = 0x7fffffff}, {v_int = 1, v_uint = 1, v_long = 1, v_ulong = 1, v_int64 = 1, v_uint64 = 1, v_float = 1.40129846e-45, v_double = 4.9406564584124654e-324, v_pointer = 0x1}}}
Yes, that's likely caused by floating point accuracy. I'll change that assertion to only use integer arithmetic later and probably add a gst_util_fraction_compare() while I'm at it.
There's something else weird going on though. The string it's failing to parse is: "video/x-raw-yuv, format = (fourcc) { I420, Y42B, Y444 }, framerate = (fraction) [1/MAX, MAX], width = (int) [ 1, MAX ], height = (int) [ 1, MAX ]" When I add that to the caps check in the testsuite, it still passes. Not sure what's going on - possibly memory corruption.
commit 8ca48752fb787ce708c86183b51505cd53d6b5ed Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> Date: Sat Aug 28 09:30:18 2010 +0200 utils: Add gst_util_fraction_compare() to compare fractions And use it for the fraction comparisons in gstvalue.c instead of using comparisons by first converting the fractions to double. Should fix bug #628174. API: gst_util_fraction_compare() Does it work now for you? I can't reproduce it in the testsuite either... Also I thought that we can't parse MAX to a fraction, only MAX/1. Does it work if you change that?
Yes, it works OK now. We can parse 'MAX' ok in this situation, because it's clear to the parser that it's a fraction. We can't parse it when the value type isn't being specified, like in video/x-raw-yuv,framerate=MAX, but with video/x-raw-yuv,framerate=(fraction)MAX is fine. For the record, the caps string comes from theoraenc, and appears to have been that way for a long time.
Ok, now a testcase for this would be nice which failed before but works now. But I wasn't able to write one :) Maybe it really was memory corruption and now works only because something changed and you have more luck ;)
No, me neither. Valgrind doesn't show anything that might indicate corruption, although immediately before the assertion it had the seemingly unrelated: ==812== Source and destination overlap in memcpy(0xb9846e0, 0xb9846e0, 622080) ==812== at 0x4027865: memcpy (mc_replace_strmem.c:497) ==812== by 0x4552926: gst_base_transform_handle_buffer (string3.h:52) ==812== by 0x4553489: gst_base_transform_chain (gstbasetransform.c:2308) ==812== by 0x45C31F4: gst_pad_chain_data_unchecked (gstpad.c:4182) ==812== by 0x45C3C53: gst_pad_push_data (gstpad.c:4411) ==812== by 0x7EAFB41: handle_slice (gstmpeg2dec.c:1040) ==812== by 0x7EB0511: gst_mpeg2dec_chain (gstmpeg2dec.c:1227) ==812== by 0x45C31F4: gst_pad_chain_data_unchecked (gstpad.c:4182) ==812== by 0x45C3C53: gst_pad_push_data (gstpad.c:4411) ==812== by 0x7D7F819: gst_queue_loop (gstqueue.c:1109) ==812== by 0x45F1460: gst_task_func (gsttask.c:271) ==812== by 0x45F2B36: default_func (gsttaskpool.c:68) ==812== by 0x476BD0B: ??? (in /lib/libglib-2.0.so.0.2400.1) ==812== by 0x4769DEE: ??? (in /lib/libglib-2.0.so.0.2400.1) ==812== by 0x47F696D: start_thread (pthread_create.c:300) ==812== by 0x48D7A4D: clone (clone.S:130)