implemented audio decoder and some of the audio node functionality

This commit is contained in:
itsmattkc
2019-10-24 21:33:46 +11:00
parent af702835da
commit 076f2699c5
12 changed files with 98 additions and 43 deletions
+1 -19
View File
@@ -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;
+1 -1
View File
@@ -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
View File
@@ -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 &params)
{
audio_params_ = params;
}
const rational &Frame::timestamp()
{
return timestamp_;
@@ -79,16 +90,26 @@ void Frame::set_native_timestamp(const int64_t &timestamp)
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
View File
@@ -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_;
+3 -3
View File
@@ -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
+23 -1
View File
@@ -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;
}
+6
View File
@@ -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
+2 -2
View File
@@ -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) {
+1 -1
View File
@@ -35,7 +35,7 @@ public:
virtual void Release() override;
StreamPtr Footage();
StreamPtr footage();
void SetFootage(StreamPtr f);
protected:
+9 -4
View File
@@ -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();
+10 -3
View File
@@ -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
+2 -1
View File
@@ -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;