This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit 0878ae59f900f74f32b1bc86fd425c0d64dae539
Author:     James Almer <[email protected]>
AuthorDate: Mon Feb 16 12:02:14 2026 -0300
Commit:     James Almer <[email protected]>
CommitDate: Sat Mar 14 20:50:21 2026 -0300

    avformat/movenc: add support for LCEVC track muxing
    
    Signed-off-by: James Almer <[email protected]>
---
 Changelog                                          |   1 +
 libavcodec/Makefile                                |   1 +
 libavformat/Makefile                               |   4 +-
 .../half2float.c => libavformat/h2645_parse.c      |   2 +-
 libavformat/lcevc.c                                | 278 +++++++++++++++++++++
 libavutil/reverse.h => libavformat/lcevc.h         |  11 +-
 libavfilter/fflcms2.c => libavformat/lcevctab.c    |   2 +-
 libavformat/movenc.c                               |  81 +++++-
 libavformat/version.h                              |   2 +-
 9 files changed, 371 insertions(+), 11 deletions(-)

diff --git a/Changelog b/Changelog
index 4d2a76aec7..a4241958bc 100644
--- a/Changelog
+++ b/Changelog
@@ -3,6 +3,7 @@ releases are sorted from youngest to oldest.
 
 version <next>:
 - Extend AMF Color Converter (vf_vpp_amf) HDR capabilities
+- LCEVC track muxing support in MP4 muxer
 
 
 version 8.1:
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 1f6c20a09b..9f7ef689c5 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1135,6 +1135,7 @@ STLIBOBJS-$(CONFIG_IMAGE_JPEGXL_PIPE_DEMUXER) += 
jpegxl_parse.o
 STLIBOBJS-$(CONFIG_JPEGXL_ANIM_DEMUXER)       += jpegxl_parse.o
 STLIBOBJS-$(CONFIG_MATROSKA_DEMUXER)   += mpeg4audio_sample_rates.o
 STLIBOBJS-$(CONFIG_MOV_DEMUXER)        += ac3_channel_layout_tab.o
+STLIBOBJS-$(CONFIG_MOV_MUXER)          += h2645_parse.o lcevctab.o
 STLIBOBJS-$(CONFIG_MXF_MUXER)          += golomb.o
 STLIBOBJS-$(CONFIG_MP3_MUXER)          += mpegaudiotabs.o
 STLIBOBJS-$(CONFIG_NUT_MUXER)          += mpegaudiotabs.o
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 4786a9345a..2fdfd61c9b 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -389,7 +389,8 @@ OBJS-$(CONFIG_MOV_DEMUXER)               += mov.o 
mov_chan.o mov_esds.o \
 OBJS-$(CONFIG_MOV_MUXER)                 += movenc.o \
                                             movenchint.o mov_chan.o rtp.o \
                                             movenccenc.o movenc_ttml.o 
rawutils.o \
-                                            apv.o dovi_isom.o evc.o cbs.o 
cbs_av1.o cbs_apv.o
+                                            apv.o dovi_isom.o evc.o cbs.o 
cbs_av1.o cbs_apv.o \
+                                            lcevc.o
 OBJS-$(CONFIG_MP2_MUXER)                 += rawenc.o
 OBJS-$(CONFIG_MP3_DEMUXER)               += mp3dec.o replaygain.o
 OBJS-$(CONFIG_MP3_MUXER)                 += mp3enc.o rawenc.o id3v2enc.o
@@ -751,6 +752,7 @@ SHLIBOBJS-$(CONFIG_JPEGXL_ANIM_DEMUXER)  += jpegxl_parse.o
 SHLIBOBJS-$(CONFIG_MATROSKA_DEMUXER)     += mpeg4audio_sample_rates.o
 SHLIBOBJS-$(CONFIG_MATROSKA_MUXER)       += opus_frame_duration_tab.o
 SHLIBOBJS-$(CONFIG_MOV_DEMUXER)          += ac3_channel_layout_tab.o
