Skip to content

Fix audio packets management #134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/AvTranscoder/codedStream/AvOutputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ AvOutputStream::AvOutputStream( OutputFile& outputFile, const size_t streamIndex
{
}

bool AvOutputStream::wrap( const CodedData& data )
IOutputStream::EWrappingStatus AvOutputStream::wrap( const CodedData& data )
{
assert( _outputFile != NULL );
return _outputFile->wrap( data, _streamIndex );
Expand Down
2 changes: 1 addition & 1 deletion src/AvTranscoder/codedStream/AvOutputStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class AvExport AvOutputStream : public IOutputStream

size_t getStreamIndex() const { return _streamIndex; }

bool wrap( const CodedData& data );
IOutputStream::EWrappingStatus wrap( const CodedData& data );

private:
OutputFile* _outputFile;
Expand Down
13 changes: 12 additions & 1 deletion src/AvTranscoder/codedStream/IOutputStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,22 @@ namespace avtranscoder
class IOutputStream
{
public:

/**
* @brief define wrapping result status
**/
enum EWrappingStatus
{
eWrappingSuccess = 0,
eWrappingWaitingForData,
eWrappingError,
};

virtual ~IOutputStream() {};

virtual size_t getStreamIndex() const = 0;

virtual bool wrap( const CodedData& data ) = 0;
virtual EWrappingStatus wrap( const CodedData& data ) = 0;
};

}
Expand Down
27 changes: 21 additions & 6 deletions src/AvTranscoder/file/OutputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ OutputFile::OutputFile( const std::string& filename )
, _stream ( NULL )
, _filename ( filename )
, _packetCount ( 0 )
, _previousProcessedStreamDuration( 0.0 )
, _verbose ( false )
{
if( ( _formatContext = avformat_alloc_context() ) == NULL )
Expand Down Expand Up @@ -66,12 +67,13 @@ IOutputStream& OutputFile::addVideoStream( const VideoCodec& videoDesc )
_stream->codec->width = videoDesc.getAVCodecContext()->width;
_stream->codec->height = videoDesc.getAVCodecContext()->height;
_stream->codec->bit_rate = videoDesc.getAVCodecContext()->bit_rate;
_stream->codec->ticks_per_frame = videoDesc.getAVCodecContext()->ticks_per_frame;
_stream->codec->pix_fmt = videoDesc.getAVCodecContext()->pix_fmt;
_stream->codec->profile = videoDesc.getAVCodecContext()->profile;
_stream->codec->level = videoDesc.getAVCodecContext()->level;

// need to set the time_base on the AVCodecContext and the AVStream...
// need to set the time_base on the AVCodecContext and the AVStream
// compensating the frame rate with the ticks_per_frame and keeping
// a coherent reading speed.
av_reduce(
&_stream->codec->time_base.num,
&_stream->codec->time_base.den,
Expand Down Expand Up @@ -145,10 +147,10 @@ bool OutputFile::beginWrap( )
return true;
}

bool OutputFile::wrap( const CodedData& data, const size_t streamId )
IOutputStream::EWrappingStatus OutputFile::wrap( const CodedData& data, const size_t streamId )
{
if( ! data.getSize() )
return true;
return IOutputStream::eWrappingSuccess;
if( _verbose )
std::cout << "wrap on stream " << streamId << " (" << data.getSize() << " bytes for frame " << _frameCount.at( streamId ) << ")" << std::endl;
AVPacket packet;
Expand All @@ -174,14 +176,27 @@ bool OutputFile::wrap( const CodedData& data, const size_t streamId )
msg += err;
// throw std::runtime_error( msg );
std::cout << msg << std::endl;
return false;
return IOutputStream::eWrappingError;
}

av_free_packet( &packet );

// get the current streams
AVStream* currentStream = _formatContext->streams[ streamId ];
// compute its duration
double currentStreamDuration = (double)currentStream->cur_dts * currentStream->time_base.num / currentStream->time_base.den;

if( currentStreamDuration < _previousProcessedStreamDuration )
{
// if the current stream is strictly shorter than the previous, wait for more data
return IOutputStream::eWrappingWaitingForData;
}

_previousProcessedStreamDuration = currentStreamDuration;

_packetCount++;
_frameCount.at( streamId )++;
return true;
return IOutputStream::eWrappingSuccess;
}

bool OutputFile::endWrap( )
Expand Down
4 changes: 3 additions & 1 deletion src/AvTranscoder/file/OutputFile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class AvExport OutputFile
* @param data coded packet information for the current stream
* @param streamId refers to the stream in output ressource
**/
virtual bool wrap( const CodedData& data, const size_t streamId );
virtual IOutputStream::EWrappingStatus wrap( const CodedData& data, const size_t streamId );

/**
* @brief Finalize the end of the wrapping
Expand Down Expand Up @@ -123,6 +123,8 @@ class AvExport OutputFile
std::string _filename;

size_t _packetCount;

double _previousProcessedStreamDuration;

bool _verbose;
};
Expand Down
44 changes: 41 additions & 3 deletions src/AvTranscoder/transcoder/StreamTranscoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,19 @@ bool StreamTranscoder::processRewrap()
if( ! _inputStream->readNextPacket( data ) )
return false;

_outputStream->wrap( data );
IOutputStream::EWrappingStatus wrappingStatus = _outputStream->wrap( data );

switch( wrappingStatus )
{
case IOutputStream::eWrappingSuccess:
return true;
case IOutputStream::eWrappingWaitingForData:
// the wrapper needs more data to write the current packet
return processRewrap();
case IOutputStream::eWrappingError:
return false;
}

return true;
}

Expand Down Expand Up @@ -355,7 +367,20 @@ bool StreamTranscoder::processTranscode()

if( _verbose )
std::cout << "wrap (" << data.getSize() << ")" << std::endl;
_outputStream->wrap( data );

IOutputStream::EWrappingStatus wrappingStatus = _outputStream->wrap( data );

switch( wrappingStatus )
{
case IOutputStream::eWrappingSuccess:
return true;
case IOutputStream::eWrappingWaitingForData:
// the wrapper needs more data to write the current packet
return processTranscode();
case IOutputStream::eWrappingError:
return false;
}

return true;
}

Expand Down Expand Up @@ -406,7 +431,20 @@ bool StreamTranscoder::processTranscode( const int subStreamIndex )
}
if( _verbose )
std::cout << "wrap (" << data.getSize() << ")" << std::endl;
_outputStream->wrap( data );

IOutputStream::EWrappingStatus wrappingStatus = _outputStream->wrap( data );

switch( wrappingStatus )
{
case IOutputStream::eWrappingSuccess:
return true;
case IOutputStream::eWrappingWaitingForData:
// the wrapper needs more data to write the current packet
return processTranscode( subStreamIndex );
case IOutputStream::eWrappingError:
return false;
}

return true;
}

Expand Down
15 changes: 15 additions & 0 deletions src/AvTranscoder/transform/AudioTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace avtranscoder

AudioTransform::AudioTransform()
: _audioConvertContext( NULL )
, _previousProcessedAudioFrameSize( 0 )
, _isInit ( false )
{
}
Expand Down Expand Up @@ -64,11 +65,25 @@ bool AudioTransform::init( const Frame& srcFrame, const Frame& dstFrame )
return true;
}

bool AudioTransform::initFrames( const Frame& srcFrame, Frame& dstFrame )
{
const AudioFrame& src = static_cast<const AudioFrame&>( srcFrame );
const AudioFrame& dst = static_cast<const AudioFrame&>( dstFrame );

int dstSampleSize = av_get_bytes_per_sample( dst.desc().getAVSampleFormat() );
dstFrame.getBuffer().resize( src.getNbSamples() * dstSampleSize );
_previousProcessedAudioFrameSize = srcFrame.getSize();
return true;
}

void AudioTransform::convert( const Frame& srcFrame, Frame& dstFrame )
{
if( ! _isInit )
_isInit = init( srcFrame, dstFrame );

if( srcFrame.getSize() != _previousProcessedAudioFrameSize )
initFrames( srcFrame, dstFrame );

const unsigned char* srcData = srcFrame.getPtr();
unsigned char* dstData = dstFrame.getPtr();

Expand Down
3 changes: 3 additions & 0 deletions src/AvTranscoder/transform/AudioTransform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ class AvExport AudioTransform : public ITransform

private:
bool init( const Frame& srcFrame, const Frame& dstFrame );
bool initFrames( const Frame& srcFrame, Frame& dstFrame );

ResampleContext* _audioConvertContext;

size_t _previousProcessedAudioFrameSize;

bool _isInit;
};
Expand Down