Message ID | 20190927143732.455148-1-matthieu.bouron@gmail.com |
---|---|
State | New |
Headers | show |
Am Fr., 27. Sept. 2019 um 16:45 Uhr schrieb Matthieu Bouron <matthieu.bouron@gmail.com>: > > --- > tests/ref/fate/hapqa-extract-snappy1-to-hapalphaonly | 2 +- > tests/ref/fate/hapqa-extract-snappy1-to-hapq | 2 +- > tests/ref/fate/hapqa-extract-snappy16-to-hapalphaonly | 2 +- > tests/ref/fate/hapqa-extract-snappy16-to-hapq | 2 +- You have to merge this into the first patch (if that patch is ok). Carl Eugen
On 27/09/2019 15:37, Matthieu Bouron wrote: > 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. Can you point to a document about this (for informational purposes)? Is this valid for both QTFF and ISOBMFF? > 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 }, /* independant and disposable samples */ Spelling mistake. - Derek
On Fri, Sep 27, 2019 at 04:14:33PM +0100, Derek Buitenhuis wrote: > On 27/09/2019 15:37, Matthieu Bouron wrote: > > 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. > > Can you point to a document about this (for informational purposes)? For the MP4 container, tt is part of ISO/IEC14496-12 but it looks like it is not public. It is also described here for the QT container: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-SW46 The specification differs in wording and presentation between the two, but the final encoded values of each flags are the same. For both specs the flags are stored in 1 byte. For sample_is_depended_on in QT, you have to use: kQTSampleDependency_NoOtherSampleDependsOnThisSample = 1<<3, kQTSampleDependency_OtherSamplesDependOnThisSample = 1<<2, In MP4, the spec describe the following layout for the flags: unsigned int(2) reserved = 0; unsigned int(2) sample_depends_on; unsigned int(2) sample_is_depended_on; unsigned int(2) sample_has_redundancy; unsigned int(2) And values for sample_is_depended_on: 0: the dependency of other samples on this sample is unknown 1: other samples depend on this one (not disposable) 2: no other sample depends on this one (disposable) 3: reserved NOTE: we already support the sdtp atom in movenc.c. > > Is this valid for both QTFF and ISOBMFF? > > > 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 }, /* independant and disposable samples */ > > Spelling mistake. Fixed locally. Thanks.
On 27/09/2019 16:45, Matthieu Bouron wrote:
> Fixed locally.
+1
- Derek
Matthieu Bouron: > On Fri, Sep 27, 2019 at 04:14:33PM +0100, Derek Buitenhuis wrote: >> On 27/09/2019 15:37, Matthieu Bouron wrote: >>> 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. >> >> Can you point to a document about this (for informational purposes)? > > For the MP4 container, tt is part of ISO/IEC14496-12 but it looks like it > is not public. > ISO/IEC 14496-12 is one of the publicly available ISO standards [1], as are two amendments to it. - Andreas [1]: https://standards.iso.org/ittf/PubliclyAvailableStandards/index.html
On Fri, Sep 27, 2019 at 04:37:31PM +0200, Matthieu Bouron wrote: > 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 | 2 ++ > libavformat/mov.c | 41 +++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 43 insertions(+) > > diff --git a/libavformat/isom.h b/libavformat/isom.h > index 69452cae8e..4943b80ccf 100644 > --- a/libavformat/isom.h > +++ b/libavformat/isom.h > @@ -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; > diff --git a/libavformat/mov.c b/libavformat/mov.c > index 8e916a28c6..7dfa07b45e 100644 > --- a/libavformat/mov.c > +++ b/libavformat/mov.c > @@ -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 }, /* independant 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; > > -- > 2.23.0 > Ping.
On 07/10/2019 16:06, Matthieu Bouron wrote: > Ping. > No objections from me. - Derek
On Mon, Oct 07, 2019 at 10:19:59PM +0100, Derek Buitenhuis wrote: > On 07/10/2019 16:06, Matthieu Bouron wrote: > > Ping. > > > > No objections from me. Pushed (with the patch updating fate squashed into this patch). Thanks,
diff --git a/libavformat/isom.h b/libavformat/isom.h index 69452cae8e..4943b80ccf 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -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; diff --git a/libavformat/mov.c b/libavformat/mov.c index 8e916a28c6..7dfa07b45e 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -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 }, /* independant 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;