[FFmpeg-devel] [PATCH] fix MXF audio PTS calculation for compressed audio (ADTS/AAC)

Markus Schumann go4shoe at hotmail.com
Wed Sep 5 02:25:58 EEST 2018


---
 libavformat/mxfdec.c | 67 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)

diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 8e1089620f..adfffd954a
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -3266,9 +3266,63 @@ static int64_t mxf_set_current_edit_unit(MXFContext *mxf, AVStream *st, int64_t
     return mxf_set_current_edit_unit(mxf, st, current_offset, 0);
 }

+static int mxf_aac_adts_count_frames(MXFContext *mxf, AVCodecParameters *par,
+                                     AVPacket *pkt)
+{
+    const uint8_t *end_ptr;
+    uint8_t *data_ptr;
+    int32_t aac_frame_length, adts_frame_count;
+    uint8_t sample_rate_index;
+    uint8_t channel_configuration;
+
+    data_ptr = pkt->data;
+    end_ptr = pkt->data + pkt->size;
+       adts_frame_count = 0;
+
+       /* ADTS header is 7 bytes */
+       if (pkt->size < 7)
+               return 0;
+
+       /* check for sync bits 0xfff */
+       if (data_ptr[0] != 0xff || (data_ptr[1] & 0xf0) != 0xf0) return AVERROR(EINVAL);
+
+       sample_rate_index = (data_ptr[2] & 0x3c) >> 2;
+
+       channel_configuration = ((data_ptr[2] & 0x01) << 2) | ((data_ptr[3] & 0xc0) >> 6);
+
+       adts_frame_count = 1;
+
+       data_ptr += 7;
+
+       for (; data_ptr + 7 < end_ptr; ++data_ptr)
+       {
+               /* check for sync bits 0xfff */
+               if (data_ptr[0] != 0xff || (data_ptr[1] & 0xf0) != 0xf0) continue;
+
+               /* make sure sample rate is identical */
+               if (sample_rate_index != (data_ptr[2] & 0x3c) >> 2) continue;
+
+               /* make sure channel configuration is identical */
+               if (channel_configuration != (((data_ptr[2] & 0x01) << 2) | ((data_ptr[3] & 0xc0) >> 6))) continue;
+
+               aac_frame_length = ((int32_t)(data_ptr[3] & 0x03) << 11) | ((int32_t)data_ptr[4] << 3) | ((int32_t)(data_ptr[5] & 0xe0) >> 5);
+
+               /* sanity check on the frame length */
+               if (aac_frame_length < 1 || aac_frame_length > 8 * 768 + 7 + 2) continue;
+
+               ++adts_frame_count;
+
+               data_ptr += 7;
+       }
+
+       return adts_frame_count;
+}
+
 static int mxf_set_audio_pts(MXFContext *mxf, AVCodecParameters *par,
                              AVPacket *pkt)
 {
+    int frame_count;
+
     MXFTrack *track = mxf->fc->streams[pkt->stream_index]->priv_data;
     int64_t bits_per_sample = par->bits_per_coded_sample;

@@ -3281,7 +3335,18 @@ static int mxf_set_audio_pts(MXFContext *mxf, AVCodecParameters *par,
         || bits_per_sample <= 0
         || par->channels * (int64_t)bits_per_sample < 8)
         return AVERROR(EINVAL);
-    track->sample_count += pkt->size / (par->channels * (int64_t)bits_per_sample / 8);
+
+    switch (par->codec_id) {
+    case AV_CODEC_ID_AAC:
+        frame_count =  mxf_aac_adts_count_frames(mxf, par, pkt);
+        if (frame_count < 0) return AVERROR(EINVAL);
+        track->sample_count += 1024 * frame_count;
+       break;
+    default:
+       /* here we assume PCM */
+       track->sample_count += pkt->size / (par->channels * (int64_t)bits_per_sample / 8);
+       break;
+    }
     return 0;
 }

--
2.17.1




More information about the ffmpeg-devel mailing list