implemented audio decoder and some of the audio node functionality
This commit is contained in:
+1
-19
@@ -58,25 +58,7 @@ public:
|
||||
// Necessary for subclassing, it's empty
|
||||
virtual ~Decoder();
|
||||
|
||||
/**
|
||||
* @brief Deleted copy constructor
|
||||
*/
|
||||
Decoder(const Decoder& other) = delete;
|
||||
|
||||
/**
|
||||
* @brief Deleted move constructor
|
||||
*/
|
||||
Decoder(Decoder&& other) = delete;
|
||||
|
||||
/**
|
||||
* @brief Deleted copy assignment
|
||||
*/
|
||||
Decoder& operator=(const Decoder& other) = delete;
|
||||
|
||||
/**
|
||||
* @brief Deleted move assignment
|
||||
*/
|
||||
Decoder& operator=(Decoder&& other) = delete;
|
||||
Q_DISABLE_COPY_MOVE(Decoder)
|
||||
|
||||
virtual QString id() = 0;
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ FramePtr FFmpegDecoder::Retrieve(const rational &timecode, const rational &lengt
|
||||
FramePtr frame_container = Frame::Create();
|
||||
frame_container->set_width(frame_->width);
|
||||
frame_container->set_height(frame_->height);
|
||||
frame_container->set_format(output_fmt_);
|
||||
frame_container->set_format(static_cast<olive::PixelFormat>(output_fmt_));
|
||||
frame_container->set_timestamp(rational(frame_->pts * avstream_->time_base.num, avstream_->time_base.den));
|
||||
frame_container->set_native_timestamp(frame_->pts);
|
||||
frame_container->allocate();
|
||||
|
||||
+26
-5
@@ -28,7 +28,8 @@
|
||||
Frame::Frame() :
|
||||
width_(0),
|
||||
height_(0),
|
||||
format_(-1),
|
||||
format_(olive::PIX_FMT_INVALID),
|
||||
sample_count_(0),
|
||||
timestamp_(0),
|
||||
native_timestamp_(0)
|
||||
{
|
||||
@@ -59,6 +60,16 @@ void Frame::set_height(const int &height)
|
||||
height_ = height;
|
||||
}
|
||||
|
||||
const AudioRenderingParams &Frame::audio_params()
|
||||
{
|
||||
return audio_params_;
|
||||
}
|
||||
|
||||
void Frame::set_audio_params(const AudioRenderingParams ¶ms)
|
||||
{
|
||||
audio_params_ = params;
|
||||
}
|
||||
|
||||
const rational &Frame::timestamp()
|
||||
{
|
||||
return timestamp_;
|
||||
@@ -79,16 +90,26 @@ void Frame::set_native_timestamp(const int64_t ×tamp)
|
||||
native_timestamp_ = timestamp;
|
||||
}
|
||||
|
||||
const int &Frame::format()
|
||||
const olive::PixelFormat &Frame::format()
|
||||
{
|
||||
return format_;
|
||||
}
|
||||
|
||||
void Frame::set_format(const int &format)
|
||||
void Frame::set_format(const olive::PixelFormat &format)
|
||||
{
|
||||
format_ = format;
|
||||
}
|
||||
|
||||
const int &Frame::sample_count()
|
||||
{
|
||||
return sample_count_;
|
||||
}
|
||||
|
||||
void Frame::set_sample_count(const int &audio_sample_count)
|
||||
{
|
||||
sample_count_ = audio_sample_count;
|
||||
}
|
||||
|
||||
uint8_t *Frame::data()
|
||||
{
|
||||
return data_.data();
|
||||
@@ -104,9 +125,9 @@ void Frame::allocate()
|
||||
// Assume this frame is intended to be a video frame
|
||||
if (width_ > 0 && height_ > 0) {
|
||||
data_.resize(PixelService::GetBufferSize(static_cast<olive::PixelFormat>(format_), width_, height_));
|
||||
} else if (sample_count_ > 0) {
|
||||
data_.resize(audio_params_.samples_to_bytes(sample_count_));
|
||||
}
|
||||
|
||||
// FIXME: Audio sample allocation
|
||||
}
|
||||
|
||||
void Frame::destroy()
|
||||
|
||||
+14
-3
@@ -25,6 +25,7 @@
|
||||
#include <QVector>
|
||||
|
||||
#include "common/rational.h"
|
||||
#include "render/audio/audioparams.h"
|
||||
#include "render/pixelformat.h"
|
||||
|
||||
class Frame;
|
||||
@@ -57,6 +58,12 @@ public:
|
||||
const int& height();
|
||||
void set_height(const int& height);
|
||||
|
||||
const AudioRenderingParams& audio_params();
|
||||
void set_audio_params(const AudioRenderingParams& params);
|
||||
|
||||
const int &sample_count();
|
||||
void set_sample_count(const int &sample_count);
|
||||
|
||||
/**
|
||||
* @brief Get frame's timestamp.
|
||||
*
|
||||
@@ -75,8 +82,8 @@ public:
|
||||
*
|
||||
* Currently this will either be an olive::PixelFormat (video) or an olive::SampleFormat (audio).
|
||||
*/
|
||||
const int& format();
|
||||
void set_format(const int& format);
|
||||
const olive::PixelFormat& format();
|
||||
void set_format(const olive::PixelFormat& format);
|
||||
|
||||
/**
|
||||
* @brief Get the data buffer of this frame
|
||||
@@ -107,7 +114,11 @@ private:
|
||||
|
||||
int height_;
|
||||
|
||||
int format_;
|
||||
olive::PixelFormat format_;
|
||||
|
||||
AudioRenderingParams audio_params_;
|
||||
|
||||
int sample_count_;
|
||||
|
||||
QVector<uint8_t> data_;
|
||||
|
||||
|
||||
@@ -61,12 +61,12 @@ bool WaveOutput::open()
|
||||
write_int<int32_t>(&file_, params_.sample_rate());
|
||||
|
||||
// Bytes per second
|
||||
write_int<int32_t>(&file_, (params_.sample_rate() * params_.bits_per_sample() * params_.channel_count())/8);
|
||||
write_int<int32_t>(&file_, params_.samples_to_bytes(params_.sample_rate()));
|
||||
|
||||
// Bytes per sample
|
||||
write_int<int16_t>(&file_, static_cast<int16_t>((params_.bits_per_sample() * params_.channel_count())/8));
|
||||
write_int<int16_t>(&file_, static_cast<int16_t>(params_.samples_to_bytes(1)));
|
||||
|
||||
// Bits per sample
|
||||
// Bits per sample per channel
|
||||
write_int<int16_t>(&file_, static_cast<int16_t>(params_.bits_per_sample()));
|
||||
|
||||
// Data chunk header
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
AudioInput::AudioInput()
|
||||
{
|
||||
|
||||
samples_output_ = new NodeOutput("samples_out");
|
||||
samples_output_->set_data_type(NodeInput::kSamples);
|
||||
AddParameter(samples_output_);
|
||||
}
|
||||
|
||||
QString AudioInput::Name()
|
||||
@@ -24,3 +26,23 @@ QString AudioInput::Description()
|
||||
{
|
||||
return tr("Import an audio footage stream.");
|
||||
}
|
||||
|
||||
QVariant AudioInput::Value(NodeOutput *output, const rational &in, const rational &out)
|
||||
{
|
||||
if (output == samples_output_) {
|
||||
// Make sure decoder is set up
|
||||
if (!SetupDecoder()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Retrieve audio samples from decoder
|
||||
frame_ = decoder_->Retrieve(in, out - in);
|
||||
|
||||
QByteArray samples;
|
||||
samples.resize(frame_->audio_params().samples_to_bytes(frame_->sample_count()));
|
||||
memcpy(samples.data(), frame_->data(), static_cast<size_t>(samples.size()));
|
||||
return samples;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,12 @@ public:
|
||||
virtual QString id() override;
|
||||
virtual QString Category() override;
|
||||
virtual QString Description() override;
|
||||
|
||||
protected:
|
||||
virtual QVariant Value(NodeOutput* output, const rational& in, const rational& out) override;
|
||||
|
||||
private:
|
||||
NodeOutput* samples_output_;
|
||||
};
|
||||
|
||||
#endif // AUDIOINPUT_H
|
||||
|
||||
@@ -35,7 +35,7 @@ void MediaInput::Release()
|
||||
decoder_ = nullptr;
|
||||
}
|
||||
|
||||
StreamPtr MediaInput::Footage()
|
||||
StreamPtr MediaInput::footage()
|
||||
{
|
||||
return footage_input_->get_value(0).value<StreamPtr>();
|
||||
}
|
||||
@@ -52,7 +52,7 @@ bool MediaInput::SetupDecoder()
|
||||
}
|
||||
|
||||
// Get currently selected Footage
|
||||
StreamPtr stream = Footage();
|
||||
StreamPtr stream = footage();
|
||||
|
||||
// If no footage is selected, return nothing
|
||||
if (stream == nullptr) {
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
|
||||
virtual void Release() override;
|
||||
|
||||
StreamPtr Footage();
|
||||
StreamPtr footage();
|
||||
void SetFootage(StreamPtr f);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -96,10 +96,15 @@ QVariant VideoInput::Value(NodeOutput *output, const rational &in, const rationa
|
||||
{
|
||||
Q_UNUSED(out)
|
||||
|
||||
// FIXME: Hardcoded value
|
||||
bool alpha_is_associated = false;
|
||||
|
||||
if (output == texture_output_) {
|
||||
if (footage() == nullptr
|
||||
|| (footage()->type() != Stream::kVideo && footage()->type() != Stream::kImage)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: Hardcoded value
|
||||
bool alpha_is_associated = false;
|
||||
|
||||
// Find the current Renderer instance
|
||||
RenderInstance* renderer = VideoRendererProcessor::CurrentInstance();
|
||||
|
||||
@@ -124,7 +129,7 @@ QVariant VideoInput::Value(NodeOutput *output, const rational &in, const rationa
|
||||
}
|
||||
|
||||
if (color_processor_ == nullptr) {
|
||||
QString colorspace = std::static_pointer_cast<VideoStream>(Footage())->colorspace();
|
||||
QString colorspace = std::static_pointer_cast<VideoStream>(footage())->colorspace();
|
||||
if (colorspace.isEmpty()) {
|
||||
// FIXME: Should use Footage() to find the Project* it belongs to instead of this
|
||||
colorspace = olive::core.GetActiveProject()->default_input_colorspace();
|
||||
|
||||
@@ -52,7 +52,14 @@ int AudioRenderingParams::time_to_bytes(const rational &time) const
|
||||
{
|
||||
Q_ASSERT(is_valid());
|
||||
|
||||
return qFloor(time.toDouble() * sample_rate()) * channel_count() * bytes_per_sample();
|
||||
return qFloor(time.toDouble() * sample_rate()) * channel_count() * bytes_per_sample_per_channel();
|
||||
}
|
||||
|
||||
int AudioRenderingParams::samples_to_bytes(const int &samples) const
|
||||
{
|
||||
Q_ASSERT(is_valid());
|
||||
|
||||
return samples * channel_count() * bytes_per_sample_per_channel();
|
||||
}
|
||||
|
||||
int AudioRenderingParams::channel_count() const
|
||||
@@ -60,7 +67,7 @@ int AudioRenderingParams::channel_count() const
|
||||
return av_get_channel_layout_nb_channels(channel_layout());
|
||||
}
|
||||
|
||||
int AudioRenderingParams::bytes_per_sample() const
|
||||
int AudioRenderingParams::bytes_per_sample_per_channel() const
|
||||
{
|
||||
switch (format_) {
|
||||
case olive::SAMPLE_FMT_U8:
|
||||
@@ -83,7 +90,7 @@ int AudioRenderingParams::bytes_per_sample() const
|
||||
|
||||
int AudioRenderingParams::bits_per_sample() const
|
||||
{
|
||||
return bytes_per_sample() * 8;
|
||||
return bytes_per_sample_per_channel() * 8;
|
||||
}
|
||||
|
||||
bool AudioRenderingParams::is_valid() const
|
||||
|
||||
@@ -29,8 +29,9 @@ public:
|
||||
AudioRenderingParams(const AudioParams& params, const olive::SampleFormat& format);
|
||||
|
||||
int time_to_bytes(const rational& time) const;
|
||||
int samples_to_bytes(const int& samples) const;
|
||||
int channel_count() const;
|
||||
int bytes_per_sample() const;
|
||||
int bytes_per_sample_per_channel() const;
|
||||
int bits_per_sample() const;
|
||||
bool is_valid() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user