Skip to content

Commit

Permalink
Merge pull request #263 from cchampet/fix_rewrapBasedOnStreamWithAnEs…
Browse files Browse the repository at this point in the history
…timateDurationBis

Fixed rewrap based on stream with an estimate duration
  • Loading branch information
cchampet committed Jul 12, 2016
2 parents 8fd9004 + cb2d7c4 commit bae3aad
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 52 deletions.
2 changes: 1 addition & 1 deletion src/AvTranscoder/decoder/AudioDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer)
&got_frame, &data.getAVPacket());
if(ret < 0)
{
throw std::runtime_error("an error occured during audio decoding" + getDescriptionFromErrorCode(ret));
throw std::runtime_error("An error occurred during audio decoding: " + getDescriptionFromErrorCode(ret));
}

// if no frame could be decompressed
Expand Down
2 changes: 1 addition & 1 deletion src/AvTranscoder/decoder/VideoDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ bool VideoDecoder::decodeNextFrame(Frame& frameBuffer)
&got_frame, &data.getAVPacket());
if(ret < 0)
{
throw std::runtime_error("an error occured during video decoding - " + getDescriptionFromErrorCode(ret));
throw std::runtime_error("An error occurred during video decoding: " + getDescriptionFromErrorCode(ret));
}

// if no frame could be decompressed
Expand Down
15 changes: 12 additions & 3 deletions src/AvTranscoder/properties/VideoProperties.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,18 @@ class AvExport VideoProperties : public StreamProperties
Rational getSar() const; // sample/pixel aspect ratio
Rational getDar() const; // display aspect ratio

size_t getBitRate() const; ///< in bits/s, 0 if unknown
/**
* @return The video bitrate in bits/s.
* @warning If there is no such info available in the container, this data is estimated by decoding the first GOP.
*/
size_t getBitRate() const;
size_t getMaxBitRate() const;
size_t getMinBitRate() const;
size_t getNbFrames() const; ///< 0 if unknown
/**
* @note 0 if unknown.
* @warning In case of a raw format, this data is estimated from the fps and the duration.
*/
size_t getNbFrames() const;
size_t getTicksPerFrame() const;
size_t getWidth() const;
size_t getHeight() const;
Expand All @@ -63,7 +71,8 @@ class AvExport VideoProperties : public StreamProperties

/**
* @brief Override method.
* @return the stream duration in seconds, 0 if not available
* @return The stream duration in seconds, 0 if not available.
* @warning In case of a raw format, this data is estimated from the file size.
*/
float getDuration() const;

Expand Down
16 changes: 5 additions & 11 deletions src/AvTranscoder/transcoder/StreamTranscoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,8 @@ void StreamTranscoder::preProcessCodecLatency()

bool StreamTranscoder::processFrame()
{
const EProcessCase processCase = getProcessCase();
std::string msg = "Current process case of the stream is a ";
switch(processCase)
switch(getProcessCase())
{
case eProcessCaseTranscode:
msg += "transcode.";
Expand All @@ -371,9 +370,6 @@ bool StreamTranscoder::processFrame()
}
LOG_DEBUG(msg)

if(processCase == eProcessCaseGenerator)
return processTranscode();

// Manage offset
if(_offset > 0)
{
Expand All @@ -382,7 +378,7 @@ bool StreamTranscoder::processFrame()
{
LOG_INFO("End of positive offset")

if(getProcessCase() == eProcessCaseTranscode)
if(_inputDecoder)
switchToInputDecoder();
else
_currentDecoder = NULL;
Expand All @@ -392,9 +388,7 @@ bool StreamTranscoder::processFrame()
{
// process generator
if(_currentDecoder != _generator)
{
switchToGeneratorDecoder();
}
}
}
else if(_offset < 0)
Expand All @@ -405,14 +399,14 @@ bool StreamTranscoder::processFrame()
{
LOG_INFO("End of negative offset")

switchToGeneratorDecoder();
if(_needToSwitchToGenerator)
switchToGeneratorDecoder();
_offset = 0;
}
}

if(processCase == eProcessCaseRewrap)
if(getProcessCase() == eProcessCaseRewrap)
return processRewrap();

return processTranscode(_subStreamIndex);
}

Expand Down
3 changes: 2 additions & 1 deletion src/AvTranscoder/transcoder/StreamTranscoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ class AvExport StreamTranscoder
void setOffset(const float offset);

//@{
// Get the current process case.
// @brief Get the current process case.
// @warning Could vary during the process.
enum EProcessCase
{
eProcessCaseTranscode,
Expand Down
60 changes: 31 additions & 29 deletions src/AvTranscoder/transcoder/Transcoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,30 +235,21 @@ bool Transcoder::processFrame()
return false;

// For each stream, process a frame
size_t nbStreamProcessStatusFailed = 0;
for(size_t streamIndex = 0; streamIndex < _streamTranscoders.size(); ++streamIndex)
{
LOG_DEBUG("Process stream " << streamIndex << "/" << (_streamTranscoders.size() - 1))
LOG_DEBUG("Process stream " << streamIndex + 1 << "/" << _streamTranscoders.size())

// if a stream failed to process
if(!_streamTranscoders.at(streamIndex)->processFrame())
{
LOG_WARN("Failed to process stream " << streamIndex)
++nbStreamProcessStatusFailed;
}
}

// Get the number of streams without the generators (they always succeed)
size_t nbStreamsWithoutGenerator = _streamTranscoders.size();
for(size_t streamIndex = 0; streamIndex < _streamTranscoders.size(); ++streamIndex)
{
if(_streamTranscoders.at(streamIndex)->getProcessCase() == StreamTranscoder::eProcessCaseGenerator)
--nbStreamsWithoutGenerator;
}
LOG_WARN("Failed to process stream at index " << streamIndex)

// If all streams failed to process a new frame
if(nbStreamsWithoutGenerator != 0 && nbStreamsWithoutGenerator == nbStreamProcessStatusFailed)
{
LOG_INFO("End of process because all streams (except generators) failed to process a new frame.")
return false;
// if this is the end of the main stream
if(streamIndex == _mainStreamIndex) {
LOG_INFO("End of process because the main stream at index " << _mainStreamIndex << " failed to process a new frame.")
return false;
}
}
}
return true;
}
Expand Down Expand Up @@ -304,7 +295,7 @@ ProcessStat Transcoder::process(IProgress& progress)
}

