Added
Link Here
|
1 |
--- src/combined/ffmpeg/ff_audio_decoder.c.orig 2022-09-08 21:43:29 UTC |
2 |
+++ src/combined/ffmpeg/ff_audio_decoder.c |
3 |
@@ -1,5 +1,5 @@ |
4 |
/* |
5 |
- * Copyright (C) 2001-2022 the xine project |
6 |
+ * Copyright (C) 2001-2023 the xine project |
7 |
* |
8 |
* This file is part of xine, a free video player. |
9 |
* |
10 |
@@ -303,7 +303,11 @@ static void ff_audio_init_codec(ff_audio_decoder_t *th |
11 |
|
12 |
this->context->bits_per_sample = this->ff_bits; |
13 |
this->context->sample_rate = this->ff_sample_rate; |
14 |
+#if XFF_AUDIO_CHANNEL_LAYOUT < 2 |
15 |
this->context->channels = this->ff_channels; |
16 |
+#else |
17 |
+ this->context->ch_layout.nb_channels = this->ff_channels; |
18 |
+#endif |
19 |
this->context->codec_id = this->codec->id; |
20 |
this->context->codec_type = this->codec->type; |
21 |
this->context->codec_tag = _x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC); |
22 |
@@ -527,17 +531,76 @@ static void ff_audio_output_close(ff_audio_decoder_t * |
23 |
this->ao_mode = 0; |
24 |
} |
25 |
|
26 |
+static unsigned int ff_list_channels (uint8_t *list, uint64_t map) { |
27 |
+ unsigned int n, bit; |
28 |
+ |
29 |
+ for (n = bit = 0; map; map >>= 1, bit++) { |
30 |
+ uint32_t b = map & 1; |
31 |
+ |
32 |
+ list[n] = bit; |
33 |
+ n += b; |
34 |
+ } |
35 |
+ return n; |
36 |
+} |
37 |
+ |
38 |
static void ff_map_channels (ff_audio_decoder_t *this) { |
39 |
uint64_t ff_map; |
40 |
+ uint8_t ff_list[64]; |
41 |
+ unsigned int ff_num; |
42 |
+ const char *type = "native"; |
43 |
int caps = this->stream->audio_out->get_capabilities (this->stream->audio_out); |
44 |
|
45 |
+#if XFF_AUDIO_CHANNEL_LAYOUT < 2 |
46 |
+ |
47 |
/* safety kludge for very old libavcodec */ |
48 |
-#ifdef AV_CH_FRONT_LEFT |
49 |
+# ifdef AV_CH_FRONT_LEFT |
50 |
ff_map = this->context->channel_layout; |
51 |
if (!ff_map) /* wma2 bug */ |
52 |
-#endif |
53 |
+# endif |
54 |
ff_map = ((uint64_t)1 << this->context->channels) - 1; |
55 |
+ ff_num = ff_list_channels (ff_list, ff_map); |
56 |
|
57 |
+#else /* XFF_AUDIO_CHANNEL_LAYOUT == 2 */ |
58 |
+ |
59 |
+ ff_num = this->context->ch_layout.nb_channels; |
60 |
+ if (ff_num > (int)(sizeof (ff_list) / sizeof (ff_list[0]))) |
61 |
+ ff_num = sizeof (ff_list) / sizeof (ff_list[0]); |
62 |
+ switch (this->context->ch_layout.order) { |
63 |
+ const AVChannelCustom *cmap; |
64 |
+ unsigned int i; |
65 |
+ |
66 |
+ case AV_CHANNEL_ORDER_UNSPEC: |
67 |
+ type = "unknown"; |
68 |
+ goto _fallback; |
69 |
+ |
70 |
+ case AV_CHANNEL_ORDER_NATIVE: |
71 |
+ ff_map = this->context->ch_layout.u.mask; |
72 |
+ if (!ff_map) /* wma2 bug */ |
73 |
+ ff_map = ((uint64_t)1 << ff_num) - 1; |
74 |
+ ff_num = ff_list_channels (ff_list, ff_map); |
75 |
+ break; |
76 |
+ |
77 |
+ case AV_CHANNEL_ORDER_CUSTOM: |
78 |
+ type = "custom"; |
79 |
+ if (!(cmap = this->context->ch_layout.u.map)) |
80 |
+ goto _fallback; |
81 |
+ ff_map = 0; |
82 |
+ for (i = 0; i < ff_num; i++) { |
83 |
+ ff_list[i] = cmap[i].id; |
84 |
+ ff_map |= (uint64_t)1 << ff_list[i]; |
85 |
+ } |
86 |
+ break; |
87 |
+ |
88 |
+ default: |
89 |
+ type = "unsupported"; |
90 |
+ /* fall through */ |
91 |
+ _fallback: |
92 |
+ ff_map = ((uint64_t)1 << ff_num) - 1; |
93 |
+ ff_num = ff_list_channels (ff_list, ff_map); |
94 |
+ } |
95 |
+ |
96 |
+#endif |
97 |
+ |
98 |
if ((caps != this->ao_caps) || (ff_map != this->ff_map)) { |
99 |
unsigned int i, j; |
100 |
/* ff: see names[] below; xine: L R RL RR C LFE */ |
101 |
@@ -562,7 +625,7 @@ static void ff_map_channels (ff_audio_decoder_t *this) |
102 |
|
103 |
this->ao_caps = caps; |
104 |
this->ff_map = ff_map; |
105 |
- this->ff_channels = this->context->channels; |
106 |
+ this->ff_channels = ff_num; |
107 |
|
108 |
/* silence out */ |
109 |
for (i = 0; i < MAX_CHANNELS; i++) |
110 |
@@ -576,20 +639,23 @@ static void ff_map_channels (ff_audio_decoder_t *this) |
111 |
this->left[0] = this->right[0] = 0; |
112 |
tries = wishlist + 0 * num_modes; |
113 |
} else if (this->ff_channels == 2) { /* stereo */ |
114 |
+ /* FIXME: libxine does not yet support audio selection _after_ decoding. |
115 |
+ * For now, treat the most common "dual mono" case as stereo. */ |
116 |
name_map[0] = 0; |
117 |
name_map[1] = 1; |
118 |
this->left[0] = 0; |
119 |
this->right[0] = 1; |
120 |
tries = wishlist + 1 * num_modes; |
121 |
} else { |
122 |
- for (i = j = 0; i < sizeof (base_map) / sizeof (base_map[0]); i++) { |
123 |
- if ((ff_map >> i) & 1) { |
124 |
- int8_t target = base_map[i]; |
125 |
- if ((target >= 0) && (this->map[target] < 0)) |
126 |
- this->map[target] = j; |
127 |
- name_map[j] = i; /* for debug output below */ |
128 |
- j++; |
129 |
- } |
130 |
+ for (i = 0; i < ff_num; i++) { |
131 |
+ int8_t target; |
132 |
+ uint32_t num = ff_list[i]; |
133 |
+ if (num >= sizeof (base_map) / sizeof (base_map[0])) |
134 |
+ continue; |
135 |
+ target = base_map[num]; |
136 |
+ if ((target >= 0) && (this->map[target] < 0)) |
137 |
+ this->map[target] = i; |
138 |
+ name_map[i] = num; /* for debug output below */ |
139 |
} |
140 |
this->left[0] = this->map[0] < 0 ? 0 : this->map[0]; |
141 |
this->map[0] = -1; |
142 |
@@ -641,8 +707,8 @@ static void ff_map_channels (ff_audio_decoder_t *this) |
143 |
"rear center", |
144 |
"side left", "side right" |
145 |
}; |
146 |
- int8_t buf[200]; |
147 |
- int p = sprintf (buf, "ff_audio_dec: channel layout: "); |
148 |
+ int8_t buf[256]; |
149 |
+ int p = sprintf (buf, "ff_audio_dec: %s channel layout: ", type); |
150 |
int8_t *indx = this->left; |
151 |
for (i = 0; i < 2; i++) { |
152 |
buf[p++] = '['; |