summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Stebbins <jstebbins@jetheaddev.com>2017-11-19 12:46:30 -0800
committerMichael Niedermayer <michael@niedermayer.cc>2017-12-02 19:14:34 +0100
commit00d454ed2ca3f8b4d454a837e95931afe604c53f (patch)
tree3582aa4f8357569685c5ae0443f30f6481daf112
parent09494d098405738a5972e0052110af65b3ff7e72 (diff)
lavf/movenc: add sdtp (sample dependency) box
The sdtp is required by the AppleTV 4K in order to play 2160p60 video. Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r--libavcodec/avcodec.h6
-rw-r--r--libavformat/isom.h5
-rw-r--r--libavformat/movenc.c30
-rw-r--r--libavformat/movenc.h2
4 files changed, 43 insertions, 0 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 0972df0bde..5db6a81320 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1444,6 +1444,12 @@ typedef struct AVPacket {
* outside the packet may be followed.
*/
#define AV_PKT_FLAG_TRUSTED 0x0008
+/**
+ * Flag is used to indicate packets that contain frames that can
+ * be discarded by the decoder. I.e. Non-reference frames.
+ */
+#define AV_PKT_FLAG_DISPOSABLE 0x0010
+
enum AVSideDataParamChangeFlags {
AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001,
diff --git a/libavformat/isom.h b/libavformat/isom.h
index ff08f5d090..65676fb0f5 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -318,6 +318,11 @@ void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id);
#define MOV_TKHD_FLAG_IN_PREVIEW 0x0004
#define MOV_TKHD_FLAG_IN_POSTER 0x0008
+#define MOV_SAMPLE_DEPENDENCY_UNKNOWN 0x0
+#define MOV_SAMPLE_DEPENDENCY_YES 0x1
+#define MOV_SAMPLE_DEPENDENCY_NO 0x2
+
+
#define TAG_IS_AVCI(tag) \
((tag) == MKTAG('a', 'i', '5', 'p') || \
(tag) == MKTAG('a', 'i', '5', 'q') || \
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 0d924ad758..901577401e 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -252,6 +252,30 @@ static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
return update_size(pb, pos);
}
+/* Sample dependency atom */
+static int mov_write_sdtp_tag(AVIOContext *pb, MOVTrack *track)
+{
+ int i;
+ uint8_t leading, dependent, reference, redundancy;
+ int64_t pos = avio_tell(pb);
+ avio_wb32(pb, 0); // size
+ ffio_wfourcc(pb, "sdtp");
+ avio_wb32(pb, 0); // version & flags
+ for (i = 0; i < track->entry; i++) {
+ dependent = MOV_SAMPLE_DEPENDENCY_YES;
+ leading = reference = redundancy = MOV_SAMPLE_DEPENDENCY_UNKNOWN;
+ if (track->cluster[i].flags & MOV_DISPOSABLE_SAMPLE) {
+ reference = MOV_SAMPLE_DEPENDENCY_NO;
+ }
+ if (track->cluster[i].flags & MOV_SYNC_SAMPLE) {
+ dependent = MOV_SAMPLE_DEPENDENCY_NO;
+ }
+ avio_w8(pb, (leading << 6) | (dependent << 4) |
+ (reference << 2) | redundancy);
+ }
+ return update_size(pb, pos);
+}
+
static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
{
avio_wb32(pb, 0x11); /* size */
@@ -2353,6 +2377,8 @@ static int mov_write_stbl_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext
track->par->codec_tag == MKTAG('r','t','p',' ')) &&
track->has_keyframes && track->has_keyframes < track->entry)
mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
+ if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable)
+ mov_write_sdtp_tag(pb, track);
if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
mov_write_stss_tag(pb, track, MOV_PARTIAL_SYNC_SAMPLE);
if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
@@ -5316,6 +5342,10 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
trk->has_keyframes++;
}
+ if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
+ trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
+ trk->has_disposable++;
+ }
trk->entry++;
trk->sample_count += samples_in_chunk;
mov->mdat_size += size;
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index cc2a155d79..c4e966b7fb 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -53,6 +53,7 @@ typedef struct MOVIentry {
int cts;
#define MOV_SYNC_SAMPLE 0x0001
#define MOV_PARTIAL_SYNC_SAMPLE 0x0002
+#define MOV_DISPOSABLE_SAMPLE 0x0004
uint32_t flags;
} MOVIentry;
@@ -89,6 +90,7 @@ typedef struct MOVTrack {
long sample_size;
long chunkCount;
int has_keyframes;
+ int has_disposable;
#define MOV_TRACK_CTTS 0x0001
#define MOV_TRACK_STPS 0x0002
#define MOV_TRACK_ENABLED 0x0004