Transcode, limit output birate to the media bitrate (no need to upscale)
This commit is contained in:
@@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
[Transcode]
|
[Transcode]
|
||||||
- some early playback end spotted on flac files or huge audio files (> several hours)
|
- some early playback end spotted on flac files or huge audio files (> several hours)
|
||||||
- limit transcode bitrate to the media bitrate (no need to upscale)
|
|
||||||
|
|
||||||
[UI]
|
[UI]
|
||||||
- handle internationalization
|
- handle internationalization
|
||||||
|
|||||||
@@ -100,7 +100,8 @@ MediaRequestHandler::processAudioPrepare(const MediaRequest::Prepare::Audio& req
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Transcode::InputMediaFile inputFile(track->getPath());
|
Transcode::InputMediaFile inputFile(track->getPath());
|
||||||
Transcode::Parameters parameters(inputFile, Transcode::Format::get( format ), bitrate);
|
Transcode::Parameters parameters(inputFile, Transcode::Format::get( format ));
|
||||||
|
parameters.setBitrate( Transcode::Stream::Audio, bitrate);
|
||||||
|
|
||||||
_transcoder = std::make_shared<Transcode::AvConvTranscoder>( parameters );
|
_transcoder = std::make_shared<Transcode::AvConvTranscoder>( parameters );
|
||||||
|
|
||||||
|
|||||||
@@ -58,9 +58,9 @@ AvConvTranscoder::AvConvTranscoder(const Parameters& parameters)
|
|||||||
oss << " -i \"" << _parameters.getInputMediaFile().getPath().string() << "\"";
|
oss << " -i \"" << _parameters.getInputMediaFile().getPath().string() << "\"";
|
||||||
|
|
||||||
// Output bitrates
|
// Output bitrates
|
||||||
oss << " -b:a " << _parameters.getOutputAudioBitrate() ;
|
oss << " -b:a " << _parameters.getOutputBitrate(Stream::Audio) ;
|
||||||
if (_parameters.getOutputFormat().getType() == Format::Video)
|
if (_parameters.getOutputFormat().getType() == Format::Video)
|
||||||
oss << " -b:v " << _parameters.getOutputVideoBitrate();
|
oss << " -b:v " << _parameters.getOutputBitrate(Stream::Video);
|
||||||
|
|
||||||
// Stream mapping
|
// Stream mapping
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ InputMediaFile::InputMediaFile(const boost::filesystem::path& p)
|
|||||||
|
|
||||||
_streams.push_back( Stream(avStreamId,
|
_streams.push_back( Stream(avStreamId,
|
||||||
type,
|
type,
|
||||||
|
avStream.getCodecContext().getBitRate(),
|
||||||
avStream.getMetadata().get("language"), // TODO define somewhere else?
|
avStream.getMetadata().get("language"), // TODO define somewhere else?
|
||||||
avStream.getCodecContext().getCodecDesc()
|
avStream.getCodecContext().getCodecDesc()
|
||||||
));
|
));
|
||||||
@@ -90,5 +91,18 @@ InputMediaFile::getStreams(Stream::Type type) const
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Stream&
|
||||||
|
InputMediaFile::getStream(Stream::Id index) const
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(const Stream& stream, _streams)
|
||||||
|
{
|
||||||
|
if (stream.getId() == index)
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
LMS_LOG(MOD_TRANSCODE, SEV_CRIT) << "Cannot find stream index " << index << " in stream map!";
|
||||||
|
throw std::runtime_error("InputMediaFile::getStream, cannot find stream idx");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Transcode
|
} // namespace Transcode
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class InputMediaFile
|
|||||||
const std::vector< CoverArt::CoverArt >& getCovers(void) const { return _covers; }
|
const std::vector< CoverArt::CoverArt >& getCovers(void) const { return _covers; }
|
||||||
|
|
||||||
// Stream handling
|
// Stream handling
|
||||||
|
const Stream& getStream(Stream::Id id) const;
|
||||||
std::vector<Stream> getStreams(Stream::Type type) const;
|
std::vector<Stream> getStreams(Stream::Type type) const;
|
||||||
const std::map<Stream::Type, Stream::Id>& getBestStreams(void) const {return _bestStreams;}
|
const std::map<Stream::Type, Stream::Id>& getBestStreams(void) const {return _bestStreams;}
|
||||||
|
|
||||||
|
|||||||
+50
-16
@@ -1,3 +1,6 @@
|
|||||||
|
|
||||||
|
#include "logger/Logger.hpp"
|
||||||
|
|
||||||
#include "av/InputFormatContext.hpp"
|
#include "av/InputFormatContext.hpp"
|
||||||
|
|
||||||
#include "Parameters.hpp"
|
#include "Parameters.hpp"
|
||||||
@@ -13,30 +16,61 @@ getMimeType(Format format)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Parameters::Parameters(const InputMediaFile& inputMediaFile,
|
Parameters::Parameters(const InputMediaFile& inputMediaFile,
|
||||||
const Format& outputFormat,
|
const Format& outputFormat)
|
||||||
std::size_t audioBitrate)
|
|
||||||
:
|
:
|
||||||
_mediaFile(inputMediaFile),
|
_mediaFile(inputMediaFile),
|
||||||
_outputFormat(outputFormat),
|
_outputFormat(outputFormat)
|
||||||
_outputAudioBitrate(audioBitrate),
|
|
||||||
_outputVideoBitrate(0)
|
|
||||||
{
|
{
|
||||||
// By default, select the best stream indexes
|
// By default, select the best stream indexes
|
||||||
_inputStreams = _mediaFile.getBestStreams();
|
_inputStreams = _mediaFile.getBestStreams();
|
||||||
|
|
||||||
|
// setBitrate(Stream::Audio, 0);
|
||||||
|
// setBitrate(Stream::Video, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Parameters::Parameters(const InputMediaFile& inputMediaFile,
|
std::size_t
|
||||||
const Format& outputFormat,
|
Parameters::setBitrate(Stream::Type type, std::size_t bitrate)
|
||||||
std::size_t audioBitrate,
|
|
||||||
std::size_t videoBitrate)
|
|
||||||
:
|
|
||||||
_mediaFile(inputMediaFile),
|
|
||||||
_outputFormat(outputFormat),
|
|
||||||
_outputAudioBitrate(audioBitrate),
|
|
||||||
_outputVideoBitrate(videoBitrate)
|
|
||||||
{
|
{
|
||||||
// By default, select the best stream indexes
|
// Limit the output bitrate to the input bitrate
|
||||||
_inputStreams = _mediaFile.getBestStreams();
|
if (_inputStreams.find(type) != _inputStreams.end())
|
||||||
|
{
|
||||||
|
const Transcode::Stream& stream = _mediaFile.getStream( _inputStreams[type] );
|
||||||
|
|
||||||
|
LMS_LOG(MOD_TRANSCODE, SEV_DEBUG) << "Stream bitrate = " << stream.getBitrate();
|
||||||
|
|
||||||
|
if (!bitrate || bitrate > stream.getBitrate())
|
||||||
|
{
|
||||||
|
LMS_LOG(MOD_TRANSCODE, SEV_INFO) << "Setting bitrate for stream idx " << _inputStreams[type] << " to input bitrate (" << stream.getBitrate() << ")";
|
||||||
|
_outputBitrate[type] = stream.getBitrate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LMS_LOG(MOD_TRANSCODE, SEV_DEBUG) << "Setting bitrate for stream idx " << _inputStreams[type] << " to " << bitrate;
|
||||||
|
_outputBitrate[type] = bitrate;
|
||||||
|
}
|
||||||
|
return _outputBitrate[type];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LMS_LOG(MOD_TRANSCODE, SEV_DEBUG) << "Cannot find stream type " << type;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t
|
||||||
|
Parameters::getOutputBitrate(Stream::Type type) const
|
||||||
|
{
|
||||||
|
std::map<Stream::Type, std::size_t>::const_iterator it = _outputBitrate.find(type);
|
||||||
|
|
||||||
|
if (it != _inputStreams.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LMS_LOG(MOD_TRANSCODE, SEV_DEBUG) << "output bitrate not set for type " << type;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Transcode
|
} // namespace Transcode
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ class Parameters {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Parameters(const InputMediaFile& InputFile, const Format& outputFormat, std::size_t audioBitrate);
|
Parameters(const InputMediaFile& InputFile, const Format& outputFormat);
|
||||||
Parameters(const InputMediaFile& InputFile, const Format& outputFormat, std::size_t audioBitrate, std::size_t videoBitrate);
|
|
||||||
|
|
||||||
// Modifiers
|
// Modifiers
|
||||||
void setOffset(boost::posix_time::time_duration offset) { _offset = offset; } // Set input offset
|
void setOffset(boost::posix_time::time_duration offset) { _offset = offset; } // Set input offset
|
||||||
void setOutputFormat(const Format& format) { _outputFormat = format; }
|
void setOutputFormat(const Format& format) { _outputFormat = format; }
|
||||||
|
std::size_t setBitrate(Stream::Type type, std::size_t bitrate);
|
||||||
|
|
||||||
// Manually select an input stream to output
|
// Manually select an input stream to output
|
||||||
// There can be only one stream per each type (video, audio, subtitle)
|
// There can be only one stream per each type (video, audio, subtitle)
|
||||||
@@ -34,8 +34,7 @@ class Parameters {
|
|||||||
//Accessors
|
//Accessors
|
||||||
boost::posix_time::time_duration getOffset(void) const {return _offset;}
|
boost::posix_time::time_duration getOffset(void) const {return _offset;}
|
||||||
const Format& getOutputFormat(void) const { return _outputFormat; }
|
const Format& getOutputFormat(void) const { return _outputFormat; }
|
||||||
std::size_t getOutputAudioBitrate(void) const { return _outputAudioBitrate; }
|
std::size_t getOutputBitrate(Stream::Type type) const;
|
||||||
std::size_t getOutputVideoBitrate(void) const { return _outputVideoBitrate; }
|
|
||||||
const InputMediaFile& getInputMediaFile(void) const { return _mediaFile;}
|
const InputMediaFile& getInputMediaFile(void) const { return _mediaFile;}
|
||||||
InputMediaFile& getInputMediaFile(void) { return _mediaFile;}
|
InputMediaFile& getInputMediaFile(void) { return _mediaFile;}
|
||||||
|
|
||||||
@@ -47,8 +46,7 @@ class Parameters {
|
|||||||
boost::posix_time::time_duration _offset; // start input offset
|
boost::posix_time::time_duration _offset; // start input offset
|
||||||
|
|
||||||
Format _outputFormat; // OGA, OGV, etc.
|
Format _outputFormat; // OGA, OGV, etc.
|
||||||
std::size_t _outputAudioBitrate; // 192000, 128000, etc.
|
std::map<Stream::Type, std::size_t> _outputBitrate;
|
||||||
std::size_t _outputVideoBitrate; // 300000, 700000, etc.
|
|
||||||
|
|
||||||
StreamMap _inputStreams;
|
StreamMap _inputStreams;
|
||||||
|
|
||||||
|
|||||||
@@ -20,12 +20,13 @@ class Stream
|
|||||||
|
|
||||||
typedef std::size_t Id;
|
typedef std::size_t Id;
|
||||||
|
|
||||||
Stream(Id id, Type type, const std::string& lang, const std::string& desc)
|
Stream(Id id, Type type, std::size_t bitrate, const std::string& lang, const std::string& desc)
|
||||||
: _id(id), _type(type), _language(lang), _desc(desc) {}
|
: _id(id), _type(type), _bitrate(bitrate), _language(lang), _desc(desc) {}
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
Id getId() const { return _id;}
|
Id getId() const { return _id;}
|
||||||
Type getType() const { return _type;}
|
Type getType() const { return _type;}
|
||||||
|
std::size_t getBitrate() const { return _bitrate;}
|
||||||
const std::string& getLanguage() const { return _language;}
|
const std::string& getLanguage() const { return _language;}
|
||||||
const std::string& getDesc() const { return _desc;}
|
const std::string& getDesc() const { return _desc;}
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ class Stream
|
|||||||
|
|
||||||
Id _id;
|
Id _id;
|
||||||
Type _type;
|
Type _type;
|
||||||
|
std::size_t _bitrate;
|
||||||
std::string _language;
|
std::string _language;
|
||||||
std::string _desc;
|
std::string _desc;
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,9 @@ AudioWidget::playTrack(boost::filesystem::path p)
|
|||||||
Transcode::InputMediaFile inputFile(p);
|
Transcode::InputMediaFile inputFile(p);
|
||||||
|
|
||||||
// TODO get the input stream bitrate and min the result with the desired bitrate
|
// TODO get the input stream bitrate and min the result with the desired bitrate
|
||||||
Transcode::Parameters parameters(inputFile, Transcode::Format::get(Transcode::Format::OGA), bitrate);
|
Transcode::Parameters parameters(inputFile, Transcode::Format::get(Transcode::Format::OGA));
|
||||||
|
|
||||||
|
parameters.setBitrate(Transcode::Stream::Audio, bitrate);
|
||||||
|
|
||||||
_mediaPlayer->load( parameters );
|
_mediaPlayer->load( parameters );
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,10 @@ VideoWidget::playVideo(boost::filesystem::path p)
|
|||||||
else
|
else
|
||||||
encoding = Transcode::Format::FLV;
|
encoding = Transcode::Format::FLV;
|
||||||
|
|
||||||
Transcode::Parameters parameters(inputFile, Transcode::Format::get(encoding), 128000, 500000);
|
Transcode::Parameters parameters(inputFile, Transcode::Format::get(encoding));
|
||||||
|
|
||||||
|
parameters.setBitrate(Transcode::Stream::Audio, 128000); // TODO
|
||||||
|
parameters.setBitrate(Transcode::Stream::Video, 500000); // TODO
|
||||||
|
|
||||||
_mediaPlayer = new VideoMediaPlayerWidget(parameters, this);
|
_mediaPlayer = new VideoMediaPlayerWidget(parameters, this);
|
||||||
_mediaPlayer->close().connect(this, &VideoWidget::backToList);
|
_mediaPlayer->close().connect(this, &VideoWidget::backToList);
|
||||||
|
|||||||
Reference in New Issue
Block a user