LCOV - code coverage report
Current view: top level - libavformat - mov_chan.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 51 83 61.4 %
Date: 2017-12-15 02:19:58 Functions: 3 4 75.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2011 Justin Ruggles
       3             :  *
       4             :  * This file is part of FFmpeg.
       5             :  *
       6             :  * FFmpeg is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU Lesser General Public
       8             :  * License as published by the Free Software Foundation; either
       9             :  * version 2.1 of the License, or (at your option) any later version.
      10             :  *
      11             :  * FFmpeg is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with FFmpeg; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : /**
      22             :  * mov 'chan' tag reading/writing.
      23             :  * @author Justin Ruggles
      24             :  */
      25             : 
      26             : #include <stdint.h>
      27             : 
      28             : #include "libavutil/channel_layout.h"
      29             : #include "libavcodec/avcodec.h"
      30             : #include "mov_chan.h"
      31             : 
      32             : /**
      33             :  * Channel Layout Tag
      34             :  * This tells which channels are present in the audio stream and the order in
      35             :  * which they appear.
      36             :  *
      37             :  * @note We're using the channel layout tag to indicate channel order
      38             :  *       when the value is greater than 0x10000. The Apple documentation has
      39             :  *       some contradictions as to how this is actually supposed to be handled.
      40             :  *
      41             :  *       Core Audio File Format Spec:
      42             :  *           "The high 16 bits indicates a specific ordering of the channels."
      43             :  *       Core Audio Data Types Reference:
      44             :  *           "These identifiers specify the channels included in a layout but
      45             :  *            do not specify a particular ordering of those channels."
      46             :  */
      47             : enum MovChannelLayoutTag {
      48             : #define MOV_CH_LAYOUT_UNKNOWN             0xFFFF0000
      49             :     MOV_CH_LAYOUT_USE_DESCRIPTIONS      = (  0 << 16) | 0,
      50             :     MOV_CH_LAYOUT_USE_BITMAP            = (  1 << 16) | 0,
      51             :     MOV_CH_LAYOUT_DISCRETEINORDER       = (147 << 16) | 0,
      52             :     MOV_CH_LAYOUT_MONO                  = (100 << 16) | 1,
      53             :     MOV_CH_LAYOUT_STEREO                = (101 << 16) | 2,
      54             :     MOV_CH_LAYOUT_STEREOHEADPHONES      = (102 << 16) | 2,
      55             :     MOV_CH_LAYOUT_MATRIXSTEREO          = (103 << 16) | 2,
      56             :     MOV_CH_LAYOUT_MIDSIDE               = (104 << 16) | 2,
      57             :     MOV_CH_LAYOUT_XY                    = (105 << 16) | 2,
      58             :     MOV_CH_LAYOUT_BINAURAL              = (106 << 16) | 2,
      59             :     MOV_CH_LAYOUT_AMBISONIC_B_FORMAT    = (107 << 16) | 4,
      60             :     MOV_CH_LAYOUT_QUADRAPHONIC          = (108 << 16) | 4,
      61             :     MOV_CH_LAYOUT_PENTAGONAL            = (109 << 16) | 5,
      62             :     MOV_CH_LAYOUT_HEXAGONAL             = (110 << 16) | 6,
      63             :     MOV_CH_LAYOUT_OCTAGONAL             = (111 << 16) | 8,
      64             :     MOV_CH_LAYOUT_CUBE                  = (112 << 16) | 8,
      65             :     MOV_CH_LAYOUT_MPEG_3_0_A            = (113 << 16) | 3,
      66             :     MOV_CH_LAYOUT_MPEG_3_0_B            = (114 << 16) | 3,
      67             :     MOV_CH_LAYOUT_MPEG_4_0_A            = (115 << 16) | 4,
      68             :     MOV_CH_LAYOUT_MPEG_4_0_B            = (116 << 16) | 4,
      69             :     MOV_CH_LAYOUT_MPEG_5_0_A            = (117 << 16) | 5,
      70             :     MOV_CH_LAYOUT_MPEG_5_0_B            = (118 << 16) | 5,
      71             :     MOV_CH_LAYOUT_MPEG_5_0_C            = (119 << 16) | 5,
      72             :     MOV_CH_LAYOUT_MPEG_5_0_D            = (120 << 16) | 5,
      73             :     MOV_CH_LAYOUT_MPEG_5_1_A            = (121 << 16) | 6,
      74             :     MOV_CH_LAYOUT_MPEG_5_1_B            = (122 << 16) | 6,
      75             :     MOV_CH_LAYOUT_MPEG_5_1_C            = (123 << 16) | 6,
      76             :     MOV_CH_LAYOUT_MPEG_5_1_D            = (124 << 16) | 6,
      77             :     MOV_CH_LAYOUT_MPEG_6_1_A            = (125 << 16) | 7,
      78             :     MOV_CH_LAYOUT_MPEG_7_1_A            = (126 << 16) | 8,
      79             :     MOV_CH_LAYOUT_MPEG_7_1_B            = (127 << 16) | 8,
      80             :     MOV_CH_LAYOUT_MPEG_7_1_C            = (128 << 16) | 8,
      81             :     MOV_CH_LAYOUT_EMAGIC_DEFAULT_7_1    = (129 << 16) | 8,
      82             :     MOV_CH_LAYOUT_SMPTE_DTV             = (130 << 16) | 8,
      83             :     MOV_CH_LAYOUT_ITU_2_1               = (131 << 16) | 3,
      84             :     MOV_CH_LAYOUT_ITU_2_2               = (132 << 16) | 4,
      85             :     MOV_CH_LAYOUT_DVD_4                 = (133 << 16) | 3,
      86             :     MOV_CH_LAYOUT_DVD_5                 = (134 << 16) | 4,
      87             :     MOV_CH_LAYOUT_DVD_6                 = (135 << 16) | 5,
      88             :     MOV_CH_LAYOUT_DVD_10                = (136 << 16) | 4,
      89             :     MOV_CH_LAYOUT_DVD_11                = (137 << 16) | 5,
      90             :     MOV_CH_LAYOUT_DVD_18                = (138 << 16) | 5,
      91             :     MOV_CH_LAYOUT_AUDIOUNIT_6_0         = (139 << 16) | 6,
      92             :     MOV_CH_LAYOUT_AUDIOUNIT_7_0         = (140 << 16) | 7,
      93             :     MOV_CH_LAYOUT_AUDIOUNIT_7_0_FRONT   = (148 << 16) | 7,
      94             :     MOV_CH_LAYOUT_AAC_6_0               = (141 << 16) | 6,
      95             :     MOV_CH_LAYOUT_AAC_6_1               = (142 << 16) | 7,
      96             :     MOV_CH_LAYOUT_AAC_7_0               = (143 << 16) | 7,
      97             :     MOV_CH_LAYOUT_AAC_OCTAGONAL         = (144 << 16) | 8,
      98             :     MOV_CH_LAYOUT_TMH_10_2_STD          = (145 << 16) | 16,
      99             :     MOV_CH_LAYOUT_TMH_10_2_FULL         = (146 << 16) | 21,
     100             :     MOV_CH_LAYOUT_AC3_1_0_1             = (149 << 16) | 2,
     101             :     MOV_CH_LAYOUT_AC3_3_0               = (150 << 16) | 3,
     102             :     MOV_CH_LAYOUT_AC3_3_1               = (151 << 16) | 4,
     103             :     MOV_CH_LAYOUT_AC3_3_0_1             = (152 << 16) | 4,
     104             :     MOV_CH_LAYOUT_AC3_2_1_1             = (153 << 16) | 4,
     105             :     MOV_CH_LAYOUT_AC3_3_1_1             = (154 << 16) | 5,
     106             :     MOV_CH_LAYOUT_EAC3_6_0_A            = (155 << 16) | 6,
     107             :     MOV_CH_LAYOUT_EAC3_7_0_A            = (156 << 16) | 7,
     108             :     MOV_CH_LAYOUT_EAC3_6_1_A            = (157 << 16) | 7,
     109             :     MOV_CH_LAYOUT_EAC3_6_1_B            = (158 << 16) | 7,
     110             :     MOV_CH_LAYOUT_EAC3_6_1_C            = (159 << 16) | 7,
     111             :     MOV_CH_LAYOUT_EAC3_7_1_A            = (160 << 16) | 8,
     112             :     MOV_CH_LAYOUT_EAC3_7_1_B            = (161 << 16) | 8,
     113             :     MOV_CH_LAYOUT_EAC3_7_1_C            = (162 << 16) | 8,
     114             :     MOV_CH_LAYOUT_EAC3_7_1_D            = (163 << 16) | 8,
     115             :     MOV_CH_LAYOUT_EAC3_7_1_E            = (164 << 16) | 8,
     116             :     MOV_CH_LAYOUT_EAC3_7_1_F            = (165 << 16) | 8,
     117             :     MOV_CH_LAYOUT_EAC3_7_1_G            = (166 << 16) | 8,
     118             :     MOV_CH_LAYOUT_EAC3_7_1_H            = (167 << 16) | 8,
     119             :     MOV_CH_LAYOUT_DTS_3_1               = (168 << 16) | 4,
     120             :     MOV_CH_LAYOUT_DTS_4_1               = (169 << 16) | 5,
     121             :     MOV_CH_LAYOUT_DTS_6_0_A             = (170 << 16) | 6,
     122             :     MOV_CH_LAYOUT_DTS_6_0_B             = (171 << 16) | 6,
     123             :     MOV_CH_LAYOUT_DTS_6_0_C             = (172 << 16) | 6,
     124             :     MOV_CH_LAYOUT_DTS_6_1_A             = (173 << 16) | 7,
     125             :     MOV_CH_LAYOUT_DTS_6_1_B             = (174 << 16) | 7,
     126             :     MOV_CH_LAYOUT_DTS_6_1_C             = (175 << 16) | 7,
     127             :     MOV_CH_LAYOUT_DTS_6_1_D             = (182 << 16) | 7,
     128             :     MOV_CH_LAYOUT_DTS_7_0               = (176 << 16) | 7,
     129             :     MOV_CH_LAYOUT_DTS_7_1               = (177 << 16) | 8,
     130             :     MOV_CH_LAYOUT_DTS_8_0_A             = (178 << 16) | 8,
     131             :     MOV_CH_LAYOUT_DTS_8_0_B             = (179 << 16) | 8,
     132             :     MOV_CH_LAYOUT_DTS_8_1_A             = (180 << 16) | 9,
     133             :     MOV_CH_LAYOUT_DTS_8_1_B             = (181 << 16) | 9,
     134             : };
     135             : 
     136             : struct MovChannelLayoutMap {
     137             :     uint32_t tag;
     138             :     uint64_t layout;
     139             : };
     140             : 
     141             : static const struct MovChannelLayoutMap mov_ch_layout_map_misc[] = {
     142             :     { MOV_CH_LAYOUT_USE_DESCRIPTIONS,   0 },
     143             :     { MOV_CH_LAYOUT_USE_BITMAP,         0 },
     144             :     { MOV_CH_LAYOUT_DISCRETEINORDER,    0 },
     145             :     { MOV_CH_LAYOUT_UNKNOWN,            0 },
     146             :     { MOV_CH_LAYOUT_TMH_10_2_STD,       0 }, // L,   R,  C,    Vhc, Lsd, Rsd,
     147             :                                              // Ls,  Rs, Vhl,  Vhr, Lw,  Rw,
     148             :                                              // Csd, Cs, LFE1, LFE2
     149             :     { MOV_CH_LAYOUT_TMH_10_2_FULL,      0 }, // L,   R,  C,    Vhc,  Lsd, Rsd,
     150             :                                              // Ls,  Rs, Vhl,  Vhr,  Lw,  Rw,
     151             :                                              // Csd, Cs, LFE1, LFE2, Lc,  Rc,
     152             :                                              // HI,  VI, Haptic
     153             :     { 0, 0 },
     154             : };
     155             : 
     156             : static const struct MovChannelLayoutMap mov_ch_layout_map_1ch[] = {
     157             :     { MOV_CH_LAYOUT_MONO,               AV_CH_LAYOUT_MONO }, // C
     158             :     { 0, 0 },
     159             : };
     160             : 
     161             : static const struct MovChannelLayoutMap mov_ch_layout_map_2ch[] = {
     162             :     { MOV_CH_LAYOUT_STEREO,             AV_CH_LAYOUT_STEREO         }, // L, R
     163             :     { MOV_CH_LAYOUT_STEREOHEADPHONES,   AV_CH_LAYOUT_STEREO         }, // L, R
     164             :     { MOV_CH_LAYOUT_BINAURAL,           AV_CH_LAYOUT_STEREO         }, // L, R
     165             :     { MOV_CH_LAYOUT_MIDSIDE,            AV_CH_LAYOUT_STEREO         }, // C, sides
     166             :     { MOV_CH_LAYOUT_XY,                 AV_CH_LAYOUT_STEREO         }, // X (left), Y (right)
     167             : 
     168             :     { MOV_CH_LAYOUT_MATRIXSTEREO,       AV_CH_LAYOUT_STEREO_DOWNMIX }, // Lt, Rt
     169             : 
     170             :     { MOV_CH_LAYOUT_AC3_1_0_1,          AV_CH_LAYOUT_MONO |            // C, LFE
     171             :                                         AV_CH_LOW_FREQUENCY         },
     172             :     { 0, 0 },
     173             : };
     174             : 
     175             : static const struct MovChannelLayoutMap mov_ch_layout_map_3ch[] = {
     176             :     { MOV_CH_LAYOUT_MPEG_3_0_A,         AV_CH_LAYOUT_SURROUND }, // L, R, C
     177             :     { MOV_CH_LAYOUT_MPEG_3_0_B,         AV_CH_LAYOUT_SURROUND }, // C, L, R
     178             :     { MOV_CH_LAYOUT_AC3_3_0,            AV_CH_LAYOUT_SURROUND }, // L, C, R
     179             : 
     180             :     { MOV_CH_LAYOUT_ITU_2_1,            AV_CH_LAYOUT_2_1      }, // L, R, Cs
     181             : 
     182             :     { MOV_CH_LAYOUT_DVD_4,              AV_CH_LAYOUT_2POINT1  }, // L, R, LFE
     183             :     { 0, 0 },
     184             : };
     185             : 
     186             : static const struct MovChannelLayoutMap mov_ch_layout_map_4ch[] = {
     187             :     { MOV_CH_LAYOUT_AMBISONIC_B_FORMAT, 0 },                    // W, X, Y, Z
     188             : 
     189             :     { MOV_CH_LAYOUT_QUADRAPHONIC,       AV_CH_LAYOUT_QUAD    }, // L, R, Rls, Rrs
     190             : 
     191             :     { MOV_CH_LAYOUT_MPEG_4_0_A,         AV_CH_LAYOUT_4POINT0 }, // L, R, C, Cs
     192             :     { MOV_CH_LAYOUT_MPEG_4_0_B,         AV_CH_LAYOUT_4POINT0 }, // C, L, R, Cs
     193             :     { MOV_CH_LAYOUT_AC3_3_1,            AV_CH_LAYOUT_4POINT0 }, // L, C, R, Cs
     194             : 
     195             :     { MOV_CH_LAYOUT_ITU_2_2,            AV_CH_LAYOUT_2_2     }, // L, R, Ls, Rs
     196             : 
     197             :     { MOV_CH_LAYOUT_DVD_5,              AV_CH_LAYOUT_2_1 |      // L, R, LFE, Cs
     198             :                                         AV_CH_LOW_FREQUENCY  },
     199             :     { MOV_CH_LAYOUT_AC3_2_1_1,          AV_CH_LAYOUT_2_1 |      // L, R, Cs, LFE
     200             :                                         AV_CH_LOW_FREQUENCY  },
     201             : 
     202             :     { MOV_CH_LAYOUT_DVD_10,             AV_CH_LAYOUT_3POINT1 }, // L, R, C, LFE
     203             :     { MOV_CH_LAYOUT_AC3_3_0_1,          AV_CH_LAYOUT_3POINT1 }, // L, C, R, LFE
     204             :     { MOV_CH_LAYOUT_DTS_3_1,            AV_CH_LAYOUT_3POINT1 }, // C, L, R, LFE
     205             :     { 0, 0 },
     206             : };
     207             : 
     208             : static const struct MovChannelLayoutMap mov_ch_layout_map_5ch[] = {
     209             :     { MOV_CH_LAYOUT_PENTAGONAL,         AV_CH_LAYOUT_5POINT0_BACK }, // L, R, Rls, Rrs, C
     210             : 
     211             :     { MOV_CH_LAYOUT_MPEG_5_0_A,         AV_CH_LAYOUT_5POINT0 },      // L, R, C,  Ls, Rs
     212             :     { MOV_CH_LAYOUT_MPEG_5_0_B,         AV_CH_LAYOUT_5POINT0 },      // L, R, Ls, Rs, C
     213             :     { MOV_CH_LAYOUT_MPEG_5_0_C,         AV_CH_LAYOUT_5POINT0 },      // L, C, R,  Ls, Rs
     214             :     { MOV_CH_LAYOUT_MPEG_5_0_D,         AV_CH_LAYOUT_5POINT0 },      // C, L, R,  Ls, Rs
     215             : 
     216             :     { MOV_CH_LAYOUT_DVD_6,              AV_CH_LAYOUT_2_2 |           // L, R, LFE, Ls, Rs
     217             :                                         AV_CH_LOW_FREQUENCY },
     218             :     { MOV_CH_LAYOUT_DVD_18,             AV_CH_LAYOUT_2_2 |           // L, R, Ls, Rs, LFE
     219             :                                         AV_CH_LOW_FREQUENCY },
     220             : 
     221             :     { MOV_CH_LAYOUT_DVD_11,             AV_CH_LAYOUT_4POINT1 },      // L, R, C, LFE, Cs
     222             :     { MOV_CH_LAYOUT_AC3_3_1_1,          AV_CH_LAYOUT_4POINT1 },      // L, C, R, Cs,  LFE
     223             :     { MOV_CH_LAYOUT_DTS_4_1,            AV_CH_LAYOUT_4POINT1 },      // C, L, R, Cs,  LFE
     224             :     { 0, 0 },
     225             : };
     226             : 
     227             : static const struct MovChannelLayoutMap mov_ch_layout_map_6ch[] = {
     228             :     { MOV_CH_LAYOUT_HEXAGONAL,          AV_CH_LAYOUT_HEXAGONAL },      // L, R,  Rls, Rrs, C,   Cs
     229             :     { MOV_CH_LAYOUT_DTS_6_0_C,          AV_CH_LAYOUT_HEXAGONAL },      // C, Cs, L,   R,   Rls, Rrs
     230             : 
     231             :     { MOV_CH_LAYOUT_MPEG_5_1_A,         AV_CH_LAYOUT_5POINT1 },        // L, R, C,  LFE, Ls, Rs
     232             :     { MOV_CH_LAYOUT_MPEG_5_1_B,         AV_CH_LAYOUT_5POINT1 },        // L, R, Ls, Rs,  C,  LFE
     233             :     { MOV_CH_LAYOUT_MPEG_5_1_C,         AV_CH_LAYOUT_5POINT1 },        // L, C, R,  Ls,  Rs, LFE
     234             :     { MOV_CH_LAYOUT_MPEG_5_1_D,         AV_CH_LAYOUT_5POINT1 },        // C, L, R,  Ls,  Rs, LFE
     235             : 
     236             :     { MOV_CH_LAYOUT_AUDIOUNIT_6_0,      AV_CH_LAYOUT_6POINT0 },        // L, R, Ls, Rs, C,  Cs
     237             :     { MOV_CH_LAYOUT_AAC_6_0,            AV_CH_LAYOUT_6POINT0 },        // C, L, R,  Ls, Rs, Cs
     238             :     { MOV_CH_LAYOUT_EAC3_6_0_A,         AV_CH_LAYOUT_6POINT0 },        // L, C, R,  Ls, Rs, Cs
     239             : 
     240             :     { MOV_CH_LAYOUT_DTS_6_0_A,          AV_CH_LAYOUT_6POINT0_FRONT },  // Lc, Rc, L, R, Ls, Rs
     241             : 
     242             :     { MOV_CH_LAYOUT_DTS_6_0_B,          AV_CH_LAYOUT_5POINT0_BACK |    // C, L, R, Rls, Rrs, Ts
     243             :                                         AV_CH_TOP_CENTER },
     244             :     { 0, 0 },
     245             : };
     246             : 
     247             : static const struct MovChannelLayoutMap mov_ch_layout_map_7ch[] = {
     248             :     { MOV_CH_LAYOUT_MPEG_6_1_A,          AV_CH_LAYOUT_6POINT1 },        // L, R, C, LFE, Ls, Rs,  Cs
     249             :     { MOV_CH_LAYOUT_AAC_6_1,             AV_CH_LAYOUT_6POINT1 },        // C, L, R, Ls,  Rs, Cs,  LFE
     250             :     { MOV_CH_LAYOUT_EAC3_6_1_A,          AV_CH_LAYOUT_6POINT1 },        // L, C, R, Ls,  Rs, LFE, Cs
     251             :     { MOV_CH_LAYOUT_DTS_6_1_D,           AV_CH_LAYOUT_6POINT1 },        // C, L, R, Ls,  Rs, LFE, Cs
     252             : 
     253             :     { MOV_CH_LAYOUT_AUDIOUNIT_7_0,       AV_CH_LAYOUT_7POINT0 },        // L, R, Ls, Rs, C,  Rls, Rrs
     254             :     { MOV_CH_LAYOUT_AAC_7_0,             AV_CH_LAYOUT_7POINT0 },        // C, L, R,  Ls, Rs, Rls, Rrs
     255             :     { MOV_CH_LAYOUT_EAC3_7_0_A,          AV_CH_LAYOUT_7POINT0 },        // L, C, R,  Ls, Rs, Rls, Rrs
     256             : 
     257             :     { MOV_CH_LAYOUT_AUDIOUNIT_7_0_FRONT, AV_CH_LAYOUT_7POINT0_FRONT },  // L,  R, Ls, Rs, C, Lc, Rc
     258             :     { MOV_CH_LAYOUT_DTS_7_0,             AV_CH_LAYOUT_7POINT0_FRONT },  // Lc, C, Rc, L,  R, Ls, Rs
     259             : 
     260             :     { MOV_CH_LAYOUT_EAC3_6_1_B,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Ts
     261             :                                          AV_CH_TOP_CENTER },
     262             : 
     263             :     { MOV_CH_LAYOUT_EAC3_6_1_C,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Vhc
     264             :                                          AV_CH_TOP_FRONT_CENTER },
     265             : 
     266             :     { MOV_CH_LAYOUT_DTS_6_1_A,           AV_CH_LAYOUT_6POINT1_FRONT },  // Lc, Rc, L, R, Ls, Rs, LFE
     267             : 
     268             :     { MOV_CH_LAYOUT_DTS_6_1_B,           AV_CH_LAYOUT_5POINT1_BACK |    // C, L, R, Rls, Rrs, Ts, LFE
     269             :                                          AV_CH_TOP_CENTER },
     270             : 
     271             :     { MOV_CH_LAYOUT_DTS_6_1_C,           AV_CH_LAYOUT_6POINT1_BACK },   // C, Cs, L, R, Rls, Rrs, LFE
     272             :     { 0, 0 },
     273             : };
     274             : 
     275             : static const struct MovChannelLayoutMap mov_ch_layout_map_8ch[] = {
     276             :     { MOV_CH_LAYOUT_OCTAGONAL,           AV_CH_LAYOUT_OCTAGONAL },      // L, R, Rls, Rrs, C,  Cs,  Ls,  Rs
     277             :     { MOV_CH_LAYOUT_AAC_OCTAGONAL,       AV_CH_LAYOUT_OCTAGONAL },      // C, L, R,   Ls,  Rs, Rls, Rrs, Cs
     278             : 
     279             :     { MOV_CH_LAYOUT_CUBE,                AV_CH_LAYOUT_QUAD     |        // L, R, Rls, Rrs, Vhl, Vhr, Rlt, Rrt
     280             :                                          AV_CH_TOP_FRONT_LEFT  |
     281             :                                          AV_CH_TOP_FRONT_RIGHT |
     282             :                                          AV_CH_TOP_BACK_LEFT   |
     283             :                                          AV_CH_TOP_BACK_RIGHT },
     284             : 
     285             :     { MOV_CH_LAYOUT_MPEG_7_1_A,          AV_CH_LAYOUT_7POINT1_WIDE },   // L,  R,  C,  LFE, Ls, Rs,  Lc, Rc
     286             :     { MOV_CH_LAYOUT_MPEG_7_1_B,          AV_CH_LAYOUT_7POINT1_WIDE },   // C,  Lc, Rc, L,   R,  Ls,  Rs, LFE
     287             :     { MOV_CH_LAYOUT_EMAGIC_DEFAULT_7_1,  AV_CH_LAYOUT_7POINT1_WIDE },   // L,  R,  Ls, Rs,  C,  LFE, Lc, Rc
     288             :     { MOV_CH_LAYOUT_EAC3_7_1_B,          AV_CH_LAYOUT_7POINT1_WIDE },   // L,  C,  R,  Ls,  Rs, LFE, Lc, Rc
     289             :     { MOV_CH_LAYOUT_DTS_7_1,             AV_CH_LAYOUT_7POINT1_WIDE },   // Lc, C,  Rc, L,   R,  Ls,  Rs, LFE
     290             : 
     291             :     { MOV_CH_LAYOUT_MPEG_7_1_C,          AV_CH_LAYOUT_7POINT1 },        // L, R, C, LFE, Ls, Rs,  Rls, Rrs
     292             :     { MOV_CH_LAYOUT_EAC3_7_1_A,          AV_CH_LAYOUT_7POINT1 },        // L, C, R, Ls,  Rs, LFE, Rls, Rrs
     293             : 
     294             :     { MOV_CH_LAYOUT_SMPTE_DTV,           AV_CH_LAYOUT_5POINT1 |         // L, R, C, LFE, Ls, Rs, Lt, Rt
     295             :                                          AV_CH_LAYOUT_STEREO_DOWNMIX },
     296             : 
     297             :     { MOV_CH_LAYOUT_EAC3_7_1_C,          AV_CH_LAYOUT_5POINT1        |  // L, C, R, Ls, Rs, LFE, Lsd, Rsd
     298             :                                          AV_CH_SURROUND_DIRECT_LEFT  |
     299             :                                          AV_CH_SURROUND_DIRECT_RIGHT },
     300             : 
     301             :     { MOV_CH_LAYOUT_EAC3_7_1_D,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Lw, Rw
     302             :                                          AV_CH_WIDE_LEFT      |
     303             :                                          AV_CH_WIDE_RIGHT },
     304             : 
     305             :     { MOV_CH_LAYOUT_EAC3_7_1_E,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Vhl, Vhr
     306             :                                          AV_CH_TOP_FRONT_LEFT |
     307             :                                          AV_CH_TOP_FRONT_RIGHT },
     308             : 
     309             :     { MOV_CH_LAYOUT_EAC3_7_1_F,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Cs, Ts
     310             :                                          AV_CH_BACK_CENTER    |
     311             :                                          AV_CH_TOP_CENTER },
     312             : 
     313             :     { MOV_CH_LAYOUT_EAC3_7_1_G,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Cs, Vhc
     314             :                                          AV_CH_BACK_CENTER    |
     315             :                                          AV_CH_TOP_FRONT_CENTER },
     316             : 
     317             :     { MOV_CH_LAYOUT_EAC3_7_1_H,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Ts, Vhc
     318             :                                          AV_CH_TOP_CENTER     |
     319             :                                          AV_CH_TOP_FRONT_CENTER },
     320             : 
     321             :     { MOV_CH_LAYOUT_DTS_8_0_A,           AV_CH_LAYOUT_2_2           |   // Lc, Rc, L, R, Ls, Rs, Rls, Rrs
     322             :                                          AV_CH_BACK_LEFT            |
     323             :                                          AV_CH_BACK_RIGHT           |
     324             :                                          AV_CH_FRONT_LEFT_OF_CENTER |
     325             :                                          AV_CH_FRONT_RIGHT_OF_CENTER },
     326             : 
     327             :     { MOV_CH_LAYOUT_DTS_8_0_B,           AV_CH_LAYOUT_5POINT0        |  // Lc, C, Rc, L, R, Ls, Cs, Rs
     328             :                                          AV_CH_FRONT_LEFT_OF_CENTER  |
     329             :                                          AV_CH_FRONT_RIGHT_OF_CENTER |
     330             :                                          AV_CH_BACK_CENTER },
     331             :     { 0, 0 },
     332             : };
     333             : 
     334             : static const struct MovChannelLayoutMap mov_ch_layout_map_9ch[] = {
     335             :     { MOV_CH_LAYOUT_DTS_8_1_A,           AV_CH_LAYOUT_2_2            | // Lc, Rc, L, R, Ls, Rs, Rls, Rrs, LFE
     336             :                                          AV_CH_BACK_LEFT             |
     337             :                                          AV_CH_BACK_RIGHT            |
     338             :                                          AV_CH_FRONT_LEFT_OF_CENTER  |
     339             :                                          AV_CH_FRONT_RIGHT_OF_CENTER |
     340             :                                          AV_CH_LOW_FREQUENCY },
     341             : 
     342             :     { MOV_CH_LAYOUT_DTS_8_1_B,           AV_CH_LAYOUT_7POINT1_WIDE   | // Lc, C, Rc, L, R, Ls, Cs, Rs, LFE
     343             :                                          AV_CH_BACK_CENTER },
     344             :     { 0, 0 },
     345             : };
     346             : 
     347             : static const struct MovChannelLayoutMap * const mov_ch_layout_map[] = {
     348             :     mov_ch_layout_map_misc,
     349             :     mov_ch_layout_map_1ch,
     350             :     mov_ch_layout_map_2ch,
     351             :     mov_ch_layout_map_3ch,
     352             :     mov_ch_layout_map_4ch,
     353             :     mov_ch_layout_map_5ch,
     354             :     mov_ch_layout_map_6ch,
     355             :     mov_ch_layout_map_7ch,
     356             :     mov_ch_layout_map_8ch,
     357             :     mov_ch_layout_map_9ch,
     358             : };
     359             : 
     360             : static const enum MovChannelLayoutTag mov_ch_layouts_aac[] = {
     361             :     MOV_CH_LAYOUT_MONO,
     362             :     MOV_CH_LAYOUT_STEREO,
     363             :     MOV_CH_LAYOUT_AC3_1_0_1,
     364             :     MOV_CH_LAYOUT_MPEG_3_0_B,
     365             :     MOV_CH_LAYOUT_ITU_2_1,
     366             :     MOV_CH_LAYOUT_DVD_4,
     367             :     MOV_CH_LAYOUT_QUADRAPHONIC,
     368             :     MOV_CH_LAYOUT_MPEG_4_0_B,
     369             :     MOV_CH_LAYOUT_ITU_2_2,
     370             :     MOV_CH_LAYOUT_AC3_2_1_1,
     371             :     MOV_CH_LAYOUT_DTS_3_1,
     372             :     MOV_CH_LAYOUT_MPEG_5_0_D,
     373             :     MOV_CH_LAYOUT_DVD_18,
     374             :     MOV_CH_LAYOUT_DTS_4_1,
     375             :     MOV_CH_LAYOUT_MPEG_5_1_D,
     376             :     MOV_CH_LAYOUT_AAC_6_0,
     377             :     MOV_CH_LAYOUT_DTS_6_0_A,
     378             :     MOV_CH_LAYOUT_AAC_6_1,
     379             :     MOV_CH_LAYOUT_AAC_7_0,
     380             :     MOV_CH_LAYOUT_DTS_6_1_A,
     381             :     MOV_CH_LAYOUT_AAC_OCTAGONAL,
     382             :     MOV_CH_LAYOUT_MPEG_7_1_B,
     383             :     MOV_CH_LAYOUT_DTS_8_0_A,
     384             :     0,
     385             : };
     386             : 
     387             : static const enum MovChannelLayoutTag mov_ch_layouts_ac3[] = {
     388             :     MOV_CH_LAYOUT_MONO,
     389             :     MOV_CH_LAYOUT_STEREO,
     390             :     MOV_CH_LAYOUT_AC3_1_0_1,
     391             :     MOV_CH_LAYOUT_AC3_3_0,
     392             :     MOV_CH_LAYOUT_ITU_2_1,
     393             :     MOV_CH_LAYOUT_DVD_4,
     394             :     MOV_CH_LAYOUT_AC3_3_1,
     395             :     MOV_CH_LAYOUT_ITU_2_2,
     396             :     MOV_CH_LAYOUT_AC3_2_1_1,
     397             :     MOV_CH_LAYOUT_AC3_3_0_1,
     398             :     MOV_CH_LAYOUT_MPEG_5_0_C,
     399             :     MOV_CH_LAYOUT_DVD_18,
     400             :     MOV_CH_LAYOUT_AC3_3_1_1,
     401             :     MOV_CH_LAYOUT_MPEG_5_1_C,
     402             :     0,
     403             : };
     404             : 
     405             : static const enum MovChannelLayoutTag mov_ch_layouts_alac[] = {
     406             :     MOV_CH_LAYOUT_MONO,
     407             :     MOV_CH_LAYOUT_STEREO,
     408             :     MOV_CH_LAYOUT_MPEG_3_0_B,
     409             :     MOV_CH_LAYOUT_MPEG_4_0_B,
     410             :     MOV_CH_LAYOUT_MPEG_5_0_D,
     411             :     MOV_CH_LAYOUT_MPEG_5_1_D,
     412             :     MOV_CH_LAYOUT_AAC_6_1,
     413             :     MOV_CH_LAYOUT_MPEG_7_1_B,
     414             :     0,
     415             : };
     416             : 
     417             : static const enum MovChannelLayoutTag mov_ch_layouts_wav[] = {
     418             :     MOV_CH_LAYOUT_MONO,
     419             :     MOV_CH_LAYOUT_STEREO,
     420             :     MOV_CH_LAYOUT_MATRIXSTEREO,
     421             :     MOV_CH_LAYOUT_MPEG_3_0_A,
     422             :     MOV_CH_LAYOUT_QUADRAPHONIC,
     423             :     MOV_CH_LAYOUT_MPEG_5_0_A,
     424             :     MOV_CH_LAYOUT_MPEG_5_1_A,
     425             :     MOV_CH_LAYOUT_MPEG_6_1_A,
     426             :     MOV_CH_LAYOUT_MPEG_7_1_A,
     427             :     MOV_CH_LAYOUT_MPEG_7_1_C,
     428             :     MOV_CH_LAYOUT_SMPTE_DTV,
     429             :     0,
     430             : };
     431             : 
     432             : static const struct {
     433             :     enum AVCodecID codec_id;
     434             :     const enum MovChannelLayoutTag *layouts;
     435             : } mov_codec_ch_layouts[] = {
     436             :     { AV_CODEC_ID_AAC,     mov_ch_layouts_aac      },
     437             :     { AV_CODEC_ID_AC3,     mov_ch_layouts_ac3      },
     438             :     { AV_CODEC_ID_ALAC,    mov_ch_layouts_alac     },
     439             :     { AV_CODEC_ID_PCM_U8,    mov_ch_layouts_wav    },
     440             :     { AV_CODEC_ID_PCM_S8,    mov_ch_layouts_wav    },
     441             :     { AV_CODEC_ID_PCM_S16LE, mov_ch_layouts_wav    },
     442             :     { AV_CODEC_ID_PCM_S16BE, mov_ch_layouts_wav    },
     443             :     { AV_CODEC_ID_PCM_S24LE, mov_ch_layouts_wav    },
     444             :     { AV_CODEC_ID_PCM_S24BE, mov_ch_layouts_wav    },
     445             :     { AV_CODEC_ID_PCM_S32LE, mov_ch_layouts_wav    },
     446             :     { AV_CODEC_ID_PCM_S32BE, mov_ch_layouts_wav    },
     447             :     { AV_CODEC_ID_PCM_F32LE, mov_ch_layouts_wav    },
     448             :     { AV_CODEC_ID_PCM_F32BE, mov_ch_layouts_wav    },
     449             :     { AV_CODEC_ID_PCM_F64LE, mov_ch_layouts_wav    },
     450             :     { AV_CODEC_ID_PCM_F64BE, mov_ch_layouts_wav    },
     451             :     { AV_CODEC_ID_NONE,    NULL                    },
     452             : };
     453             : 
     454          35 : uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap)
     455             : {
     456             :     int i, channels;
     457             :     const struct MovChannelLayoutMap *layout_map;
     458             : 
     459             :     /* use ff_mov_get_channel_label() to build a layout instead */
     460          35 :     if (tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS)
     461           0 :         return 0;
     462             : 
     463             :     /* handle the use of the channel bitmap */
     464          35 :     if (tag == MOV_CH_LAYOUT_USE_BITMAP)
     465           6 :         return bitmap < 0x40000 ? bitmap : 0;
     466             : 
     467             :     /* get the layout map based on the channel count for the specified layout tag */
     468          29 :     channels = tag & 0xFFFF;
     469          29 :     if (channels > 9)
     470           0 :         channels = 0;
     471          29 :     layout_map = mov_ch_layout_map[channels];
     472             : 
     473             :     /* find the channel layout for the specified layout tag */
     474          34 :     for (i = 0; layout_map[i].tag != 0; i++) {
     475          34 :         if (layout_map[i].tag == tag)
     476          29 :             break;
     477             :     }
     478          29 :     return layout_map[i].layout;
     479             : }
     480             : 
     481           0 : static uint32_t mov_get_channel_label(uint32_t label)
     482             : {
     483           0 :     if (label == 0)
     484           0 :         return 0;
     485           0 :     if (label <= 18)
     486           0 :         return 1U << (label - 1);
     487           0 :     if (label == 38)
     488           0 :         return AV_CH_STEREO_LEFT;
     489           0 :     if (label == 39)
     490           0 :         return AV_CH_STEREO_RIGHT;
     491           0 :     return 0;
     492             : }
     493             : 
     494          28 : uint32_t ff_mov_get_channel_layout_tag(enum AVCodecID codec_id,
     495             :                                        uint64_t channel_layout,
     496             :                                        uint32_t *bitmap)
     497             : {
     498             :     int i, j;
     499          28 :     uint32_t tag = 0;
     500          28 :     const enum MovChannelLayoutTag *layouts = NULL;
     501             : 
     502             :     /* find the layout list for the specified codec */
     503         244 :     for (i = 0; mov_codec_ch_layouts[i].codec_id != AV_CODEC_ID_NONE; i++) {
     504         233 :         if (mov_codec_ch_layouts[i].codec_id == codec_id)
     505          17 :             break;
     506             :     }
     507          28 :     if (mov_codec_ch_layouts[i].codec_id != AV_CODEC_ID_NONE)
     508          17 :         layouts = mov_codec_ch_layouts[i].layouts;
     509             : 
     510          28 :     if (layouts) {
     511             :         int channels;
     512             :         const struct MovChannelLayoutMap *layout_map;
     513             : 
     514             :         /* get the layout map based on the channel count */
     515          17 :         channels = av_get_channel_layout_nb_channels(channel_layout);
     516          17 :         if (channels > 9)
     517           0 :             channels = 0;
     518          17 :         layout_map = mov_ch_layout_map[channels];
     519             : 
     520             :         /* find the layout tag for the specified channel layout */
     521          32 :         for (i = 0; layouts[i] != 0; i++) {
     522          32 :             if ((layouts[i] & 0xFFFF) != channels)
     523          15 :                 continue;
     524          17 :             for (j = 0; layout_map[j].tag != 0; j++) {
     525          34 :                 if (layout_map[j].tag    == layouts[i] &&
     526          17 :                     layout_map[j].layout == channel_layout)
     527          17 :                     break;
     528             :             }
     529          17 :             if (layout_map[j].tag)
     530          17 :                 break;
     531             :         }
     532          17 :         tag = layouts[i];
     533             :     }
     534             : 
     535             :     /* if no tag was found, use channel bitmap as a backup if possible */
     536          28 :     if (tag == 0 && channel_layout > 0 && channel_layout < 0x40000) {
     537          11 :         tag     = MOV_CH_LAYOUT_USE_BITMAP;
     538          11 :         *bitmap = (uint32_t)channel_layout;
     539             :     } else
     540          17 :         *bitmap = 0;
     541             : 
     542             :     /* TODO: set channel descriptions as a secondary backup */
     543             : 
     544          28 :     return tag;
     545             : }
     546             : 
     547          35 : int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st,
     548             :                      int64_t size)
     549             : {
     550             :     uint32_t layout_tag, bitmap, num_descr, label_mask;
     551             :     int i;
     552             : 
     553          35 :     if (size < 12)
     554           0 :         return AVERROR_INVALIDDATA;
     555             : 
     556          35 :     layout_tag = avio_rb32(pb);
     557          35 :     bitmap     = avio_rb32(pb);
     558          35 :     num_descr  = avio_rb32(pb);
     559             : 
     560          35 :     av_log(s, AV_LOG_TRACE, "chan: layout=%"PRIu32" "
     561             :            "bitmap=%"PRIu32" num_descr=%"PRIu32"\n",
     562             :            layout_tag, bitmap, num_descr);
     563             : 
     564          35 :     if (size < 12ULL + num_descr * 20ULL)
     565           0 :         return 0;
     566             : 
     567          35 :     label_mask = 0;
     568          35 :     for (i = 0; i < num_descr; i++) {
     569             :         uint32_t label;
     570           0 :         if (pb->eof_reached) {
     571           0 :             av_log(s, AV_LOG_ERROR,
     572             :                    "reached EOF while reading channel layout\n");
     573           0 :             return AVERROR_INVALIDDATA;
     574             :         }
     575           0 :         label     = avio_rb32(pb);          // mChannelLabel
     576           0 :         avio_rb32(pb);                      // mChannelFlags
     577           0 :         avio_rl32(pb);                      // mCoordinates[0]
     578           0 :         avio_rl32(pb);                      // mCoordinates[1]
     579           0 :         avio_rl32(pb);                      // mCoordinates[2]
     580           0 :         size -= 20;
     581           0 :         if (layout_tag == 0) {
     582           0 :             uint32_t mask_incr = mov_get_channel_label(label);
     583           0 :             if (mask_incr == 0) {
     584           0 :                 label_mask = 0;
     585           0 :                 break;
     586             :             }
     587           0 :             label_mask |= mask_incr;
     588             :         }
     589             :     }
     590          35 :     if (layout_tag == 0) {
     591           0 :         if (label_mask)
     592           0 :             st->codecpar->channel_layout = label_mask;
     593             :     } else
     594          35 :         st->codecpar->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap);
     595          35 :     avio_skip(pb, size - 12);
     596             : 
     597          35 :     return 0;
     598             : }

Generated by: LCOV version 1.13