Skip to content

Commit eae46ea

Browse files
authored
Merge pull request #320 from avTranscoder/fix/compensate_codec_latency_in_positive_offset
Fix: compensate codec latency in positive offset
2 parents e644bb6 + 76481a8 commit eae46ea

File tree

7 files changed

+60
-4
lines changed

7 files changed

+60
-4
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
*.la
1313
*.a
1414

15-
build
15+
build*
1616
dist
17+
install*
18+
test/**/test*[.wav|.avi|.mov|.h264|.mxf]
1719

1820
# CMake
1921
CMakeCache.txt

src/AvTranscoder/decoder/AudioDecoder.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ bool AudioDecoder::decodeNextFrame(IFrame& frameBuffer)
121121
return false;
122122
}
123123
}
124+
125+
if(decodeNextFrame)
126+
incrementNbDecodedFrames(frameBuffer.getAVFrame().nb_samples);
127+
124128
return decodeNextFrame;
125129
}
126130

src/AvTranscoder/decoder/AudioGenerator.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ bool AudioGenerator::decodeNextFrame(IFrame& frameBuffer)
5858
LOG_DEBUG("Convert data of the audio specified when decode next frame")
5959
_audioTransform.convert(*_inputFrame, frameBuffer);
6060
}
61+
62+
incrementNbDecodedFrames(_silent->getNbSamplesPerChannel());
6163
return true;
6264
}
6365

src/AvTranscoder/decoder/IDecoder.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ namespace avtranscoder
1010

1111
class AvExport IDecoder
1212
{
13+
protected:
14+
IDecoder()
15+
: _decoded_frames_counter(0)
16+
{
17+
}
18+
1319
public:
1420
virtual ~IDecoder(){};
1521

@@ -51,6 +57,16 @@ class AvExport IDecoder
5157
* @note Not sense for generators.
5258
*/
5359
virtual void flushDecoder() {}
60+
61+
size_t getNbDecodedFrames() { return _decoded_frames_counter; }
62+
63+
protected:
64+
void incrementNbDecodedFrames(const size_t& nb_frames = 1) {
65+
_decoded_frames_counter += nb_frames;
66+
}
67+
68+
private:
69+
size_t _decoded_frames_counter;
5470
};
5571
}
5672

src/AvTranscoder/decoder/VideoDecoder.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ bool VideoDecoder::decodeNextFrame(IFrame& frameBuffer)
114114
return false;
115115
}
116116
}
117+
118+
if(decodeNextFrame)
119+
incrementNbDecodedFrames();
120+
117121
return decodeNextFrame;
118122
}
119123

src/AvTranscoder/decoder/VideoGenerator.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ bool VideoGenerator::decodeNextFrame(IFrame& frameBuffer)
5151
LOG_DEBUG("Convert data of the image specified when decode next frame")
5252
_videoTransform.convert(*_inputFrame, frameBuffer);
5353
}
54+
55+
incrementNbDecodedFrames();
5456
return true;
5557
}
5658

src/AvTranscoder/transcoder/StreamTranscoder.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,20 @@ bool StreamTranscoder::processFrame()
617617
// Manage offset
618618
if(_offset > 0)
619619
{
620-
const bool endOfOffset = _outputStream->getStreamDuration() >= _offset;
620+
bool endOfOffset = false;
621+
if(_currentDecoder == _generators.at(0))
622+
{
623+
const double fps = 1.0 * _outputEncoder->getCodec().getAVCodecContext().time_base.den /
624+
(_outputEncoder->getCodec().getAVCodecContext().time_base.num * _outputEncoder->getCodec().getAVCodecContext().ticks_per_frame);
625+
const double frame_duration = 1.0 / fps;
626+
const double generated_duration = _currentDecoder->getNbDecodedFrames() * frame_duration;
627+
endOfOffset = generated_duration >= _offset;
628+
}
629+
else
630+
{
631+
endOfOffset = _outputStream->getStreamDuration() >= _offset;
632+
}
633+
621634
if(endOfOffset)
622635
{
623636
LOG_INFO("End of positive offset")
@@ -704,6 +717,7 @@ bool StreamTranscoder::processTranscode()
704717
assert(_outputEncoder != NULL);
705718
assert(! _decodedData.empty());
706719
assert(_transform != NULL);
720+
assert(_generators.size() == _inputDecoders.size());
707721

708722
LOG_DEBUG("StreamTranscoder::processTranscode")
709723

@@ -750,8 +764,7 @@ bool StreamTranscoder::processTranscode()
750764
}
751765
}
752766

753-
// Transform
754-
CodedData data;
767+
// Check decoding status
755768
bool continueProcess = true;
756769
for(size_t index = 0; index < decodingStatus.size(); ++index)
757770
{
@@ -760,6 +773,17 @@ bool StreamTranscoder::processTranscode()
760773
if(!_filterGraph->hasFilters() || !_filterGraph->hasBufferedFrames(index))
761774
{
762775
continueProcess = false;
776+
if(_needToSwitchToGenerator)
777+
{
778+
switchToGeneratorDecoder();
779+
LOG_INFO("Force reallocation of the decoded data buffers since the decoders could have cleared them.")
780+
for(std::vector<IFrame*>::iterator it = _decodedData.begin(); it != _decodedData.end(); ++it)
781+
{
782+
if(! (*it)->isDataAllocated())
783+
(*it)->allocateData();
784+
}
785+
return processTranscode();
786+
}
763787
break;
764788
}
765789
LOG_DEBUG("Some frames remain into filter graph buffer " << index);
@@ -771,8 +795,10 @@ bool StreamTranscoder::processTranscode()
771795
}
772796
}
773797

798+
CodedData data;
774799
if(continueProcess)
775800
{
801+
// Transform
776802
IFrame* dataToTransform = NULL;
777803
if(_filterGraph->hasFilters())
778804
{

0 commit comments

Comments
 (0)