+SHLIBOBJS-$(CONFIG_MOV_MUXER)            += h2645_parse.o lcevctab.o
 SHLIBOBJS-$(CONFIG_MP3_MUXER)            += mpegaudiotabs.o
 SHLIBOBJS-$(CONFIG_MXF_MUXER)            += golomb_tab.o \
                                             rangecoder_dec.o
diff --git a/libavcodec/half2float.c b/libavformat/h2645_parse.c
similarity index 95%
copy from libavcodec/half2float.c
copy to libavformat/h2645_parse.c
index 1b023f96a5..5a6ce628e1 100644
--- a/libavcodec/half2float.c
+++ b/libavformat/h2645_parse.c
@@ -16,4 +16,4 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/half2float.c"
+#include "libavcodec/h2645_parse.c"
diff --git a/libavformat/lcevc.c b/libavformat/lcevc.c
new file mode 100644
index 0000000000..1cadefce11
--- /dev/null
+++ b/libavformat/lcevc.c
@@ -0,0 +1,278 @@
+/*
+ * LCEVC helper functions for muxers
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/error.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mem.h"
+#include "libavcodec/bytestream.h"
+#include "libavcodec/h2645_parse.h"
+#include "libavcodec/lcevc.h"
+#include "libavcodec/lcevctab.h"
+#include "libavcodec/lcevc_parse.h"
+#include "avio.h"
+#include "avio_internal.h"
+#include "lcevc.h"
+
+typedef struct LCEVCDecoderConfigurationRecord {
+    uint8_t  profile_idc;
+    uint8_t  level_idc;
+    uint8_t  chroma_format_idc;
+    uint8_t  bit_depth_luma_minus8;
+    uint8_t  bit_depth_chroma_minus8;
+    uint32_t pic_width_in_luma_samples;
+    uint32_t pic_height_in_luma_samples;
+} LCEVCDecoderConfigurationRecord;
+
+/**
+ * Rewrite the NALu stripping the unneeded blocks.
+ * Given that length fields coded inside the NALu are not aware of any 
emulation_3bytes
+ * present in the bitstream, we need to keep track of the raw buffer as we 
navigate
+ * the stripped buffer in order to write proper NALu sizes.
+ */
+static int write_nalu(LCEVCDecoderConfigurationRecord *lvcc, AVIOContext *pb,
+                      const H2645NAL *nal)
+{
+    GetByteContext gbc, raw_gbc;
+    int64_t start = avio_tell(pb), end;
+    int sc = 0, gc = 0;
+    int skipped_byte_pos = 0, nalu_length = 3;
+
+    bytestream2_init(&gbc, nal->data, nal->size);
+    bytestream2_init(&raw_gbc, nal->raw_data, nal->raw_size);
+    avio_wb16(pb, 0); // size placeholder
+    avio_wb16(pb, bytestream2_get_be16(&gbc)); // nal_unit_header
+    bytestream2_skip(&raw_gbc, 2);
+
+    while (bytestream2_get_bytes_left(&gbc) > 1 && (!sc || !gc)) {
+        GetBitContext gb;
+        uint64_t payload_size;
+        int payload_size_type, payload_type;
+        int block_size, raw_block_size, block_end;
+
+        init_get_bits8(&gb, gbc.buffer, bytestream2_get_bytes_left(&gbc));
+
+        payload_size_type = get_bits(&gb, 3);
+        payload_type      = get_bits(&gb, 5);
+        payload_size      = payload_size_type;
+        if (payload_size_type == 6)
+            return AVERROR_PATCHWELCOME;
+        if (payload_size_type == 7)
+            payload_size = get_mb(&gb);
+
+        if (payload_size > INT_MAX - (get_bits_count(&gb) >> 3))
+            return AVERROR_INVALIDDATA;
+
+        block_size = raw_block_size = payload_size + (get_bits_count(&gb) >> 
3);
+        if (block_size >= bytestream2_get_bytes_left(&gbc))
+            return AVERROR_INVALIDDATA;
+
+        block_end = bytestream2_tell(&gbc) + block_size;
+        // Take into account removed emulation 3bytes, as payload_size in
+        // the bitstream is not aware of them.
+        for (; skipped_byte_pos < nal->skipped_bytes; skipped_byte_pos++) {
+            if (nal->skipped_bytes_pos[skipped_byte_pos] >= block_end)
+                break;
+            raw_block_size++;
+        }
+
+        switch (payload_type) {
+        case 0:
+            if (sc)
+                break;
+
+            lvcc->profile_idc = get_bits(&gb, 4);
+            lvcc->level_idc = get_bits(&gb, 4);
+
+            avio_write(pb, raw_gbc.buffer, raw_block_size);
+            nalu_length += raw_block_size;
+            sc = 1;
+            break;
+        case 1: {
+            int resolution_type, bit_depth;
+            int processed_planes_type_flag;
+
+            if (gc)
+                break;
+
+            processed_planes_type_flag = get_bits1(&gb);
+            resolution_type = get_bits(&gb, 6);
+
+            skip_bits1(&gb);
+            lvcc->chroma_format_idc = get_bits(&gb, 2);
+
+            skip_bits(&gb, 2);
+            bit_depth = get_bits(&gb, 2) * 2; // enhancement_depth_type
+            lvcc->bit_depth_luma_minus8 = bit_depth;
+            lvcc->bit_depth_chroma_minus8 = bit_depth;
+
+            if (resolution_type < 63) {
+                lvcc->pic_width_in_luma_samples  = 
ff_lcevc_resolution_type[resolution_type].width;
+                lvcc->pic_height_in_luma_samples = 
ff_lcevc_resolution_type[resolution_type].height;
+            } else {
+                int upsample_type, tile_dimensions_type;
+                int temporal_step_width_modifier_signalled_flag, 
level1_filtering_signalled_flag;
+                // Skip syntax elements until we get to the custom dimension 
ones
+                temporal_step_width_modifier_signalled_flag = get_bits1(&gb);
+                skip_bits(&gb, 3);
+                upsample_type = get_bits(&gb, 3);
+                level1_filtering_signalled_flag = get_bits1(&gb);
+                skip_bits(&gb, 4);
+                tile_dimensions_type = get_bits(&gb, 2);
+                skip_bits(&gb, 4);
+                if (processed_planes_type_flag)
+                    skip_bits(&gb, 4);
+                if (temporal_step_width_modifier_signalled_flag)
+                    skip_bits(&gb, 8);
+                if (upsample_type)
+                    skip_bits_long(&gb, 64);
+                if (level1_filtering_signalled_flag)
+                    skip_bits(&gb, 8);
+                if (tile_dimensions_type) {
+                    if (tile_dimensions_type == 3)
+                        skip_bits_long(&gb, 32);
+                    skip_bits(&gb, 8);
+                }
+
+                lvcc->pic_width_in_luma_samples = get_bits(&gb, 16);
+                lvcc->pic_height_in_luma_samples = get_bits(&gb, 16);
+            }
+
+            if (!lvcc->pic_width_in_luma_samples || 
!lvcc->pic_height_in_luma_samples)
+                break;
+
+            avio_write(pb, raw_gbc.buffer, raw_block_size);
+            nalu_length += raw_block_size;
+            gc = 1;
+            break;
+        }
+        case 5:
+            avio_write(pb, raw_gbc.buffer, raw_block_size);
+            nalu_length += raw_block_size;
+            break;
+        default:
+            break;
+        }
+
+        bytestream2_skip(&gbc, block_size);
+        bytestream2_skip(&raw_gbc, raw_block_size);
+    }
+
+    if (!sc || !gc)
+        return AVERROR_INVALIDDATA;
+
+    avio_w8(pb, 0x80); // rbsp_alignment bits
+
+    end = avio_tell(pb);
+    avio_seek(pb, start, SEEK_SET);
+    avio_wb16(pb, nalu_length);
+    avio_seek(pb, end, SEEK_SET);
+
+    return 0;
+}
+
+int ff_isom_write_lvcc(AVIOContext *pb, const uint8_t *data, int len)
+{
+    LCEVCDecoderConfigurationRecord lvcc = { 0 };
+    AVIOContext *idr_pb = NULL, *nidr_pb = NULL;
+    H2645Packet h2645_pkt = { 0 };
+    uint8_t *idr, *nidr;
+    uint32_t idr_size = 0, nidr_size = 0;
+    int ret, nb_idr = 0, nb_nidr = 0;
+
+    if (len <= 6)
+        return AVERROR_INVALIDDATA;
+
+    /* check for start code */
+    if (AV_RB32(data) != 0x00000001 &&
+        AV_RB24(data) != 0x000001) {
+        avio_write(pb, data, len);
+        return 0;
+    }
+
+    ret = ff_h2645_packet_split(&h2645_pkt, data, len, NULL, 0, 
AV_CODEC_ID_LCEVC, 0);
+    if (ret < 0)
+        return ret;
+
+    ret = avio_open_dyn_buf(&idr_pb);
+    if (ret < 0)
+        goto fail;
+    ret = avio_open_dyn_buf(&nidr_pb);
+    if (ret < 0)
+        goto fail;
+
+    /* look for IDR or NON_IDR */
+    for (int i = 0; i < h2645_pkt.nb_nals; i++) {
+        const H2645NAL *nal = &h2645_pkt.nals[i];
+
+        if (nal->type == LCEVC_IDR_NUT) {
+            nb_idr++;
+
+            ret = write_nalu(&lvcc, idr_pb, nal);
+            if (ret < 0)
+                return ret;
+        } else if (nal->type == LCEVC_NON_IDR_NUT) {
+            nb_nidr++;
+
+            ret = write_nalu(&lvcc, nidr_pb, nal);
+            if (ret < 0)
+                return ret;
+        }
+    }
+    idr_size = avio_get_dyn_buf(idr_pb, &idr);
+    nidr_size = avio_get_dyn_buf(nidr_pb, &nidr);
+
+    if (!idr_size && !nidr_size) {
+        ret = AVERROR_INVALIDDATA;
+        goto fail;
+    }
+
+    avio_w8(pb, 1); /* version */
+    avio_w8(pb, lvcc.profile_idc);
+    avio_w8(pb, lvcc.level_idc);
+    avio_w8(pb, (lvcc.chroma_format_idc     << 6) |
+                (lvcc.bit_depth_luma_minus8 << 3) |
+                 lvcc.bit_depth_chroma_minus8);
+    avio_w8(pb, 0xff); /* 2 bits nal size length - 1 (11) + 6 bits reserved 
(111111)*/
+    avio_wb32(pb, lvcc.pic_width_in_luma_samples);
+    avio_wb32(pb, lvcc.pic_height_in_luma_samples);
+    avio_w8(pb, 0xff);
+
+    int nb_arrays = !!nb_idr + !!nb_nidr;
+    avio_w8(pb, nb_arrays);
+
+    if (nb_idr) {
+        avio_w8(pb, LCEVC_IDR_NUT);
+        avio_wb16(pb, nb_idr);
+        avio_write(pb, idr, idr_size);
+    }
+    if (nb_nidr) {
+        avio_w8(pb, LCEVC_NON_IDR_NUT);
+        avio_wb16(pb, nb_idr);
+        avio_write(pb, nidr, nidr_size);
+    }
+
+    ret = 0;
+fail:
+    ffio_free_dyn_buf(&idr_pb);
+    ffio_free_dyn_buf(&nidr_pb);
+    ff_h2645_packet_uninit(&h2645_pkt);
+
+    return ret;
+}
diff --git a/libavutil/reverse.h b/libavformat/lcevc.h
similarity index 79%
copy from libavutil/reverse.h
copy to libavformat/lcevc.h
index 4eb6123932..76093c4a36 100644
--- a/libavutil/reverse.h
+++ b/libavformat/lcevc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002-2004 Michael Niedermayer <[email protected]>
+ * LCEVC helper functions for muxers
  *
  * This file is part of FFmpeg.
  *
