Skip to content

Commit ee5f730

Browse files
author
Clement Champetier
committed
Transcoder: can extract several channels in the same streams
* Handle a vector of channel index instead of a single index (with -1 to get all of them).
1 parent b371beb commit ee5f730

15 files changed

+124
-66
lines changed

app/avProcessor/avProcessor.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,22 @@ void parseConfigFile(const std::string& configFilename, avtranscoder::Transcoder
2929
std::stringstream ss(streamId);
3030
size_t streamIndex = 0;
3131
char separator;
32-
int subStreamIndex = -1;
32+
std::vector<size_t> channelIndexArray;
3333
ss >> streamIndex;
3434
ss >> separator;
3535
if(separator == '.')
36+
{
37+
int subStreamIndex = -1;
3638
ss >> subStreamIndex;
39+
channelIndexArray.push_back(subStreamIndex);
40+
}
3741

3842
// generated stream
3943
if(!filename.length())
4044
transcoder.addGeneratedStream(transcodeProfile);
4145
else
4246
{
43-
avtranscoder::InputStreamDesc inputDesc(filename, streamIndex, subStreamIndex);
47+
avtranscoder::InputStreamDesc inputDesc(filename, streamIndex, channelIndexArray);
4448
transcoder.addStream(inputDesc, transcodeProfile);
4549
}
4650
}

src/AvTranscoder/decoder/AudioDecoder.cpp

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer)
116116
return decodeNextFrame;
117117
}
118118

119-
bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex)
119+
bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const std::vector<size_t> channelsIndex)
120120
{
121121
AudioFrame& audioBuffer = static_cast<AudioFrame&>(frameBuffer);
122122

@@ -136,37 +136,52 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex
136136
if(decodedSize == 0)
137137
return false;
138138

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)
141141
{
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+
}
149152
}
150153

151154
// copy frame properties of decoded frame
152155
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()));
155158
audioBuffer.setNbSamplesPerChannel(allDataOfNextFrame.getNbSamplesPerChannel());
156159

157160
// @todo manage cases with data of frame not only on data[0] (use _frame.linesize)
158161
unsigned char* src = allDataOfNextFrame.getData()[0];
159162
unsigned char* dst = audioBuffer.getData()[0];
160163

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)
166166
{
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+
}
170185
}
171186

172187
return true;

src/AvTranscoder/decoder/AudioDecoder.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class AvExport AudioDecoder : public IDecoder
1717
void setupDecoder(const ProfileLoader::Profile& profile = ProfileLoader::Profile());
1818

1919
bool decodeNextFrame(Frame& frameBuffer);
20-
bool decodeNextFrame(Frame& frameBuffer, const size_t channelIndex);
20+
bool decodeNextFrame(Frame& frameBuffer, const std::vector<size_t> channelsIndex);
2121

2222
void flushDecoder();
2323

src/AvTranscoder/decoder/AudioGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ bool AudioGenerator::decodeNextFrame(Frame& frameBuffer)
7171
return true;
7272
}
7373

74-
bool AudioGenerator::decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex)
74+
bool AudioGenerator::decodeNextFrame(Frame& frameBuffer, const std::vector<size_t> channelsIndex)
7575
{
7676
return decodeNextFrame(frameBuffer);
7777
}

src/AvTranscoder/decoder/AudioGenerator.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class AvExport AudioGenerator : public IDecoder
1919
~AudioGenerator();
2020

2121
bool decodeNextFrame(Frame& frameBuffer);
22-
bool decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex);
22+
bool decodeNextFrame(Frame& frameBuffer, const std::vector<size_t> channelsIndex);
2323

2424
void setNextFrame(Frame& inputFrame) { _inputFrame = &inputFrame; }
2525

src/AvTranscoder/decoder/IDecoder.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ class AvExport IDecoder
3333
/**
3434
* @brief Decode substream of next frame
3535
* @param frameBuffer: the frame decoded
36-
* @param channelIndex: index of channel to extract
36+
* @param channelIndex: list of channels to extract
3737
* @return status of decoding
3838
*/
39-
virtual bool decodeNextFrame(Frame& frameBuffer, const size_t channelIndex) = 0;
39+
virtual bool decodeNextFrame(Frame& frameBuffer, const std::vector<size_t> channelsIndex) = 0;
4040

4141
/**
4242
* @brief Set the next frame of the input stream (which bypass the work of decoding)

src/AvTranscoder/decoder/VideoDecoder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ bool VideoDecoder::decodeNextFrame(Frame& frameBuffer)
114114
return decodeNextFrame;
115115
}
116116

117-
bool VideoDecoder::decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex)
117+
bool VideoDecoder::decodeNextFrame(Frame& frameBuffer, const std::vector<size_t> channelsIndex)
118118
{
119119
return false;
120120
}

src/AvTranscoder/decoder/VideoDecoder.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class AvExport VideoDecoder : public IDecoder
1717
void setupDecoder(const ProfileLoader::Profile& profile = ProfileLoader::Profile());
1818

1919
bool decodeNextFrame(Frame& frameBuffer);
20-
bool decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex);
20+
bool decodeNextFrame(Frame& frameBuffer, const std::vector<size_t> channelsIndex);
2121

2222
void flushDecoder();
2323

src/AvTranscoder/decoder/VideoGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ bool VideoGenerator::decodeNextFrame(Frame& frameBuffer)
7272
return true;
7373
}
7474

75-
bool VideoGenerator::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex)
75+
bool VideoGenerator::decodeNextFrame(Frame& frameBuffer, const std::vector<size_t> channelsIndex)
7676
{
7777
return false;
7878
}

src/AvTranscoder/decoder/VideoGenerator.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class AvExport VideoGenerator : public IDecoder
1919
~VideoGenerator();
2020

2121
bool decodeNextFrame(Frame& frameBuffer);
22-
bool decodeNextFrame(Frame& frameBuffer, const size_t channelIndex);
22+
bool decodeNextFrame(Frame& frameBuffer, const std::vector<size_t> channelsIndex);
2323

2424
void setNextFrame(Frame& inputFrame) { _inputFrame = &inputFrame; }
2525

0 commit comments

Comments
 (0)