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