@@ -43,16 +43,61 @@ StreamTranscoder::StreamTranscoder(
43
43
{
44
44
case AVMEDIA_TYPE_VIDEO :
45
45
{
46
+ VideoFrameDesc inputFrameDesc ( _inputStream->getVideoCodec ().getVideoFrameDesc () );
47
+
48
+ // generator decoder
49
+ VideoGenerator* generatorVideo = new VideoGenerator ();
50
+ generatorVideo->setVideoFrameDesc ( inputFrameDesc );
51
+ _generator = generatorVideo;
52
+
53
+ // buffers to process
54
+ _sourceBuffer = new VideoFrame ( inputFrameDesc );
55
+ _frameBuffer = new VideoFrame ( inputFrameDesc );
56
+
57
+ // transform
58
+ _transform = new VideoTransform ();
59
+
60
+ // output encoder
61
+ VideoEncoder* outputVideo = new VideoEncoder ( _inputStream->getVideoCodec ().getCodecName () );
62
+ outputVideo->getVideoCodec ().setImageParameters ( inputFrameDesc );
63
+ outputVideo->setup ();
64
+ _outputEncoder = outputVideo;
65
+
66
+ // output stream
46
67
_outputStream = &outputFile.addVideoStream ( _inputStream->getVideoCodec () );
68
+
47
69
break ;
48
70
}
49
71
case AVMEDIA_TYPE_AUDIO :
50
72
{
73
+ AudioFrameDesc inputFrameDesc ( _inputStream->getAudioCodec ().getAudioFrameDesc () );
74
+
75
+ // generator decoder
76
+ AudioGenerator* generatorAudio = new AudioGenerator ();
77
+ generatorAudio->setAudioFrameDesc ( inputFrameDesc );
78
+ _generator = generatorAudio;
79
+
80
+ // buffers to process
81
+ _sourceBuffer = new AudioFrame ( inputFrameDesc );
82
+ _frameBuffer = new AudioFrame ( inputFrameDesc );
83
+
84
+ // transform
85
+ _transform = new AudioTransform ();
86
+
87
+ // output encoder
88
+ AudioEncoder* outputAudio = new AudioEncoder ( _inputStream->getAudioCodec ().getCodecName () );
89
+ outputAudio->getAudioCodec ().setAudioParameters ( inputFrameDesc );
90
+ outputAudio->setup ();
91
+ _outputEncoder = outputAudio;
92
+
93
+ // output stream
51
94
_outputStream = &outputFile.addAudioStream ( _inputStream->getAudioCodec () );
95
+
52
96
break ;
53
97
}
54
98
case AVMEDIA_TYPE_DATA :
55
99
{
100
+ // @warning: rewrap a data stream can't be lengthen by a generator (end of rewrapping will end the all process)
56
101
_outputStream = &outputFile.addDataStream ( _inputStream->getDataCodec () );
57
102
break ;
58
103
}
@@ -87,41 +132,47 @@ StreamTranscoder::StreamTranscoder(
87
132
{
88
133
case AVMEDIA_TYPE_VIDEO :
89
134
{
135
+ // input decoder
90
136
_inputDecoder = new VideoDecoder ( *static_cast <InputStream*>( _inputStream ) );
91
137
_inputDecoder->setup ();
138
+ _currentDecoder = _inputDecoder;
92
139
140
+ // output encoder
93
141
VideoEncoder* outputVideo = new VideoEncoder ( profile.at ( constants::avProfileCodec ) );
94
-
95
142
_outputEncoder = outputVideo;
96
143
97
144
VideoFrameDesc outputFrameDesc = _inputStream->getVideoCodec ().getVideoFrameDesc ();
98
145
outputFrameDesc.setParameters ( profile );
99
146
outputVideo->setProfile ( profile, outputFrameDesc );
100
-
147
+
148
+ // output stream
101
149
_outputStream = &outputFile.addVideoStream ( outputVideo->getVideoCodec () );
102
150
151
+ // buffers to process
103
152
_sourceBuffer = new VideoFrame ( _inputStream->getVideoCodec ().getVideoFrameDesc () );
104
153
_frameBuffer = new VideoFrame ( outputVideo->getVideoCodec ().getVideoFrameDesc () );
105
-
154
+
155
+ // transform
106
156
_transform = new VideoTransform ();
107
157
158
+ // generator decoder
108
159
VideoGenerator* generatorVideo = new VideoGenerator ();
109
160
generatorVideo->setVideoFrameDesc ( outputVideo->getVideoCodec ().getVideoFrameDesc () );
110
161
_generator = generatorVideo;
111
162
112
- _currentDecoder = _inputDecoder;
113
-
114
163
break ;
115
164
}
116
165
case AVMEDIA_TYPE_AUDIO :
117
166
{
167
+ // input decoder
118
168
_inputDecoder = new AudioDecoder ( *static_cast <InputStream*>( _inputStream ) );
119
169
_inputDecoder->setup ();
120
-
121
- AudioEncoder* outputAudio = new AudioEncoder ( profile.at ( constants::avProfileCodec ) );
170
+ _currentDecoder = _inputDecoder;
122
171
172
+ // output encoder
173
+ AudioEncoder* outputAudio = new AudioEncoder ( profile.at ( constants::avProfileCodec ) );
123
174
_outputEncoder = outputAudio;
124
-
175
+
125
176
AudioFrameDesc outputFrameDesc ( _inputStream->getAudioCodec ().getAudioFrameDesc () );
126
177
outputFrameDesc.setParameters ( profile );
127
178
if ( subStreamIndex > -1 )
@@ -131,23 +182,25 @@ StreamTranscoder::StreamTranscoder(
131
182
}
132
183
outputAudio->setProfile ( profile, outputFrameDesc );
133
184
185
+ // output stream
134
186
_outputStream = &outputFile.addAudioStream ( outputAudio->getAudioCodec () );
135
187
188
+ // buffers to process
136
189
AudioFrameDesc inputFrameDesc ( _inputStream->getAudioCodec ().getAudioFrameDesc () );
137
190
if ( subStreamIndex > -1 )
138
191
inputFrameDesc.setChannels ( 1 );
139
-
192
+
140
193
_sourceBuffer = new AudioFrame ( inputFrameDesc );
141
194
_frameBuffer = new AudioFrame ( outputAudio->getAudioCodec ().getAudioFrameDesc () );
142
-
195
+
196
+ // transform
143
197
_transform = new AudioTransform ();
144
198
199
+ // generator decoder
145
200
AudioGenerator* generatorAudio = new AudioGenerator ();
146
201
generatorAudio->setAudioFrameDesc ( outputAudio->getAudioCodec ().getAudioFrameDesc () );
147
202
_generator = generatorAudio;
148
203
149
- _currentDecoder = _inputDecoder;
150
-
151
204
break ;
152
205
}
153
206
default :
@@ -181,57 +234,55 @@ StreamTranscoder::StreamTranscoder(
181
234
{
182
235
if ( profile.find ( constants::avProfileType )->second == constants::avProfileTypeVideo )
183
236
{
184
- // Create input essence based on a given input VideoCodec
237
+ // generator decoder
185
238
VideoGenerator* generatorVideo = new VideoGenerator ();
186
239
const VideoCodec& inputVideoCodec = static_cast <const VideoCodec&>( inputCodec );
187
240
generatorVideo->setVideoFrameDesc ( inputVideoCodec.getVideoFrameDesc () );
188
- _inputDecoder = generatorVideo;
241
+ _currentDecoder = generatorVideo;
189
242
190
- // Create inputFrame, and outputFrame which is based on a given profile
243
+ // buffers to process
191
244
VideoFrameDesc inputFrameDesc = inputVideoCodec.getVideoFrameDesc ();
192
245
VideoFrameDesc outputFrameDesc = inputFrameDesc;
193
246
outputFrameDesc.setParameters ( profile );
194
247
_sourceBuffer = new VideoFrame ( inputFrameDesc );
195
248
_frameBuffer = new VideoFrame ( outputFrameDesc );
196
249
197
- // Create output essence
250
+ // transform
251
+ _transform = new VideoTransform ();
252
+
253
+ // output encoder
198
254
VideoEncoder* outputVideo = new VideoEncoder ( profile.at ( constants::avProfileCodec ) );
199
255
outputVideo->setProfile ( profile, outputFrameDesc );
200
256
_outputEncoder = outputVideo;
201
257
202
- // Create a video stream in the output file
258
+ // output stream
203
259
_outputStream = &outputFile.addVideoStream ( outputVideo->getVideoCodec () );
204
-
205
- _transform = new VideoTransform ();
206
-
207
- _currentDecoder = _inputDecoder;
208
260
}
209
261
else if ( profile.find ( constants::avProfileType )->second == constants::avProfileTypeAudio )
210
262
{
211
- // Create input essence based on a given input AudioCodec
263
+ // generator decoder
212
264
AudioGenerator* generatorAudio = new AudioGenerator ();
213
265
const AudioCodec& inputAudioCodec = static_cast <const AudioCodec&>( inputCodec );
214
266
generatorAudio->setAudioFrameDesc ( inputAudioCodec.getAudioFrameDesc () );
215
- _inputDecoder = generatorAudio;
267
+ _currentDecoder = generatorAudio;
216
268
217
- // Create inputFrame, and outputFrame which is based on a given profile
269
+ // buffers to process
218
270
AudioFrameDesc inputFrameDesc = inputAudioCodec.getAudioFrameDesc ();
219
271
AudioFrameDesc outputFrameDesc = inputFrameDesc;
220
272
outputFrameDesc.setParameters ( profile );
221
273
_sourceBuffer = new AudioFrame ( inputFrameDesc );
222
274
_frameBuffer = new AudioFrame ( outputFrameDesc );
223
275
224
- // Create output essence
276
+ // transform
277
+ _transform = new AudioTransform ();
278
+
279
+ // output encoder
225
280
AudioEncoder* outputAudio = new AudioEncoder ( profile.at ( constants::avProfileCodec ) );
226
281
outputAudio->setProfile ( profile, outputFrameDesc );
227
282
_outputEncoder = outputAudio;
228
283
229
- // Create an audio stream in the output file
284
+ // output stream
230
285
_outputStream = &outputFile.addAudioStream ( outputAudio->getAudioCodec () );
231
-
232
- _transform = new AudioTransform ();
233
-
234
- _currentDecoder = _inputDecoder;
235
286
}
236
287
else
237
288
{
@@ -241,8 +292,8 @@ StreamTranscoder::StreamTranscoder(
241
292
242
293
StreamTranscoder::~StreamTranscoder ()
243
294
{
244
- delete _frameBuffer;
245
295
delete _sourceBuffer;
296
+ delete _frameBuffer;
246
297
delete _generator;
247
298
delete _outputEncoder;
248
299
delete _transform;
@@ -252,7 +303,7 @@ StreamTranscoder::~StreamTranscoder()
252
303
void StreamTranscoder::preProcessCodecLatency ()
253
304
{
254
305
// rewrap case: no need to take care of the latency of codec
255
- if ( ! _inputDecoder )
306
+ if ( ! _currentDecoder )
256
307
return ;
257
308
258
309
int latency = _outputEncoder->getCodec ().getLatency ();
@@ -271,7 +322,7 @@ void StreamTranscoder::preProcessCodecLatency()
271
322
272
323
bool StreamTranscoder::processFrame ()
273
324
{
274
- if ( ! _inputDecoder )
325
+ if ( ! _currentDecoder )
275
326
{
276
327
return processRewrap ();
277
328
}
@@ -291,7 +342,14 @@ bool StreamTranscoder::processRewrap()
291
342
CodedData data;
292
343
293
344
if ( ! _inputStream->readNextPacket ( data ) )
345
+ {
346
+ if ( _canSwitchToGenerator )
347
+ {
348
+ switchToGeneratorDecoder ();
349
+ return processTranscode ();
350
+ }
294
351
return false ;
352
+ }
295
353
296
354
IOutputStream::EWrappingStatus wrappingStatus = _outputStream->wrap ( data );
297
355
@@ -311,7 +369,7 @@ bool StreamTranscoder::processRewrap()
311
369
312
370
bool StreamTranscoder::processTranscode ( const int subStreamIndex )
313
371
{
314
- assert ( _inputDecoder != NULL );
372
+ assert ( _outputStream != NULL );
315
373
assert ( _currentDecoder != NULL );
316
374
assert ( _outputEncoder != NULL );
317
375
assert ( _sourceBuffer != NULL );
0 commit comments