Skip to content

Commit b81e198

Browse files
author
Clement Champetier
committed
transcoder: added methods to transcode several inputs to one output stream
1 parent 6a62a21 commit b81e198

File tree

4 files changed

+50
-35
lines changed

4 files changed

+50
-35
lines changed

src/AvTranscoder/transcoder/StreamTranscoder.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu
126126
setOffset(offset);
127127
}
128128

129-
StreamTranscoder::StreamTranscoder(const InputStreamDesc& inputStreamDesc, IInputStream& inputStream, IOutputFile& outputFile,
129+
StreamTranscoder::StreamTranscoder(const std::vector<InputStreamDesc>& inputStreamsDesc, std::vector<IInputStream*>& inputStreams, IOutputFile& outputFile,
130130
const ProfileLoader::Profile& profile, const float offset)
131-
: _inputStreamDesc()
132-
, _inputStreams()
131+
: _inputStreamDesc(inputStreamsDesc)
132+
, _inputStreams(inputStreams)
133133
, _outputStream(NULL)
134134
, _decodedData()
135135
, _filteredData(NULL)
@@ -143,10 +143,16 @@ StreamTranscoder::StreamTranscoder(const InputStreamDesc& inputStreamDesc, IInpu
143143
, _offset(offset)
144144
, _needToSwitchToGenerator(false)
145145
{
146-
_inputStreamDesc.push_back(inputStreamDesc);
147-
_inputStreams.push_back(&inputStream);
146+
// add as many decoders as input streams
147+
size_t nbOutputChannels = 0;
148+
for(size_t index = 0; index < inputStreams.size(); ++index)
149+
{
150+
addDecoder(_inputStreamDesc.at(index), *_inputStreams.at(index));
151+
nbOutputChannels += _inputStreamDesc.at(index)._channelIndexArray.size();
152+
}
148153

149-
addDecoder(inputStreamDesc, inputStream);
154+
IInputStream& inputStream = *_inputStreams.at(0);
155+
const InputStreamDesc& inputStreamDesc = inputStreamsDesc.at(0);
150156

151157
// create a transcode case
152158
switch(inputStream.getProperties().getStreamType())
@@ -168,7 +174,7 @@ StreamTranscoder::StreamTranscoder(const InputStreamDesc& inputStreamDesc, IInpu
168174
_outputStream = &outputFile.addVideoStream(outputVideo->getVideoCodec());
169175

170176
// buffers to process
171-
_filteredData = new VideoFrame(inputStream.getVideoCodec().getVideoFrameDesc());
177+
_filteredData = new VideoFrame(outputVideo->getVideoCodec().getVideoFrameDesc());
172178
_transformedData = new VideoFrame(outputVideo->getVideoCodec().getVideoFrameDesc());
173179

174180
// transform
@@ -180,6 +186,9 @@ StreamTranscoder::StreamTranscoder(const InputStreamDesc& inputStreamDesc, IInpu
180186
{
181187
// filter
182188
_filterGraph = new FilterGraph(inputStream.getAudioCodec());
189+
// merge two or more audio streams into a single multi-channel stream.
190+
if(inputStreams.size() > 1)
191+
_filterGraph->addFilter("amerge");
183192

184193
// output encoder
185194
AudioEncoder* outputAudio = new AudioEncoder(profile.at(constants::avProfileCodec));
@@ -188,7 +197,7 @@ StreamTranscoder::StreamTranscoder(const InputStreamDesc& inputStreamDesc, IInpu
188197
AudioFrameDesc outputFrameDesc(inputStream.getAudioCodec().getAudioFrameDesc());
189198
outputFrameDesc.setParameters(profile);
190199
if(inputStreamDesc.demultiplexing())
191-
outputFrameDesc._nbChannels = inputStreamDesc._channelIndexArray.size();
200+
outputFrameDesc._nbChannels = nbOutputChannels;
192201
outputAudio->setupAudioEncoder(outputFrameDesc, profile);
193202

194203
// output stream
@@ -197,7 +206,7 @@ StreamTranscoder::StreamTranscoder(const InputStreamDesc& inputStreamDesc, IInpu
197206
// buffers to process
198207
AudioFrameDesc inputFrameDesc(inputStream.getAudioCodec().getAudioFrameDesc());
199208
if(inputStreamDesc.demultiplexing())
200-
inputFrameDesc._nbChannels = inputStreamDesc._channelIndexArray.size();
209+
inputFrameDesc._nbChannels = nbOutputChannels;
201210

202211
_filteredData = new AudioFrame(inputFrameDesc);
203212
_transformedData = new AudioFrame(outputAudio->getAudioCodec().getAudioFrameDesc());

src/AvTranscoder/transcoder/StreamTranscoder.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ class AvExport StreamTranscoder
3333
StreamTranscoder(IInputStream& inputStream, IOutputFile& outputFile, const float offset = 0);
3434

3535
/**
36-
* @brief Transcode the given stream.
36+
* @brief Transcode the given streams.
37+
* @note The data are wrapped to one output stream.
3738
**/
38-
StreamTranscoder(const InputStreamDesc& inputStreamDesc, IInputStream& inputStream, IOutputFile& outputFile,
39+
StreamTranscoder(const std::vector<InputStreamDesc>& inputStreamsDesc, std::vector<IInputStream*>& inputStreams, IOutputFile& outputFile,
3940
const ProfileLoader::Profile& profile, const float offset = 0);
4041

4142
/**

src/AvTranscoder/transcoder/Transcoder.cpp

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,14 @@ void Transcoder::addStream(const InputStreamDesc& inputStreamDesc, const Profile
6767
if(!inputStreamDesc._filename.length())
6868
throw std::runtime_error("Can't transcode a stream without a filename indicated.");
6969

70-
addTranscodeStream(inputStreamDesc, profile, offset);
70+
std::vector<InputStreamDesc> inputStreamDescArray;
71+
inputStreamDescArray.push_back(inputStreamDesc);
72+
addStream(inputStreamDescArray, profile, offset);
73+
}
74+
75+
void Transcoder::addStream(const std::vector<InputStreamDesc>& inputStreamDescArray, const ProfileLoader::Profile& profile, const float offset)
76+
{
77+
addTranscodeStream(inputStreamDescArray, profile, offset);
7178
}
7279

7380
void Transcoder::addGeneratedStream(const std::string& encodingProfileName)
@@ -206,39 +213,31 @@ void Transcoder::addRewrapStream(const InputStreamDesc& inputStreamDesc, const f
206213
_streamTranscoders.push_back(_streamTranscodersAllocated.back());
207214
}
208215

209-
void Transcoder::addTranscodeStream(const InputStreamDesc& inputStreamDesc, const ProfileLoader::Profile& profile,
216+
void Transcoder::addTranscodeStream(const std::vector<InputStreamDesc>& inputStreamDescArray, const ProfileLoader::Profile& profile,
210217
const float offset)
211218
{
212219
// Add profile
213220
if(!_profileLoader.hasProfile(profile))
214221
_profileLoader.loadProfile(profile);
215222

216-
LOG_INFO("Add transcode stream from " << inputStreamDesc << "with encodingProfile="
217-
<< profile.at(constants::avProfileIdentificatorHuman) << std::endl
223+
std::stringstream sources;
224+
for(size_t index = 0; index < inputStreamDescArray.size(); ++index)
225+
sources << inputStreamDescArray.at(index);
226+
LOG_INFO("Add transcode stream from the following inputs:" << std::endl << sources.str()
227+
<< "with encodingProfile=" << profile.at(constants::avProfileIdentificatorHuman) << std::endl
218228
<< "and offset=" << offset << "s")
219229

220230
// Add input file
221-
InputFile* referenceFile = addInputFile(inputStreamDesc._filename, inputStreamDesc._streamIndex, offset);
222-
IInputStream& inputStream = referenceFile->getStream(inputStreamDesc._streamIndex);
223-
224-
switch(inputStream.getProperties().getStreamType())
231+
std::vector<IInputStream*> inputStreams;
232+
for(std::vector<InputStreamDesc>::const_iterator it = inputStreamDescArray.begin(); it != inputStreamDescArray.end(); ++it)
225233
{
226-
case AVMEDIA_TYPE_VIDEO:
227-
case AVMEDIA_TYPE_AUDIO:
228-
{
229-
_streamTranscodersAllocated.push_back(
230-
new StreamTranscoder(inputStreamDesc, inputStream, _outputFile, profile, offset));
231-
_streamTranscoders.push_back(_streamTranscodersAllocated.back());
232-
break;
233-
}
234-
case AVMEDIA_TYPE_DATA:
235-
case AVMEDIA_TYPE_SUBTITLE:
236-
case AVMEDIA_TYPE_ATTACHMENT:
237-
default:
238-
{
239-
throw std::runtime_error("unsupported media type in transcode setup");
240-
}
234+
InputFile* referenceFile = addInputFile(it->_filename, it->_streamIndex, offset);
235+
inputStreams.push_back(&referenceFile->getStream(it->_streamIndex));
241236
}
237+
238+
_streamTranscodersAllocated.push_back(
239+
new StreamTranscoder(inputStreamDescArray, inputStreams, _outputFile, profile, offset));
240+
_streamTranscoders.push_back(_streamTranscodersAllocated.back());
242241
}
243242

244243
InputFile* Transcoder::addInputFile(const std::string& filename, const int streamIndex, const float offset)

src/AvTranscoder/transcoder/Transcoder.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ class AvExport Transcoder
6565
void addStream(const InputStreamDesc& inputStreamDesc, const ProfileLoader::Profile& profile, const float offset = 0);
6666
//@}
6767

68+
//@{
69+
// @brief Add a new stream to the output file, created from the given input description to process.
70+
// @param inputStreamDescArray: the type of the described streams should be of the same type.
71+
void addStream(const std::vector<InputStreamDesc>& inputStreamDescArray, const ProfileLoader::Profile& profile, const float offset = 0);
72+
//@}
73+
6874
//@{
6975
// @brief Add a new generated stream to the output file, created from the given encoding profile.
7076
void addGeneratedStream(const std::string& encodingProfileName);
@@ -129,7 +135,7 @@ class AvExport Transcoder
129135

130136
private:
131137
void addRewrapStream(const InputStreamDesc& inputStreamDesc, const float offset);
132-
void addTranscodeStream(const InputStreamDesc& inputStreamDesc, const ProfileLoader::Profile& profile,
138+
void addTranscodeStream(const std::vector<InputStreamDesc>& inputStreamDescArray, const ProfileLoader::Profile& profile,
133139
const float offset = 0);
134140

135141
/**

0 commit comments

Comments
 (0)