filesink: fails with matroskamux when writing files larger than 2GiB on Windows
I can save an H.264 stream to an MKV file just fine until it reaches over 2GiB in size. As soon as it surpasses this, the fseeko
function fails in gstfilesink.c:gst_file_sink_do_seek(). However, when removing the MKV muxer (matroskamux), filesink works without issue (tested up to file sizes around 12GB). This appears to be a problem with filesink when used with matroskamux, not an issue with matroskamux itself.
Environment is Windows 10 1903, MSYS2 using mingw-w64 Gstreamer 1.16.2 packages (/mingw64/bin/gst-launch-1.0.exe).
Pipeline to reproduce issue (bitrate is set so that it reaches 2GiB quickly; the error still occurs if omitted):
gst-launch-1.0.exe videotestsrc ! 'video/x-raw, width=1920, height=1080, framerate=30/1' ! x264enc bitrate=50000 ! matroskamux ! filesink location=test.mkv
The following pipelines execute without error (though the saved file might not be playable):
gst-launch-1.0.exe videotestsrc ! 'video/x-raw, width=1920, height=1080, framerate=30/1' ! x264enc bitrate=50000 ! filesink location=test.mkv
gst-launch-1.0.exe videotestsrc num-buffers=20000 ! 'video/x-raw, width=1920, height=1080, framerate=30/1' ! x264enc bitrate=50000 ! mp4mux ! filesink location=test.mp4
This appears to be a problem with Windows, as the bad pipeline gives no error when running on Linux (tested on Ubuntu 18.04 using GStreamer 1.14.5 and Ubuntu 20.04 using GStreamer 1.16.2 from apt packages). My guess is that fseek should be replaced with something else on Windows (_fseeki64?), though I have no experience using any of this.
Full log attached for reference (most of it is ignorablebad_mkv_pipeline.tar.gz), but problematic section is here:
...
// Successful seek and write
0:02:38.703314800 836 25f1900 DEBUG basesink gstbasesink.c:3354:gst_base_sink_event:<filesink0> received event 000000000348d850 segment event: 000000000348d850, time 99:99:99.999999999, seq-num 147, GstEventSegment, segment=(GstSegment)"GstSegment, flags=(GstSegmentFlags)GST_SEGMENT_FLAG_NONE, rate=(double)1, applied-rate=(double)1, format=(GstFormat)GST_FORMAT_BYTES, base=(guint64)0, offset=(guint64)0, start=(guint64)2108148716, stop=(guint64)18446744073709551615, time=(guint64)0, position=(guint64)0, duration=(guint64)18446744073709551615;";
0:02:38.703343800 836 25f1900 DEBUG filesink gstfilesink.c:503:gst_file_sink_do_seek:<filesink0> Seeking to offset 2108148716 using fseeko
0:02:38.703373200 836 25f1900 DEBUG basesink gstbasesink.c:3289:gst_base_sink_default_event:<filesink0> configured segment bytes segment start=2108148716, offset=0, stop=-1, rate=1.000000, applied_rate=1.000000, flags=0x00, time=0, base=0, position 0, duration -1
0:02:38.703409300 836 25f1900 DEBUG GST_PADS gstpad.c:5781:gst_pad_send_event_unchecked:<filesink0:sink> sent event, ret ok
0:02:38.703428400 836 25f1900 LOG GST_EVENT gstevent.c:222:_gst_event_free: freeing event 000000000348d7e0 type segment
0:02:38.703447500 836 25f1900 LOG GST_PADS gstpad.c:5224:store_sticky_event:<filesink0:sink> stored sticky event segment
0:02:38.703468800 836 25f1900 LOG GST_PADS gstpad.c:5415:gst_pad_push_event_unchecked:<matroskamux0:src> sent event 000000000348d850 (segment) to peerpad <filesink0:sink>, ret ok
0:02:38.703489300 836 25f1900 DEBUG GST_PADS gstpad.c:3936:push_sticky:<matroskamux0:src> event segment marked received
...
// Next (failed) write
0:02:38.704550500 836 25f1900 DEBUG basesink gstbasesink.c:3354:gst_base_sink_event:<filesink0> received event 000000000348d7e0 segment event: 000000000348d7e0, time 99:99:99.999999999, seq-num 148, GstEventSegment, segment=(GstSegment)"GstSegment, flags=(GstSegmentFlags)GST_SEGMENT_FLAG_NONE, rate=(double)1, applied-rate=(double)1, format=(GstFormat)GST_FORMAT_BYTES, base=(guint64)0, offset=(guint64)0, start=(guint64)2155122157, stop=(guint64)18446744073709551615, time=(guint64)0, position=(guint64)0, duration=(guint64)18446744073709551615;";
0:02:38.704578400 836 25f1900 DEBUG filesink gstfilesink.c:503:gst_file_sink_do_seek:<filesink0> Seeking to offset 2155122157 using fseeko
0:02:38.704596900 836 25f1900 DEBUG filesink gstfilesink.c:713:gst_file_sink_flush_buffer:<filesink0> Flushing out buffer of size 8
0:02:38.704616400 836 25f1900 DEBUG filesink gstfilesink.c:655:gst_file_sink_render_buffers:<filesink0> writing 1 buffers (1 memories, 8 bytes) at position 2108148716
0:02:38.704636500 836 25f1900 LOG default gstelements_private.c:239:gst_writev_buffers:<filesink0> 1 buffers, 1 memories
0:02:38.704676800 836 25f1900 DEBUG filesink gstfilesink.c:535:gst_file_sink_do_seek:<filesink0> Seeking failed: Invalid argument
0:02:38.704719100 836 25f1900 WARN filesink gstfilesink.c:604:gst_file_sink_event:<filesink0> error: Error while seeking in file "test.mkv".
0:02:38.704744000 836 25f1900 WARN filesink gstfilesink.c:604:gst_file_sink_event:<filesink0> error: system error: Invalid argument
0:02:38.704765400 836 25f1900 DEBUG GST_MESSAGE gstelement.c:2110:gst_element_message_full_with_details:<filesink0> start
0:02:38.704791900 836 25f1900 INFO GST_ERROR_SYSTEM gstelement.c:2140:gst_element_message_full_with_details:<filesink0> posting message: Error while seeking in file "test.mkv".
... // Pipeline closing and cleanup