GNOME Bugzilla – Bug 575988
On Windows filesink can't write files longer than 2-4 GiB, uses 32-bit fseek/ftell
Last modified: 2009-03-20 13:14:11 UTC
This also applies to some file-i/o-related elements (qtmux, queue2). Here's the patches for all three: diff --git a/plugins/elements/gstfilesink.c b/plugins/elements/gstfilesink.c index 92abe6e..feb151f 100644 --- a/plugins/elements/gstfilesink.c +++ b/plugins/elements/gstfilesink.c @@ -423,6 +423,8 @@ gst_file_sink_query (GstPad * pad, GstQuery * query) # define __GST_STDIO_SEEK_FUNCTION "fseeko" #elif defined (G_OS_UNIX) # define __GST_STDIO_SEEK_FUNCTION "lseek" +#elif defined (G_OS_WIN32) +# define __GST_STDIO_SEEK_FUNCTION "_fseeki64" #else # define __GST_STDIO_SEEK_FUNCTION "fseek" #endif @@ -443,6 +445,9 @@ gst_file_sink_do_seek (GstFileSink * filesink, guint64 new_offset) if (lseek (fileno (filesink->file), (off_t) new_offset, SEEK_SET) == (off_t) - 1) goto seek_failed; +#elif defined (G_OS_WIN32) + if (_fseeki64 (filesink->file, new_offset, SEEK_SET) != 0) + goto seek_failed; #else if (fseek (filesink->file, (long) new_offset, SEEK_SET) != 0) goto seek_failed; @@ -547,6 +552,8 @@ gst_file_sink_get_current_offset (GstFileSink * filesink, guint64 * p_pos) /* ignore and continue */ } ret = lseek (fileno (filesink->file), 0, SEEK_CUR); +#elif defined (G_OS_WIN32) + ret = _ftelli64 (filesink->file); #else ret = (off_t) ftell (filesink->file); #endif diff --git a/gst/playback/gstqueue2.c b/gst/playback/gstqueue2.c index d9550d0..73665db 100644 --- a/gst/playback/gstqueue2.c +++ b/gst/playback/gstqueue2.c @@ -827,7 +827,15 @@ gst_queue_write_buffer_to_file (GstQueue * queue, GstBuffer * buffer) guint8 *data; int ret; +#ifdef HAVE_FSEEKO + fseeko (queue->temp_file, (off_t) queue->writing_pos, SEEK_SET); +#elif defined (G_OS_UNIX) + lseek (fileno (queue->temp_file), (off_t) queue->writing_pos, SEEK_SET); +#elif defined (G_OS_WIN32) + _fseeki64 (queue->temp_file, queue->writing_pos, SEEK_SET); +#else fseek (queue->temp_file, queue->writing_pos, SEEK_SET); +#endif data = GST_BUFFER_DATA (buffer); size = GST_BUFFER_SIZE (buffer); @@ -876,6 +884,9 @@ gst_queue_create_read (GstQueue * queue, guint64 offset, guint length, if (lseek (fileno (queue->temp_file), (off_t) offset, SEEK_SET) == (off_t) - 1) goto seek_failed; +#elif defined (G_OS_WIN32) + if (_fseeki64 (queue->temp_file, offset, SEEK_SET) != 0) + goto seek_failed; #else if (fseek (queue->temp_file, (long) offset, SEEK_SET) != 0) goto seek_failed; diff --git a/gst/qtmux/gstqtmux.c b/gst/qtmux/gstqtmux.c index c3ac67f..662311d 100644 --- a/gst/qtmux/gstqtmux.c +++ b/gst/qtmux/gstqtmux.c @@ -603,8 +603,20 @@ gst_qt_mux_send_buffered_data (GstQTMux * qtmux, guint64 * offset) if (fflush (qtmux->fast_start_file)) goto flush_failed; - if (fseek (qtmux->fast_start_file, 0, SEEK_SET)) +#ifdef HAVE_FSEEKO + if (fseeko (qtmux->fast_start_file, (off_t) 0, SEEK_SET) != 0) goto seek_failed; +#elif defined (G_OS_UNIX) + if (lseek (fileno (qtmux->fast_start_file), (off_t) 0, + SEEK_SET) == (off_t) - 1) + goto seek_failed; +#elif defined (G_OS_WIN32) + if (_fseeki64 (qtmux->fast_start_file, 0, SEEK_SET) != 0) + goto seek_failed; +#else + if (fseek (qtmux->fast_start_file, (long) 0, SEEK_SET) != 0) + goto seek_failed; +#endif /* hm, this could all take a really really long time, * but there may not be another way to get moov atom first Also nsf.c in -bad is still broken (i didn't dare to touch it).
Created attachment 130993 [details] [review] OK, forget everything i've said. Here is the correct patch for core.
Created attachment 130997 [details] [review] OK, this is THE patch that works. Tested it on gst-launch-0.10 --gst-debug-level=5 videotestsrc ! matroskamux ! filesink location=c://videotestsrc.mkv
commit 286e9b6ff9c96bf6d9b610396e9cecd6856b7383 Author: LRN <lrn1986 at gmail dot com> Date: Fri Mar 20 14:12:55 2009 +0100 win32: fix seeking in files >4GB Use 64-bit functions on windows to implement seeking in files bigger than 4GB. Fixes #575988