Skip to content

Commit a1435c1

Browse files
Merge pull request #56 from cchampet/dev_Manage_end_of_encoding
StreamTranscoder: manage end of encoding
2 parents daeb051 + e9e212f commit a1435c1

File tree

12 files changed

+83
-30
lines changed

12 files changed

+83
-30
lines changed

app/genericProcessor/genericProcessor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ int main( int argc, char** argv )
117117
transcoder.setVerbose( verbose );
118118
transcoder.setProcessMethod( avtranscoder::eProcessMethodInfinity );
119119
//transcoder.setOutputFps( 12 );
120+
transcoder.init();
120121

121122
if( verbose )
122123
std::cout << "start Transcode" << std::endl;

src/AvTranscoder/CodedStructures/CodedDesc.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ AVCodecID CodedDesc::getCodecId() const
3939
return m_codecContext->codec_id;
4040
}
4141

42+
int CodedDesc::getLatency() const
43+
{
44+
assert( m_codecContext != NULL );
45+
return m_codecContext->delay;
46+
}
47+
4248
void CodedDesc::setCodec( const std::string& codecName )
4349
{
4450
avcodec_register_all(); // Warning: should be called only once

src/AvTranscoder/CodedStructures/CodedDesc.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class AvExport CodedDesc
2323
std::string getCodecName() const;
2424
AVCodecID getCodecId() const;
2525

26+
int getLatency() const;
27+
2628
void setCodec( const std::string& codecName );
2729
void setCodec( const AVCodecID codecId );
2830

src/AvTranscoder/EssenceStream/OutputAudio.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,23 @@ namespace avtranscoder
1616
{
1717

1818
OutputAudio::OutputAudio()
19-
: OutputEssence()
20-
, _audioDesc( "pcm_s16le" )
19+
: OutputEssence( "pcm_s16le" )
2120
{
2221
}
2322

2423
void OutputAudio::setup()
2524
{
2625
av_register_all(); // Warning: should be called only once
2726

28-
AVCodecContext* codecContext( _audioDesc.getCodecContext() );
27+
AVCodecContext* codecContext( _codedDesc.getCodecContext() );
2928

3029
if( codecContext == NULL )
3130
{
3231
throw std::runtime_error( "could not allocate audio codec context" );
3332
}
3433

3534
// try to open encoder with parameters.
36-
int ret = avcodec_open2( codecContext, _audioDesc.getCodec(), NULL );
35+
int ret = avcodec_open2( codecContext, _codedDesc.getCodec(), NULL );
3736
if( ret < 0 )
3837
{
3938
char err[250];
@@ -52,7 +51,7 @@ bool OutputAudio::encodeFrame( const Frame& sourceFrame, DataStream& codedFrame
5251
AVFrame* frame = avcodec_alloc_frame();
5352
#endif
5453

55-
AVCodecContext* codecContext = _audioDesc.getCodecContext();
54+
AVCodecContext* codecContext = _codedDesc.getCodecContext();
5655

5756
// Set default frame parameters
5857
#if LIBAVCODEC_VERSION_MAJOR > 54
@@ -140,7 +139,7 @@ bool OutputAudio::encodeFrame( const Frame& sourceFrame, DataStream& codedFrame
140139

141140
bool OutputAudio::encodeFrame( DataStream& codedFrame )
142141
{
143-
AVCodecContext* codecContext = _audioDesc.getCodecContext();
142+
AVCodecContext* codecContext = _codedDesc.getCodecContext();
144143

145144
AVPacket packet;
146145
av_init_packet( &packet );
@@ -181,11 +180,11 @@ void OutputAudio::setProfile( const Profile::ProfileDesc& desc, const AudioFrame
181180
throw std::runtime_error( "The profile " + desc.find( Profile::avProfileIdentificatorHuman )->second + " is invalid." );
182181
}
183182

184-
_audioDesc.setCodec( desc.find( Profile::avProfileCodec )->second );
183+
_codedDesc.setCodec( desc.find( Profile::avProfileCodec )->second );
185184

186-
_audioDesc.setAudioParameters( frameDesc );
185+
static_cast<AudioDesc>( _codedDesc ).setAudioParameters( frameDesc );
187186

188-
ParamSet paramSet( _audioDesc.getCodecContext() );
187+
ParamSet paramSet( _codedDesc.getCodecContext() );
189188

190189
for( Profile::ProfileDesc::const_iterator it = desc.begin(); it != desc.end(); ++it )
191190
{

src/AvTranscoder/EssenceStream/OutputAudio.hpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,7 @@ class OutputAudio : public OutputEssence
3131

3232
void setProfile( const Profile::ProfileDesc& desc, const AudioFrameDesc& frameDesc );
3333

34-
AudioDesc& getAudioDesc() { return _audioDesc; }
35-
36-
private:
37-
AudioDesc _audioDesc;
34+
AudioDesc getAudioDesc() { return _codedDesc; }
3835
};
3936

4037
}

src/AvTranscoder/EssenceStream/OutputEssence.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33

44
#include <AvTranscoder/EssenceStructures/Frame.hpp>
55
#include <AvTranscoder/CodedStructures/DataStream.hpp>
6+
#include <AvTranscoder/CodedStructures/CodedDesc.hpp>
67

78
namespace avtranscoder
89
{
910

1011
class AvExport OutputEssence
1112
{
1213
public:
13-
OutputEssence()
14+
OutputEssence( const std::string& codecName )
15+
: _codedDesc( codecName )
1416
{}
1517

1618
virtual ~OutputEssence()
@@ -36,6 +38,11 @@ class AvExport OutputEssence
3638
*/
3739
virtual bool encodeFrame( DataStream& codedFrame ) = 0;
3840

41+
CodedDesc& getCodedDesc() { return _codedDesc; }
42+
43+
protected:
44+
CodedDesc _codedDesc;
45+
3946
};
4047

4148
}

src/AvTranscoder/EssenceStream/OutputVideo.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,23 @@ namespace avtranscoder
1717
{
1818

1919
OutputVideo::OutputVideo( )
20-
: OutputEssence( )
21-
, _videoDesc( "mpeg2video" )
20+
: OutputEssence( "mpeg2video" )
2221
{
2322
}
2423

2524
void OutputVideo::setup( )
2625
{
2726
av_register_all(); // Warning: should be called only once
2827

29-
AVCodecContext* codecContext( _videoDesc.getCodecContext() );
28+
AVCodecContext* codecContext( _codedDesc.getCodecContext() );
3029

3130
if( codecContext == NULL )
3231
{
3332
throw std::runtime_error( "could not allocate video codec context" );
3433
}
3534

3635
// try to open encoder with parameters
37-
int ret = avcodec_open2( codecContext, _videoDesc.getCodec(), NULL );
36+
int ret = avcodec_open2( codecContext, _codedDesc.getCodec(), NULL );
3837
if( ret < 0 )
3938
{
4039
char err[250];
@@ -54,7 +53,7 @@ bool OutputVideo::encodeFrame( const Frame& sourceFrame, DataStream& codedFrame
5453
AVFrame* frame = avcodec_alloc_frame();
5554
#endif
5655

57-
AVCodecContext* codecContext = _videoDesc.getCodecContext();
56+
AVCodecContext* codecContext = this->_codedDesc.getCodecContext();
5857

5958
// Set default frame parameters
6059
#if LIBAVCODEC_VERSION_MAJOR > 54
@@ -141,7 +140,7 @@ bool OutputVideo::encodeFrame( const Frame& sourceFrame, DataStream& codedFrame
141140

142141
bool OutputVideo::encodeFrame( DataStream& codedFrame )
143142
{
144-
AVCodecContext* codecContext = _videoDesc.getCodecContext();
143+
AVCodecContext* codecContext = _codedDesc.getCodecContext();
145144

146145
AVPacket packet;
147146
av_init_packet( &packet );
@@ -183,14 +182,14 @@ void OutputVideo::setProfile( const Profile::ProfileDesc& desc, const avtranscod
183182
throw std::runtime_error( "The profile " + desc.find( Profile::avProfileIdentificatorHuman )->second + " is invalid." );
184183
}
185184

186-
_videoDesc.setCodec( desc.find( Profile::avProfileCodec )->second );
185+
_codedDesc.setCodec( desc.find( Profile::avProfileCodec )->second );
187186

188187
const size_t frameRate = std::strtoul( desc.find( Profile::avProfileFrameRate )->second.c_str(), NULL, 0 );
189-
_videoDesc.setTimeBase( 1, frameRate );
188+
static_cast<VideoDesc>( _codedDesc ).setTimeBase( 1, frameRate );
190189

191-
_videoDesc.setImageParameters( frameDesc );
190+
static_cast<VideoDesc>( _codedDesc ).setImageParameters( frameDesc );
192191

193-
ParamSet paramSet( _videoDesc.getCodecContext() );
192+
ParamSet paramSet( _codedDesc.getCodecContext() );
194193

195194
for( Profile::ProfileDesc::const_iterator it = desc.begin(); it != desc.end(); ++it )
196195
{

src/AvTranscoder/EssenceStream/OutputVideo.hpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ class AvExport OutputVideo : public OutputEssence
1919

2020
void setup();
2121

22-
//void setVideoDesc( const VideoDesc& videoDesc );
23-
2422
/**
2523
* @param[out] codedFrame blabla
2624
*/
@@ -33,10 +31,7 @@ class AvExport OutputVideo : public OutputEssence
3331

3432
void setProfile( const Profile::ProfileDesc& desc, const avtranscoder::VideoFrameDesc& frameDesc );
3533

36-
VideoDesc& getVideoDesc() { return _videoDesc; }
37-
38-
private:
39-
VideoDesc _videoDesc;
34+
VideoDesc getVideoDesc() { return _codedDesc; }
4035
};
4136

4237
}

src/AvTranscoder/Transcoder/StreamTranscoder.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ StreamTranscoder::StreamTranscoder(
3030
, _frameBuffer( NULL )
3131
, _inputEssence( NULL )
3232
, _dummyEssence( NULL )
33+
, _currentEssence( NULL )
3334
, _outputEssence( NULL )
3435
, _transform( NULL )
3536
, _subStreamIndex( -1 )
@@ -76,6 +77,7 @@ StreamTranscoder::StreamTranscoder(
7677
, _frameBuffer( NULL )
7778
, _inputEssence( NULL )
7879
, _dummyEssence( NULL )
80+
, _currentEssence( NULL )
7981
, _outputEssence( NULL )
8082
, _transform( NULL )
8183
, _subStreamIndex( subStreamIndex )
@@ -170,6 +172,7 @@ StreamTranscoder::StreamTranscoder(
170172
, _frameBuffer( NULL )
171173
, _inputEssence( &inputEssence )
172174
, _dummyEssence( NULL )
175+
, _currentEssence( NULL )
173176
, _outputEssence( NULL )
174177
, _transform( NULL )
175178
, _subStreamIndex( -1 )
@@ -248,6 +251,26 @@ StreamTranscoder::~StreamTranscoder()
248251
delete _transform;
249252
}
250253

254+
void StreamTranscoder::init()
255+
{
256+
// rewrap
257+
if( ! _inputEssence )
258+
return;
259+
260+
int latency = _outputEssence->getCodedDesc().getLatency();
261+
if( _verbose )
262+
std::cout << "latency of stream: " << latency << std::endl;
263+
264+
if( ! latency ||
265+
latency < _outputEssence->getCodedDesc().getCodecContext()->frame_number )
266+
return;
267+
268+
while( ( --latency ) > 0 )
269+
{
270+
processFrame();
271+
}
272+
}
273+
251274
bool StreamTranscoder::processFrame()
252275
{
253276
++_frameProcessed;

src/AvTranscoder/Transcoder/StreamTranscoder.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ class StreamTranscoder
3939

4040
~StreamTranscoder();
4141

42+
/**
43+
* @brief Init before encoding to pre-process frames necessary to delete the latency.
44+
* @note This can be called several times with no side effects.
45+
* @note Can take a little bit of time.
46+
*/
47+
void init();
48+
4249
/**
4350
* @brief process a single frame for the current stream
4451
* @return the process status result

src/AvTranscoder/Transcoder/Transcoder.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,16 @@ void Transcoder::add( StreamTranscoder& stream )
203203
_streamTranscoders.push_back( &stream );
204204
}
205205

206+
void Transcoder::init()
207+
{
208+
for( size_t streamIndex = 0; streamIndex < _streamTranscoders.size(); ++streamIndex )
209+
{
210+
if( _verbose )
211+
std::cout << "init stream " << streamIndex << std::endl;
212+
_streamTranscoders.at( streamIndex )->init();
213+
}
214+
}
215+
206216
bool Transcoder::processFrame()
207217
{
208218
if( _streamTranscoders.size() == 0 )

src/AvTranscoder/Transcoder/Transcoder.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ class Transcoder
9494
*/
9595
void add( StreamTranscoder& stream );
9696

97+
/**
98+
* @brief Initialize all streams added, by ensure process necessary frames in case of latency.
99+
* @note This can be called several times with no side effects.
100+
* @note Can take a little bit of time.
101+
*/
102+
void init();
103+
97104
/**
98105
* @brief Process the next frame of all streams.
99106
* @return if a frame was processed or not.

0 commit comments

Comments
 (0)