mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 00:06:36 +00:00
qtdemux: fix seeking in fragmented file without mfra random access info
... which no longer worked due to unconditionally clearing sample info and ending up in inconsistent state. Let's tread a bit more carefully and also allow for the old seek handling that resorts to scanning if no mfra info is available.
This commit is contained in:
parent
52c017caca
commit
854f85acb4
1 changed files with 41 additions and 22 deletions
|
@ -4816,9 +4816,15 @@ gst_qtdemux_activate_segment (GstQTDemux * qtdemux, QtDemuxStream * stream,
|
|||
* (FIXME: doesn't seem to work so well with ismv and wmv, as no parser; the
|
||||
* tfra entries tells us which trun/sample the key unit is in, but we don't
|
||||
* make use of this additional information at the moment) */
|
||||
if (qtdemux->fragmented) {
|
||||
if (qtdemux->fragmented && !qtdemux->fragmented_seek_pending) {
|
||||
stream->to_sample = G_MAXUINT32;
|
||||
return TRUE;
|
||||
} else {
|
||||
/* well, it will be taken care of below */
|
||||
qtdemux->fragmented_seek_pending = FALSE;
|
||||
/* FIXME ideally the do_fragmented_seek can be done right here,
|
||||
* rather than at loop level
|
||||
* (which might even allow handling edit lists in a fragmented file) */
|
||||
}
|
||||
|
||||
/* We don't need to look for a sample in push-based */
|
||||
|
@ -5604,6 +5610,8 @@ gst_qtdemux_do_fragmented_seek (GstQTDemux * qtdemux)
|
|||
|
||||
g_assert (qtdemux->n_streams > 0);
|
||||
|
||||
/* first see if we can determine where to go to using mfra,
|
||||
* before we start clearing things */
|
||||
for (i = 0; i < qtdemux->n_streams; i++) {
|
||||
const QtDemuxRandomAccessEntry *entry;
|
||||
QtDemuxStream *stream;
|
||||
|
@ -5611,24 +5619,6 @@ gst_qtdemux_do_fragmented_seek (GstQTDemux * qtdemux)
|
|||
|
||||
stream = qtdemux->streams[i];
|
||||
|
||||
g_free (stream->samples);
|
||||
stream->samples = NULL;
|
||||
stream->n_samples = 0;
|
||||
stream->stbl_index = -1; /* no samples have yet been parsed */
|
||||
stream->sample_index = -1;
|
||||
|
||||
if (stream->protection_scheme_info) {
|
||||
/* Clear out any old cenc crypto info entries as we'll move to a new moof */
|
||||
if (stream->protection_scheme_type == FOURCC_cenc) {
|
||||
QtDemuxCencSampleSetInfo *info =
|
||||
(QtDemuxCencSampleSetInfo *) stream->protection_scheme_info;
|
||||
if (info->crypto_info) {
|
||||
g_ptr_array_free (info->crypto_info, TRUE);
|
||||
info->crypto_info = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stream->ra_entries == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -5654,11 +5644,37 @@ gst_qtdemux_do_fragmented_seek (GstQTDemux * qtdemux)
|
|||
best_entry = entry;
|
||||
}
|
||||
|
||||
/* no luck, will handle seek otherwise */
|
||||
if (best_entry == NULL) {
|
||||
GST_OBJECT_UNLOCK (qtdemux);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* ok, now we can prepare for processing as of located moof */
|
||||
for (i = 0; i < qtdemux->n_streams; i++) {
|
||||
QtDemuxStream *stream;
|
||||
|
||||
stream = qtdemux->streams[i];
|
||||
|
||||
g_free (stream->samples);
|
||||
stream->samples = NULL;
|
||||
stream->n_samples = 0;
|
||||
stream->stbl_index = -1; /* no samples have yet been parsed */
|
||||
stream->sample_index = -1;
|
||||
|
||||
if (stream->protection_scheme_info) {
|
||||
/* Clear out any old cenc crypto info entries as we'll move to a new moof */
|
||||
if (stream->protection_scheme_type == FOURCC_cenc) {
|
||||
QtDemuxCencSampleSetInfo *info =
|
||||
(QtDemuxCencSampleSetInfo *) stream->protection_scheme_info;
|
||||
if (info->crypto_info) {
|
||||
g_ptr_array_free (info->crypto_info, TRUE);
|
||||
info->crypto_info = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GST_INFO_OBJECT (qtdemux, "seek to %" GST_TIME_FORMAT ", best fragment "
|
||||
"moof offset: %" G_GUINT64_FORMAT ", ts %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (qtdemux->streams[0]->time_position),
|
||||
|
@ -5694,9 +5710,12 @@ gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)
|
|||
|
||||
if (qtdemux->fragmented_seek_pending) {
|
||||
GST_INFO_OBJECT (qtdemux, "pending fragmented seek");
|
||||
gst_qtdemux_do_fragmented_seek (qtdemux);
|
||||
GST_INFO_OBJECT (qtdemux, "fragmented seek done!");
|
||||
qtdemux->fragmented_seek_pending = FALSE;
|
||||
if (gst_qtdemux_do_fragmented_seek (qtdemux)) {
|
||||
GST_INFO_OBJECT (qtdemux, "fragmented seek done!");
|
||||
qtdemux->fragmented_seek_pending = FALSE;
|
||||
} else {
|
||||
GST_INFO_OBJECT (qtdemux, "fragmented seek still pending");
|
||||
}
|
||||
}
|
||||
|
||||
/* Figure out the next stream sample to output, min_time is expressed in
|
||||
|
|
Loading…
Reference in a new issue