@@ -18,11 +18,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef AVUTIL_REVERSE_H
-#define AVUTIL_REVERSE_H
+#ifndef AVFORMAT_LCEVC_H
+#define AVFORMAT_LCEVC_H
 
 #include <stdint.h>
+#include "avio.h"
 
-extern const uint8_t ff_reverse[256];
+int ff_isom_write_lvcc(AVIOContext *pb, const uint8_t *data, int len);
 
-#endif /* AVUTIL_REVERSE_H */
+#endif /* AVFORMAT_LCEVC_H */
diff --git a/libavfilter/fflcms2.c b/libavformat/lcevctab.c
similarity index 95%
copy from libavfilter/fflcms2.c
copy to libavformat/lcevctab.c
index 822462de87..3711ec5870 100644
--- a/libavfilter/fflcms2.c
+++ b/libavformat/lcevctab.c
@@ -16,4 +16,4 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/fflcms2.c"
+#include "libavcodec/lcevctab.c"
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index fe6b259561..ae2d5ab4f9 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -38,6 +38,7 @@
 #include "avc.h"
 #include "evc.h"
 #include "apv.h"
+#include "lcevc.h"
 #include "libavcodec/ac3_parser_internal.h"
 #include "libavcodec/dnxhddata.h"
 #include "libavcodec/flac.h"
@@ -1681,6 +1682,19 @@ static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack 
*track)
     return update_size(pb, pos);
 }
 
+static int mov_write_lvcc_tag(AVIOContext *pb, MOVTrack *track)
+{
+    int64_t pos = avio_tell(pb);
+
+    avio_wb32(pb, 0);
+    ffio_wfourcc(pb, "lvcC");
+
+    ff_isom_write_lvcc(pb, track->extradata[track->last_stsd_index],
+                       track->extradata_size[track->last_stsd_index]);
+
+    return update_size(pb, pos);
+}
+
 static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
@@ -2880,6 +2894,8 @@ static int mov_write_video_tag(AVFormatContext *s, 
AVIOContext *pb, MOVMuxContex
     }
     else if (track->par->codec_id ==AV_CODEC_ID_EVC) {
         mov_write_evcc_tag(pb, track);
+    } else if (track->par->codec_id == AV_CODEC_ID_LCEVC) {
+        mov_write_lvcc_tag(pb, track);
     } else if (track->par->codec_id ==AV_CODEC_ID_APV) {
         mov_write_apvc_tag(mov->fc, pb, track);
     } else if (track->par->codec_id == AV_CODEC_ID_VP9) {
@@ -5222,6 +5238,9 @@ static int mov_write_moov_tag(AVIOContext *pb, 
MOVMuxContext *mov,
         if (track->tag == MKTAG('r','t','p',' ')) {
             track->tref_tag = MKTAG('h','i','n','t');
             track->tref_id = mov->tracks[track->src_track].track_id;
+        } else if (track->tag == MKTAG('l','v','c','1')) {
+            track->tref_tag = MKTAG('s','b','a','s');
+            track->tref_id = mov->tracks[track->src_track].track_id;
         } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
             const AVPacketSideData *sd = 
av_packet_side_data_get(track->st->codecpar->coded_side_data,
                                                                  
track->st->codecpar->nb_coded_side_data,
@@ -6847,6 +6866,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
          par->codec_id == AV_CODEC_ID_VVC ||
          par->codec_id == AV_CODEC_ID_VP9 ||
          par->codec_id == AV_CODEC_ID_EVC ||
+         par->codec_id == AV_CODEC_ID_LCEVC ||
          par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
          !TAG_IS_AVCI(trk->tag)) {
         /* copy frame to create needed atoms */
@@ -6957,6 +6977,25 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket 
*pkt)
         } else {
             size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
         }
+    } else if (par->codec_id == AV_CODEC_ID_LCEVC && 
trk->extradata_size[trk->last_stsd_index] > 0 &&
+              *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1) {
+        /* extradata is Annex B, assume the bitstream is too and convert it */
+        if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
+            ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data, &size);
+            if (ret < 0)
+                return ret;
+            avio_write(pb, reformatted_data, size);
+        } else {
+            if (trk->cenc.aes_ctr) {
+                size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb, 
pkt->data, size);
+                if (size < 0) {
+                    ret = size;
+                    goto err;
+                }
+            } else {
+                size = ff_nal_parse_units(pb, pkt->data, pkt->size);
+            }
+        }
     } else if (par->codec_id == AV_CODEC_ID_AV1 && !trk->cenc.aes_ctr) {
         if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
             ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
@@ -8041,10 +8080,25 @@ static int mov_init(AVFormatContext *s)
         s->streams[0]->disposition |= AV_DISPOSITION_DEFAULT;
     }
 
