mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-02 14:20:06 +00:00
isomp4: fsync after sending updates in robust mode
Use the new GstBuffer SYNC_AFTER flag to trigger an fsync after updating the moov or mdat atom, and after updating the free atom to make it visible.
This commit is contained in:
parent
3e17cd8acb
commit
23d610140d
1 changed files with 43 additions and 22 deletions
|
@ -1543,7 +1543,7 @@ fail:
|
|||
*/
|
||||
static GstFlowReturn
|
||||
gst_qt_mux_send_mdat_header (GstQTMux * qtmux, guint64 * off, guint64 size,
|
||||
gboolean extended)
|
||||
gboolean extended, gboolean fsync_after)
|
||||
{
|
||||
GstBuffer *buf;
|
||||
GstMapInfo map;
|
||||
|
@ -1587,6 +1587,9 @@ gst_qt_mux_send_mdat_header (GstQTMux * qtmux, guint64 * off, guint64 size,
|
|||
}
|
||||
|
||||
GST_LOG_OBJECT (qtmux, "Pushing mdat header");
|
||||
if (fsync_after)
|
||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_SYNC_AFTER);
|
||||
|
||||
return gst_qt_mux_send_buffer (qtmux, buf, off, FALSE);
|
||||
|
||||
}
|
||||
|
@ -1597,7 +1600,7 @@ gst_qt_mux_send_mdat_header (GstQTMux * qtmux, guint64 * off, guint64 size,
|
|||
*/
|
||||
static GstFlowReturn
|
||||
gst_qt_mux_update_mdat_size (GstQTMux * qtmux, guint64 mdat_pos,
|
||||
guint64 mdat_size, guint64 * offset)
|
||||
guint64 mdat_size, guint64 * offset, gboolean fsync_after)
|
||||
{
|
||||
GstSegment segment;
|
||||
|
||||
|
@ -1609,7 +1612,8 @@ gst_qt_mux_update_mdat_size (GstQTMux * qtmux, guint64 mdat_pos,
|
|||
segment.start = mdat_pos;
|
||||
gst_pad_push_event (qtmux->srcpad, gst_event_new_segment (&segment));
|
||||
|
||||
return gst_qt_mux_send_mdat_header (qtmux, offset, mdat_size, TRUE);
|
||||
return gst_qt_mux_send_mdat_header (qtmux, offset, mdat_size, TRUE,
|
||||
fsync_after);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
@ -1721,7 +1725,8 @@ gst_qt_mux_set_header_on_caps (GstQTMux * mux, GstBuffer * buf)
|
|||
* size, but a smaller buffer is sent
|
||||
*/
|
||||
static GstFlowReturn
|
||||
gst_qt_mux_send_free_atom (GstQTMux * qtmux, guint64 * off, guint32 size)
|
||||
gst_qt_mux_send_free_atom (GstQTMux * qtmux, guint64 * off, guint32 size,
|
||||
gboolean fsync_after)
|
||||
{
|
||||
Atom *node_header;
|
||||
GstBuffer *buf;
|
||||
|
@ -1746,6 +1751,9 @@ gst_qt_mux_send_free_atom (GstQTMux * qtmux, guint64 * off, guint32 size)
|
|||
buf = _gst_buffer_new_take_data (data, offset);
|
||||
g_free (node_header);
|
||||
|
||||
if (fsync_after)
|
||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_SYNC_AFTER);
|
||||
|
||||
GST_LOG_OBJECT (qtmux, "Pushing free atom");
|
||||
ret = gst_qt_mux_send_buffer (qtmux, buf, off, FALSE);
|
||||
|
||||
|
@ -1804,7 +1812,7 @@ gst_qt_mux_configure_moov (GstQTMux * qtmux)
|
|||
|
||||
static GstFlowReturn
|
||||
gst_qt_mux_send_moov (GstQTMux * qtmux, guint64 * _offset,
|
||||
guint64 padded_moov_size, gboolean mind_fast)
|
||||
guint64 padded_moov_size, gboolean mind_fast, gboolean fsync_after)
|
||||
{
|
||||
guint64 offset = 0, size = 0;
|
||||
guint8 *data;
|
||||
|
@ -1829,13 +1837,18 @@ gst_qt_mux_send_moov (GstQTMux * qtmux, guint64 * _offset,
|
|||
* (apparently used by a flumotion util) */
|
||||
if (qtmux->state == GST_QT_MUX_STATE_EOS)
|
||||
gst_qt_mux_set_header_on_caps (qtmux, buf);
|
||||
|
||||
if (fsync_after)
|
||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_SYNC_AFTER);
|
||||
ret = gst_qt_mux_send_buffer (qtmux, buf, _offset, mind_fast);
|
||||
|
||||
/* Write out a free atom if needed */
|
||||
if (ret == GST_FLOW_OK && offset < padded_moov_size) {
|
||||
GST_LOG_OBJECT (qtmux, "Writing out free atom of size %u",
|
||||
(guint32) (padded_moov_size - offset));
|
||||
ret = gst_qt_mux_send_free_atom (qtmux, _offset, padded_moov_size - offset);
|
||||
ret =
|
||||
gst_qt_mux_send_free_atom (qtmux, _offset, padded_moov_size - offset,
|
||||
fsync_after);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -2077,7 +2090,9 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
|
|||
qtmux->mdat_pos = qtmux->header_size;
|
||||
/* extended atom in case we go over 4GB while writing and need
|
||||
* the full 64-bit atom */
|
||||
ret = gst_qt_mux_send_mdat_header (qtmux, &qtmux->header_size, 0, TRUE);
|
||||
ret =
|
||||
gst_qt_mux_send_mdat_header (qtmux, &qtmux->header_size, 0, TRUE,
|
||||
FALSE);
|
||||
break;
|
||||
case GST_QT_MUX_MODE_ROBUST_RECORDING:
|
||||
|
||||
|
@ -2094,7 +2109,9 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
|
|||
/* Extra 8 bytes for the padding free atom header */
|
||||
guint padding = (guint) (16 - (qtmux->header_size % 8));
|
||||
GST_LOG_OBJECT (qtmux, "Rounding ftyp by %u bytes", padding);
|
||||
ret = gst_qt_mux_send_free_atom (qtmux, &qtmux->header_size, padding);
|
||||
ret =
|
||||
gst_qt_mux_send_free_atom (qtmux, &qtmux->header_size, padding,
|
||||
FALSE);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
}
|
||||
|
@ -2109,11 +2126,11 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
|
|||
gst_qt_mux_configure_moov (qtmux);
|
||||
gst_qt_mux_setup_metadata (qtmux);
|
||||
/* Empty free atom to begin, starting on an 8-byte boundary */
|
||||
ret = gst_qt_mux_send_free_atom (qtmux, &qtmux->header_size, 8);
|
||||
ret = gst_qt_mux_send_free_atom (qtmux, &qtmux->header_size, 8, FALSE);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
/* Moov header, not padded yet */
|
||||
ret = gst_qt_mux_send_moov (qtmux, &qtmux->header_size, 0, FALSE);
|
||||
ret = gst_qt_mux_send_moov (qtmux, &qtmux->header_size, 0, FALSE, FALSE);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
/* The moov we just sent contains the 'base' size of the moov, before
|
||||
|
@ -2148,14 +2165,14 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
|
|||
/* Now that we know how much reserved space is targetted,
|
||||
* output a free atom to fill the extra reserved */
|
||||
ret = gst_qt_mux_send_free_atom (qtmux, &qtmux->header_size,
|
||||
qtmux->reserved_moov_size - qtmux->base_moov_size);
|
||||
qtmux->reserved_moov_size - qtmux->base_moov_size, FALSE);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
/* Then a free atom containing 'pong' buffer, with an
|
||||
* extra 8 bytes to account for the free atom header itself */
|
||||
ret = gst_qt_mux_send_free_atom (qtmux, &qtmux->header_size,
|
||||
qtmux->reserved_moov_size + 8);
|
||||
qtmux->reserved_moov_size + 8, FALSE);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
|
@ -2168,7 +2185,9 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
|
|||
qtmux->mdat_pos = qtmux->header_size;
|
||||
/* extended atom in case we go over 4GB while writing and need
|
||||
* the full 64-bit atom */
|
||||
ret = gst_qt_mux_send_mdat_header (qtmux, &qtmux->header_size, 0, TRUE);
|
||||
ret =
|
||||
gst_qt_mux_send_mdat_header (qtmux, &qtmux->header_size, 0, TRUE,
|
||||
FALSE);
|
||||
break;
|
||||
case GST_QT_MUX_MODE_FAST_START:
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
|
@ -2195,7 +2214,7 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
|
|||
/* prepare moov and/or tags */
|
||||
gst_qt_mux_configure_moov (qtmux);
|
||||
gst_qt_mux_setup_metadata (qtmux);
|
||||
ret = gst_qt_mux_send_moov (qtmux, &qtmux->header_size, 0, FALSE);
|
||||
ret = gst_qt_mux_send_moov (qtmux, &qtmux->header_size, 0, FALSE, FALSE);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
/* extra atoms */
|
||||
|
@ -2432,7 +2451,7 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
segment.start = qtmux->moov_pos;
|
||||
gst_pad_push_event (qtmux->srcpad, gst_event_new_segment (&segment));
|
||||
/* no need to seek back */
|
||||
return gst_qt_mux_send_moov (qtmux, NULL, 0, FALSE);
|
||||
return gst_qt_mux_send_moov (qtmux, NULL, 0, FALSE, FALSE);
|
||||
}
|
||||
case GST_QT_MUX_MODE_ROBUST_RECORDING:{
|
||||
ret = gst_qt_mux_robust_recording_rewrite_moov (qtmux);
|
||||
|
@ -2442,7 +2461,7 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
* it's been 0, which means 'rest of the file'
|
||||
* No need to seek back after this, we won't write any more */
|
||||
return gst_qt_mux_update_mdat_size (qtmux, qtmux->mdat_pos,
|
||||
qtmux->mdat_size, NULL);
|
||||
qtmux->mdat_size, NULL, TRUE);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
@ -2494,7 +2513,7 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
/* write out moov and extra atoms */
|
||||
/* note: as of this point, we no longer care about tracking written data size,
|
||||
* since there is no more use for it anyway */
|
||||
ret = gst_qt_mux_send_moov (qtmux, NULL, 0, FALSE);
|
||||
ret = gst_qt_mux_send_moov (qtmux, NULL, 0, FALSE, FALSE);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
|
@ -2509,7 +2528,7 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
/* mdat needs update iff not using faststart */
|
||||
GST_DEBUG_OBJECT (qtmux, "updating mdat size");
|
||||
ret = gst_qt_mux_update_mdat_size (qtmux, qtmux->mdat_pos,
|
||||
qtmux->mdat_size, NULL);
|
||||
qtmux->mdat_size, NULL, FALSE);
|
||||
/* note; no seeking back to the end of file is done,
|
||||
* since we no longer write anything anyway */
|
||||
break;
|
||||
|
@ -2519,7 +2538,7 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
/* send mdat atom and move buffered data into it */
|
||||
/* mdat_size = accumulated (buffered data) */
|
||||
ret = gst_qt_mux_send_mdat_header (qtmux, NULL, qtmux->mdat_size,
|
||||
large_file);
|
||||
large_file, FALSE);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
ret = gst_qt_mux_send_buffered_data (qtmux, NULL);
|
||||
|
@ -2594,7 +2613,7 @@ flush:
|
|||
atom_array_get_len (&pad->fragment_buffers), total_size);
|
||||
if (ret == GST_FLOW_OK)
|
||||
ret = gst_qt_mux_send_mdat_header (qtmux, &qtmux->header_size, total_size,
|
||||
FALSE);
|
||||
FALSE, FALSE);
|
||||
for (i = 0; i < atom_array_get_len (&pad->fragment_buffers); i++) {
|
||||
if (G_LIKELY (ret == GST_FLOW_OK))
|
||||
ret = gst_qt_mux_send_buffer (qtmux,
|
||||
|
@ -2709,7 +2728,9 @@ gst_qt_mux_robust_recording_rewrite_moov (GstQTMux * qtmux)
|
|||
segment.start = new_moov_offset;
|
||||
gst_pad_push_event (qtmux->srcpad, gst_event_new_segment (&segment));
|
||||
|
||||
ret = gst_qt_mux_send_moov (qtmux, NULL, qtmux->reserved_moov_size, FALSE);
|
||||
ret =
|
||||
gst_qt_mux_send_moov (qtmux, NULL, qtmux->reserved_moov_size, FALSE,
|
||||
TRUE);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
|
@ -2753,7 +2774,7 @@ gst_qt_mux_robust_recording_rewrite_moov (GstQTMux * qtmux)
|
|||
segment.start = freeA_offset;
|
||||
gst_pad_push_event (qtmux->srcpad, gst_event_new_segment (&segment));
|
||||
|
||||
ret = gst_qt_mux_send_free_atom (qtmux, NULL, new_freeA_size);
|
||||
ret = gst_qt_mux_send_free_atom (qtmux, NULL, new_freeA_size, TRUE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue