Skip to content

Commit bba77ad

Browse files
author
Clement Champetier
committed
StreamTranscoder: manage end of encoding
* Transcoder: add init function to initialize all streams. * StreamTranscoder: add init function to pre-process frames necessary to delete the latency. * OutputEssence: add a CodedDesc and its getter function. With that, we can get the description of essence whithout knowing its type (video, audio...). * Update OutputVideo and OutputAudio to getVideoDesc and getAudioDesc by cast the CodedDesc in OutputEssence. * CodedDesc: add getLatency. * Update avProcessor app.: init the transcoder before start transcode. * fix #49
1 parent daeb051 commit bba77ad

File tree

12 files changed

+80
-28
lines changed

12 files changed

+80
-28
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 & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,7 @@ class AvExport OutputVideo : public OutputEssence
3333

3434
void setProfile( const Profile::ProfileDesc& desc, const avtranscoder::VideoFrameDesc& frameDesc );
3535

36-
VideoDesc& getVideoDesc() { return _videoDesc; }
37-
38-
private:
39-
VideoDesc _videoDesc;
36+
VideoDesc getVideoDesc() { return _codedDesc; }
4037
};
4138

4239
}

src/AvTranscoder/Transcoder/StreamTranscoder.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,26 @@ StreamTranscoder::~StreamTranscoder()
248248
delete _transform;
249249
}
250250

251+
void StreamTranscoder::init()
252+
{
253+
// rewrap
254+
if( ! _inputEssence )
255+
return;
256+
257+
int latency = _outputEssence->getCodedDesc().getLatency();
258+
if( _verbose )
259+
std::cout << "latency of stream: " << latency << std::endl;
260+
261+
if( ! latency ||
262+
latency < _outputEssence->getCodedDesc().getCodecContext()->frame_number )
263+
return;
264+
265+
while( ( --latency ) > 0 )
266+
{
267+
processFrame();
268+
}
269+
}
270+
251271
bool StreamTranscoder::processFrame()
252272
{
253273
++_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

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy