[FFmpeg-devel] [PATCH 05/12] avformat/mxfdec: make edit_units_per_packet a track property
Marton Balint
cus at passwd.hu
Sun Jun 10 13:36:43 EEST 2018
Signed-off-by: Marton Balint <cus at passwd.hu>
---
libavformat/mxfdec.c | 51 ++++++++++++++++++++++++++-------------------------
1 file changed, 26 insertions(+), 25 deletions(-)
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 67b0028e88..be6884edbe 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -173,6 +173,7 @@ typedef struct {
int index_sid;
int body_sid;
MXFWrappingScheme wrapping;
+ int edit_units_per_packet; /* how many edit units to read at a time (PCM, ClipWrapped) */
} MXFTrack;
typedef struct MXFDescriptor {
@@ -286,7 +287,6 @@ typedef struct MXFContext {
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)
} MXFContext;
/* NOTE: klv_offset is not set (-1) for local keys */
@@ -2874,36 +2874,46 @@ static AVStream* mxf_get_opatom_stream(MXFContext *mxf)
return NULL;
}
+static MXFIndexTable *mxf_find_index_table(MXFContext *mxf, int index_sid)
+{
+ int i;
+ for (i = 0; i < mxf->nb_index_tables; i++)
+ if (mxf->index_tables[i].index_sid == index_sid)
+ return &mxf->index_tables[i];
+ return NULL;
+}
+
/**
* Deal with the case where for some audio atoms EditUnitByteCount is
* very small (2, 4..). In those cases we should read more than one
* sample per call to mxf_read_packet().
*/
-static void mxf_handle_small_eubc(AVFormatContext *s)
+static void mxf_compute_edit_units_per_packet(MXFContext *mxf, AVStream *st)
{
- MXFContext *mxf = s->priv_data;
- MXFTrack *track;
+ MXFTrack *track = st->priv_data;
+ MXFIndexTable *t;
- /* assuming non-OPAtom == frame wrapped
- * no sane writer would wrap 2 byte PCM packets with 20 byte headers.. */
- AVStream *st = mxf_get_opatom_stream(mxf);
- if (!st)
+ if (!track)
return;
+ track->edit_units_per_packet = 1;
+ if (track->wrapping != ClipWrapped)
+ return;
+
+ t = mxf_find_index_table(mxf, track->index_sid);
/* expect PCM with exactly one index table segment and a small (< 32) EUBC */
if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
!is_pcm(st->codecpar->codec_id) ||
- mxf->nb_index_tables != 1 ||
- mxf->index_tables[0].nb_segments != 1 ||
- mxf->index_tables[0].segments[0]->edit_unit_byte_count >= 32)
+ !t ||
+ t->nb_segments != 1 ||
+ t->segments[0]->edit_unit_byte_count >= 32)
return;
/* arbitrarily default to 48 kHz PAL audio frame size */
/* 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. */
- track = st->priv_data;
- mxf->edit_units_per_packet = FFMAX(1, track->edit_rate.num / track->edit_rate.den / 25);
+ track->edit_units_per_packet = FFMAX(1, track->edit_rate.num / track->edit_rate.den / 25);
}
/**
@@ -3028,7 +3038,6 @@ static int mxf_read_header(AVFormatContext *s)
int ret;
mxf->last_forward_tell = INT64_MAX;
- mxf->edit_units_per_packet = 1;
if (!mxf_read_sync(s->pb, mxf_header_partition_pack_key, 14)) {
av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n");
@@ -3127,7 +3136,8 @@ static int mxf_read_header(AVFormatContext *s)
mxf_compute_essence_containers(s);
- mxf_handle_small_eubc(s);
+ for (int i = 0; i < s->nb_streams; i++)
+ mxf_compute_edit_units_per_packet(mxf, s->streams[i]);
return 0;
fail:
@@ -3136,15 +3146,6 @@ fail:
return ret;
}
-static MXFIndexTable *mxf_find_index_table(MXFContext *mxf, int index_sid)
-{
- int i;
- for (i = 0; i < mxf->nb_index_tables; i++)
- if (mxf->index_tables[i].index_sid == index_sid)
- return &mxf->index_tables[i];
- return NULL;
-}
-
/* Get the edit unit of the next packet from current_offset in a track. The returned edit unit can be original_duration as well! */
static int mxf_get_next_track_edit_unit(MXFContext *mxf, MXFTrack *track, int64_t current_offset, int64_t *edit_unit_out)
{
@@ -3406,7 +3407,7 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
if (mxf->current_edit_unit >= track->original_duration)
return AVERROR_EOF;
- edit_units = FFMIN(mxf->edit_units_per_packet, track->original_duration - mxf->current_edit_unit);
+ edit_units = FFMIN(track->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;
--
2.16.4
More information about the ffmpeg-devel
mailing list