@@ -116,7 +116,7 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer)
116
116
return decodeNextFrame;
117
117
}
118
118
119
- bool AudioDecoder::decodeNextFrame (Frame& frameBuffer, const size_t channelIndex )
119
+ bool AudioDecoder::decodeNextFrame (Frame& frameBuffer, const std::vector< size_t > channelsIndex )
120
120
{
121
121
AudioFrame& audioBuffer = static_cast <AudioFrame&>(frameBuffer);
122
122
@@ -136,37 +136,52 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex
136
136
if (decodedSize == 0 )
137
137
return false ;
138
138
139
- // check if the expected channel exists
140
- if ( channelIndex > srcNbChannels - 1 )
139
+ // check if each expected channel exists
140
+ for (std::vector< size_t >::const_iterator channelIndex = channelsIndex. begin (); channelIndex != channelsIndex. end (); ++channelIndex )
141
141
{
142
- std::stringstream msg;
143
- msg << " The channel at index " ;
144
- msg << channelIndex;
145
- msg << " doesn't exist (srcNbChannels = " ;
146
- msg << srcNbChannels;
147
- msg << " )." ;
148
- throw std::runtime_error (msg.str ());
142
+ if ((*channelIndex) > srcNbChannels - 1 )
143
+ {
144
+ std::stringstream msg;
145
+ msg << " The channel at index " ;
146
+ msg << (*channelIndex);
147
+ msg << " doesn't exist (srcNbChannels = " ;
148
+ msg << srcNbChannels;
149
+ msg << " )." ;
150
+ throw std::runtime_error (msg.str ());
151
+ }
149
152
}
150
153
151
154
// copy frame properties of decoded frame
152
155
audioBuffer.copyProperties (allDataOfNextFrame);
153
- av_frame_set_channels (&audioBuffer.getAVFrame (), 1 );
154
- av_frame_set_channel_layout (&audioBuffer.getAVFrame (), AV_CH_LAYOUT_MONO );
156
+ av_frame_set_channels (&audioBuffer.getAVFrame (), channelsIndex. size () );
157
+ av_frame_set_channel_layout (&audioBuffer.getAVFrame (), av_get_default_channel_layout (channelsIndex. size ()) );
155
158
audioBuffer.setNbSamplesPerChannel (allDataOfNextFrame.getNbSamplesPerChannel ());
156
159
157
160
// @todo manage cases with data of frame not only on data[0] (use _frame.linesize)
158
161
unsigned char * src = allDataOfNextFrame.getData ()[0 ];
159
162
unsigned char * dst = audioBuffer.getData ()[0 ];
160
163
161
- // offset
162
- src += channelIndex * bytePerSample;
163
-
164
- // extract one channel
165
- for (int sample = 0 ; sample < allDataOfNextFrame.getAVFrame ().nb_samples ; ++sample)
164
+ // extract one or more channels
165
+ for (size_t sample = 0 ; sample < allDataOfNextFrame.getNbSamplesPerChannel (); ++sample)
166
166
{
167
- memcpy (dst, src, bytePerSample);
168
- dst += bytePerSample;
169
- src += bytePerSample * srcNbChannels;
167
+ // offset in source buffer
168
+ src += channelsIndex.at (0 ) * bytePerSample;
169
+
170
+ for (size_t i = 0 ; i < channelsIndex.size (); ++i)
171
+ {
172
+ memcpy (dst, src, bytePerSample);
173
+ dst += bytePerSample;
174
+
175
+ // shift to the corresponding sample in the next channel of the current layout
176
+ if (i < channelsIndex.size () - 1 )
177
+ src += (channelsIndex.at (i+1 ) - channelsIndex.at (i)) * bytePerSample;
178
+ // else shift to the next layout
179
+ else
180
+ {
181
+ src += (srcNbChannels - channelsIndex.at (i)) * bytePerSample;
182
+ break ;
183
+ }
184
+ }
170
185
}
171
186
172
187
return true ;
0 commit comments