// check progressDuration
if(progressDuration >= expectedOutputDuration)
if(_eProcessMethod == eProcessMethodBasedOnDuration && progressDuration >= expectedOutputDuration)
{
LOG_INFO("End of process because the output program duration ("
<< progressDuration << "s) is equal or upper than " << expectedOutputDuration << "s.")
Expand All @@ -314,7 +305,7 @@ ProcessStat Transcoder::process(IProgress& progress)

_outputFile.endWrap();

LOG_INFO("End of process: " << frame << " frames processed")
LOG_INFO("End of process: " << ++frame << " frames processed")

LOG_INFO("Get process statistics")
ProcessStat processStat;
Expand Down Expand Up @@ -498,32 +489,43 @@ ProfileLoader::Profile Transcoder::getProfileFromFile(InputFile& inputFile, cons
return profile;
}

float Transcoder::getStreamDuration(size_t indexStream) const
float Transcoder::getStreamDuration(const size_t indexStream) const
{
return _streamTranscoders.at(indexStream)->getDuration();
}

float Transcoder::getMinTotalDuration() const
float Transcoder::getMinTotalDuration()
{
float minTotalDuration = std::numeric_limits<float>::max();
for(size_t i = 0; i < _streamTranscoders.size(); ++i)
for(size_t streamIndex = 0; streamIndex < _streamTranscoders.size(); ++streamIndex)
{
minTotalDuration = std::min(getStreamDuration(i), minTotalDuration);
const float streamDuration = getStreamDuration(streamIndex);
if(std::min(streamDuration, minTotalDuration) == streamDuration)
{
minTotalDuration = streamDuration;
_mainStreamIndex = streamIndex;
}

}
return minTotalDuration;
}

float Transcoder::getMaxTotalDuration() const
float Transcoder::getMaxTotalDuration()
{
float maxTotalDuration = 0;
for(size_t i = 0; i < _streamTranscoders.size(); ++i)
for(size_t streamIndex = 0; streamIndex < _streamTranscoders.size(); ++streamIndex)
{
maxTotalDuration = std::max(getStreamDuration(i), maxTotalDuration);
const float streamDuration = getStreamDuration(streamIndex);
if(std::max(streamDuration, maxTotalDuration) == streamDuration)
{
maxTotalDuration = streamDuration;
_mainStreamIndex = streamIndex;
}
}
return maxTotalDuration;
}

float Transcoder::getExpectedOutputDuration() const
float Transcoder::getExpectedOutputDuration()
{
switch(_eProcessMethod)
{
Expand Down
14 changes: 8 additions & 6 deletions src/AvTranscoder/transcoder/Transcoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,20 +197,22 @@ class AvExport Transcoder
float getStreamDuration(size_t indexStream) const;

/**
* @brief Get the duration of the shortest stream, in seconds
*/
float getMinTotalDuration() const;
* @brief Get the duration of the shortest stream, in seconds
* @note Set the index of the main stream to stop the process at the end of the shortest stream.
*/
float getMinTotalDuration();

/**
* @brief Get the duration of the longest stream, in seconds
* @note Set the index of the main stream to stop the process at the end of the longest stream.
*/
float getMaxTotalDuration() const;
float getMaxTotalDuration();

/**
* @brief Get the expected duration of the output program
* @note Depends on the streams, the process method, and the main stream index.
*/
float getExpectedOutputDuration() const;
float getExpectedOutputDuration();

/**
* @brief Get the current duration of the output program
Expand Down Expand Up @@ -240,7 +242,7 @@ class AvExport Transcoder

EProcessMethod _eProcessMethod; ///< Processing policy
size_t
_mainStreamIndex; ///< Index of stream used to stop the process of transcode in case of eProcessMethodBasedOnStream.
_mainStreamIndex; ///< Index of stream used to stop the process.
float _outputDuration; ///< Duration of output media used to stop the process of transcode in case of
/// eProcessMethodBasedOnDuration.
};
Expand Down
2 changes: 2 additions & 0 deletions test/pyTest/testOffset.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ def testRewrapAudioNegativeOffset():
assert_equals( src_audioStream.getNbSamples() + ( offset * dst_audioStream.getSampleRate() * dst_audioStream.getNbChannels() ), dst_audioStream.getNbSamples() )


# The output video stream has not the correct duration.
@nottest
def testTranscodeVideoPositiveOffset():
"""
Transcode one video stream (profile mpeg2) with offset at the beginning of the process.
Expand Down

0 comments on commit bae3aad

Please sign in to comment.