Commit 556061ee authored by Adrien Béraud's avatar Adrien Béraud

audioframe: add constructor from format

Change-Id: I1866e82a9b36c8df09f1c7178c472c822948d732
parent 9591971b
......@@ -67,6 +67,43 @@ MediaFrame::reset() noexcept
av_frame_unref(frame_.get());
}
AudioFrame::AudioFrame(const ring::AudioFormat& format, size_t nb_samples)
: MediaFrame()
{
setFormat(format);
if (nb_samples)
reserve(nb_samples);
}
void
AudioFrame::setFormat(const ring::AudioFormat& format)
{
auto d = pointer();
d->channels = format.nb_channels;
d->channel_layout = av_get_default_channel_layout(format.nb_channels);
d->sample_rate = format.sample_rate;
d->format = format.sampleFormat;
}
void
AudioFrame::reserve(size_t nb_samples)
{
if (nb_samples != 0) {
auto d = pointer();
d->nb_samples = nb_samples;
int err;
if ((err = av_frame_get_buffer(d, 0)) < 0) {
throw std::bad_alloc();
}
}
}
void
AudioFrame::mix(const AudioFrame&)
{
RING_ERR("AudioFrame::mix not implemented yet");
}
VideoFrame::~VideoFrame()
{
if (releaseBufferCb_)
......
......@@ -35,14 +35,18 @@ struct AVPacket;
#include <map>
#include <string>
#include <functional>
#include <chrono>
#include <cstdint>
#include <cstdlib>
#if __APPLE__
#import "TargetConditionals.h"
#endif
namespace ring {
struct AudioFormat;
}
namespace DRing {
[[deprecated("Replaced by registerSignalHandlers")]] DRING_PUBLIC
......@@ -88,7 +92,17 @@ protected:
std::unique_ptr<AVFrame, void(*)(AVFrame*)> frame_;
};
class DRING_PUBLIC AudioFrame : public MediaFrame {};
class DRING_PUBLIC AudioFrame : public MediaFrame {
public:
AudioFrame() : MediaFrame() {}
AudioFrame(const ring::AudioFormat& format, size_t nb_samples = 0);
~AudioFrame() {};
void mix(const AudioFrame& o);
private:
void setFormat(const ring::AudioFormat& format);
void reserve(size_t nb_samples = 0);
};
class DRING_PUBLIC VideoFrame : public MediaFrame {
public:
......
......@@ -30,15 +30,14 @@ extern "C" {
namespace ring {
// NOTE 160 samples should the minimum that will be provided (20 ms @ 8kHz),
// barring files that for some obscure reason have smaller packets
AudioFrameResizer::AudioFrameResizer(const AudioFormat& format, int frameSize, std::function<void(std::unique_ptr<AudioFrame>&&)> cb)
: format_(format)
, frameSize_(frameSize)
, cb_(cb)
{
// NOTE 160 samples should the minimum that will be provided (20 ms @ 8kHz),
// barring files that for some obscure reason have smaller packets
queue_ = av_audio_fifo_alloc(format.sampleFormat, format.nb_channels, 160);
}
, queue_(av_audio_fifo_alloc(format.sampleFormat, format.nb_channels, 160))
{}
AudioFrameResizer::~AudioFrameResizer()
{
......@@ -94,24 +93,12 @@ AudioFrameResizer::dequeue()
if (samples() < frameSize_)
return {};
auto frame = std::make_unique<AudioFrame>(format_, frameSize_);
int ret;
auto frame = std::make_unique<AudioFrame>();
auto f = frame->pointer();
f->format = (int)format_.sampleFormat;
f->channels = format_.nb_channels;
f->channel_layout = av_get_default_channel_layout(format_.nb_channels);
f->sample_rate = format_.sample_rate;
f->nb_samples = frameSize_;
if ((ret = av_frame_get_buffer(f, 0)) < 0) {
RING_ERR() << "Failed to allocate audio buffers: " << libav_utils::getError(ret);
return {};
}
if ((ret = av_audio_fifo_read(queue_, reinterpret_cast<void**>(f->data), frameSize_)) < 0) {
if ((ret = av_audio_fifo_read(queue_, reinterpret_cast<void**>(frame->pointer()->data), frameSize_)) < 0) {
RING_ERR() << "Could not read samples from queue: " << libav_utils::getError(ret);
return {};
}
return frame;
}
......
......@@ -301,22 +301,8 @@ size_t AudioBuffer::copy(AudioSample* in, size_t sample_num, size_t pos_out /* =
std::unique_ptr<AudioFrame>
AudioBuffer::toAVFrame() const
{
auto audioFrame = std::make_unique<AudioFrame>();
auto frame = audioFrame->pointer();
frame->format = AV_SAMPLE_FMT_S16;
frame->nb_samples = frames();
frame->channel_layout = av_get_default_channel_layout(channels());
frame->channels = channels();
frame->sample_rate = getSampleRate();
if (av_frame_get_buffer(frame, 0) < 0) {
RING_ERR() << "Failed to allocate audio frame";
av_frame_free(&frame);
return nullptr;
}
interleave(reinterpret_cast<AudioSample*>(frame->data[0]));
auto audioFrame = std::make_unique<AudioFrame>(getFormat(), frames());
interleave(reinterpret_cast<AudioSample*>(audioFrame->pointer()->data[0]));
return audioFrame;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment