mirror of https://git.ffmpeg.org/ffmpeg.git
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>
This commit is contained in:
parent
09494d0984
commit
00d454ed2c
|
@ -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,
|
||||
|
|
|
@ -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') || \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue