PR #23306 opened by James Almer (jamrial)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23306
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23306.patch

Backport of part of !23264


>From f7f5f066cd21cc0641b0335522078e0295d68bde Mon Sep 17 00:00:00 2001
From: James Almer <[email protected]>
Date: Sun, 31 May 2026 13:23:06 -0300
Subject: [PATCH 1/2] avformat/mov_chan: keep the layout untouched on chan/chnl
 box failure

Needed to keep the process going if some issue was found while parsing these 
boxes.

Signed-off-by: James Almer <[email protected]>
(cherry picked from commit fd1c8fa0e611f03681f5fce496848da7c73651a2)
---
 libavformat/mov_chan.c | 37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c
index 3c7274b737..5ba18b62d5 100644
--- a/libavformat/mov_chan.c
+++ b/libavformat/mov_chan.c
@@ -312,16 +312,22 @@ static int mov_get_channel_layout(AVChannelLayout 
*ch_layout, uint32_t tag)
     /* find the channel layout for the specified layout tag */
     layout_map = find_layout_map(tag);
     if (layout_map) {
+        AVChannelLayout tmp = { 0 };
         int ret;
-        av_channel_layout_uninit(ch_layout);
-        ret = av_channel_layout_custom_init(ch_layout, channels);
+        ret = av_channel_layout_custom_init(ch_lay&tmpout, channels);
         if (ret < 0)
             return ret;
         for (i = 0; i < channels; i++) {
             enum AVChannel id = layout_map[i].id;
-            ch_layout->u.map[i].id = (id != AV_CHAN_NONE ? id : 
AV_CHAN_UNKNOWN);
+            tmp.map[i].id = (id != AV_CHAN_NONE ? id : AV_CHAN_UNKNOWN);
         }
-        return av_channel_layout_retype(ch_layout, 0, 
AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
+
+        ret = av_channel_layout_retype(&tmp, 0, 
AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
+        if (ret < 0)
+            return ret;
+
+        av_channel_layout_uninit(ch_layout);
+        *ch_layout = tmp;
     }
     return 0;
 }
@@ -462,6 +468,7 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, 
AVStream *st,
         return 0;
 
     if (layout_tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS) {
+        AVChannelLayout tmp = { 0 };
         int nb_channels = ch_layout->nb_channels;
 
         if (!num_descr || num_descr < nb_channels) {
@@ -481,8 +488,7 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, 
AVStream *st,
             num_descr = nb_channels;
         }
 
-        av_channel_layout_uninit(ch_layout);
-        ret = av_channel_layout_custom_init(ch_layout, nb_channels);
+        ret = av_channel_layout_custom_init(&tmp, nb_channels);
         if (ret < 0)
             goto out;
 
@@ -499,12 +505,15 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, 
AVStream *st,
             avio_rl32(pb);                      // mCoordinates[1]
             avio_rl32(pb);                      // mCoordinates[2]
             size -= 20;
-            ch_layout->u.map[i].id = mov_get_channel_id(label);
+            tmp.u.map[i].id = mov_get_channel_id(label);
         }
 
-        ret = av_channel_layout_retype(ch_layout, 0, 
AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
+        ret = av_channel_layout_retype(&tmp, 0, 
AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
         if (ret < 0)
             goto out;
+
+       av_channel_layout_uninit(ch_layout);
+       *ch_layout = tmp;
     } else if (layout_tag == MOV_CH_LAYOUT_USE_BITMAP) {
         if (!ch_layout->nb_channels || av_popcount(bitmap) == 
ch_layout->nb_channels) {
             if (bitmap < 0x40000) {
@@ -783,11 +792,10 @@ int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, 
AVStream *st)
 
         av_log(s, AV_LOG_TRACE, "'chnl' layout %d\n", layout);
         if (!layout) {
-            AVChannelLayout *ch_layout = &st->codecpar->ch_layout;
+            AVChannelLayout tmp = { 0 }, *ch_layout = &st->codecpar->ch_layout;
             int nb_channels = ch_layout->nb_channels;
 
-            av_channel_layout_uninit(ch_layout);
-            ret = av_channel_layout_custom_init(ch_layout, nb_channels);
+            ret = av_channel_layout_custom_init(&tmp, nb_channels);
             if (ret < 0)
                 return ret;
 
@@ -808,12 +816,15 @@ int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, 
AVStream *st)
                     channel = AV_CHAN_UNKNOWN;
                 }
 
-                ch_layout->u.map[i].id = channel;
+                tmp.u.map[i].id = channel;
             }
 
-            ret = av_channel_layout_retype(ch_layout, 0, 
AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
+            ret = av_channel_layout_retype(&tmp, 0, 
AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
             if (ret < 0)
                 return ret;
+
+            av_channel_layout_uninit(ch_layout);
+            *ch_layout = tmp;
         } else {
             uint64_t omitted_channel_map = avio_rb64(pb);
 
-- 
2.52.0


>From ff000e900c7c051a36794b760fea22aa7e1cab24 Mon Sep 17 00:00:00 2001
From: James Almer <[email protected]>
Date: Thu, 28 May 2026 12:05:29 -0300
Subject: [PATCH 2/2] avformat/mov: don't abort on unsupported or invalid chnl
 boxes

They are optional and just define a channel layout, which may also be defined
by the underlying codec.

Signed-off-by: James Almer <[email protected]>
(cherry picked from commit 95fe0658d7b3c2e5549ca9a41652ef8c613df8ec)
---
 libavformat/mov.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 1dd8bef4e4..31a806b5dc 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1178,15 +1178,13 @@ static int mov_read_chnl(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
     version = avio_r8(pb);
     flags   = avio_rb24(pb);
     if (version != 0 || flags != 0) {
-        av_log(c->fc, AV_LOG_ERROR,
-               "Unsupported 'chnl' box with version %d, flags: %#x",
+        av_log(c->fc, AV_LOG_WARNING,
+               "Unsupported 'chnl' box with version %d, flags: %#x\n",
                version, flags);
-        return AVERROR_INVALIDDATA;
+        return 0;
     }
 
-    ret = ff_mov_read_chnl(c->fc, pb, st);
-    if (ret < 0)
-        return ret;
+    ff_mov_read_chnl(c->fc, pb, st);
 
     if (avio_tell(pb) != end) {
         av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data 
inside chnl\n",
-- 
2.52.0

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

Reply via email to