mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-09 08:55:33 +00:00
qtmux: protect access to GstElement.sinkpads
This commit is contained in:
parent
e2462005fb
commit
5766731bd4
1 changed files with 107 additions and 28 deletions
|
@ -750,7 +750,6 @@ gst_qt_mux_reset (GstQTMux * qtmux, gboolean alloc)
|
|||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
gst_tag_setter_reset_tags (GST_TAG_SETTER (qtmux));
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
/* reset pad data */
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
|
@ -772,6 +771,7 @@ gst_qt_mux_reset (GstQTMux * qtmux, gboolean alloc)
|
|||
atom_moov_add_trak (qtmux->moov, qtpad->trak);
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
qtmux->current_pad = NULL;
|
||||
qtmux->current_chunk_size = 0;
|
||||
|
@ -1843,6 +1843,7 @@ gst_qt_mux_setup_metadata (GstQTMux * qtmux)
|
|||
GST_DEBUG_OBJECT (qtmux, "No new tags received");
|
||||
}
|
||||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qpad = GST_QT_MUX_PAD (l->data);
|
||||
|
||||
|
@ -1856,6 +1857,7 @@ gst_qt_mux_setup_metadata (GstQTMux * qtmux)
|
|||
GST_DEBUG_OBJECT (qpad, "No new tags received");
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
}
|
||||
|
||||
static inline GstBuffer *
|
||||
|
@ -2293,12 +2295,15 @@ gst_qt_mux_send_moov (GstQTMux * qtmux, guint64 * _offset,
|
|||
|
||||
/* update modification times */
|
||||
qtmux->moov->mvhd.time_info.modification_time = current_time;
|
||||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qtpad = (GstQTMuxPad *) l->data;
|
||||
|
||||
qtpad->trak->mdia.mdhd.time_info.modification_time = current_time;
|
||||
qtpad->trak->tkhd.modification_time = current_time;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
/* serialize moov */
|
||||
offset = size = 0;
|
||||
|
@ -2431,17 +2436,21 @@ gst_qt_mux_prepare_moov_recovery (GstQTMux * qtmux)
|
|||
|
||||
gst_qt_mux_prepare_ftyp (qtmux, &ftyp, &prefix);
|
||||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
if (!atoms_recov_write_headers (qtmux->moov_recov_file, ftyp, prefix,
|
||||
qtmux->moov, qtmux->timescale,
|
||||
g_list_length (GST_ELEMENT (qtmux)->sinkpads))) {
|
||||
GST_WARNING_OBJECT (qtmux, "Failed to write moov recovery file " "headers");
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
goto fail;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
atom_ftyp_free (ftyp);
|
||||
if (prefix)
|
||||
gst_buffer_unref (prefix);
|
||||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qpad = (GstQTMuxPad *) l->data;
|
||||
/* write info for each stream */
|
||||
|
@ -2452,6 +2461,7 @@ gst_qt_mux_prepare_moov_recovery (GstQTMux * qtmux)
|
|||
break;
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
return;
|
||||
|
||||
|
@ -2692,6 +2702,7 @@ find_video_sample_duration (GstQTMux * qtmux, guint * dur_n, guint * dur_d)
|
|||
|
||||
/* Find the (first) video track and assume that we have to output
|
||||
* in that size */
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *tmp_qpad = (GstQTMuxPad *) l->data;
|
||||
|
||||
|
@ -2701,6 +2712,7 @@ find_video_sample_duration (GstQTMux * qtmux, guint * dur_n, guint * dur_d)
|
|||
break;
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
if (l == NULL) {
|
||||
GST_INFO_OBJECT (qtmux,
|
||||
|
@ -2763,6 +2775,7 @@ find_best_pad_prefill_start (GstQTMux * qtmux)
|
|||
/* If interleave limits have been specified and the current pad is within
|
||||
* those interleave limits, pick that one, otherwise let's try to figure out
|
||||
* the next best one. */
|
||||
|
||||
if (qtmux->current_pad &&
|
||||
(qtmux->interleave_bytes != 0 || qtmux->interleave_time != 0) &&
|
||||
(qtmux->interleave_bytes == 0
|
||||
|
@ -2775,10 +2788,14 @@ find_best_pad_prefill_start (GstQTMux * qtmux)
|
|||
if (qtmux->current_pad->total_duration < qtmux->reserved_max_duration) {
|
||||
best_pad = qtmux->current_pad;
|
||||
}
|
||||
} else if (GST_ELEMENT_CAST (qtmux)->sinkpads->next) {
|
||||
/* Attempt to try another pad if we have one. Otherwise use the only pad
|
||||
* present */
|
||||
best_pad = qtmux->current_pad = NULL;
|
||||
} else {
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
if (GST_ELEMENT_CAST (qtmux)->sinkpads->next) {
|
||||
/* Attempt to try another pad if we have one. Otherwise use the only pad
|
||||
* present */
|
||||
best_pad = qtmux->current_pad = NULL;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
}
|
||||
|
||||
/* The next best pad is the one which has the lowest timestamp and hasn't
|
||||
|
@ -2787,6 +2804,7 @@ find_best_pad_prefill_start (GstQTMux * qtmux)
|
|||
GList *l;
|
||||
GstClockTime best_time = GST_CLOCK_TIME_NONE;
|
||||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qtpad = (GstQTMuxPad *) l->data;
|
||||
GstClockTime timestamp;
|
||||
|
@ -2802,6 +2820,7 @@ find_best_pad_prefill_start (GstQTMux * qtmux)
|
|||
best_time = timestamp;
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
}
|
||||
|
||||
return best_pad;
|
||||
|
@ -2821,17 +2840,22 @@ gst_qt_mux_prefill_samples (GstQTMux * qtmux)
|
|||
|
||||
/* Update expected sample sizes/durations as needed, this is for raw
|
||||
* audio where samples are actual audio samples. */
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qpad = (GstQTMuxPad *) l->data;
|
||||
|
||||
if (!prefill_update_sample_size (qtmux, qpad))
|
||||
if (!prefill_update_sample_size (qtmux, qpad)) {
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
if (qtmux_klass->format == GST_QT_MUX_FORMAT_QT) {
|
||||
/* For the first sample check/update timecode as needed. We do that before
|
||||
* all actual samples as the code in gst_qt_mux_add_buffer() does it with
|
||||
* initial buffer directly, not with last_buf */
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qpad = (GstQTMuxPad *) l->data;
|
||||
GstBuffer *buffer =
|
||||
|
@ -2866,6 +2890,7 @@ gst_qt_mux_prefill_samples (GstQTMux * qtmux)
|
|||
if (buffer)
|
||||
gst_buffer_unref (buffer);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
}
|
||||
|
||||
while ((qpad = find_best_pad_prefill_start (qtmux))) {
|
||||
|
@ -3238,6 +3263,9 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
|
|||
FALSE);
|
||||
break;
|
||||
case GST_QT_MUX_MODE_ROBUST_RECORDING_PREFILL:
|
||||
{
|
||||
guint32 atom_size;
|
||||
|
||||
ret = gst_qt_mux_prepare_and_send_ftyp (qtmux);
|
||||
if (ret != GST_FLOW_OK)
|
||||
break;
|
||||
|
@ -3263,18 +3291,20 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
|
|||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
atom_size = 12 * g_list_length (GST_ELEMENT (qtmux)->sinkpads) + 8;
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
/* last_moov_size now contains the full size of the moov, moov_pos the
|
||||
* position. This allows us to rewrite it in the very end as needed */
|
||||
qtmux->reserved_moov_size =
|
||||
qtmux->last_moov_size +
|
||||
12 * g_list_length (GST_ELEMENT (qtmux)->sinkpads) + 8;
|
||||
qtmux->reserved_moov_size = qtmux->last_moov_size + atom_size;
|
||||
|
||||
/* Send an additional free atom at the end so we definitely have space
|
||||
* to rewrite the moov header at the end and remove the samples that
|
||||
* were not actually written */
|
||||
ret =
|
||||
gst_qt_mux_send_free_atom (qtmux, &qtmux->header_size,
|
||||
12 * g_list_length (GST_ELEMENT (qtmux)->sinkpads) + 8, FALSE);
|
||||
gst_qt_mux_send_free_atom (qtmux, &qtmux->header_size, atom_size,
|
||||
FALSE);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
|
@ -3317,6 +3347,7 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
|
|||
qtmux->current_pad = NULL;
|
||||
qtmux->longest_chunk = GST_CLOCK_TIME_NONE;
|
||||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qtpad = (GstQTMuxPad *) l->data;
|
||||
|
||||
|
@ -3326,8 +3357,10 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
|
|||
qtpad->last_dts = GST_CLOCK_TIME_NONE;
|
||||
qtpad->sample_offset = 0;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
break;
|
||||
}
|
||||
case GST_QT_MUX_MODE_FAST_START:
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
qtmux->fast_start_file = g_fopen (qtmux->fast_start_file_path, "wb+");
|
||||
|
@ -3395,9 +3428,14 @@ static GstFlowReturn
|
|||
gst_qt_mux_send_last_buffers (GstQTMux * qtmux)
|
||||
{
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
GList *l;
|
||||
GList *sinkpads, *l;
|
||||
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
sinkpads = g_list_copy_deep (GST_ELEMENT_CAST (qtmux)->sinkpads,
|
||||
(GCopyFunc) gst_object_ref, NULL);
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
for (l = sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qtpad = (GstQTMuxPad *) l->data;
|
||||
|
||||
/* avoid add_buffer complaining if not negotiated
|
||||
|
@ -3418,6 +3456,8 @@ gst_qt_mux_send_last_buffers (GstQTMux * qtmux)
|
|||
}
|
||||
}
|
||||
|
||||
g_list_free_full (sinkpads, gst_object_unref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3432,6 +3472,7 @@ gst_qt_mux_update_global_statistics (GstQTMux * qtmux)
|
|||
|
||||
qtmux->first_ts = qtmux->last_dts = GST_CLOCK_TIME_NONE;
|
||||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qtpad = (GstQTMuxPad *) l->data;
|
||||
|
||||
|
@ -3484,9 +3525,11 @@ gst_qt_mux_update_global_statistics (GstQTMux * qtmux)
|
|||
atom_trak_update_bitrates (qtpad->trak, avgbitrate, maxbitrate);
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
/* need to update values on subtitle traks now that we know the
|
||||
* max width and height */
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qtpad = (GstQTMuxPad *) l->data;
|
||||
|
||||
|
@ -3500,6 +3543,7 @@ gst_qt_mux_update_global_statistics (GstQTMux * qtmux)
|
|||
atom_trak_tx3g_update_dimension (qtpad->trak, max_width, max_height);
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
}
|
||||
|
||||
/* Called after gst_qt_mux_update_global_statistics() updates the
|
||||
|
@ -3514,6 +3558,7 @@ gst_qt_mux_update_edit_lists (GstQTMux * qtmux)
|
|||
/* add/update EDTSs for late streams. configure_moov will have
|
||||
* set the trak durations above by summing the sample tables,
|
||||
* here we extend that if needing to insert an empty segment */
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qtpad = (GstQTMuxPad *) l->data;
|
||||
|
||||
|
@ -3587,6 +3632,7 @@ gst_qt_mux_update_edit_lists (GstQTMux * qtmux)
|
|||
}
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
@ -3626,7 +3672,7 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
gboolean ret = GST_FLOW_OK;
|
||||
guint64 offset = 0, size = 0;
|
||||
gboolean large_file;
|
||||
GList *l;
|
||||
GList *sinkpads, *l;
|
||||
|
||||
GST_DEBUG_OBJECT (qtmux, "Updating remaining values and sending last data");
|
||||
|
||||
|
@ -3641,18 +3687,28 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
}
|
||||
|
||||
gst_qt_mux_update_global_statistics (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
sinkpads = g_list_copy_deep (GST_ELEMENT_CAST (qtmux)->sinkpads,
|
||||
(GCopyFunc) gst_object_ref, NULL);
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
for (l = sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qtpad = (GstQTMuxPad *) l->data;
|
||||
|
||||
if (qtpad->tc_pos != -1) {
|
||||
/* File is being stopped and timecode hasn't been updated. Update it now
|
||||
* with whatever we have */
|
||||
ret = gst_qt_mux_update_timecode (qtmux, qtpad);
|
||||
if (ret != GST_FLOW_OK)
|
||||
if (ret != GST_FLOW_OK) {
|
||||
g_list_free_full (sinkpads, gst_object_unref);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free_full (sinkpads, gst_object_unref);
|
||||
|
||||
switch (qtmux->mux_mode) {
|
||||
case GST_QT_MUX_MODE_FRAGMENTED:{
|
||||
GstSegment segment;
|
||||
|
@ -3698,6 +3754,7 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
GList *l;
|
||||
guint32 next_track_id = qtmux->moov->mvhd.next_track_id;
|
||||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qpad = (GstQTMuxPad *) l->data;
|
||||
guint64 block_idx;
|
||||
|
@ -3817,6 +3874,8 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
qpad->trak->tkhd.track_ID = next_track_id++;
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
qtmux->moov->mvhd.next_track_id = next_track_id;
|
||||
|
||||
gst_qt_mux_update_global_statistics (qtmux);
|
||||
|
@ -3828,6 +3887,7 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
* reserved for this in the moov and the pre-finalized moov would have
|
||||
* broken A/V synchronization. Error out here now
|
||||
*/
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qpad = (GstQTMuxPad *) l->data;
|
||||
|
||||
|
@ -3836,9 +3896,12 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
GST_ELEMENT_ERROR (qtmux, STREAM, MUX, (NULL),
|
||||
("Can't support gaps in prefill mode"));
|
||||
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
gst_qt_mux_setup_metadata (qtmux);
|
||||
atom_moov_chunks_set_offset (qtmux->moov, qtmux->header_size);
|
||||
|
@ -4985,6 +5048,7 @@ find_best_pad (GstQTMux * qtmux)
|
|||
guint64 smallest_offset = G_MAXUINT64;
|
||||
guint64 chunk_offset = 0;
|
||||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qtpad = (GstQTMuxPad *) l->data;
|
||||
const TrakBufferEntryInfo *sample_entry;
|
||||
|
@ -5028,6 +5092,7 @@ find_best_pad (GstQTMux * qtmux)
|
|||
chunk_offset = sample_entry->chunk_offset;
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
if (chunk_offset != qtmux->current_chunk_offset) {
|
||||
qtmux->current_pad = NULL;
|
||||
|
@ -5054,20 +5119,25 @@ find_best_pad (GstQTMux * qtmux)
|
|||
GST_DEBUG_OBJECT (qtmux, "Reusing pad %s:%s",
|
||||
GST_DEBUG_PAD_NAME (best_pad));
|
||||
}
|
||||
} else if (GST_ELEMENT (qtmux)->sinkpads->next) {
|
||||
/* Only switch pads if we have more than one, otherwise
|
||||
* we can just put everything into a single chunk and save
|
||||
* a few bytes of offsets
|
||||
*/
|
||||
if (qtmux->current_pad)
|
||||
GST_DEBUG_OBJECT (qtmux, "Switching from pad %s:%s",
|
||||
GST_DEBUG_PAD_NAME (qtmux->current_pad));
|
||||
best_pad = qtmux->current_pad = NULL;
|
||||
} else {
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
if (GST_ELEMENT (qtmux)->sinkpads->next) {
|
||||
/* Only switch pads if we have more than one, otherwise
|
||||
* we can just put everything into a single chunk and save
|
||||
* a few bytes of offsets
|
||||
*/
|
||||
if (qtmux->current_pad)
|
||||
GST_DEBUG_OBJECT (qtmux, "Switching from pad %s:%s",
|
||||
GST_DEBUG_PAD_NAME (qtmux->current_pad));
|
||||
best_pad = qtmux->current_pad = NULL;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
}
|
||||
|
||||
if (!best_pad) {
|
||||
GstClockTime best_time = GST_CLOCK_TIME_NONE;
|
||||
|
||||
GST_OBJECT_LOCK (qtmux);
|
||||
for (l = GST_ELEMENT_CAST (qtmux)->sinkpads; l; l = l->next) {
|
||||
GstQTMuxPad *qtpad = (GstQTMuxPad *) l->data;
|
||||
GstBuffer *tmp_buf;
|
||||
|
@ -5097,6 +5167,7 @@ find_best_pad (GstQTMux * qtmux)
|
|||
if (tmp_buf)
|
||||
gst_buffer_unref (tmp_buf);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (qtmux);
|
||||
|
||||
if (best_pad) {
|
||||
GST_DEBUG_OBJECT (qtmux, "Choosing pad %s:%s",
|
||||
|
@ -5113,12 +5184,18 @@ static gboolean
|
|||
gst_qt_mux_are_all_pads_eos (GstQTMux * mux)
|
||||
{
|
||||
GList *l;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
GST_OBJECT_LOCK (mux);
|
||||
for (l = GST_ELEMENT_CAST (mux)->sinkpads; l; l = l->next) {
|
||||
if (!gst_aggregator_pad_is_eos (GST_AGGREGATOR_PAD (l->data)))
|
||||
return FALSE;
|
||||
if (!gst_aggregator_pad_is_eos (GST_AGGREGATOR_PAD (l->data))) {
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
GST_OBJECT_UNLOCK (mux);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
@ -6351,12 +6428,14 @@ gst_qt_mux_release_pad (GstElement * element, GstPad * pad)
|
|||
mux->current_chunk_duration = 0;
|
||||
}
|
||||
|
||||
GST_OBJECT_LOCK (mux);
|
||||
if (GST_ELEMENT (mux)->sinkpads == NULL) {
|
||||
/* No more outstanding request pads, reset our counters */
|
||||
mux->video_pads = 0;
|
||||
mux->audio_pads = 0;
|
||||
mux->subtitle_pads = 0;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (mux);
|
||||
}
|
||||
|
||||
static GstAggregatorPad *
|
||||
|
|
Loading…
Reference in a new issue