From dd2e1873446e2019a3020e9d62c6efc29b43d930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20M=C3=BCller?= Date: Fri, 8 Jun 2018 23:10:52 +0200 Subject: Audaspace: add support for latest ffmpeg. --- extern/audaspace/plugins/ffmpeg/FFMPEG.cpp | 2 + extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp | 124 ++++++++++--- extern/audaspace/plugins/ffmpeg/FFMPEGReader.h | 5 + extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp | 216 +++++++++++++++++------ extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h | 13 +- 5 files changed, 274 insertions(+), 86 deletions(-) (limited to 'extern/audaspace') 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 #include +#include } 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) : m_pkgbuf(), + m_codecCtx(nullptr), + m_frame(nullptr), m_membuffer(buffer), m_membufferpos(0) { - m_membuf = reinterpret_cast(av_malloc(FF_MIN_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE)); + m_membuf = reinterpret_cast(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) : 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 @@ -79,6 +79,11 @@ private: */ AVCodecContext* m_codecCtx; + /** + * The AVFrame structure for using ffmpeg. + */ + AVFrame* m_frame; + /** * The AVIOContext to read the data from. */ 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), reinterpret_cast(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), m_input_buffer.getSize(), 0) < 0) + if(avcodec_fill_audio_frame(m_frame, m_specs.channels, m_codecCtx->sample_fmt, reinterpret_cast(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(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. -- cgit v1.2.3