int parsing_backward;
int64_t last_forward_tell;
int last_forward_partition;
- int current_edit_unit;
+ int64_t current_edit_unit;
int nb_index_tables;
MXFIndexTable *index_tables;
int edit_units_per_packet; ///< how many edit units to read at a time (PCM, OPAtom)
uint64_t footer_partition;
uint32_t nb_essence_containers;
+ if (mxf->partitions_count >= INT_MAX / 2)
+ return AVERROR_INVALIDDATA;
+
tmp_part = av_realloc_array(mxf->partitions, mxf->partitions_count + 1, sizeof(*mxf->partitions));
if (!tmp_part)
return AVERROR(ENOMEM);
*/
static int mxf_absolute_bodysid_offset(MXFContext *mxf, int body_sid, int64_t offset, int64_t *offset_out)
{
- int x;
MXFPartition *last_p = NULL;
+ int a, b, m, m0;
if (offset < 0)
return AVERROR(EINVAL);
- for (x = 0; x < mxf->partitions_count; x++) {
- MXFPartition *p = &mxf->partitions[x];
+ a = -1;
+ b = mxf->partitions_count;
- if (p->body_sid != body_sid)
- continue;
+ while (b - a > 1) {
+ m0 = m = (a + b) >> 1;
- if (p->body_offset > offset)
- break;
+ while (m < b && mxf->partitions[m].body_sid != body_sid)
+ m++;
- last_p = p;
+ if (m < b && mxf->partitions[m].body_offset <= offset)
+ a = m;
+ else
+ b = m0;
}
+ if (a >= 0)
+ last_p = &mxf->partitions[a];
+
if (last_p && (!last_p->essence_length || last_p->essence_length > (offset - last_p->body_offset))) {
*offset_out = last_p->essence_offset + (offset - last_p->body_offset);
return 0;
static void mxf_handle_small_eubc(AVFormatContext *s)
{
MXFContext *mxf = s->priv_data;
+ MXFTrack *track;
/* assuming non-OPAtom == frame wrapped
* no sane writer would wrap 2 byte PCM packets with 20 byte headers.. */
/* TODO: We could compute this from the ratio between the audio
* and video edit rates for 48 kHz NTSC we could use the
* 1802-1802-1802-1802-1801 pattern. */
- mxf->edit_units_per_packet = 1920;
+ track = st->priv_data;
+ mxf->edit_units_per_packet = FFMAX(1, track->edit_rate.num / track->edit_rate.den / 25);
}
/**
* truncate the packet since it's probably very large (>2 GiB is common) */
avpriv_request_sample(s,
"OPAtom misinterpreted as OP1a? "
- "KLV for edit unit %i extending into "
+ "KLV for edit unit %"PRId64" extending into "
"next edit unit",
mxf->current_edit_unit);
klv.length = next_ofs - avio_tell(s->pb);
int64_t ret64, pos, next_pos;
AVStream *st;
MXFIndexTable *t;
+ MXFTrack *track;
int edit_units;
if (mxf->op != OPAtom)
if (!st)
return AVERROR_EOF;
+ track = st->priv_data;
+
/* OPAtom - clip wrapped demuxing */
/* NOTE: mxf_read_header() makes sure nb_index_tables > 0 for OPAtom */
t = &mxf->index_tables[0];
- if (mxf->current_edit_unit >= st->duration)
+ if (mxf->current_edit_unit >= track->original_duration)
return AVERROR_EOF;
- edit_units = FFMIN(mxf->edit_units_per_packet, st->duration - mxf->current_edit_unit);
+ edit_units = FFMIN(mxf->edit_units_per_packet, track->original_duration - mxf->current_edit_unit);
if ((ret = mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit, NULL, &pos, 1)) < 0)
return ret;