GNOME Bugzilla – Bug 536848
[giosrc] Doesn't handle short reads properly
Last modified: 2008-06-11 09:31:38 UTC
Trying to play an mp4 file over gvfs/SMB: pipeline to PAUSED ... Pipeline is PREROLLING ... ERROR: from element /playbin0/decodebin0/qtdemux0: This file is incomplete and cannot be played. Additional debug info: qtdemux.c(1057): gst_qtdemux_loop_state_header (): /playbin0/decodebin0/qtdemux0: We got less than expected (received 65535, wanted 719800) ERROR: pipeline doesn't want to preroll. Setting pipeline to NULL ... FREEING pipeline ... 65535 is the maximum that SMB will pass on as one read. Either a giosrc or a qtdemux bug, you choose.
giosrc bug. The only time when it's allowed to return less than requested is at the end of the file.
btw. gnome-vfs does that also. I worked around that by reading in a loop until it got enough so that pulling from gnome-vfs src return the requested bytes.
I hope this is just a bug in the gvfs backend... it would be annoying for applications to handle this IMHO and could very well be handled in GIO. Stefan, could you make your gnomevfs bug available somewhere? I don't see it in CVS :)
g_input_stream_read() says: "On success, the number of bytes read into the buffer is returned. It is not an error if this is not the same as the requested size, as it can happen e.g. near the end of a file." Having to handle short-reads isn't news, and g_file_load_contents() does the looping as you would expect it to.
Created attachment 112401 [details] [review] Loop over short reads That allows me to play Quicktime files over SMB
Filed the similar issue + patch for gnomevfssrc at Bug #537380.
Created attachment 112420 [details] [review] gio.diff
Ok, this code now does what your patch does (minus a small bug) and also some changes for bug #536849. It has the loop to read as much as possible, caches buffers and reads in blocks of >= 4k and has logic for disabling random access for some uri schemes. Please test :)
2008-06-11 Sebastian Dröge <slomo@circular-chaos.org> * ext/gio/gstgiobasesrc.c: (gst_gio_base_src_finalize), (gst_gio_base_src_create): * ext/gio/gstgiobasesrc.h: Try to read the requested number of bytes, even if the first read returns less than requested, until nothing is read anymore or we have the requested amount of bytes. This fixes playback of files via Samba as Samba only allows to read 64k at once. Implement a caching algorithm that makes sure that we read at least 4k of data every time. Some elements will try to read a few bytes, then seek, read again a few bytes and so on and this is painfully slow as every operation has to go over DBus if GVfs is used as backend. Fixes bug #536849 and #536848. * ext/gio/gstgiosrc.c: (gst_gio_src_class_init), (gst_gio_src_check_get_range): Override check_get_range() to blacklist http/https URIs and whitelist file URIs. More to be added on demand.