From 1339fe7fa746121932650f90dd68dc708315b96a Mon Sep 17 00:00:00 2001 From: Valentin Noel Date: Mon, 8 Dec 2014 16:58:27 +0100 Subject: [PATCH 1/2] AvInputVideo: fix missing frame when transcoding (flush decoder buffer) --- src/AvTranscoder/essenceStream/AvInputVideo.cpp | 15 +++++++++------ src/AvTranscoder/essenceStream/AvInputVideo.hpp | 2 -- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/AvTranscoder/essenceStream/AvInputVideo.cpp b/src/AvTranscoder/essenceStream/AvInputVideo.cpp index 50677416..a50fabb6 100644 --- a/src/AvTranscoder/essenceStream/AvInputVideo.cpp +++ b/src/AvTranscoder/essenceStream/AvInputVideo.cpp @@ -22,7 +22,6 @@ AvInputVideo::AvInputVideo( AvInputStream& inputStream ) , _inputStream ( &inputStream ) , _codec( &inputStream.getVideoCodec() ) , _frame ( NULL ) - , _selectedStream( inputStream.getStreamIndex() ) { } @@ -106,24 +105,28 @@ bool AvInputVideo::decodeNextFrame() while( ! got_frame ) { CodedData data; - if( ! _inputStream->readNextPacket( data ) ) // error or end of file - return false; AVPacket packet; av_init_packet( &packet ); - packet.stream_index = _selectedStream; //_inputStream->getStreamIndex(); - packet.data = data.getPtr(); //nextPacketRead ? data.getPtr(): NULL; + bool nextPacketRead = _inputStream->readNextPacket( data ); + + packet.stream_index = _inputStream->getStreamIndex(); + packet.data = nextPacketRead ? data.getPtr(): NULL; packet.size = data.getSize(); int ret = avcodec_decode_video2( _codec->getAVCodecContext(), _frame, &got_frame, &packet ); + av_free_packet( &packet ); + + if( ! nextPacketRead && ret == 0 && got_frame == 0 ) // error or end of file + return false; + if( ret < 0 ) { char err[AV_ERROR_MAX_STRING_SIZE]; av_strerror( ret, err, sizeof(err) ); throw std::runtime_error( "an error occured during video decoding - " + std::string(err) ); } - av_free_packet( &packet ); } return true; } diff --git a/src/AvTranscoder/essenceStream/AvInputVideo.hpp b/src/AvTranscoder/essenceStream/AvInputVideo.hpp index 0a2292ec..90b7e03f 100644 --- a/src/AvTranscoder/essenceStream/AvInputVideo.hpp +++ b/src/AvTranscoder/essenceStream/AvInputVideo.hpp @@ -34,8 +34,6 @@ class AvExport AvInputVideo : public IInputEssence AvInputStream* _inputStream; ///< Stream from which we read next frames const VideoCodec* _codec; ///< Video decoder. Has link (no ownership) AVFrame* _frame; ///< Libav object to store decoded data - - int _selectedStream; ///< Index of the selected stream in the input file }; } From b3d4e3e1525a1f662cd3876795ebde489b767d72 Mon Sep 17 00:00:00 2001 From: Valentin Noel Date: Mon, 8 Dec 2014 17:45:47 +0100 Subject: [PATCH 2/2] AvInputAudio: flush decoder buffer at the end of the transcode process --- .../essenceStream/AvInputAudio.cpp | 18 ++++++++++-------- .../essenceStream/AvInputAudio.hpp | 2 -- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/AvTranscoder/essenceStream/AvInputAudio.cpp b/src/AvTranscoder/essenceStream/AvInputAudio.cpp index 00a08013..77711fc9 100644 --- a/src/AvTranscoder/essenceStream/AvInputAudio.cpp +++ b/src/AvTranscoder/essenceStream/AvInputAudio.cpp @@ -22,7 +22,6 @@ AvInputAudio::AvInputAudio( AvInputStream& inputStream ) , _inputStream ( &inputStream ) , _codec( &inputStream.getAudioCodec() ) , _frame ( NULL ) - , _selectedStream( inputStream.getStreamIndex() ) { } @@ -156,25 +155,28 @@ bool AvInputAudio::decodeNextFrame() while( ! got_frame ) { CodedData data; - if( ! _inputStream->readNextPacket( data ) ) // error or end of file - return false; AVPacket packet; av_init_packet( &packet ); - packet.stream_index = _selectedStream; - packet.data = data.getPtr(); - packet.size = data.getSize(); + bool nextPacketRead = _inputStream->readNextPacket( data ); + + packet.stream_index = _inputStream->getStreamIndex(); + packet.data = nextPacketRead ? data.getPtr(): NULL; + packet.size = data.getSize(); int ret = avcodec_decode_audio4( _codec->getAVCodecContext(), _frame, &got_frame, &packet ); + av_free_packet( &packet ); + + if( ! nextPacketRead && ret == 0 && got_frame == 0 ) // error or end of file + return false; + if( ret < 0 ) { char err[AV_ERROR_MAX_STRING_SIZE]; av_strerror( ret, err, sizeof(err) ); throw std::runtime_error( "an error occured during audio decoding" + std::string( err ) ); } - - av_free_packet( &packet ); } return true; } diff --git a/src/AvTranscoder/essenceStream/AvInputAudio.hpp b/src/AvTranscoder/essenceStream/AvInputAudio.hpp index 26b0fc9c..2ee95a9d 100644 --- a/src/AvTranscoder/essenceStream/AvInputAudio.hpp +++ b/src/AvTranscoder/essenceStream/AvInputAudio.hpp @@ -28,8 +28,6 @@ class AvExport AvInputAudio : public IInputEssence AvInputStream* _inputStream; ///< Stream from which we read next frames const AudioCodec* _codec; ///< Audio decoder. Has link (no ownership) AVFrame* _frame; ///< Libav object to store decoded data - - int _selectedStream; ///< Index of the selected stream in the input file }; }