-#if CONFIG_IAMFENC
     for (i = 0; i < s->nb_stream_groups; i++) {
         AVStreamGroup *stg = s->stream_groups[i];
 
+        if (stg->type == AV_STREAM_GROUP_PARAMS_LCEVC) {
+            if (stg->nb_streams != 2) {
+                av_log(s, AV_LOG_ERROR, "Exactly two Streams are supported for 
Stream Groups of type LCEVC\n");
+                return AVERROR(EINVAL);
+            }
+            AVStreamGroupLCEVC *lcevc = stg->params.lcevc;
+            if (lcevc->lcevc_index > 1)
+                return AVERROR(EINVAL);
+            AVStream *st = stg->streams[lcevc->lcevc_index];
+            if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC) {
+                av_log(s, AV_LOG_ERROR, "Stream #%u is not an LCEVC stream\n", 
lcevc->lcevc_index);
+                return AVERROR(EINVAL);
+            }
+        }
+
+#if CONFIG_IAMFENC
         if (stg->type != AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT)
             continue;
 
@@ -8062,8 +8116,8 @@ static int mov_init(AVFormatContext *s)
 
         if (!mov->nb_tracks) // We support one track for the entire IAMF 
structure
             mov->nb_tracks++;
-    }
 #endif
+    }
 
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
@@ -8378,6 +8432,28 @@ static int mov_init(AVFormatContext *s)
         }
     }
 
