@@ -33,6 +33,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu
33
33
, _outputEncoder(NULL )
34
34
, _transform(NULL )
35
35
, _filterGraph(NULL )
36
+ , _firstInputStreamIndex(0 )
36
37
, _offset(offset)
37
38
, _needToSwitchToGenerator(false )
38
39
{
@@ -140,19 +141,35 @@ StreamTranscoder::StreamTranscoder(const std::vector<InputStreamDesc>& inputStre
140
141
, _outputEncoder(NULL )
141
142
, _transform(NULL )
142
143
, _filterGraph(NULL )
144
+ , _firstInputStreamIndex(std::numeric_limits<size_t >::max())
143
145
, _offset(offset)
144
146
, _needToSwitchToGenerator(false )
145
147
{
146
148
// add as many decoders as input streams
147
149
size_t nbOutputChannels = 0 ;
148
150
for (size_t index = 0 ; index < inputStreams.size (); ++index)
149
151
{
150
- addDecoder (_inputStreamDesc.at (index), *_inputStreams.at (index));
151
- nbOutputChannels += _inputStreamDesc.at (index)._channelIndexArray .size ();
152
+ if (_inputStreams.at (index) != NULL )
153
+ {
154
+ LOG_INFO (" add decoder for input stream " << index);
155
+ addDecoder (_inputStreamDesc.at (index), *_inputStreams.at (index));
156
+ nbOutputChannels += _inputStreamDesc.at (index)._channelIndexArray .size ();
157
+ if (_firstInputStreamIndex == std::numeric_limits<size_t >::max ())
158
+ _firstInputStreamIndex = index;
159
+ }
160
+ else
161
+ {
162
+ LOG_INFO (" add generator for empty input " << index);
163
+ addGenerator (_inputStreamDesc.at (index), profile);
164
+ nbOutputChannels++;
165
+ }
152
166
}
153
167
154
- IInputStream& inputStream = *_inputStreams.at (0 );
155
- const InputStreamDesc& inputStreamDesc = inputStreamsDesc.at (0 );
168
+ if (_firstInputStreamIndex == std::numeric_limits<size_t >::max ())
169
+ throw std::runtime_error (" Cannot handle empty only input streams" );
170
+
171
+ IInputStream& inputStream = *_inputStreams.at (_firstInputStreamIndex);
172
+ const InputStreamDesc& inputStreamDesc = inputStreamsDesc.at (_firstInputStreamIndex);
156
173
157
174
// create a transcode case
158
175
switch (inputStream.getProperties ().getStreamType ())
@@ -278,6 +295,53 @@ void StreamTranscoder::addDecoder(const InputStreamDesc& inputStreamDesc, IInput
278
295
}
279
296
}
280
297
298
+ void StreamTranscoder::addGenerator (const InputStreamDesc& inputStreamDesc, const ProfileLoader::Profile& profile)
299
+ {
300
+ // create a transcode case
301
+ if (profile.find (constants::avProfileType)->second == constants::avProfileTypeVideo)
302
+ {
303
+ VideoCodec inputVideoCodec (eCodecTypeEncoder, profile.find (constants::avProfileCodec)->second );
304
+ VideoFrameDesc inputFrameDesc (profile);
305
+ inputVideoCodec.setImageParameters (inputFrameDesc);
306
+
307
+ // generator decoder
308
+ VideoGenerator* generator = new VideoGenerator (inputFrameDesc);
309
+ _generators.push_back (generator);
310
+ _currentDecoder = generator;
311
+
312
+ // buffers to process
313
+ VideoFrameDesc outputFrameDesc = inputFrameDesc;
314
+ outputFrameDesc.setParameters (profile);
315
+ _decodedData.push_back (new VideoFrame (inputFrameDesc));
316
+
317
+ // no decoder for this input
318
+ _inputDecoders.push_back (NULL );
319
+
320
+ }
321
+ else if (profile.find (constants::avProfileType)->second == constants::avProfileTypeAudio)
322
+ {
323
+ // corresponding input codec
324
+ AudioCodec inputAudioCodec (eCodecTypeEncoder, profile.find (constants::avProfileCodec)->second );
325
+ AudioFrameDesc inputFrameDesc (profile);
326
+ inputFrameDesc._nbChannels = 1 ;
327
+ inputAudioCodec.setAudioParameters (inputFrameDesc);
328
+
329
+ // generator decoder
330
+ AudioGenerator* generator = new AudioGenerator (inputFrameDesc);
331
+ _generators.push_back (generator);
332
+ _currentDecoder = generator;
333
+ // buffers to get the decoded data
334
+ _decodedData.push_back (new AudioFrame (inputFrameDesc));
335
+
336
+ // no decoder for this input
337
+ _inputDecoders.push_back (NULL );
338
+ }
339
+ else
340
+ {
341
+ throw std::runtime_error (" unupported stream type" );
342
+ }
343
+ }
344
+
281
345
StreamTranscoder::StreamTranscoder (IOutputFile& outputFile, const ProfileLoader::Profile& profile)
282
346
: _inputStreamDesc()
283
347
, _inputStreams()
@@ -291,6 +355,7 @@ StreamTranscoder::StreamTranscoder(IOutputFile& outputFile, const ProfileLoader:
291
355
, _outputEncoder(NULL )
292
356
, _transform(NULL )
293
357
, _filterGraph(NULL )
358
+ , _firstInputStreamIndex(0 )
294
359
, _offset(0 )
295
360
, _needToSwitchToGenerator(false )
296
361
{
@@ -375,7 +440,8 @@ StreamTranscoder::~StreamTranscoder()
375
440
376
441
for (std::vector<IDecoder*>::iterator it = _inputDecoders.begin (); it != _inputDecoders.end (); ++it)
377
442
{
378
- delete (*it);
443
+ if (*it != NULL )
444
+ delete (*it);
379
445
}
380
446
for (std::vector<IDecoder*>::iterator it = _generators.begin (); it != _generators.end (); ++it)
381
447
{
@@ -536,7 +602,8 @@ bool StreamTranscoder::processTranscode()
536
602
std::vector<bool > decodingStatus (_generators.size (), true );
537
603
for (size_t index = 0 ; index < _generators.size (); ++index)
538
604
{
539
- if (getProcessCase () == eProcessCaseTranscode)
605
+ EProcessCase processCase = getProcessCase (index);
606
+ if (processCase == eProcessCaseTranscode)
540
607
_currentDecoder = _inputDecoders.at (index);
541
608
else
542
609
_currentDecoder = _generators.at (index);
@@ -548,9 +615,9 @@ bool StreamTranscoder::processTranscode()
548
615
}
549
616
550
617
// check the next data buffers in case of audio frames
551
- if (_decodedData.at (0 )->isAudioFrame ())
618
+ if (_decodedData.at (_firstInputStreamIndex )->isAudioFrame ())
552
619
{
553
- const int nbInputSamplesPerChannel = _decodedData.at (0 )->getAVFrame ().nb_samples ;
620
+ const int nbInputSamplesPerChannel = _decodedData.at (_firstInputStreamIndex )->getAVFrame ().nb_samples ;
554
621
555
622
// Reallocate output frame
556
623
if (nbInputSamplesPerChannel > _filteredData->getAVFrame ().nb_samples )
@@ -670,7 +737,11 @@ float StreamTranscoder::getDuration() const
670
737
float minStreamDuration = -1 ;
671
738
for (size_t index = 0 ; index < _inputStreams.size (); ++index)
672
739
{
673
- const StreamProperties& streamProperties = _inputStreams.at (index)->getProperties ();
740
+ IInputStream* inputStream = _inputStreams.at (index);
741
+ if (inputStream == NULL )
742
+ continue ;
743
+
744
+ const StreamProperties& streamProperties = inputStream->getProperties ();
674
745
if (minStreamDuration == -1 || streamProperties.getDuration () < minStreamDuration)
675
746
minStreamDuration = streamProperties.getDuration ();
676
747
}
@@ -722,13 +793,30 @@ void StreamTranscoder::setOffset(const float offset)
722
793
}
723
794
}
724
795
725
- StreamTranscoder::EProcessCase StreamTranscoder::getProcessCase () const
796
+ StreamTranscoder::EProcessCase StreamTranscoder::getProcessCase (const size_t decoderIndex ) const
726
797
{
727
- if (! _inputStreams.empty () && ! _inputDecoders.empty () && std::find (_inputDecoders.begin (), _inputDecoders.end (), _currentDecoder) != _inputDecoders.end () )
728
- return eProcessCaseTranscode;
729
- else if (! _inputStreams.empty () && _inputDecoders.empty () && !_currentDecoder)
730
- return eProcessCaseRewrap;
798
+ if (_inputStreamDesc.size () <= 1 )
799
+ {
800
+ if (! _inputStreams.empty () && ! _inputDecoders.empty () && std::find (_inputDecoders.begin (), _inputDecoders.end (), _currentDecoder) != _inputDecoders.end () )
801
+ return eProcessCaseTranscode;
802
+ else if (! _inputStreams.empty () && _inputDecoders.empty () && !_currentDecoder)
803
+ return eProcessCaseRewrap;
804
+ else
805
+ return eProcessCaseGenerator;
806
+ }
731
807
else
808
+ {
809
+ if (! _inputStreams.empty () && _currentDecoder != NULL )
810
+ {
811
+ if ( _inputStreams.at (decoderIndex) != NULL )
812
+ return eProcessCaseTranscode;
813
+ return eProcessCaseGenerator;
814
+ }
815
+ else if (! _inputStreams.empty () && _inputDecoders.empty () && !_currentDecoder)
816
+ {
817
+ return eProcessCaseRewrap;
818
+ }
732
819
return eProcessCaseGenerator;
820
+ }
733
821
}
734
822
}
0 commit comments