mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 05:59:10 +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
|
* (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
|
* 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) */
|
* make use of this additional information at the moment) */
|
||||||
if (qtdemux->fragmented) {
|
if (qtdemux->fragmented && !qtdemux->fragmented_seek_pending) {
|
||||||
stream->to_sample = G_MAXUINT32;
|
stream->to_sample = G_MAXUINT32;
|
||||||
return TRUE;
|
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 */
|
/* 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);
|
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++) {
|
for (i = 0; i < qtdemux->n_streams; i++) {
|
||||||
const QtDemuxRandomAccessEntry *entry;
|
const QtDemuxRandomAccessEntry *entry;
|
||||||
QtDemuxStream *stream;
|
QtDemuxStream *stream;
|
||||||
|
@ -5611,24 +5619,6 @@ gst_qtdemux_do_fragmented_seek (GstQTDemux * qtdemux)
|
||||||
|
|
||||||
stream = qtdemux->streams[i];
|
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)
|
if (stream->ra_entries == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -5654,11 +5644,37 @@ gst_qtdemux_do_fragmented_seek (GstQTDemux * qtdemux)
|
||||||
best_entry = entry;
|
best_entry = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* no luck, will handle seek otherwise */
|
||||||
if (best_entry == NULL) {
|
if (best_entry == NULL) {
|
||||||
GST_OBJECT_UNLOCK (qtdemux);
|
GST_OBJECT_UNLOCK (qtdemux);
|
||||||
return FALSE;
|
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 "
|
GST_INFO_OBJECT (qtdemux, "seek to %" GST_TIME_FORMAT ", best fragment "
|
||||||
"moof offset: %" G_GUINT64_FORMAT ", ts %" GST_TIME_FORMAT,
|
"moof offset: %" G_GUINT64_FORMAT ", ts %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (qtdemux->streams[0]->time_position),
|
GST_TIME_ARGS (qtdemux->streams[0]->time_position),
|
||||||
|
@ -5694,9 +5710,12 @@ gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)
|
||||||
|
|
||||||
if (qtdemux->fragmented_seek_pending) {
|
if (qtdemux->fragmented_seek_pending) {
|
||||||
GST_INFO_OBJECT (qtdemux, "pending fragmented seek");
|
GST_INFO_OBJECT (qtdemux, "pending fragmented seek");
|
||||||
gst_qtdemux_do_fragmented_seek (qtdemux);
|
if (gst_qtdemux_do_fragmented_seek (qtdemux)) {
|
||||||
GST_INFO_OBJECT (qtdemux, "fragmented seek done!");
|
GST_INFO_OBJECT (qtdemux, "fragmented seek done!");
|
||||||
qtdemux->fragmented_seek_pending = FALSE;
|
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
|
/* Figure out the next stream sample to output, min_time is expressed in
|
||||||
|
|
Loading…
Reference in a new issue