+    for (i = 0; i < s->nb_stream_groups; i++) {
+        AVStreamGroup *stg = s->stream_groups[i];
+
+        if (stg->type != AV_STREAM_GROUP_PARAMS_LCEVC)
+            continue;
+
+        AVStreamGroupLCEVC *lcevc = stg->params.lcevc;
+        AVStream *st    = stg->streams[lcevc->lcevc_index];
+        MOVTrack *track = st->priv_data;
+
+        for (i = 0; i < mov->nb_tracks; i++) {
+            MOVTrack *trk = &mov->tracks[i];
+
+            if (trk->st == stg->streams[!lcevc->lcevc_index])
+                break;
+        }
+        track->src_track = i;
+
+        track->par->width = lcevc->width;
+        track->par->height = track->height = lcevc->height;
+    }
+
     enable_tracks(s);
     return 0;
 }
@@ -8892,6 +8968,7 @@ static const AVCodecTag codec_mp4_tags[] = {
     { AV_CODEC_ID_VVC,             MKTAG('v', 'v', 'c', '1') },
     { AV_CODEC_ID_VVC,             MKTAG('v', 'v', 'i', '1') },
     { AV_CODEC_ID_EVC,             MKTAG('e', 'v', 'c', '1') },
+    { AV_CODEC_ID_LCEVC,           MKTAG('l', 'v', 'c', '1') },
     { AV_CODEC_ID_APV,             MKTAG('a', 'p', 'v', '1') },
     { AV_CODEC_ID_MPEG2VIDEO,      MKTAG('m', 'p', '4', 'v') },
     { AV_CODEC_ID_MPEG1VIDEO,      MKTAG('m', 'p', '4', 'v') },
diff --git a/libavformat/version.h b/libavformat/version.h
index e8fad25023..cd62aaf1ca 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -32,7 +32,7 @@
 #include "version_major.h"
 
 #define LIBAVFORMAT_VERSION_MINOR  13
-#define LIBAVFORMAT_VERSION_MICRO 100
+#define LIBAVFORMAT_VERSION_MICRO 101
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to