Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

range restriction on Gst.Bus.timed_pop_filtered doesnt work with Gst.CLOCK_TIME_NONE #246

Open
mxh69420 opened this issue Jul 15, 2020 · 8 comments

Comments

@mxh69420
Copy link

hello

ive tried porting the hello world example from gstreamer into lua. Gst.Bus.timed_pop_filtered is supposed to take a timeout value, or Gst.CLOCK_TIME_NONE if you dont want it to time out.

my lua version: luajit 2.1.0-beta3

local bit = require "bit"

local lgi = require "lgi"
local Gst = lgi.Gst

local pipeline = Gst.parse_launch("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm")
pipeline:set_state('PLAYING')

local bus = pipeline:get_bus()

local msg = bus:timed_pop_filtered(Gst.CLOCK_TIME_NONE, bit.bor(Gst.MessageType.EOS, Gst.MessageType.ERROR))
--bad argument #2 to 'timed_pop_filtered' (-1 is out of <0, 1.844674407371e+19>)

pipeline:set_state('NULL')

changing Gst.CLOCK_TIME_NONE to Gst.SECOND * 10000 works just fine, but this of course wont work for videos longer than 10000 seconds.

@mxh69420
Copy link
Author

using 0xFFFFFFFF seems to work as a workaround (0xFFFFFFFFFFFFFFFF oddly doesnt)

@psychon
Copy link
Collaborator

psychon commented Jul 17, 2020

I downloaded the debian package and extracted it to /tmp without installing:

$ GI_TYPELIB_PATH=/tmp/data/usr/lib/x86_64-linux-gnu/girepository-1.0 lua -e 'print(require("lgi").Gst.CLOCK_TIME_NONE)'
1.844674407371e+19

So... apparently the contained value is correct. I guess this is some overflow somewhere. A double has less than 64 bits for the mantissa, so it cannot represent the value exactly. Since (in older Lua versions) all numbers are doubles, I guess this cannot always work correctly. LuaJIT is one of those Luas where all numbers are doubles, I think.

For future-me:

The argument in question has type GstClockTime, which is a typedef of guint64:
https://github.com/GStreamer/gstreamer/blob/9831c9bbdbd89ad7adac3cdb837d3730a3f6e39e/gst/gstclock.h#L41-L46
GST_CLOCK_TIME_NONE is defined here as ((GstClockTime) -1): https://github.com/GStreamer/gstreamer/blob/9831c9bbdbd89ad7adac3cdb837d3730a3f6e39e/gst/gstclock.h#L68-L73

@psychon
Copy link
Collaborator

psychon commented Jul 17, 2020

Huh, I forgot an important step: Trying to reproduce the problem. Actually, I cannot reproduce. Your program above runs without any errors for me, for all the Lua versions that I have available.

for lua in lua5.1 lua5.2 lua5.3 luajit ; do echo ; echo $lua ; GI_TYPELIB_PATH=/tmp/data/usr/lib/x86_64-linux-gnu/girepository-1.0 $lua -e 'Gst = require("lgi").Gst; local pipeline = Gst.parse_launch("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm"); pipeline:set_state("PLAYING"); local bus = pipeline:get_bus(); local msg = bus:timed_pop_filtered(Gst.CLOCK_TIME_NONE, (Gst.MessageType.EOS + Gst.MessageType.ERROR))' ; done

LuaJIT is 2.1.0-beta3, same as yours. I am on debian testing.

@psychon
Copy link
Collaborator

psychon commented Jul 17, 2020

I set a breakpoint on gst_bus_timed_pop_filtered in gdb. Sadly, I do not have debugging symbols installed, but:

(gdb) info registers 
rax            0x0                 0
rbx            0x400581d0          1074102736
rcx            0x20                32
rdx            0x3                 3
rsi            0x0                 0
rdi            0x555555889250      93824995594832
rbp            0x7fffffffe2d0      0x7fffffffe2d0
rsp            0x7fffffffe2c8      0x7fffffffe2c8
r8             0x400003b8          1073742776
r9             0x0                 0
r10            0x0                 0
r11            0x7ffff75c9e40      140737343430208
r12            0x0                 0
r13            0x7fffffffe380      140737488348032
r14            0x40058268          1074102888
r15            0x7fffffffe37c      140737488348028
rip            0x7ffff75c9e40      0x7ffff75c9e40 <gst_bus_timed_pop_filtered>
eflags         0x246               [ PF ZF IF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0

If I got the calling convention right, the second argument should be rsi, so is 0x0. That could explain why that function returns here immediately with nil. :-/

@psychon
Copy link
Collaborator

psychon commented Jul 17, 2020

@samiam308 Could you run the following and tell me its output? For me, this produces 0 (which matches the output that gdb gives me).

gobject = require("lgi").GObject
value = gobject.Value()
value:init(11 * 4) -- This is G_TYPE_UINT64
value:set_uint64(require("lgi").Gst.CLOCK_TIME_NONE)
print(value:get_uint64())

@mxh69420
Copy link
Author

mxh69420 commented Aug 4, 2020

sorry it took me a while. for me, it doesnt even reach the print.

luajit: script.lua:4: bad argument #2 to 'set_uint64' (-1 is out of <0, 1.844674407371e+19>)
stack traceback:
	[C]: in function 'set_uint64'
	script.lua:4: in main chunk
	[C]: at 0x559e47c0e200

@psychon
Copy link
Collaborator

psychon commented Aug 5, 2020

Weird. No idea where that difference could come from. Sorry.

@v1993
Copy link
Contributor

v1993 commented Dec 6, 2020

I'm not sure how this should behave, but for me (git lgi)

v@v-home:~$ lua
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> gobject = require("lgi").GObject
> value = gobject.Value()
> value:init(11 * 4) -- This is G_TYPE_UINT64
lgi.rec 0x558f17534ce8:GObject.Value
> value:set_uint64(require("lgi").Gst.CLOCK_TIME_NONE)
stdin:1: bad argument #2 to 'set_uint64' (-1 is out of <0, 9223372036854775807>)
stack traceback:
	[C]: in method 'set_uint64'
	stdin:1: in main chunk
	[C]: in ?

> require("lgi").Gst.CLOCK_TIME_NONE
-1

It seems that Lua exports negative unsigned values without wrapping them from their max value? Or something like this.

Another possibility: Lua can't store max value of unsigned 64-bit integer correctly (well, it can't). It would do so imprecisely in double (5.1/5.2) and just fail to in 64-bit signed integer in 5.3+.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants