[FFmpeg-devel] [PATCH 4/5] avformat/movenc: reduce tfra box size when every sample is a sync sample

"zhilizhao(赵志立)" quinkblack at foxmail.com
Fri Dec 3 09:37:33 EET 2021



> On Dec 3, 2021, at 1:06 PM, Zhao Zhili <quinkblack at foxmail.com> wrote:
> 
> ---
> libavformat/movenc.c  |  8 +++++
> libavformat/movenc.h  |  1 +
> tests/ref/fate/movenc | 80 +++++++++++++++++++++----------------------
> 3 files changed, 49 insertions(+), 40 deletions(-)
> 
> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> index f8731d33c5..01dfd21a43 100644
> --- a/libavformat/movenc.c
> +++ b/libavformat/movenc.c
> @@ -4938,6 +4938,7 @@ static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
>     int number_of_entry = 0;
>     int i;
> 
> +    if (!track->every_sample_keyframe) {
>     /* We can't write and then update number_of_entry, because we cannot fix
>      * the case when number_of_entry is zero, since zero indicates that every
>      * sample is a sync sample. So get number_of_entry first.
> @@ -4948,6 +4949,7 @@ static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
>     }
>     if (!number_of_entry)
>         return 0;
> +    }
> 
>     avio_wb32(pb, 0); /* size placeholder */
>     ffio_wfourcc(pb, "tfra");
> @@ -4956,6 +4958,9 @@ static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
> 
>     avio_wb32(pb, track->track_id);
>     avio_wb32(pb, 0); /* length of traf/trun/sample num */
> +    if (track->every_sample_keyframe) {
> +    avio_wb32(pb, 0);
> +    } else {
>     avio_wb32(pb, number_of_entry);
>     for (i = 0; i < track->nb_frag_info; i++) {
>         if (!(track->frag_info[i].first_sample_flags & MOV_SYNC_SAMPLE))
> @@ -4966,6 +4971,7 @@ static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
>         avio_w8(pb, 1); /* trun number */
>         avio_w8(pb, 1); /* sample number */
>     }
> +    }

The patch is according to the spec. However, when there is a single track and every
sample is a sync sample, I think we still want to have the table entry to get moof
offset (when there is no other index method like sidx). So enable the optimization
conditionally, or just drop the optimization, any idea? 

> 
>     return update_size(pb, pos);
> }
> @@ -5999,6 +6005,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
>         trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
>         trk->has_disposable++;
>     }
> +    trk->every_sample_keyframe &= !!(pkt->flags & AV_PKT_FLAG_KEY);
> 
>     prft = (AVProducerReferenceTime *)av_packet_get_side_data(pkt, AV_PKT_DATA_PRFT, &prft_size);
>     if (prft && prft_size == sizeof(AVProducerReferenceTime))
> @@ -6769,6 +6776,7 @@ static int mov_init(AVFormatContext *s)
>         if (track->language < 0)
>             track->language = 32767;  // Unspecified Macintosh language code
>         track->mode = mov->mode;
> +        track->every_sample_keyframe = 1;
>         track->tag  = mov_find_codec_tag(s, track);
>         if (!track->tag) {
>             av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
> diff --git a/libavformat/movenc.h b/libavformat/movenc.h
> index e3a5e2864a..e78a08c2dd 100644
> --- a/libavformat/movenc.h
> +++ b/libavformat/movenc.h
> @@ -97,6 +97,7 @@ typedef struct MOVTrack {
>     long        chunkCount;
>     int         has_keyframes;
>     int         has_disposable;
> +    int         every_sample_keyframe;
> #define MOV_TRACK_CTTS         0x0001
> #define MOV_TRACK_STPS         0x0002
> #define MOV_TRACK_ENABLED      0x0004



More information about the ffmpeg-devel mailing list