@@ -36,60 +36,75 @@ StreamTranscoder::StreamTranscoder(
36
36
, _transform( NULL )
37
37
, _subStreamIndex( -1 )
38
38
, _offset( offset )
39
- , _canSwitchToGenerator ( false )
39
+ , _needToSwitchToGenerator ( false )
40
40
{
41
41
// create a re-wrapping case
42
42
switch ( _inputStream->getStreamType () )
43
43
{
44
44
case AVMEDIA_TYPE_VIDEO :
45
45
{
46
- VideoFrameDesc inputFrameDesc ( _inputStream->getVideoCodec ().getVideoFrameDesc () );
46
+ // output stream
47
+ _outputStream = &outputFile.addVideoStream ( _inputStream->getVideoCodec () );
47
48
48
- // generator decoder
49
- VideoGenerator* generatorVideo = new VideoGenerator ();
50
- generatorVideo->setVideoFrameDesc ( inputFrameDesc );
51
- _generator = generatorVideo;
49
+ try
50
+ {
51
+ VideoFrameDesc inputFrameDesc ( _inputStream->getVideoCodec ().getVideoFrameDesc () );
52
52
53
- // buffers to process
54
- _sourceBuffer = new VideoFrame ( inputFrameDesc );
55
- _frameBuffer = new VideoFrame ( inputFrameDesc );
53
+ // generator decoder
54
+ VideoGenerator* generatorVideo = new VideoGenerator ();
55
+ generatorVideo->setVideoFrameDesc ( inputFrameDesc );
56
+ _generator = generatorVideo;
56
57
57
- // transform
58
- _transform = new VideoTransform ();
58
+ // buffers to process
59
+ _sourceBuffer = new VideoFrame ( inputFrameDesc );
60
+ _frameBuffer = new VideoFrame ( inputFrameDesc );
59
61
60
- // output encoder
61
- VideoEncoder* outputVideo = new VideoEncoder ( _inputStream->getVideoCodec ().getCodecName () );
62
- outputVideo->setupVideoEncoder ( inputFrameDesc );
63
- _outputEncoder = outputVideo;
62
+ // transform
63
+ _transform = new VideoTransform ();
64
64
65
- // output stream
66
- _outputStream = &outputFile.addVideoStream ( _inputStream->getVideoCodec () );
65
+ // output encoder
66
+ VideoEncoder* outputVideo = new VideoEncoder ( _inputStream->getVideoCodec ().getCodecName () );
67
+ outputVideo->setupVideoEncoder ( inputFrameDesc );
68
+ _outputEncoder = outputVideo;
69
+ }
70
+ catch ( std::runtime_error& e )
71
+ {
72
+ LOG_WARN ( " Cannot create the video encoder for stream " << _inputStream->getStreamIndex () << " if needed. " << e.what () )
73
+ }
67
74
68
75
break ;
69
76
}
70
77
case AVMEDIA_TYPE_AUDIO :
71
78
{
72
- AudioFrameDesc inputFrameDesc ( _inputStream->getAudioCodec ().getAudioFrameDesc () );
79
+ // output stream
80
+ _outputStream = &outputFile.addAudioStream ( _inputStream->getAudioCodec () );
73
81
74
- // generator decoder
75
- AudioGenerator* generatorAudio = new AudioGenerator ();
76
- generatorAudio->setAudioFrameDesc ( inputFrameDesc );
77
- _generator = generatorAudio;
82
+ try
83
+ {
84
+ AudioFrameDesc inputFrameDesc ( _inputStream->getAudioCodec ().getAudioFrameDesc () );
78
85
79
- // buffers to process
80
- _sourceBuffer = new AudioFrame ( inputFrameDesc );
81
- _frameBuffer = new AudioFrame ( inputFrameDesc );
86
+ // generator decoder
87
+ AudioGenerator* generatorAudio = new AudioGenerator ();
88
+ generatorAudio->setAudioFrameDesc ( inputFrameDesc );
89
+ _generator = generatorAudio;
82
90
83
- // transform
84
- _transform = new AudioTransform ();
91
+ // buffers to process
92
+ _sourceBuffer = new AudioFrame ( inputFrameDesc );
93
+ _frameBuffer = new AudioFrame ( inputFrameDesc );
85
94
86
- // output encoder
87
- AudioEncoder* outputAudio = new AudioEncoder ( _inputStream->getAudioCodec ().getCodecName () );
88
- outputAudio->setupAudioEncoder ( inputFrameDesc );
89
- _outputEncoder = outputAudio;
95
+ // transform
96
+ _transform = new AudioTransform ();
90
97
91
- // output stream
92
- _outputStream = &outputFile.addAudioStream ( _inputStream->getAudioCodec () );
98
+ // output encoder
99
+ AudioEncoder* outputAudio = new AudioEncoder ( _inputStream->getAudioCodec ().getCodecName () );
100
+ outputAudio->setupAudioEncoder ( inputFrameDesc );
101
+ _outputEncoder = outputAudio;
102
+ }
103
+
104
+ catch ( std::runtime_error& e )
105
+ {
106
+ LOG_WARN ( " Cannot create the audio encoder for stream " << _inputStream->getStreamIndex () << " if needed. " << e.what () )
107
+ }
93
108
94
109
break ;
95
110
}
@@ -102,6 +117,7 @@ StreamTranscoder::StreamTranscoder(
102
117
default :
103
118
break ;
104
119
}
120
+ setOffset ( offset );
105
121
}
106
122
107
123
StreamTranscoder::StreamTranscoder (
@@ -122,7 +138,7 @@ StreamTranscoder::StreamTranscoder(
122
138
, _transform( NULL )
123
139
, _subStreamIndex( subStreamIndex )
124
140
, _offset( offset )
125
- , _canSwitchToGenerator ( false )
141
+ , _needToSwitchToGenerator ( false )
126
142
{
127
143
// create a transcode case
128
144
switch ( _inputStream->getStreamType () )
@@ -208,6 +224,7 @@ StreamTranscoder::StreamTranscoder(
208
224
break ;
209
225
}
210
226
}
227
+ setOffset ( offset );
211
228
}
212
229
213
230
StreamTranscoder::StreamTranscoder (
@@ -226,7 +243,7 @@ StreamTranscoder::StreamTranscoder(
226
243
, _transform( NULL )
227
244
, _subStreamIndex( -1 )
228
245
, _offset( 0 )
229
- , _canSwitchToGenerator ( false )
246
+ , _needToSwitchToGenerator ( false )
230
247
{
231
248
if ( profile.find ( constants::avProfileType )->second == constants::avProfileTypeVideo )
232
249
{
@@ -300,6 +317,20 @@ StreamTranscoder::~StreamTranscoder()
300
317
301
318
void StreamTranscoder::preProcessCodecLatency ()
302
319
{
320
+ if ( ! _outputEncoder )
321
+ {
322
+ std::stringstream os;
323
+ os << " No output encoder found for stream " ;
324
+ if ( getProcessCase () == eProcessCaseGenerator )
325
+ os << " generator" ;
326
+ else
327
+ os << _inputStream->getStreamIndex ();
328
+ os << " : will not preProcessCodecLatency." ;
329
+ LOG_INFO ( os.str () )
330
+
331
+ return ;
332
+ }
333
+
303
334
int latency = _outputEncoder->getCodec ().getLatency ();
304
335
305
336
LOG_DEBUG ( " Latency of stream: " << latency )
@@ -323,6 +354,9 @@ void StreamTranscoder::preProcessCodecLatency()
323
354
324
355
bool StreamTranscoder::processFrame ()
325
356
{
357
+ if ( getProcessCase () == eProcessCaseGenerator )
358
+ return processTranscode ();
359
+
326
360
// Manage offset
327
361
if ( _offset > 0 )
328
362
{
@@ -357,7 +391,7 @@ bool StreamTranscoder::processFrame()
357
391
switchToGeneratorDecoder ();
358
392
_offset = 0 ;
359
393
}
360
- }
394
+ }
361
395
362
396
if ( getProcessCase () == eProcessCaseRewrap )
363
397
return processRewrap ();
@@ -382,7 +416,7 @@ bool StreamTranscoder::processRewrap()
382
416
CodedData data;
383
417
if ( ! _inputStream->readNextPacket ( data ) )
384
418
{
385
- if ( _canSwitchToGenerator )
419
+ if ( _needToSwitchToGenerator )
386
420
{
387
421
switchToGeneratorDecoder ();
388
422
return processTranscode ();
@@ -437,7 +471,7 @@ bool StreamTranscoder::processTranscode( const int subStreamIndex )
437
471
LOG_DEBUG ( " Encode last frame(s)" )
438
472
if ( ! _outputEncoder->encodeFrame ( data ) )
439
473
{
440
- if ( _canSwitchToGenerator )
474
+ if ( _needToSwitchToGenerator )
441
475
{
442
476
switchToGeneratorDecoder ();
443
477
return processTranscode ();
@@ -479,7 +513,7 @@ void StreamTranscoder::switchToInputDecoder()
479
513
}
480
514
481
515
float StreamTranscoder::getDuration () const
482
- {
516
+ {
483
517
if ( _inputStream )
484
518
{
485
519
const float totalDuration = _inputStream->getDuration () + _offset;
@@ -490,10 +524,36 @@ float StreamTranscoder::getDuration() const
490
524
}
491
525
return totalDuration;
492
526
}
527
+ // generator
493
528
else
494
529
return std::numeric_limits<float >::max ();
495
530
}
496
531
532
+ bool StreamTranscoder::canSwitchToGenerator ()
533
+ {
534
+ if ( _sourceBuffer && _frameBuffer && _generator && _outputEncoder && _transform )
535
+ return true ;
536
+ return false ;
537
+ }
538
+
539
+ void StreamTranscoder::needToSwitchToGenerator ( const bool needToSwitch )
540
+ {
541
+ if ( needToSwitch && ! canSwitchToGenerator () )
542
+ {
543
+ std::stringstream os;
544
+ os << " The stream " << _inputStream->getStreamIndex () << " needs to switch to a generator during the process, but it cannot." ;
545
+ throw std::runtime_error ( os.str () );
546
+ }
547
+ _needToSwitchToGenerator = needToSwitch;
548
+ }
549
+
550
+ void StreamTranscoder::setOffset ( const float offset )
551
+ {
552
+ _offset = offset;
553
+ if ( _offset > 0 )
554
+ needToSwitchToGenerator ();
555
+ }
556
+
497
557
StreamTranscoder::EProcessCase StreamTranscoder::getProcessCase () const
498
558
{
499
559
if ( _inputStream && _inputDecoder )
0 commit comments