Previously we always assumed that the channels are in native order, even if
they were not. The new channel layout API allows us to signal the proper
channel order, so let's do so.
Fixes ticket #98.
---
libavformat/mov_chan.c | 464 +++++++++++++++++++----------------------
1 file changed, 211 insertions(+), 253 deletions(-)
diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c
index ead3a9b91b..d48cfeabb0 100644
--- a/libavformat/mov_chan.c
+++ b/libavformat/mov_chan.c
@@ -25,228 +25,163 @@
#include <stdint.h>
+#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavcodec/codec_id.h"
#include "mov_chan.h"
-struct MovChannelLayoutMap {
- uint32_t tag;
- uint64_t layout;
-};
-
-static const struct MovChannelLayoutMap mov_ch_layout_map_misc[] = {
- { MOV_CH_LAYOUT_USE_DESCRIPTIONS, 0 },
- { MOV_CH_LAYOUT_USE_BITMAP, 0 },
- { MOV_CH_LAYOUT_DISCRETEINORDER, 0 },
- { MOV_CH_LAYOUT_UNKNOWN, 0 },
- { MOV_CH_LAYOUT_TMH_10_2_STD, 0 }, // L, R, C, Vhc, Lsd, Rsd,
- // Ls, Rs, Vhl, Vhr, Lw, Rw,
- // Csd, Cs, LFE1, LFE2
- { MOV_CH_LAYOUT_TMH_10_2_FULL, 0 }, // L, R, C, Vhc, Lsd, Rsd,
- // Ls, Rs, Vhl, Vhr, Lw, Rw,
- // Csd, Cs, LFE1, LFE2, Lc, Rc,
- // HI, VI, Haptic
- { 0, 0 },
-};
-
-static const struct MovChannelLayoutMap mov_ch_layout_map_1ch[] = {
- { MOV_CH_LAYOUT_MONO, AV_CH_LAYOUT_MONO }, // C
- { 0, 0 },
-};
-
-static const struct MovChannelLayoutMap mov_ch_layout_map_2ch[] = {
- { MOV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_STEREO }, // L, R
- { MOV_CH_LAYOUT_STEREOHEADPHONES, AV_CH_LAYOUT_STEREO }, // L, R
- { MOV_CH_LAYOUT_BINAURAL, AV_CH_LAYOUT_STEREO }, // L, R
- { MOV_CH_LAYOUT_MIDSIDE, AV_CH_LAYOUT_STEREO }, // C,
sides
- { MOV_CH_LAYOUT_XY, AV_CH_LAYOUT_STEREO }, // X
(left), Y (right)
-
- { MOV_CH_LAYOUT_MATRIXSTEREO, AV_CH_LAYOUT_STEREO_DOWNMIX }, // Lt,
Rt
-
- { MOV_CH_LAYOUT_AC3_1_0_1, AV_CH_LAYOUT_MONO | // C,
LFE
- AV_CH_LOW_FREQUENCY },
- { 0, 0 },
-};
-
-static const struct MovChannelLayoutMap mov_ch_layout_map_3ch[] = {
- { MOV_CH_LAYOUT_MPEG_3_0_A, AV_CH_LAYOUT_SURROUND }, // L, R, C
- { MOV_CH_LAYOUT_MPEG_3_0_B, AV_CH_LAYOUT_SURROUND }, // C, L, R
- { MOV_CH_LAYOUT_AC3_3_0, AV_CH_LAYOUT_SURROUND }, // L, C, R
-
- { MOV_CH_LAYOUT_ITU_2_1, AV_CH_LAYOUT_2_1 }, // L, R, Cs
-
- { MOV_CH_LAYOUT_DVD_4, AV_CH_LAYOUT_2POINT1 }, // L, R, LFE
- { 0, 0 },
-};
-
-static const struct MovChannelLayoutMap mov_ch_layout_map_4ch[] = {
- { MOV_CH_LAYOUT_AMBISONIC_B_FORMAT, 0 }, // W, X, Y, Z
-
- { MOV_CH_LAYOUT_QUADRAPHONIC, AV_CH_LAYOUT_QUAD }, // L, R, Rls,
Rrs
-
- { MOV_CH_LAYOUT_MPEG_4_0_A, AV_CH_LAYOUT_4POINT0 }, // L, R, C, Cs
- { MOV_CH_LAYOUT_MPEG_4_0_B, AV_CH_LAYOUT_4POINT0 }, // C, L, R, Cs
- { MOV_CH_LAYOUT_AC3_3_1, AV_CH_LAYOUT_4POINT0 }, // L, C, R, Cs
-
- { MOV_CH_LAYOUT_ITU_2_2, AV_CH_LAYOUT_2_2 }, // L, R, Ls, Rs
-
- { MOV_CH_LAYOUT_DVD_5, AV_CH_LAYOUT_2_1 | // L, R, LFE,
Cs
- AV_CH_LOW_FREQUENCY },
- { MOV_CH_LAYOUT_AC3_2_1_1, AV_CH_LAYOUT_2_1 | // L, R, Cs,
LFE
- AV_CH_LOW_FREQUENCY },
-
- { MOV_CH_LAYOUT_DVD_10, AV_CH_LAYOUT_3POINT1 }, // L, R, C, LFE
- { MOV_CH_LAYOUT_AC3_3_0_1, AV_CH_LAYOUT_3POINT1 }, // L, C, R, LFE
- { MOV_CH_LAYOUT_DTS_3_1, AV_CH_LAYOUT_3POINT1 }, // C, L, R, LFE
- { 0, 0 },
-};
-
-static const struct MovChannelLayoutMap mov_ch_layout_map_5ch[] = {
- { MOV_CH_LAYOUT_PENTAGONAL, AV_CH_LAYOUT_5POINT0_BACK }, // L, R,
Rls, Rrs, C
-
- { MOV_CH_LAYOUT_MPEG_5_0_A, AV_CH_LAYOUT_5POINT0 }, // L, R,
C, Ls, Rs
- { MOV_CH_LAYOUT_MPEG_5_0_B, AV_CH_LAYOUT_5POINT0 }, // L, R,
Ls, Rs, C
- { MOV_CH_LAYOUT_MPEG_5_0_C, AV_CH_LAYOUT_5POINT0 }, // L, C,
R, Ls, Rs
- { MOV_CH_LAYOUT_MPEG_5_0_D, AV_CH_LAYOUT_5POINT0 }, // C, L,
R, Ls, Rs
-
- { MOV_CH_LAYOUT_DVD_6, AV_CH_LAYOUT_2_2 | // L, R,
LFE, Ls, Rs
- AV_CH_LOW_FREQUENCY },
- { MOV_CH_LAYOUT_DVD_18, AV_CH_LAYOUT_2_2 | // L, R,
Ls, Rs, LFE
- AV_CH_LOW_FREQUENCY },
-
- { MOV_CH_LAYOUT_DVD_11, AV_CH_LAYOUT_4POINT1 }, // L, R,
C, LFE, Cs
- { MOV_CH_LAYOUT_AC3_3_1_1, AV_CH_LAYOUT_4POINT1 }, // L, C,
R, Cs, LFE
- { MOV_CH_LAYOUT_DTS_4_1, AV_CH_LAYOUT_4POINT1 }, // C, L,
R, Cs, LFE
- { 0, 0 },
-};
-
-static const struct MovChannelLayoutMap mov_ch_layout_map_6ch[] = {
- { MOV_CH_LAYOUT_HEXAGONAL, AV_CH_LAYOUT_HEXAGONAL }, // L,
R, Rls, Rrs, C, Cs
- { MOV_CH_LAYOUT_DTS_6_0_C, AV_CH_LAYOUT_HEXAGONAL }, // C,
Cs, L, R, Rls, Rrs
-
- { MOV_CH_LAYOUT_MPEG_5_1_A, AV_CH_LAYOUT_5POINT1 }, // L,
R, C, LFE, Ls, Rs
- { MOV_CH_LAYOUT_MPEG_5_1_B, AV_CH_LAYOUT_5POINT1 }, // L,
R, Ls, Rs, C, LFE
- { MOV_CH_LAYOUT_MPEG_5_1_C, AV_CH_LAYOUT_5POINT1 }, // L,
C, R, Ls, Rs, LFE
- { MOV_CH_LAYOUT_MPEG_5_1_D, AV_CH_LAYOUT_5POINT1 }, // C,
L, R, Ls, Rs, LFE
-
- { MOV_CH_LAYOUT_AUDIOUNIT_6_0, AV_CH_LAYOUT_6POINT0 }, // L,
R, Ls, Rs, C, Cs
- { MOV_CH_LAYOUT_AAC_6_0, AV_CH_LAYOUT_6POINT0 }, // C,
L, R, Ls, Rs, Cs
- { MOV_CH_LAYOUT_EAC3_6_0_A, AV_CH_LAYOUT_6POINT0 }, // L,
C, R, Ls, Rs, Cs
-
- { MOV_CH_LAYOUT_DTS_6_0_A, AV_CH_LAYOUT_6POINT0_FRONT }, // Lc,
Rc, L, R, Ls, Rs
-
- { MOV_CH_LAYOUT_DTS_6_0_B, AV_CH_LAYOUT_5POINT0_BACK | // C,
L, R, Rls, Rrs, Ts
- AV_CH_TOP_CENTER },
- { 0, 0 },
-};
-
-static const struct MovChannelLayoutMap mov_ch_layout_map_7ch[] = {
- { MOV_CH_LAYOUT_MPEG_6_1_A, AV_CH_LAYOUT_6POINT1 }, // L,
R, C, LFE, Ls, Rs, Cs
- { MOV_CH_LAYOUT_AAC_6_1, AV_CH_LAYOUT_6POINT1 }, // C,
L, R, Ls, Rs, Cs, LFE
- { MOV_CH_LAYOUT_EAC3_6_1_A, AV_CH_LAYOUT_6POINT1 }, // L,
C, R, Ls, Rs, LFE, Cs
- { MOV_CH_LAYOUT_DTS_6_1_D, AV_CH_LAYOUT_6POINT1 }, // C,
L, R, Ls, Rs, LFE, Cs
-
- { MOV_CH_LAYOUT_AUDIOUNIT_7_0, AV_CH_LAYOUT_7POINT0 }, // L,
R, Ls, Rs, C, Rls, Rrs
- { MOV_CH_LAYOUT_AAC_7_0, AV_CH_LAYOUT_7POINT0 }, // C,
L, R, Ls, Rs, Rls, Rrs
- { MOV_CH_LAYOUT_EAC3_7_0_A, AV_CH_LAYOUT_7POINT0 }, // L,
C, R, Ls, Rs, Rls, Rrs
-
- { MOV_CH_LAYOUT_AUDIOUNIT_7_0_FRONT, AV_CH_LAYOUT_7POINT0_FRONT }, // L,
R, Ls, Rs, C, Lc, Rc
- { MOV_CH_LAYOUT_DTS_7_0, AV_CH_LAYOUT_7POINT0_FRONT }, // Lc,
C, Rc, L, R, Ls, Rs
-
- { MOV_CH_LAYOUT_EAC3_6_1_B, AV_CH_LAYOUT_5POINT1 | // L,
C, R, Ls, Rs, LFE, Ts
- AV_CH_TOP_CENTER },
-
- { MOV_CH_LAYOUT_EAC3_6_1_C, AV_CH_LAYOUT_5POINT1 | // L,
C, R, Ls, Rs, LFE, Vhc
- AV_CH_TOP_FRONT_CENTER },
-
- { MOV_CH_LAYOUT_DTS_6_1_A, AV_CH_LAYOUT_6POINT1_FRONT }, // Lc,
Rc, L, R, Ls, Rs, LFE
-
- { MOV_CH_LAYOUT_DTS_6_1_B, AV_CH_LAYOUT_5POINT1_BACK | // C,
L, R, Rls, Rrs, Ts, LFE
- AV_CH_TOP_CENTER },
-
- { MOV_CH_LAYOUT_DTS_6_1_C, AV_CH_LAYOUT_6POINT1_BACK }, // C,
Cs, L, R, Rls, Rrs, LFE
- { 0, 0 },
+enum ShortChannelName {
+ c_L = AV_CHAN_FRONT_LEFT,
+ c_R = AV_CHAN_FRONT_RIGHT,
+ c_C = AV_CHAN_FRONT_CENTER,
+ c_LFE = AV_CHAN_LOW_FREQUENCY,
+ c_Rls = AV_CHAN_BACK_LEFT,
+ c_Rrs = AV_CHAN_BACK_RIGHT,
+ c_Lc = AV_CHAN_FRONT_LEFT_OF_CENTER,
+ c_Rc = AV_CHAN_FRONT_RIGHT_OF_CENTER,
+ c_Cs = AV_CHAN_BACK_CENTER,
+ c_Ls = AV_CHAN_SIDE_LEFT,
+ c_Rs = AV_CHAN_SIDE_RIGHT,
+ c_Ts = AV_CHAN_TOP_CENTER,
+ c_Vhl = AV_CHAN_TOP_FRONT_LEFT,
+ c_Vhc = AV_CHAN_TOP_FRONT_CENTER,
+ c_Vhr = AV_CHAN_TOP_FRONT_RIGHT,
+ c_Rlt = AV_CHAN_TOP_BACK_LEFT,
+ // = AV_CHAN_TOP_BACK_CENTER,
+ c_Rrt = AV_CHAN_TOP_BACK_RIGHT,
+ c_Lt = AV_CHAN_STEREO_LEFT,
+ c_Rt = AV_CHAN_STEREO_RIGHT,
+ c_Lw = AV_CHAN_WIDE_LEFT,
+ c_Rw = AV_CHAN_WIDE_RIGHT,
+ c_Lsd = AV_CHAN_SURROUND_DIRECT_LEFT,
+ c_Rsd = AV_CHAN_SURROUND_DIRECT_RIGHT,
+ c_LFE2 = AV_CHAN_LOW_FREQUENCY_2,
+ // = AV_CHAN_TOP_SIDE_LEFT,
+ // = AV_CHAN_TOP_SIDE_RIGHT,
+ // = AV_CHAN_BOTTOM_FRONT_CENTER,
+ // = AV_CHAN_BOTTOM_FRONT_LEFT,
+ // = AV_CHAN_BOTTOM_FRONT_RIGHT,
+ c_W = AV_CHAN_AMBISONIC_BASE,
+ c_Y = AV_CHAN_AMBISONIC_BASE + 1,
+ c_Z = AV_CHAN_AMBISONIC_BASE + 2,
+ c_X = AV_CHAN_AMBISONIC_BASE + 3,
+ /* The following have no exact counterparts */
+ c_LFE1 = AV_CHAN_LOW_FREQUENCY,
+ c_Csd = AV_CHAN_NONE,
+ c_HI = AV_CHAN_NONE,
+ c_VI = AV_CHAN_NONE,
+ c_Haptic = AV_CHAN_NONE,
};
-static const struct MovChannelLayoutMap mov_ch_layout_map_8ch[] = {
- { MOV_CH_LAYOUT_OCTAGONAL, AV_CH_LAYOUT_OCTAGONAL }, // L,
R, Rls, Rrs, C, Cs, Ls, Rs
- { MOV_CH_LAYOUT_AAC_OCTAGONAL, AV_CH_LAYOUT_OCTAGONAL }, // C,
L, R, Ls, Rs, Rls, Rrs, Cs
-
- { MOV_CH_LAYOUT_CUBE, AV_CH_LAYOUT_CUBE }, // L,
R, Rls, Rrs, Vhl, Vhr, Rlt, Rrt
-
- { MOV_CH_LAYOUT_MPEG_7_1_A, AV_CH_LAYOUT_7POINT1_WIDE }, // L,
R, C, LFE, Ls, Rs, Lc, Rc
- { MOV_CH_LAYOUT_MPEG_7_1_B, AV_CH_LAYOUT_7POINT1_WIDE }, // C,
Lc, Rc, L, R, Ls, Rs, LFE
- { MOV_CH_LAYOUT_EMAGIC_DEFAULT_7_1, AV_CH_LAYOUT_7POINT1_WIDE }, // L,
R, Ls, Rs, C, LFE, Lc, Rc
- { MOV_CH_LAYOUT_EAC3_7_1_B, AV_CH_LAYOUT_7POINT1_WIDE }, // L,
C, R, Ls, Rs, LFE, Lc, Rc
- { MOV_CH_LAYOUT_DTS_7_1, AV_CH_LAYOUT_7POINT1_WIDE }, // Lc,
C, Rc, L, R, Ls, Rs, LFE
-
- { MOV_CH_LAYOUT_MPEG_7_1_C, AV_CH_LAYOUT_7POINT1 }, // L,
R, C, LFE, Ls, Rs, Rls, Rrs
- { MOV_CH_LAYOUT_EAC3_7_1_A, AV_CH_LAYOUT_7POINT1 }, // L,
C, R, Ls, Rs, LFE, Rls, Rrs
-
- { MOV_CH_LAYOUT_SMPTE_DTV, AV_CH_LAYOUT_5POINT1 | // L,
R, C, LFE, Ls, Rs, Lt, Rt
- AV_CH_LAYOUT_STEREO_DOWNMIX },
-
- { MOV_CH_LAYOUT_EAC3_7_1_C, AV_CH_LAYOUT_5POINT1 | // L,
C, R, Ls, Rs, LFE, Lsd, Rsd
- AV_CH_SURROUND_DIRECT_LEFT |
- AV_CH_SURROUND_DIRECT_RIGHT },
-
- { MOV_CH_LAYOUT_EAC3_7_1_D, AV_CH_LAYOUT_5POINT1 | // L,
C, R, Ls, Rs, LFE, Lw, Rw
- AV_CH_WIDE_LEFT |
- AV_CH_WIDE_RIGHT },
-
- { MOV_CH_LAYOUT_EAC3_7_1_E, AV_CH_LAYOUT_5POINT1 | // L,
C, R, Ls, Rs, LFE, Vhl, Vhr
- AV_CH_TOP_FRONT_LEFT |
- AV_CH_TOP_FRONT_RIGHT },
-
- { MOV_CH_LAYOUT_EAC3_7_1_F, AV_CH_LAYOUT_5POINT1 | // L,
C, R, Ls, Rs, LFE, Cs, Ts
- AV_CH_BACK_CENTER |
- AV_CH_TOP_CENTER },
-
- { MOV_CH_LAYOUT_EAC3_7_1_G, AV_CH_LAYOUT_5POINT1 | // L,
C, R, Ls, Rs, LFE, Cs, Vhc
- AV_CH_BACK_CENTER |
- AV_CH_TOP_FRONT_CENTER },
-
- { MOV_CH_LAYOUT_EAC3_7_1_H, AV_CH_LAYOUT_5POINT1 | // L,
C, R, Ls, Rs, LFE, Ts, Vhc
- AV_CH_TOP_CENTER |
- AV_CH_TOP_FRONT_CENTER },
-
- { MOV_CH_LAYOUT_DTS_8_0_A, AV_CH_LAYOUT_2_2 | // Lc,
Rc, L, R, Ls, Rs, Rls, Rrs
- AV_CH_BACK_LEFT |
- AV_CH_BACK_RIGHT |
- AV_CH_FRONT_LEFT_OF_CENTER |
- AV_CH_FRONT_RIGHT_OF_CENTER },
-
- { MOV_CH_LAYOUT_DTS_8_0_B, AV_CH_LAYOUT_5POINT0 | // Lc,
C, Rc, L, R, Ls, Cs, Rs
- AV_CH_FRONT_LEFT_OF_CENTER |
- AV_CH_FRONT_RIGHT_OF_CENTER |
- AV_CH_BACK_CENTER },
- { 0, 0 },
-};
-
-static const struct MovChannelLayoutMap mov_ch_layout_map_9ch[] = {
- { MOV_CH_LAYOUT_DTS_8_1_A, AV_CH_LAYOUT_2_2 | // Lc,
Rc, L, R, Ls, Rs, Rls, Rrs, LFE
- AV_CH_BACK_LEFT |
- AV_CH_BACK_RIGHT |
- AV_CH_FRONT_LEFT_OF_CENTER |
- AV_CH_FRONT_RIGHT_OF_CENTER |
- AV_CH_LOW_FREQUENCY },
-
- { MOV_CH_LAYOUT_DTS_8_1_B, AV_CH_LAYOUT_7POINT1_WIDE | // Lc,
C, Rc, L, R, Ls, Cs, Rs, LFE
- AV_CH_BACK_CENTER },
- { 0, 0 },
+struct MovChannelLayoutMap {
+ union {
+ uint32_t tag;
+ enum AVChannel id;
+ };
};
-static const struct MovChannelLayoutMap * const mov_ch_layout_map[] = {
- mov_ch_layout_map_misc,
- mov_ch_layout_map_1ch,
- mov_ch_layout_map_2ch,
- mov_ch_layout_map_3ch,
- mov_ch_layout_map_4ch,
- mov_ch_layout_map_5ch,
- mov_ch_layout_map_6ch,
- mov_ch_layout_map_7ch,
- mov_ch_layout_map_8ch,
- mov_ch_layout_map_9ch,
+#define TAG(_0) (struct
MovChannelLayoutMap){.tag = _0}
+#define ID(_0) (struct
MovChannelLayoutMap){.id = c_##_0}