@@ -147,12 +147,22 @@ StreamTranscoder::StreamTranscoder(const std::vector<InputStreamDesc>& inputStre
147
147
size_t nbOutputChannels =0 ;
148
148
for (size_t index =0 ; index < inputStreams.size (); ++index)
149
149
{
150
- addDecoder (_inputStreamDesc.at (index), *_inputStreams.at (index));
151
- nbOutputChannels += _inputStreamDesc.at (index)._channelIndexArray .size ();
150
+ if (_inputStreams.at (index) !=NULL )
151
+ {
152
+ LOG_INFO (" add decoder for input stream" << index);
153
+ addDecoder (_inputStreamDesc.at (index), *_inputStreams.at (index));
154
+ nbOutputChannels += _inputStreamDesc.at (index)._channelIndexArray .size ();
155
+ }
156
+ else
157
+ {
158
+ LOG_INFO (" add generator for empty input" << index);
159
+ addGenerator (_inputStreamDesc.at (index), profile);
160
+ }
152
161
}
153
162
154
- IInputStream& inputStream = *_inputStreams.at (0 );
155
- const InputStreamDesc& inputStreamDesc = inputStreamsDesc.at (0 );
163
+ const size_t firstInputStreamIndex =getFirstInputStreamIndex ();
164
+ IInputStream& inputStream = *_inputStreams.at (firstInputStreamIndex);
165
+ const InputStreamDesc& inputStreamDesc = inputStreamsDesc.at (firstInputStreamIndex);
156
166
157
167
// create a transcode case
158
168
switch (inputStream.getProperties ().getStreamType ())
@@ -229,6 +239,16 @@ StreamTranscoder::StreamTranscoder(const std::vector<InputStreamDesc>& inputStre
229
239
setOffset (offset);
230
240
}
231
241
242
+ size_t StreamTranscoder::getFirstInputStreamIndex ()
243
+ {
244
+ for (size_t index =0 ; index < _inputStreams.size (); ++index)
245
+ {
246
+ if (_inputStreams.at (index) !=NULL )
247
+ return index;
248
+ }
249
+ throw std::runtime_error (" Cannot handle only null input streams" );
250
+ }
251
+
232
252
void StreamTranscoder::addDecoder (const InputStreamDesc& inputStreamDesc, IInputStream& inputStream)
233
253
{
234
254
// create a transcode case
@@ -278,6 +298,53 @@ void StreamTranscoder::addDecoder(const InputStreamDesc& inputStreamDesc, IInput
278
298
}
279
299
}
280
300
301
+ void StreamTranscoder::addGenerator (const InputStreamDesc& inputStreamDesc,const ProfileLoader::Profile& profile)
302
+ {
303
+ // create a transcode case
304
+ if (profile.find (constants::avProfileType)->second == constants::avProfileTypeVideo)
305
+ {
306
+ VideoCodecinputVideoCodec (eCodecTypeEncoder, profile.find (constants::avProfileCodec)->second );
307
+ VideoFrameDescinputFrameDesc (profile);
308
+ inputVideoCodec.setImageParameters (inputFrameDesc);
309
+
310
+ // generator decoder
311
+ VideoGenerator* generator =new VideoGenerator (inputFrameDesc);
312
+ _generators.push_back (generator);
313
+ _currentDecoder = generator;
314
+
315
+ // buffers to process
316
+ VideoFrameDesc outputFrameDesc = inputFrameDesc;
317
+ outputFrameDesc.setParameters (profile);
318
+ _decodedData.push_back (new VideoFrame (inputFrameDesc));
319
+
320
+ // no decoder for this input
321
+ _inputDecoders.push_back (NULL );
322
+
323
+ }
324
+ else if (profile.find (constants::avProfileType)->second == constants::avProfileTypeAudio)
325
+ {
326
+ // corresponding input codec
327
+ AudioCodecinputAudioCodec (eCodecTypeEncoder, profile.find (constants::avProfileCodec)->second );
328
+ AudioFrameDescinputFrameDesc (profile);
329
+ inputFrameDesc._nbChannels =1 ;
330
+ inputAudioCodec.setAudioParameters (inputFrameDesc);
331
+
332
+ // generator decoder
333
+ AudioGenerator* generator =new AudioGenerator (inputFrameDesc);
334
+ _generators.push_back (generator);
335
+ _currentDecoder = generator;
336
+ // buffers to get the decoded data
337
+ _decodedData.push_back (new AudioFrame (inputFrameDesc));
338
+
339
+ // no decoder for this input
340
+ _inputDecoders.push_back (NULL );
341
+ }
342
+ else
343
+ {
344
+ throw std::runtime_error (" unupported stream type" );
345
+ }
346
+ }
347
+
281
348
StreamTranscoder::StreamTranscoder (IOutputFile& outputFile,const ProfileLoader::Profile& profile)
282
349
: _inputStreamDesc()
283
350
, _inputStreams()
@@ -375,7 +442,8 @@ StreamTranscoder::~StreamTranscoder()
375
442
376
443
for (std::vector<IDecoder*>::iterator it = _inputDecoders.begin (); it != _inputDecoders.end (); ++it)
377
444
{
378
- delete (*it);
445
+ if (*it !=NULL )
446
+ delete (*it);
379
447
}
380
448
for (std::vector<IDecoder*>::iterator it = _generators.begin (); it != _generators.end (); ++it)
381
449
{
@@ -548,9 +616,10 @@ bool StreamTranscoder::processTranscode()
548
616
}
549
617
550
618
// check the next data buffers in case of audio frames
551
- if (_decodedData.at (0 )->isAudioFrame ())
619
+ const size_t firstInputStreamIndex =getFirstInputStreamIndex ();
620
+ if (_decodedData.at (firstInputStreamIndex)->isAudioFrame ())
552
621
{
553
- const int nbInputSamplesPerChannel = _decodedData.at (0 )->getAVFrame ().nb_samples ;
622
+ const int nbInputSamplesPerChannel = _decodedData.at (firstInputStreamIndex )->getAVFrame ().nb_samples ;
554
623
555
624
// Reallocate output frame
556
625
if (nbInputSamplesPerChannel > _filteredData->getAVFrame ().nb_samples )
@@ -670,7 +739,11 @@ float StreamTranscoder::getDuration() const
670
739
float minStreamDuration = -1 ;
671
740
for (size_t index =0 ; index < _inputStreams.size (); ++index)
672
741
{
673
- const StreamProperties& streamProperties = _inputStreams.at (index)->getProperties ();
742
+ IInputStream* inputStream = _inputStreams.at (index);
743
+ if (inputStream ==NULL )
744
+ continue ;
745
+
746
+ const StreamProperties& streamProperties = inputStream->getProperties ();
674
747
if (minStreamDuration == -1 || streamProperties.getDuration () < minStreamDuration)
675
748
minStreamDuration = streamProperties.getDuration ();
676
749
}