Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Müller <nexyon@gmail.com>2018-06-09 00:10:52 +0300
committerJörg Müller <nexyon@gmail.com>2018-06-09 00:11:16 +0300
commitdd2e1873446e2019a3020e9d62c6efc29b43d930 (patch)
treeb80355531f37ab9f30967b7d73df2974206cceb7 /extern/audaspace
parent528dc6440bb41e6cbfeea62756ba5ae5debcd27f (diff)
Audaspace: add support for latest ffmpeg.
Diffstat (limited to 'extern/audaspace')
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEG.cpp2
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp124
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGReader.h5
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp216
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h13
5 files changed, 274 insertions, 86 deletions
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp
index 7f9b762f816..3ffe963b2b9 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp
@@ -23,7 +23,9 @@ AUD_NAMESPACE_BEGIN
FFMPEG::FFMPEG()
{
+#if LIBAVCODEC_VERSION_MAJOR < 58
av_register_all();
+#endif
}
void FFMPEG::registerPlugin()
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
index 6b79cc5abfd..2da84ce0d4c 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
@@ -22,37 +22,37 @@
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avio.h>
+#include <libavutil/avutil.h>
}
AUD_NAMESPACE_BEGIN
+#if LIBAVCODEC_VERSION_MAJOR < 58
+#define FFMPEG_OLD_CODE
+#endif
+
int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
{
- AVFrame* frame = nullptr;
+ int buf_size = buffer.getSize();
+ int buf_pos = 0;
+
+#ifdef FFMPEG_OLD_CODE
int got_frame;
int read_length;
uint8_t* orig_data = packet.data;
int orig_size = packet.size;
- int buf_size = buffer.getSize();
- int buf_pos = 0;
-
while(packet.size > 0)
{
got_frame = 0;
- if(!frame)
- frame = av_frame_alloc();
- else
- av_frame_unref(frame);
-
- read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet);
+ read_length = avcodec_decode_audio4(m_codecCtx, m_frame, &got_frame, &packet);
if(read_length < 0)
break;
if(got_frame)
{
- int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, frame->nb_samples, m_codecCtx->sample_fmt, 1);
+ int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, m_frame->nb_samples, m_codecCtx->sample_fmt, 1);
if(buf_size - buf_pos < data_size)
{
@@ -62,18 +62,18 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
if(m_tointerleave)
{
- int single_size = data_size / m_codecCtx->channels / frame->nb_samples;
+ int single_size = data_size / m_codecCtx->channels / m_frame->nb_samples;
for(int channel = 0; channel < m_codecCtx->channels; channel++)
{
- for(int i = 0; i < frame->nb_samples; i++)
+ for(int i = 0; i < m_frame->nb_samples; i++)
{
std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
- frame->data[channel] + i * single_size, single_size);
+ m_frame->data[channel] + i * single_size, single_size);
}
}
}
else
- std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos, frame->data[0], data_size);
+ std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos, m_frame->data[0], data_size);
buf_pos += data_size;
}
@@ -83,7 +83,42 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
packet.data = orig_data;
packet.size = orig_size;
- av_free(frame);
+#else
+ avcodec_send_packet(m_codecCtx, &packet);
+
+ while(true)
+ {
+ auto ret = avcodec_receive_frame(m_codecCtx, m_frame);
+
+ if(ret != 0)
+ break;
+
+ int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, m_frame->nb_samples, m_codecCtx->sample_fmt, 1);
+
+ if(buf_size - buf_pos < data_size)
+ {
+ buffer.resize(buf_size + data_size, true);
+ buf_size += data_size;
+ }
+
+ if(m_tointerleave)
+ {
+ int single_size = data_size / m_codecCtx->channels / m_frame->nb_samples;
+ for(int channel = 0; channel < m_codecCtx->channels; channel++)
+ {
+ for(int i = 0; i < m_frame->nb_samples; i++)
+ {
+ std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
+ m_frame->data[channel] + i * single_size, single_size);
+ }
+ }
+ }
+ else
+ std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos, m_frame->data[0], data_size);
+
+ buf_pos += data_size;
+ }
+#endif
return buf_pos;
}
@@ -101,7 +136,11 @@ void FFMPEGReader::init()
for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
{
+#ifdef FFMPEG_OLD_CODE
if((m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+#else
+ if((m_formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
+#endif
&& (m_stream < 0))
{
m_stream=i;
@@ -112,12 +151,34 @@ void FFMPEGReader::init()
if(m_stream == -1)
AUD_THROW(FileException, "File couldn't be read, no audio stream found by ffmpeg.");
- m_codecCtx = m_formatCtx->streams[m_stream]->codec;
-
// get a decoder and open it
- AVCodec* aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
+#ifndef FFMPEG_OLD_CODE
+ AVCodec* aCodec = avcodec_find_decoder(m_formatCtx->streams[m_stream]->codecpar->codec_id);
+
if(!aCodec)
AUD_THROW(FileException, "File couldn't be read, no decoder found with ffmpeg.");
+#endif
+
+ m_frame = av_frame_alloc();
+
+ if(!m_frame)
+ AUD_THROW(FileException, "File couldn't be read, ffmpeg frame couldn't be allocated.");
+
+#ifdef FFMPEG_OLD_CODE
+ m_codecCtx = m_formatCtx->streams[m_stream]->codec;
+
+ AVCodec* aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
+#else
+ m_codecCtx = avcodec_alloc_context3(aCodec);
+#endif
+
+ if(!m_codecCtx)
+ AUD_THROW(FileException, "File couldn't be read, ffmpeg context couldn't be allocated.");
+
+#ifndef FFMPEG_OLD_CODE
+ if(avcodec_parameters_to_context(m_codecCtx, m_formatCtx->streams[m_stream]->codecpar) < 0)
+ AUD_THROW(FileException, "File couldn't be read, ffmpeg decoder parameters couldn't be copied to decoder context.");
+#endif
if(avcodec_open2(m_codecCtx, aCodec, nullptr) < 0)
AUD_THROW(FileException, "File couldn't be read, ffmpeg codec couldn't be opened.");
@@ -157,6 +218,8 @@ void FFMPEGReader::init()
FFMPEGReader::FFMPEGReader(std::string filename) :
m_pkgbuf(),
m_formatCtx(nullptr),
+ m_codecCtx(nullptr),
+ m_frame(nullptr),
m_aviocontext(nullptr),
m_membuf(nullptr)
{
@@ -177,12 +240,14 @@ FFMPEGReader::FFMPEGReader(std::string filename) :
FFMPEGReader::FFMPEGReader(std::shared_ptr<Buffer> buffer) :
m_pkgbuf(),
+ m_codecCtx(nullptr),
+ m_frame(nullptr),
m_membuffer(buffer),
m_membufferpos(0)
{
- m_membuf = reinterpret_cast<data_t*>(av_malloc(FF_MIN_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE));
+ m_membuf = reinterpret_cast<data_t*>(av_malloc(AV_INPUT_BUFFER_MIN_SIZE + AV_INPUT_BUFFER_PADDING_SIZE));
- m_aviocontext = avio_alloc_context(m_membuf, FF_MIN_BUFFER_SIZE, 0, this, read_packet, nullptr, seek_packet);
+ m_aviocontext = avio_alloc_context(m_membuf, AV_INPUT_BUFFER_MIN_SIZE, 0, this, read_packet, nullptr, seek_packet);
if(!m_aviocontext)
{
@@ -212,7 +277,14 @@ FFMPEGReader::FFMPEGReader(std::shared_ptr<Buffer> buffer) :
FFMPEGReader::~FFMPEGReader()
{
+ if(m_frame)
+ av_frame_free(&m_frame);
+#ifdef FFMPEG_OLD_CODE
avcodec_close(m_codecCtx);
+#else
+ if(m_codecCtx)
+ avcodec_free_context(&m_codecCtx);
+#endif
avformat_close_input(&m_formatCtx);
}
@@ -312,7 +384,7 @@ void FFMPEGReader::seek(int position)
}
}
}
- av_free_packet(&packet);
+ av_packet_unref(&packet);
}
}
else
@@ -343,7 +415,7 @@ Specs FFMPEGReader::getSpecs() const
void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
{
// read packages and decode them
- AVPacket packet;
+ AVPacket packet = {};
int data_size = 0;
int pkgbuf_pos;
int left = length;
@@ -359,7 +431,7 @@ void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
data_size = std::min(pkgbuf_pos, left * sample_size);
m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
- left -= data_size/sample_size;
+ left -= data_size / sample_size;
}
// for each frame read as long as there isn't enough data already
@@ -375,9 +447,9 @@ void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
data_size = std::min(pkgbuf_pos, left * sample_size);
m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
- left -= data_size/sample_size;
+ left -= data_size / sample_size;
}
- av_free_packet(&packet);
+ av_packet_unref(&packet);
}
// read more data than necessary?
if(pkgbuf_pos > data_size)
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
index e2ae959912d..a69ac7709c8 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
@@ -80,6 +80,11 @@ private:
AVCodecContext* m_codecCtx;
/**
+ * The AVFrame structure for using ffmpeg.
+ */
+ AVFrame* m_frame;
+
+ /**
* The AVIOContext to read the data from.
*/
AVIOContext* m_aviocontext;
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
index f79f0f7fc6b..09b70897c31 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
@@ -27,6 +27,10 @@ extern "C" {
AUD_NAMESPACE_BEGIN
+#if LIBAVCODEC_VERSION_MAJOR < 58
+#define FFMPEG_OLD_CODE
+#endif
+
void FFMPEGWriter::encode()
{
sample_t* data = m_input_buffer.getBuffer();
@@ -58,82 +62,106 @@ void FFMPEGWriter::encode()
if(m_input_size)
m_convert(reinterpret_cast<data_t*>(data), reinterpret_cast<data_t*>(data), m_input_samples * m_specs.channels);
- AVPacket packet;
-
- packet.data = nullptr;
- packet.size = 0;
+#ifdef FFMPEG_OLD_CODE
+ m_packet->data = nullptr;
+ m_packet->size = 0;
- av_init_packet(&packet);
+ av_init_packet(m_packet);
- AVFrame* frame = av_frame_alloc();
- av_frame_unref(frame);
+ av_frame_unref(m_frame);
int got_packet;
+#endif
- frame->nb_samples = m_input_samples;
- frame->format = m_codecCtx->sample_fmt;
- frame->channel_layout = m_codecCtx->channel_layout;
+ m_frame->nb_samples = m_input_samples;
+ m_frame->format = m_codecCtx->sample_fmt;
+ m_frame->channel_layout = m_codecCtx->channel_layout;
- if(avcodec_fill_audio_frame(frame, m_specs.channels, m_codecCtx->sample_fmt, reinterpret_cast<data_t*>(data), m_input_buffer.getSize(), 0) < 0)
+ if(avcodec_fill_audio_frame(m_frame, m_specs.channels, m_codecCtx->sample_fmt, reinterpret_cast<data_t*>(data), m_input_buffer.getSize(), 0) < 0)
AUD_THROW(FileException, "File couldn't be written, filling the audio frame failed with ffmpeg.");
AVRational sample_time = { 1, static_cast<int>(m_specs.rate) };
- frame->pts = av_rescale_q(m_position - m_input_samples, m_codecCtx->time_base, sample_time);
+ m_frame->pts = av_rescale_q(m_position - m_input_samples, m_codecCtx->time_base, sample_time);
- if(avcodec_encode_audio2(m_codecCtx, &packet, frame, &got_packet))
+#ifdef FFMPEG_OLD_CODE
+ if(avcodec_encode_audio2(m_codecCtx, m_packet, m_frame, &got_packet))
{
- av_frame_free(&frame);
AUD_THROW(FileException, "File couldn't be written, audio encoding failed with ffmpeg.");
}
if(got_packet)
{
- packet.flags |= AV_PKT_FLAG_KEY;
- packet.stream_index = m_stream->index;
- if(av_write_frame(m_formatCtx, &packet) < 0)
+ m_packet->flags |= AV_PKT_FLAG_KEY;
+ m_packet->stream_index = m_stream->index;
+ if(av_write_frame(m_formatCtx, m_packet) < 0)
{
- av_free_packet(&packet);
- av_frame_free(&frame);
+ av_free_packet(m_packet);
AUD_THROW(FileException, "Frame couldn't be writen to the file with ffmpeg.");
}
- av_free_packet(&packet);
+ av_free_packet(m_packet);
}
+#else
+ if(avcodec_send_frame(m_codecCtx, m_frame) < 0)
+ AUD_THROW(FileException, "File couldn't be written, audio encoding failed with ffmpeg.");
+
+ while(avcodec_receive_packet(m_codecCtx, m_packet) == 0)
+ {
+ m_packet->stream_index = m_stream->index;
- av_frame_free(&frame);
+ if(av_write_frame(m_formatCtx, m_packet) < 0)
+ AUD_THROW(FileException, "Frame couldn't be writen to the file with ffmpeg.");
+ }
+#endif
}
void FFMPEGWriter::close()
{
+#ifdef FFMPEG_OLD_CODE
int got_packet = true;
while(got_packet)
{
- AVPacket packet;
+ m_packet->data = nullptr;
+ m_packet->size = 0;
- packet.data = nullptr;
- packet.size = 0;
+ av_init_packet(m_packet);
- av_init_packet(&packet);
-
- if(avcodec_encode_audio2(m_codecCtx, &packet, nullptr, &got_packet))
+ if(avcodec_encode_audio2(m_codecCtx, m_packet, nullptr, &got_packet))
AUD_THROW(FileException, "File end couldn't be written, audio encoding failed with ffmpeg.");
if(got_packet)
{
- packet.flags |= AV_PKT_FLAG_KEY;
- packet.stream_index = m_stream->index;
- if(av_write_frame(m_formatCtx, &packet))
+ m_packet->flags |= AV_PKT_FLAG_KEY;
+ m_packet->stream_index = m_stream->index;
+ if(av_write_frame(m_formatCtx, m_packet))
{
- av_free_packet(&packet);
+ av_free_packet(m_packet);
AUD_THROW(FileException, "Final frames couldn't be writen to the file with ffmpeg.");
}
- av_free_packet(&packet);
+ av_free_packet(m_packet);
}
}
+#else
+ if(avcodec_send_frame(m_codecCtx, nullptr) < 0)
+ AUD_THROW(FileException, "File couldn't be written, audio encoding failed with ffmpeg.");
+
+ while(avcodec_receive_packet(m_codecCtx, m_packet) == 0)
+ {
+ m_packet->stream_index = m_stream->index;
+
+ if(av_write_frame(m_formatCtx, m_packet) < 0)
+ AUD_THROW(FileException, "Frame couldn't be writen to the file with ffmpeg.");
+ }
+#endif
}
FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate) :
m_position(0),
m_specs(specs),
+ m_formatCtx(nullptr),
+ m_codecCtx(nullptr),
+ m_stream(nullptr),
+ m_packet(nullptr),
+ m_frame(nullptr),
m_input_samples(0),
m_deinterleave(false)
{
@@ -142,75 +170,105 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
if(avformat_alloc_output_context2(&m_formatCtx, nullptr, formats[format], filename.c_str()) < 0)
AUD_THROW(FileException, "File couldn't be written, format couldn't be found with ffmpeg.");
- m_outputFmt = m_formatCtx->oformat;
+ AVOutputFormat* outputFmt = m_formatCtx->oformat;
- if(!m_outputFmt) {
+ if(!outputFmt) {
avformat_free_context(m_formatCtx);
AUD_THROW(FileException, "File couldn't be written, output format couldn't be found with ffmpeg.");
}
- m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+ outputFmt->audio_codec = AV_CODEC_ID_NONE;
switch(codec)
{
case CODEC_AAC:
- m_outputFmt->audio_codec = AV_CODEC_ID_AAC;
+ outputFmt->audio_codec = AV_CODEC_ID_AAC;
break;
case CODEC_AC3:
- m_outputFmt->audio_codec = AV_CODEC_ID_AC3;
+ outputFmt->audio_codec = AV_CODEC_ID_AC3;
break;
case CODEC_FLAC:
- m_outputFmt->audio_codec = AV_CODEC_ID_FLAC;
+ outputFmt->audio_codec = AV_CODEC_ID_FLAC;
break;
case CODEC_MP2:
- m_outputFmt->audio_codec = AV_CODEC_ID_MP2;
+ outputFmt->audio_codec = AV_CODEC_ID_MP2;
break;
case CODEC_MP3:
- m_outputFmt->audio_codec = AV_CODEC_ID_MP3;
+ outputFmt->audio_codec = AV_CODEC_ID_MP3;
break;
case CODEC_OPUS:
- m_outputFmt->audio_codec = AV_CODEC_ID_OPUS;
+ outputFmt->audio_codec = AV_CODEC_ID_OPUS;
break;
case CODEC_PCM:
switch(specs.format)
{
case FORMAT_U8:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_U8;
+ outputFmt->audio_codec = AV_CODEC_ID_PCM_U8;
break;
case FORMAT_S16:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
+ outputFmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
break;
case FORMAT_S24:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S24LE;
+ outputFmt->audio_codec = AV_CODEC_ID_PCM_S24LE;
break;
case FORMAT_S32:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S32LE;
+ outputFmt->audio_codec = AV_CODEC_ID_PCM_S32LE;
break;
case FORMAT_FLOAT32:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F32LE;
+ outputFmt->audio_codec = AV_CODEC_ID_PCM_F32LE;
break;
case FORMAT_FLOAT64:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F64LE;
+ outputFmt->audio_codec = AV_CODEC_ID_PCM_F64LE;
break;
default:
- m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+ outputFmt->audio_codec = AV_CODEC_ID_NONE;
break;
}
break;
case CODEC_VORBIS:
- m_outputFmt->audio_codec = AV_CODEC_ID_VORBIS;
+ outputFmt->audio_codec = AV_CODEC_ID_VORBIS;
break;
default:
- m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+ outputFmt->audio_codec = AV_CODEC_ID_NONE;
+ break;
+ }
+
+ uint64_t channel_layout = 0;
+
+ switch(m_specs.channels)
+ {
+ case CHANNELS_MONO:
+ channel_layout = AV_CH_LAYOUT_MONO;
+ break;
+ case CHANNELS_STEREO:
+ channel_layout = AV_CH_LAYOUT_STEREO;
+ break;
+ case CHANNELS_STEREO_LFE:
+ channel_layout = AV_CH_LAYOUT_2POINT1;
+ break;
+ case CHANNELS_SURROUND4:
+ channel_layout = AV_CH_LAYOUT_QUAD;
+ break;
+ case CHANNELS_SURROUND5:
+ channel_layout = AV_CH_LAYOUT_5POINT0_BACK;
+ break;
+ case CHANNELS_SURROUND51:
+ channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
+ break;
+ case CHANNELS_SURROUND61:
+ channel_layout = AV_CH_LAYOUT_6POINT1_BACK;
+ break;
+ case CHANNELS_SURROUND71:
+ channel_layout = AV_CH_LAYOUT_7POINT1;
break;
}
try
{
- if(m_outputFmt->audio_codec == AV_CODEC_ID_NONE)
+ if(outputFmt->audio_codec == AV_CODEC_ID_NONE)
AUD_THROW(FileException, "File couldn't be written, audio codec not found with ffmpeg.");
- AVCodec* codec = avcodec_find_encoder(m_outputFmt->audio_codec);
+ AVCodec* codec = avcodec_find_encoder(outputFmt->audio_codec);
if(!codec)
AUD_THROW(FileException, "File couldn't be written, audio encoder couldn't be found with ffmpeg.");
@@ -220,7 +278,14 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
m_stream->id = m_formatCtx->nb_streams - 1;
+#ifdef FFMPEG_OLD_CODE
m_codecCtx = m_stream->codec;
+#else
+ m_codecCtx = avcodec_alloc_context3(codec);
+#endif
+
+ if(!m_codecCtx)
+ AUD_THROW(FileException, "File couldn't be written, context creation failed with ffmpeg.");
switch(m_specs.format)
{
@@ -247,7 +312,7 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
}
if(m_formatCtx->oformat->flags & AVFMT_GLOBALHEADER)
- m_codecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+ m_codecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
bool format_supported = false;
@@ -328,9 +393,13 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
m_specs.rate = m_codecCtx->sample_rate;
- m_codecCtx->codec_id = m_outputFmt->audio_codec;
+#ifdef FFMPEG_OLD_CODE
+ m_codecCtx->codec_id = outputFmt->audio_codec;
+#endif
+
m_codecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
m_codecCtx->bit_rate = bitrate;
+ m_codecCtx->channel_layout = channel_layout;
m_codecCtx->channels = m_specs.channels;
m_stream->time_base.num = m_codecCtx->time_base.num = 1;
m_stream->time_base.den = m_codecCtx->time_base.den = m_codecCtx->sample_rate;
@@ -338,6 +407,11 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
if(avcodec_open2(m_codecCtx, codec, nullptr) < 0)
AUD_THROW(FileException, "File couldn't be written, encoder couldn't be opened with ffmpeg.");
+#ifndef FFMPEG_OLD_CODE
+ if(avcodec_parameters_from_context(m_stream->codecpar, m_codecCtx) < 0)
+ AUD_THROW(FileException, "File couldn't be written, codec parameters couldn't be copied to the context.");
+#endif
+
int samplesize = std::max(int(AUD_SAMPLE_SIZE(m_specs)), AUD_DEVICE_SAMPLE_SIZE(m_specs));
if((m_input_size = m_codecCtx->frame_size))
@@ -346,13 +420,26 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
if(avio_open(&m_formatCtx->pb, filename.c_str(), AVIO_FLAG_WRITE))
AUD_THROW(FileException, "File couldn't be written, file opening failed with ffmpeg.");
- avformat_write_header(m_formatCtx, nullptr);
+ if(avformat_write_header(m_formatCtx, nullptr) < 0)
+ AUD_THROW(FileException, "File couldn't be written, writing the header failed.");
}
catch(Exception&)
{
+#ifndef FFMPEG_OLD_CODE
+ if(m_codecCtx)
+ avcodec_free_context(&m_codecCtx);
+#endif
avformat_free_context(m_formatCtx);
throw;
}
+
+#ifdef FFMPEG_OLD_CODE
+ m_packet = new AVPacket({});
+#else
+ m_packet = av_packet_alloc();
+#endif
+
+ m_frame = av_frame_alloc();
}
FFMPEGWriter::~FFMPEGWriter()
@@ -365,9 +452,26 @@ FFMPEGWriter::~FFMPEGWriter()
av_write_trailer(m_formatCtx);
+ if(m_frame)
+ av_frame_free(&m_frame);
+
+ if(m_packet)
+ {
+#ifdef FFMPEG_OLD_CODE
+ delete m_packet;
+#else
+ av_packet_free(&m_packet);
+#endif
+ }
+
+#ifdef FFMPEG_OLD_CODE
avcodec_close(m_codecCtx);
+#else
+ if(m_codecCtx)
+ avcodec_free_context(&m_codecCtx);
+#endif
- avio_close(m_formatCtx->pb);
+ avio_closep(&m_formatCtx->pb);
avformat_free_context(m_formatCtx);
}
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h
index 690185deb64..c22f479d83c 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h
@@ -66,14 +66,19 @@ private:
AVCodecContext* m_codecCtx;
/**
- * The AVOutputFormat structure for using ffmpeg.
+ * The AVStream structure for using ffmpeg.
*/
- AVOutputFormat* m_outputFmt;
+ AVStream* m_stream;
/**
- * The AVStream structure for using ffmpeg.
+ * The AVPacket structure for using ffmpeg.
*/
- AVStream* m_stream;
+ AVPacket* m_packet;
+
+ /**
+ * The AVFrame structure for using ffmpeg.
+ */
+ AVFrame* m_frame;
/**
* The input buffer for the format converted data before encoding.