Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Muxing silent audio channels#304

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 ourterms of service andprivacy 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 fromall 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 deletionsrc/AvTranscoder/transcoder/InputStreamDesc.hpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,7 +63,7 @@ struct InputStreamDesc
bool demultiplexing() const { return !_channelIndexArray.empty(); }

public:
std::string _filename; ///< Source file path.
std::string _filename; ///< Source file path. If empty, a generator is used as source.
size_t _streamIndex; ///< Source stream to extract.
std::vector<size_t> _channelIndexArray; ///< List of source channels to extract from the stream
};
Expand Down
116 changes: 102 additions & 14 deletionssrc/AvTranscoder/transcoder/StreamTranscoder.cpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu
, _outputEncoder(NULL)
, _transform(NULL)
, _filterGraph(NULL)
, _firstInputStreamIndex(0)
, _offset(offset)
, _needToSwitchToGenerator(false)
{
Expand DownExpand Up@@ -140,19 +141,35 @@ StreamTranscoder::StreamTranscoder(const std::vector<InputStreamDesc>& inputStre
, _outputEncoder(NULL)
, _transform(NULL)
, _filterGraph(NULL)
, _firstInputStreamIndex(std::numeric_limits<size_t>::max())
, _offset(offset)
, _needToSwitchToGenerator(false)
{
// add as many decoders as input streams
size_t nbOutputChannels = 0;
for(size_t index = 0; index < inputStreams.size(); ++index)
{
addDecoder(_inputStreamDesc.at(index), *_inputStreams.at(index));
nbOutputChannels += _inputStreamDesc.at(index)._channelIndexArray.size();
if(_inputStreams.at(index) != NULL)
{
LOG_INFO("add decoder for input stream " << index);
addDecoder(_inputStreamDesc.at(index), *_inputStreams.at(index));
nbOutputChannels += _inputStreamDesc.at(index)._channelIndexArray.size();
if(_firstInputStreamIndex == std::numeric_limits<size_t>::max())
_firstInputStreamIndex = index;
}
else
{
LOG_INFO("add generator for empty input " << index);
addGenerator(_inputStreamDesc.at(index), profile);
nbOutputChannels++;
}
}

IInputStream& inputStream = *_inputStreams.at(0);
const InputStreamDesc& inputStreamDesc = inputStreamsDesc.at(0);
if(_firstInputStreamIndex == std::numeric_limits<size_t>::max())
throw std::runtime_error("Cannot handle empty only input streams");

IInputStream& inputStream = *_inputStreams.at(_firstInputStreamIndex);
const InputStreamDesc& inputStreamDesc = inputStreamsDesc.at(_firstInputStreamIndex);

// create a transcode case
switch(inputStream.getProperties().getStreamType())
Expand DownExpand Up@@ -278,6 +295,53 @@ void StreamTranscoder::addDecoder(const InputStreamDesc& inputStreamDesc, IInput
}
}

void StreamTranscoder::addGenerator(const InputStreamDesc& inputStreamDesc, const ProfileLoader::Profile& profile)
{
// create a transcode case
if(profile.find(constants::avProfileType)->second == constants::avProfileTypeVideo)
{
VideoCodec inputVideoCodec(eCodecTypeEncoder, profile.find(constants::avProfileCodec)->second);
VideoFrameDesc inputFrameDesc(profile);
inputVideoCodec.setImageParameters(inputFrameDesc);

// generator decoder
VideoGenerator* generator = new VideoGenerator(inputFrameDesc);
_generators.push_back(generator);
_currentDecoder = generator;

// buffers to process
VideoFrameDesc outputFrameDesc = inputFrameDesc;
outputFrameDesc.setParameters(profile);
_decodedData.push_back(new VideoFrame(inputFrameDesc));

// no decoder for this input
_inputDecoders.push_back(NULL);

}
else if(profile.find(constants::avProfileType)->second == constants::avProfileTypeAudio)
{
// corresponding input codec
AudioCodec inputAudioCodec(eCodecTypeEncoder, profile.find(constants::avProfileCodec)->second);
AudioFrameDesc inputFrameDesc(profile);
inputFrameDesc._nbChannels = 1;
inputAudioCodec.setAudioParameters(inputFrameDesc);

// generator decoder
AudioGenerator* generator = new AudioGenerator(inputFrameDesc);
_generators.push_back(generator);
_currentDecoder = generator;
// buffers to get the decoded data
_decodedData.push_back(new AudioFrame(inputFrameDesc));

// no decoder for this input
_inputDecoders.push_back(NULL);
}
else
{
throw std::runtime_error("unupported stream type");
}
}

StreamTranscoder::StreamTranscoder(IOutputFile& outputFile, const ProfileLoader::Profile& profile)
: _inputStreamDesc()
, _inputStreams()
Expand All@@ -291,6 +355,7 @@ StreamTranscoder::StreamTranscoder(IOutputFile& outputFile, const ProfileLoader:
, _outputEncoder(NULL)
, _transform(NULL)
, _filterGraph(NULL)
, _firstInputStreamIndex(0)
, _offset(0)
, _needToSwitchToGenerator(false)
{
Expand DownExpand Up@@ -375,7 +440,8 @@ StreamTranscoder::~StreamTranscoder()

for(std::vector<IDecoder*>::iterator it = _inputDecoders.begin(); it != _inputDecoders.end(); ++it)
{
delete(*it);
if(*it != NULL)
delete(*it);
}
for(std::vector<IDecoder*>::iterator it = _generators.begin(); it != _generators.end(); ++it)
{
Expand DownExpand Up@@ -536,7 +602,8 @@ bool StreamTranscoder::processTranscode()
std::vector<bool> decodingStatus(_generators.size(), true);
for(size_t index = 0; index < _generators.size(); ++index)
{
if(getProcessCase() == eProcessCaseTranscode)
EProcessCase processCase = getProcessCase(index);
if(processCase == eProcessCaseTranscode)
_currentDecoder = _inputDecoders.at(index);
else
_currentDecoder = _generators.at(index);
Expand All@@ -548,9 +615,9 @@ bool StreamTranscoder::processTranscode()
}

// check the next data buffers in case of audio frames
if(_decodedData.at(0)->isAudioFrame())
if(_decodedData.at(_firstInputStreamIndex)->isAudioFrame())
{
const int nbInputSamplesPerChannel = _decodedData.at(0)->getAVFrame().nb_samples;
const int nbInputSamplesPerChannel = _decodedData.at(_firstInputStreamIndex)->getAVFrame().nb_samples;

// Reallocate output frame
if(nbInputSamplesPerChannel > _filteredData->getAVFrame().nb_samples)
Expand DownExpand Up@@ -670,7 +737,11 @@ float StreamTranscoder::getDuration() const
float minStreamDuration = -1;
for(size_t index = 0; index < _inputStreams.size(); ++index)
{
const StreamProperties& streamProperties = _inputStreams.at(index)->getProperties();
IInputStream* inputStream = _inputStreams.at(index);
if(inputStream == NULL)
continue;

const StreamProperties& streamProperties = inputStream->getProperties();
if(minStreamDuration == -1 || streamProperties.getDuration() < minStreamDuration)
minStreamDuration = streamProperties.getDuration();
}
Expand DownExpand Up@@ -722,13 +793,30 @@ void StreamTranscoder::setOffset(const float offset)
}
}

StreamTranscoder::EProcessCase StreamTranscoder::getProcessCase() const
StreamTranscoder::EProcessCase StreamTranscoder::getProcessCase(const size_t decoderIndex) const
{
if(! _inputStreams.empty() && ! _inputDecoders.empty() && std::find(_inputDecoders.begin(), _inputDecoders.end(), _currentDecoder) != _inputDecoders.end() )
return eProcessCaseTranscode;
else if(! _inputStreams.empty() && _inputDecoders.empty() && !_currentDecoder)
return eProcessCaseRewrap;
if(_inputStreamDesc.size() <= 1)
{
if(! _inputStreams.empty() && ! _inputDecoders.empty() && std::find(_inputDecoders.begin(), _inputDecoders.end(), _currentDecoder) != _inputDecoders.end() )
return eProcessCaseTranscode;
else if(! _inputStreams.empty() && _inputDecoders.empty() && !_currentDecoder)
return eProcessCaseRewrap;
else
return eProcessCaseGenerator;
}
else
{
if(! _inputStreams.empty() && _currentDecoder != NULL)
{
if( _inputStreams.at(decoderIndex) != NULL)
return eProcessCaseTranscode;
return eProcessCaseGenerator;
}
else if(! _inputStreams.empty() && _inputDecoders.empty() && !_currentDecoder)
{
return eProcessCaseRewrap;
}
return eProcessCaseGenerator;
}
}
}
5 changes: 4 additions & 1 deletionsrc/AvTranscoder/transcoder/StreamTranscoder.hpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -115,7 +115,7 @@ class AvExport StreamTranscoder
eProcessCaseRewrap,
eProcessCaseGenerator
};
EProcessCase getProcessCase() const;
EProcessCase getProcessCase(const size_t decoderIndex = 0) const;
//@}

private:
Expand All@@ -125,6 +125,7 @@ class AvExport StreamTranscoder
* @param inputStream
*/
void addDecoder(const InputStreamDesc& inputStreamDesc, IInputStream& inputStream);
void addGenerator(const InputStreamDesc& inputStreamDesc, const ProfileLoader::Profile& profile);

bool processRewrap();
bool processTranscode();
Expand All@@ -147,6 +148,8 @@ class AvExport StreamTranscoder

FilterGraph* _filterGraph; ///< Filter graph (has ownership)

size_t _firstInputStreamIndex; ///< Index of the first non-null input stream.

float _offset; ///< Offset, in seconds, at the beginning of the StreamTranscoder.

bool _needToSwitchToGenerator; ///< Set if need to switch to a generator during the process (because, of other streams
Expand Down
34 changes: 32 additions & 2 deletionssrc/AvTranscoder/transcoder/Transcoder.cpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -260,6 +260,12 @@ void Transcoder::addTranscodeStream(const std::vector<InputStreamDesc>& inputStr
AVMediaType commonStreamType = AVMEDIA_TYPE_UNKNOWN;
for(std::vector<InputStreamDesc>::const_iterator it = inputStreamDescArray.begin(); it != inputStreamDescArray.end(); ++it)
{
if(it->_filename.empty())
{
inputStreams.push_back(NULL);
continue;
}

InputFile* referenceFile = addInputFile(it->_filename, it->_streamIndex, offset);
inputStreams.push_back(&referenceFile->getStream(it->_streamIndex));

Expand DownExpand Up@@ -329,7 +335,19 @@ ProfileLoader::Profile Transcoder::getProfileFromInputs(const std::vector<InputS
assert(inputStreamDescArray.size() >= 1);

// Get properties from the first input
const InputStreamDesc& inputStreamDesc = inputStreamDescArray.at(0);
size_t nonEmptyFileName = std::numeric_limits<size_t>::max();
for(size_t i = 0; i < inputStreamDescArray.size(); ++i)
{
if(!inputStreamDescArray.at(i)._filename.empty())
{
nonEmptyFileName = i;
break;
}
}
if(nonEmptyFileName == std::numeric_limits<size_t>::max())
throw std::runtime_error("Cannot get profile from empty input streams");

const InputStreamDesc& inputStreamDesc = inputStreamDescArray.at(nonEmptyFileName);
InputFile inputFile(inputStreamDesc._filename);

const StreamProperties* streamProperties = &inputFile.getProperties().getStreamPropertiesWithIndex(inputStreamDesc._streamIndex);
Expand DownExpand Up@@ -519,7 +537,19 @@ void Transcoder::fillProcessStat(ProcessStat& processStat)
LOG_WARN("Cannot process statistics of generated stream.")
continue;
}
const IInputStream* inputStream = _streamTranscoders.at(streamIndex)->getInputStreams().at(0);

size_t nonNullInputStreamIndex = 0;
std::vector<IInputStream*> inputStreams = _streamTranscoders.at(streamIndex)->getInputStreams();
for(size_t i = 0; i < inputStreams.size(); ++i)
{
if(inputStreams.at(i) != NULL)
{
nonNullInputStreamIndex = i;
break;
}
}

const IInputStream* inputStream = inputStreams.at(nonNullInputStreamIndex);
const AVMediaType mediaType = inputStream->getProperties().getStreamType();
switch(mediaType)
{
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp