mxfdec: calculate the index in display order
This should fix seeking for open GOP files as well. Reviewed-by: Tomas Härdin <tomas.hardin@codemill.se> Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
@@ -233,6 +233,7 @@ typedef struct MXFIndexTable {
|
|||||||
int nb_segments;
|
int nb_segments;
|
||||||
MXFIndexTableSegment **segments; /* sorted by IndexStartPosition */
|
MXFIndexTableSegment **segments; /* sorted by IndexStartPosition */
|
||||||
AVIndexEntry *fake_index; /* used for calling ff_index_search_timestamp() */
|
AVIndexEntry *fake_index; /* used for calling ff_index_search_timestamp() */
|
||||||
|
int8_t *offsets; /* temporal offsets for display order to stored order conversion */
|
||||||
} MXFIndexTable;
|
} MXFIndexTable;
|
||||||
|
|
||||||
typedef struct MXFContext {
|
typedef struct MXFContext {
|
||||||
@@ -1334,6 +1335,7 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta
|
|||||||
{
|
{
|
||||||
int i, j, x;
|
int i, j, x;
|
||||||
int8_t max_temporal_offset = -128;
|
int8_t max_temporal_offset = -128;
|
||||||
|
uint8_t *flags;
|
||||||
|
|
||||||
/* first compute how many entries we have */
|
/* first compute how many entries we have */
|
||||||
for (i = 0; i < index_table->nb_segments; i++) {
|
for (i = 0; i < index_table->nb_segments; i++) {
|
||||||
@@ -1352,8 +1354,12 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!(index_table->ptses = av_calloc(index_table->nb_ptses, sizeof(int64_t))) ||
|
if (!(index_table->ptses = av_calloc(index_table->nb_ptses, sizeof(int64_t))) ||
|
||||||
!(index_table->fake_index = av_calloc(index_table->nb_ptses, sizeof(AVIndexEntry)))) {
|
!(index_table->fake_index = av_calloc(index_table->nb_ptses, sizeof(AVIndexEntry))) ||
|
||||||
|
!(index_table->offsets = av_calloc(index_table->nb_ptses, sizeof(int8_t))) ||
|
||||||
|
!(flags = av_calloc(index_table->nb_ptses, sizeof(uint8_t)))) {
|
||||||
av_freep(&index_table->ptses);
|
av_freep(&index_table->ptses);
|
||||||
|
av_freep(&index_table->fake_index);
|
||||||
|
av_freep(&index_table->offsets);
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1411,8 +1417,7 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
index_table->fake_index[x].timestamp = x;
|
flags[x] = !(s->flag_entries[j] & 0x30) ? AVINDEX_KEYFRAME : 0;
|
||||||
index_table->fake_index[x].flags = !(s->flag_entries[j] & 0x30) ? AVINDEX_KEYFRAME : 0;
|
|
||||||
|
|
||||||
if (index < 0 || index >= index_table->nb_ptses) {
|
if (index < 0 || index >= index_table->nb_ptses) {
|
||||||
av_log(mxf->fc, AV_LOG_ERROR,
|
av_log(mxf->fc, AV_LOG_ERROR,
|
||||||
@@ -1421,11 +1426,20 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
index_table->offsets[x] = offset;
|
||||||
index_table->ptses[index] = x;
|
index_table->ptses[index] = x;
|
||||||
max_temporal_offset = FFMAX(max_temporal_offset, offset);
|
max_temporal_offset = FFMAX(max_temporal_offset, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* calculate the fake index table in display order */
|
||||||
|
for (x = 0; x < index_table->nb_ptses; x++) {
|
||||||
|
index_table->fake_index[x].timestamp = x;
|
||||||
|
if (index_table->ptses[x] != AV_NOPTS_VALUE)
|
||||||
|
index_table->fake_index[index_table->ptses[x]].flags = flags[x];
|
||||||
|
}
|
||||||
|
av_freep(&flags);
|
||||||
|
|
||||||
index_table->first_dts = -max_temporal_offset;
|
index_table->first_dts = -max_temporal_offset;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3085,6 +3099,7 @@ static int mxf_read_close(AVFormatContext *s)
|
|||||||
av_freep(&mxf->index_tables[i].segments);
|
av_freep(&mxf->index_tables[i].segments);
|
||||||
av_freep(&mxf->index_tables[i].ptses);
|
av_freep(&mxf->index_tables[i].ptses);
|
||||||
av_freep(&mxf->index_tables[i].fake_index);
|
av_freep(&mxf->index_tables[i].fake_index);
|
||||||
|
av_freep(&mxf->index_tables[i].offsets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
av_freep(&mxf->index_tables);
|
av_freep(&mxf->index_tables);
|
||||||
@@ -3158,6 +3173,8 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
|
|||||||
/* behave as if we have a proper index */
|
/* behave as if we have a proper index */
|
||||||
if ((sample_time = ff_index_search_timestamp(t->fake_index, t->nb_ptses, sample_time, flags)) < 0)
|
if ((sample_time = ff_index_search_timestamp(t->fake_index, t->nb_ptses, sample_time, flags)) < 0)
|
||||||
return sample_time;
|
return sample_time;
|
||||||
|
/* get the stored order index from the display order index */
|
||||||
|
sample_time += t->offsets[sample_time];
|
||||||
} else {
|
} else {
|
||||||
/* no IndexEntryArray (one or more CBR segments)
|
/* no IndexEntryArray (one or more CBR segments)
|
||||||
* make sure we don't seek past the end */
|
* make sure we don't seek past the end */
|
||||||
|
|||||||
@@ -43,6 +43,6 @@ ret:-1 st: 1 flags:0 ts: 2.671667
|
|||||||
ret: 0 st: 1 flags:1 ts: 1.565833
|
ret: 0 st: 1 flags:1 ts: 1.565833
|
||||||
ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24711
|
ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24711
|
||||||
ret: 0 st:-1 flags:0 ts: 0.460008
|
ret: 0 st:-1 flags:0 ts: 0.460008
|
||||||
ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24711
|
ret: 0 st: 0 flags:1 dts: 0.360000 pts: 0.480000 pos: 211968 size: 24786
|
||||||
ret: 0 st:-1 flags:1 ts:-0.645825
|
ret: 0 st:-1 flags:1 ts:-0.645825
|
||||||
ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6656 size: 24801
|
ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6656 size: 24801
|
||||||
|
|||||||
Reference in New Issue
Block a user