[FFmpeg-devel] [PATCH, v4] libavformat/movenc: Add support for HEVC in .3gp

Jan Ekström jeebjp at gmail.com
Fri Dec 11 12:39:54 EET 2020


On Fri, Dec 11, 2020 at 11:51 AM Gyan Doshi <ffmpeg at gyani.pro> wrote:
>
>
>
> On 11-12-2020 11:28 am, hisunzhenliang at outlook.com wrote:
> > From: SunZhenliang <hisunzhenliang at outlook.com>
> >
> > Just add HEVC's tag in 3gp tag list and it works to support HEVC in
> > 3gp files.
> >
> > Signed-off-by: SunZhenliang <hisunzhenliang at outlook.com>
> > ---
> >   libavformat/movenc.c | 29 +++++++++++++++++++++--------
> >   1 file changed, 21 insertions(+), 8 deletions(-)
> >
> > diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> > index 18fa3f9b5e..daf33b634f 100644
> > --- a/libavformat/movenc.c
> > +++ b/libavformat/movenc.c
> > @@ -4923,7 +4923,7 @@ static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
> >   }
> >
> >   static void mov_write_ftyp_tag_internal(AVIOContext *pb, AVFormatContext *s,
> > -                                        int has_h264, int has_video, int write_minor)
> > +                                        int has_h2645, int has_video, int write_minor)
> >   {
> >       MOVMuxContext *mov = s->priv_data;
> >       int minor = 0x200;
> > @@ -4931,11 +4931,11 @@ static void mov_write_ftyp_tag_internal(AVIOContext *pb, AVFormatContext *s,
> >       if (mov->major_brand && strlen(mov->major_brand) >= 4)
> >           ffio_wfourcc(pb, mov->major_brand);
> >       else if (mov->mode == MODE_3GP) {
> > -        ffio_wfourcc(pb, has_h264 ? "3gp6"  : "3gp4");
> > -        minor =     has_h264 ?   0x100 :   0x200;
> > +        ffio_wfourcc(pb, has_h2645 ? "3gp6"  : "3gp4");
> > +        minor =     has_h2645 ?   0x100 :   0x200;
> >       } else if (mov->mode & MODE_3G2) {
> > -        ffio_wfourcc(pb, has_h264 ? "3g2b"  : "3g2a");
> > -        minor =     has_h264 ? 0x20000 : 0x10000;
> > +        ffio_wfourcc(pb, has_h2645 ? "3g2b"  : "3g2a");
> > +        minor =     has_h2645 ? 0x20000 : 0x10000;
> >       } else if (mov->mode == MODE_PSP)
> >           ffio_wfourcc(pb, "MSNV");
> >       else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
> > @@ -4964,7 +4964,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
> >   {
> >       MOVMuxContext *mov = s->priv_data;
> >       int64_t pos = avio_tell(pb);
> > -    int has_h264 = 0, has_av1 = 0, has_video = 0;
> > +    int has_h264 = 0, has_h265 = 0, has_av1 = 0, has_video = 0;
> > +    uint32_t h265_codec_tag = 0;
> >       int i;
> >
> >       for (i = 0; i < s->nb_streams; i++) {
> > @@ -4975,6 +4976,10 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
> >               has_video = 1;
> >           if (st->codecpar->codec_id == AV_CODEC_ID_H264)
> >               has_h264 = 1;
> > +        if (st->codecpar->codec_id == AV_CODEC_ID_H265){
> > +            has_h265 = 1;
> > +            h265_codec_tag = st->codecpar->codec_tag;
> > +        }
> >           if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
> >               has_av1 = 1;
> >       }
> > @@ -4983,9 +4988,9 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
> >       ffio_wfourcc(pb, "ftyp");
> >
> >       // Write major brand
> > -    mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
> > +    mov_write_ftyp_tag_internal(pb, s, has_h264 || has_h265 , has_video, 1);
> >       // Write the major brand as the first compatible brand as well
> > -    mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
> > +    mov_write_ftyp_tag_internal(pb, s, has_h264 || has_h265, has_video, 0);
> >
> >       // Write compatible brands, ensuring that we don't write the major brand as a
> >       // compatible brand a second time.
> > @@ -5018,6 +5023,12 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
> >               ffio_wfourcc(pb, "iso2");
> >               if (has_h264)
> >                   ffio_wfourcc(pb, "avc1");
> > +            if (has_h265){
> > +                if (h265_codec_tag == MKTAG('h','e','v','1'))
> > +                    ffio_wfourcc(pb, "hev1");
> > +                else
> > +                    ffio_wfourcc(pb, "hvc1");
> > +            }
>
> One final note:  add a comment here that these major brands need to be
> verified.
>

I have the 2016 version of 14496-15 (FDIS with HEVC added) on hand,
and it only speaks of the AVC file format, not HEVC file format. And
for AVC it only mentions avc1, so if similar logic is required for
brands:

1. It'd be separate from the 3GPP enablement patch, since it'd be
fixing our HEVC mappings in general (if the brand is required, it's
required for all mp4-likes, although technically the spec does say
"AVC content may be used in an MPEG-4 context; in a file with
extension “.mp4”, the major brand may be ‘avc1’.").
2. But - at least looking at the 14496-15 document available to me -
there is no definition of a major brand for HEVC since "8.4.1 HEVC
video stream definition" does not make any mention of it. Although
this might just be an old version of the spec, unfortunately newer
versions are not publicly available.

Jan


More information about the ffmpeg-devel mailing list