Skip to content

Commit 67475cc

Browse files
committed
Merge pull request #1 from valnoel/fix_audio_packets_management
Fix audio packets management
2 parents 0b16a95 + 59755cc commit 67475cc

File tree

8 files changed

+97
-13
lines changed

8 files changed

+97
-13
lines changed

src/AvTranscoder/codedStream/AvOutputStream.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ AvOutputStream::AvOutputStream( OutputFile& outputFile, const size_t streamIndex
1414
{
1515
}
1616

17-
bool AvOutputStream::wrap( const CodedData& data )
17+
IOutputStream::EWrappingStatus AvOutputStream::wrap( const CodedData& data )
1818
{
1919
assert( _outputFile != NULL );
2020
return _outputFile->wrap( data, _streamIndex );

src/AvTranscoder/codedStream/AvOutputStream.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class AvExport AvOutputStream : public IOutputStream
1515

1616
size_t getStreamIndex() const { return _streamIndex; }
1717

18-
bool wrap( const CodedData& data );
18+
IOutputStream::EWrappingStatus wrap( const CodedData& data );
1919

2020
private:
2121
OutputFile* _outputFile;

src/AvTranscoder/codedStream/IOutputStream.hpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,22 @@ namespace avtranscoder
1111
class IOutputStream
1212
{
1313
public:
14+
15+
/**
16+
* @brief define wrapping result status
17+
**/
18+
enum EWrappingStatus
19+
{
20+
eWrappingSuccess = 0,
21+
eWrappingWaitingForData,
22+
eWrappingError,
23+
};
24+
1425
virtual ~IOutputStream() {};
1526

1627
virtual size_t getStreamIndex() const = 0;
1728

18-
virtual bool wrap( const CodedData& data ) = 0;
29+
virtual EWrappingStatus wrap( const CodedData& data ) = 0;
1930
};
2031

2132
}

src/AvTranscoder/file/OutputFile.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ OutputFile::OutputFile( const std::string& filename )
2020
, _stream ( NULL )
2121
, _filename ( filename )
2222
, _packetCount ( 0 )
23+
, _previousProcessedStreamDuration( 0.0 )
2324
, _verbose ( false )
2425
{
2526
if( ( _formatContext = avformat_alloc_context() ) == NULL )
@@ -66,12 +67,13 @@ IOutputStream& OutputFile::addVideoStream( const VideoCodec& videoDesc )
6667
_stream->codec->width = videoDesc.getAVCodecContext()->width;
6768
_stream->codec->height = videoDesc.getAVCodecContext()->height;
6869
_stream->codec->bit_rate = videoDesc.getAVCodecContext()->bit_rate;
69-
_stream->codec->ticks_per_frame = videoDesc.getAVCodecContext()->ticks_per_frame;
7070
_stream->codec->pix_fmt = videoDesc.getAVCodecContext()->pix_fmt;
7171
_stream->codec->profile = videoDesc.getAVCodecContext()->profile;
7272
_stream->codec->level = videoDesc.getAVCodecContext()->level;
7373

74-
// need to set the time_base on the AVCodecContext and the AVStream...
74+
// need to set the time_base on the AVCodecContext and the AVStream
75+
// compensating the frame rate with the ticks_per_frame and keeping
76+
// a coherent reading speed.
7577
av_reduce(
7678
&_stream->codec->time_base.num,
7779
&_stream->codec->time_base.den,
@@ -145,10 +147,10 @@ bool OutputFile::beginWrap( )
145147
return true;
146148
}
147149

148-
bool OutputFile::wrap( const CodedData& data, const size_t streamId )
150+
IOutputStream::EWrappingStatus OutputFile::wrap( const CodedData& data, const size_t streamId )
149151
{
150152
if( ! data.getSize() )
151-
return true;
153+
return IOutputStream::eWrappingSuccess;
152154
if( _verbose )
153155
std::cout << "wrap on stream " << streamId << " (" << data.getSize() << " bytes for frame " << _frameCount.at( streamId ) << ")" << std::endl;
154156
AVPacket packet;
@@ -174,14 +176,27 @@ bool OutputFile::wrap( const CodedData& data, const size_t streamId )
174176
msg += err;
175177
// throw std::runtime_error( msg );
176178
std::cout << msg << std::endl;
177-
return false;
179+
return IOutputStream::eWrappingError;
178180
}
179181

180182
av_free_packet( &packet );
181183

184+
// get the current streams
185+
AVStream* currentStream = _formatContext->streams[ streamId ];
186+
// compute its duration
187+
double currentStreamDuration = (double)currentStream->cur_dts * currentStream->time_base.num / currentStream->time_base.den;
188+
189+
if( currentStreamDuration < _previousProcessedStreamDuration )
190+
{
191+
// if the current stream is strictly shorter than the previous, wait for more data
192+
return IOutputStream::eWrappingWaitingForData;
193+
}
194+
195+
_previousProcessedStreamDuration = currentStreamDuration;
196+
182197
_packetCount++;
183198
_frameCount.at( streamId )++;
184-
return true;
199+
return IOutputStream::eWrappingSuccess;
185200
}
186201

187202
bool OutputFile::endWrap( )

src/AvTranscoder/file/OutputFile.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class AvExport OutputFile
8686
* @param data coded packet information for the current stream
8787
* @param streamId refers to the stream in output ressource
8888
**/
89-
virtual bool wrap( const CodedData& data, const size_t streamId );
89+
virtual IOutputStream::EWrappingStatus wrap( const CodedData& data, const size_t streamId );
9090

9191
/**
9292
* @brief Finalize the end of the wrapping
@@ -123,6 +123,8 @@ class AvExport OutputFile
123123
std::string _filename;
124124

125125
size_t _packetCount;
126+
127+
double _previousProcessedStreamDuration;
126128

127129
bool _verbose;
128130
};

src/AvTranscoder/transcoder/StreamTranscoder.cpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,19 @@ bool StreamTranscoder::processRewrap()
303303
if( ! _inputStream->readNextPacket( data ) )
304304
return false;
305305

306-
_outputStream->wrap( data );
306+
IOutputStream::EWrappingStatus wrappingStatus = _outputStream->wrap( data );
307+
308+
switch( wrappingStatus )
309+
{
310+
case IOutputStream::eWrappingSuccess:
311+
return true;
312+
case IOutputStream::eWrappingWaitingForData:
313+
// the wrapper needs more data to write the current packet
314+
return processRewrap();
315+
case IOutputStream::eWrappingError:
316+
return false;
317+
}
318+
307319
return true;
308320
}
309321

@@ -355,7 +367,20 @@ bool StreamTranscoder::processTranscode()
355367

356368
if( _verbose )
357369
std::cout << "wrap (" << data.getSize() << ")" << std::endl;
358-
_outputStream->wrap( data );
370+
371+
IOutputStream::EWrappingStatus wrappingStatus = _outputStream->wrap( data );
372+
373+
switch( wrappingStatus )
374+
{
375+
case IOutputStream::eWrappingSuccess:
376+
return true;
377+
case IOutputStream::eWrappingWaitingForData:
378+
// the wrapper needs more data to write the current packet
379+
return processTranscode();
380+
case IOutputStream::eWrappingError:
381+
return false;
382+
}
383+
359384
return true;
360385
}
361386

@@ -406,7 +431,20 @@ bool StreamTranscoder::processTranscode( const int subStreamIndex )
406431
}
407432
if( _verbose )
408433
std::cout << "wrap (" << data.getSize() << ")" << std::endl;
409-
_outputStream->wrap( data );
434+
435+
IOutputStream::EWrappingStatus wrappingStatus = _outputStream->wrap( data );
436+
437+
switch( wrappingStatus )
438+
{
439+
case IOutputStream::eWrappingSuccess:
440+
return true;
441+
case IOutputStream::eWrappingWaitingForData:
442+
// the wrapper needs more data to write the current packet
443+
return processTranscode( subStreamIndex );
444+
case IOutputStream::eWrappingError:
445+
return false;
446+
}
447+
410448
return true;
411449
}
412450

src/AvTranscoder/transform/AudioTransform.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ namespace avtranscoder
3232

3333
AudioTransform::AudioTransform()
3434
: _audioConvertContext( NULL )
35+
, _previousProcessedAudioFrameSize( 0 )
3536
, _isInit ( false )
3637
{
3738
}
@@ -64,11 +65,25 @@ bool AudioTransform::init( const Frame& srcFrame, const Frame& dstFrame )
6465
return true;
6566
}
6667

68+
bool AudioTransform::initFrames( const Frame& srcFrame, Frame& dstFrame )
69+
{
70+
const AudioFrame& src = static_cast<const AudioFrame&>( srcFrame );
71+
const AudioFrame& dst = static_cast<const AudioFrame&>( dstFrame );
72+
73+
int dstSampleSize = av_get_bytes_per_sample( dst.desc().getAVSampleFormat() );
74+
dstFrame.getBuffer().resize( src.getNbSamples() * dstSampleSize );
75+
_previousProcessedAudioFrameSize = srcFrame.getSize();
76+
return true;
77+
}
78+
6779
void AudioTransform::convert( const Frame& srcFrame, Frame& dstFrame )
6880
{
6981
if( ! _isInit )
7082
_isInit = init( srcFrame, dstFrame );
7183

84+
if( srcFrame.getSize() != _previousProcessedAudioFrameSize )
85+
initFrames( srcFrame, dstFrame );
86+
7287
const unsigned char* srcData = srcFrame.getPtr();
7388
unsigned char* dstData = dstFrame.getPtr();
7489

src/AvTranscoder/transform/AudioTransform.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ class AvExport AudioTransform : public ITransform
2626

2727
private:
2828
bool init( const Frame& srcFrame, const Frame& dstFrame );
29+
bool initFrames( const Frame& srcFrame, Frame& dstFrame );
2930

3031
ResampleContext* _audioConvertContext;
32+
33+
size_t _previousProcessedAudioFrameSize;
3134

3235
bool _isInit;
3336
};

0 commit comments

Comments
 (0)