[FFmpeg-devel,05/12] avformat/mxfdec: make edit_units_per_packet a track property

Submitted by Marton Balint on June 10, 2018, 10:36 a.m.

Details

Message ID 20180610103650.10155-5-cus@passwd.hu
State Accepted
Commit ae64c682084b0693dea983b8c1a93c3a21808727
Headers show

Commit Message

Marton Balint June 10, 2018, 10:36 a.m.
Signed-off-by: Marton Balint <cus@passwd.hu>
---
 libavformat/mxfdec.c | 51 ++++++++++++++++++++++++++-------------------------
 1 file changed, 26 insertions(+), 25 deletions(-)

Comments

Tomas Härdin June 13, 2018, 3:07 p.m.
sön 2018-06-10 klockan 12:36 +0200 skrev Marton Balint:
> > Signed-off-by: Marton Balint <cus@passwd.hu>
> ---
>  libavformat/mxfdec.c | 51 ++++++++++++++++++++++++++-------------------------
>  1 file changed, 26 insertions(+), 25 deletions(-)
> 
> diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c

Looks OK. Nice to get these things generalized

/Tomas

Patch hide | download patch | download mbox

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;