[FFmpeg-devel] [PATCH] mxfdec: Parse IndexTableSegments and convert them into AVIndexEntry arrays
Tomas Härdin
tomas.hardin at codemill.se
Mon Oct 10 13:03:31 CEST 2011
On Sat, 2011-10-08 at 22:33 +0200, Georg Lippitsch wrote:
> Am 06.10.2011, 17:20 Uhr, schrieb Tomas Härdin <tomas.hardin at codemill.se>:
>
> > I've split this patch in two parts per Baptiste's request.
> > The first part reads and converts the IndexTableSegments into
> > AVIndexEntry arrays while the second part implements the clip wrapping.
>
> From my perspective, your patches look fine!
>
> > * handling audio duration % 8192 != 0
>
> Actually I didn't like this kind of audio handling very much, so I wrote
> another patch for this.
> After all, it avoids parsing the index table and furthermore generating
> st->index_entries if there is only one table-segment, and if this segments
> has no entries but only EditUnitByteCount set. It is meant to handle the
> audio-files with small EditUnitByteCount correctly, and certainly also
> saves much memory in this case.
Sounds reasonable I suppose. While I'm not the biggest fan of having
different code paths here, the proposed way is at least easy to
understand.
> diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
> index 1069167..06dda3f 100644
> --- a/libavformat/mxfdec.c
> +++ b/libavformat/mxfdec.c
> @@ -187,6 +187,7 @@ typedef struct {
> int64_t first_essence_length;
> KLVPacket current_klv_data;
> int current_klv_index;
> + int single_eubc;
> } MXFContext;
>
> enum MXFWrappingScheme {
> @@ -368,8 +369,11 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
> klv = mxf->current_klv_data;
> index = mxf->current_klv_index;
> tr = s->streams[index]->priv_data;
> - klv.length = FFMIN(s->streams[index]->index_entries[tr->current_sample_index].size,
> - mxf->current_klv_data.length);
> + if (mxf->single_eubc)
> + klv.length = FFMAX(mxf->single_eubc, 8192);
You should probably make sure klv.length % samples_per_byte == 0. 24-bit
could have a problem with this. For instance, PAL mono 24-bit 48 kHz ->
5760 B, meaning it'd pick 8192 which isn't divisible by 3.
Shouldn't this also do FFMIN() with current_klv_data.length just like
below?
> + else
> + klv.length = FFMIN(s->streams[index]->index_entries[tr->current_sample_index].size,
> + mxf->current_klv_data.length);
> mxf->current_klv_data.offset += klv.length;
> mxf->current_klv_data.length -= klv.length;
> av_dlog(s, "Clip-wrapped reading. klv.length=%"PRId64" current_sample_index=%d\n",
> @@ -398,9 +402,10 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
> }
> if (s->streams[index]->discard == AVDISCARD_ALL)
> goto skip;
> - if (tr->current_sample_index < s->streams[index]->nb_index_entries &&
> + if ((tr->current_sample_index < s->streams[index]->nb_index_entries &&
> klv.length > s->streams[index]->index_entries[tr->current_sample_index].size &&
> - s->streams[index]->index_entries[tr->current_sample_index].size) {
> + s->streams[index]->index_entries[tr->current_sample_index].size) ||
> + mxf->single_eubc) {
> mxf->current_klv_data = klv;
> mxf->current_klv_index = index;
> return mxf_read_packet(s, pkt);
> @@ -952,6 +957,14 @@ static int mxf_parse_index(MXFContext *mxf, int i, AVStream *st)
> if ((ret = mxf_get_sorted_table_segments(mxf, &nb_sorted_segments, &sorted_segments)))
> return ret;
>
> + if (nb_sorted_segments == 1 && !sorted_segments[0]->index_duration &&
> + sorted_segments[0]->edit_unit_byte_count > 0)
> + {
> + mxf->single_eubc = sorted_segments[0]->edit_unit_byte_count;
> + av_free(sorted_segments);
> + return 0;
> + }
> +
> for (j = 0; j < nb_sorted_segments; j++) {
> int n_delta = i;
> int duration, sample_duration = 1, last_sample_size = 0;
> @@ -1447,13 +1460,23 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
> index = 0;
> if (index < 0)
> return -1;
> - seekpos = st->index_entries[index].pos;
> + seekpos = st->index_entries[index].pos;
Not intended?
> av_update_cur_dts(s, st, st->index_entries[index].timestamp);
> tr->current_sample_index = index;
> if (!index) {
> mxf->current_klv_data.length = 0;
> mxf->current_klv_index = 0;
> }
> + } else if (mxf->single_eubc) {
> + seekpos = mxf->single_eubc * sample_time + mxf->essence_offset;
> + if (sample_time > 0 && seekpos)
> + seekpos += mxf->first_essence_kl_length;
> + av_update_cur_dts(s, st, sample_time);
> + tr->current_sample_index = sample_time;
> + if (!sample_time) {
> + mxf->current_klv_data.length = 0;
> + mxf->current_klv_index = 0;
> + }
Looks reasonable.
/Tomas
More information about the ffmpeg-devel
mailing list