avformat/mov: parse sdtp atom and set the pkt disposable flag accordingly
authorMatthieu Bouron <matthieu.bouron@gmail.com>
Fri, 27 Sep 2019 12:57:09 +0000 (14:57 +0200)
committerMatthieu Bouron <matthieu.bouron@gmail.com>
Sat, 12 Oct 2019 12:36:15 +0000 (14:36 +0200)
Allows the creation of the sdtp atom while remuxing MP4 to MP4. This
atom is required by Apple devices (iPhone, Apple TV) in order to accept
2160p medias.

libavformat/isom.h
libavformat/mov.c
tests/ref/fate/hapqa-extract-snappy1-to-hapalphaonly
tests/ref/fate/hapqa-extract-snappy1-to-hapq
tests/ref/fate/hapqa-extract-snappy16-to-hapalphaonly
tests/ref/fate/hapqa-extract-snappy16-to-hapq

index 69452ca..4943b80 100644 (file)
@@ -163,6 +163,8 @@ typedef struct MOVStreamContext {
     int64_t *chunk_offsets;
     unsigned int stts_count;
     MOVStts *stts_data;
+    unsigned int sdtp_count;
+    uint8_t *sdtp_data;
     unsigned int ctts_count;
     unsigned int ctts_allocated_size;
     MOVStts *ctts_data;
index 8e916a2..4f69664 100644 (file)
@@ -2959,6 +2959,40 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     return 0;
 }
 
+static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    AVStream *st;
+    MOVStreamContext *sc;
+    int64_t i, entries;
+
+    if (c->fc->nb_streams < 1)
+        return 0;
+    st = c->fc->streams[c->fc->nb_streams - 1];
+    sc = st->priv_data;
+
+    avio_r8(pb); /* version */
+    avio_rb24(pb); /* flags */
+    entries = atom.size - 4;
+
+    av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
+           c->fc->nb_streams - 1, entries);
+
+    if (sc->sdtp_data)
+        av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
+    av_freep(&sc->sdtp_data);
+    sc->sdtp_count = 0;
+
+    sc->sdtp_data = av_mallocz(entries);
+    if (!sc->sdtp_data)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < entries && !pb->eof_reached; i++)
+        sc->sdtp_data[i] = avio_r8(pb);
+    sc->sdtp_count = i;
+
+    return 0;
+}
+
 static void mov_update_dts_shift(MOVStreamContext *sc, int duration)
 {
     if (duration < 0) {
@@ -6767,6 +6801,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
 { MKTAG('s','t','t','s'), mov_read_stts },
 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
+{ MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
 { MKTAG('t','f','d','t'), mov_read_tfdt },
 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
@@ -7231,6 +7266,7 @@ static int mov_read_close(AVFormatContext *s)
         av_freep(&sc->sample_sizes);
         av_freep(&sc->keyframes);
         av_freep(&sc->stts_data);
+        av_freep(&sc->sdtp_data);
         av_freep(&sc->stps_data);
         av_freep(&sc->elst_data);
         av_freep(&sc->rap_group);
@@ -7820,6 +7856,11 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
     }
     if (st->discard == AVDISCARD_ALL)
         goto retry;
+    if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
+        uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
+        uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
+        pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
+    }
     pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
     pkt->pos = sample->pos;
 
index 9ab123f..7edd5fa 100644 (file)
@@ -3,4 +3,4 @@
 #codec_id 0: hap
 #dimensions 0: 127x71
 #sar 0: 1/1
-0,          0,          0,        1,     3044, 0xcaf6ddd0
+0,          0,          0,        1,     3044, 0xcaf6ddd0, F=0x11
index f658b1c..1340f77 100644 (file)
@@ -3,4 +3,4 @@
 #codec_id 0: hap
 #dimensions 0: 127x71
 #sar 0: 1/1
-0,          0,          0,        1,     8217, 0x04271f0f
+0,          0,          0,        1,     8217, 0x04271f0f, F=0x11
index 1bd9206..e6adc00 100644 (file)
@@ -3,4 +3,4 @@
 #codec_id 0: hap
 #dimensions 0: 127x71
 #sar 0: 1/1
-0,          0,          0,        1,     3513, 0x69c7014f
+0,          0,          0,        1,     3513, 0x69c7014f, F=0x11
index 8334d53..f356301 100644 (file)
@@ -3,4 +3,4 @@
 #codec_id 0: hap
 #dimensions 0: 127x71
 #sar 0: 1/1
-0,          0,          0,        1,     8726, 0xf889691c
+0,          0,          0,        1,     8726, 0xf889691c, F=0x11