commit dcc3c465bb69d884faaac88dacf407a144adac4a
parent ac482d779e9c591adea53929070dbc9294929cf5
Author: Alexander Kojevnikov <alexander@kojevnikov.com>
Date: Sun, 26 Nov 2017 15:27:08 -0800
Fix FFmpeg warnings about using AVStream->codec
Diffstat:
2 files changed, 49 insertions(+), 38 deletions(-)
diff --git a/configure.ac b/configure.ac
@@ -46,8 +46,8 @@ AM_COND_IF([USE_VALGRIND], [use_valgrind=yes], [use_valgrind=no])
AC_CHECK_LIB(m, log10)
-PKG_CHECK_MODULES(AVFORMAT, [libavformat >= 53.17])
-PKG_CHECK_MODULES(AVCODEC, [libavcodec >= 55.46])
+PKG_CHECK_MODULES(AVFORMAT, [libavformat >= 57.33.100])
+PKG_CHECK_MODULES(AVCODEC, [libavcodec >= 57.33.100])
PKG_CHECK_MODULES(AVUTIL, [libavutil >= 51.17])
AM_OPTIONS_WXCONFIG
diff --git a/src/spek-audio.cc b/src/spek-audio.cc
@@ -14,9 +14,9 @@ class AudioFileImpl : public AudioFile
{
public:
AudioFileImpl(
- AudioError error, AVFormatContext *format_context, int audio_stream,
- const std::string& codec_name, int bit_rate, int sample_rate, int bits_per_sample,
- int streams, int channels, double duration
+ AudioError error, AVFormatContext *format_context, AVCodecContext *codec_context,
+ int audio_stream, const std::string& codec_name, int bit_rate, int sample_rate,
+ int bits_per_sample, int streams, int channels, double duration
);
~AudioFileImpl() override;
void start(int channel, int samples) override;
@@ -38,6 +38,7 @@ public:
private:
AudioError error;
AVFormatContext *format_context;
+ AVCodecContext *codec_context;
int audio_stream;
std::string codec_name;
int bit_rate;
@@ -93,7 +94,7 @@ std::unique_ptr<AudioFile> Audio::open(const std::string& file_name, int stream)
int streams = 0;
if (!error) {
for (unsigned int i = 0; i < format_context->nb_streams; i++) {
- if (format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ if (format_context->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
if (stream == streams) {
audio_stream = i;
}
@@ -106,12 +107,12 @@ std::unique_ptr<AudioFile> Audio::open(const std::string& file_name, int stream)
}
AVStream *avstream = nullptr;
- AVCodecContext *codec_context = nullptr;
+ AVCodecParameters *codecpar = nullptr;
AVCodec *codec = nullptr;
if (!error) {
avstream = format_context->streams[audio_stream];
- codec_context = avstream->codec;
- codec = avcodec_find_decoder(codec_context->codec_id);
+ codecpar = avstream->codecpar;
+ codec = avcodec_find_decoder(codecpar->codec_id);
if (!codec) {
error = AudioError::NO_DECODER;
}
@@ -126,24 +127,24 @@ std::unique_ptr<AudioFile> Audio::open(const std::string& file_name, int stream)
if (!error) {
// We can already fill in the stream info even if the codec won't be able to open it.
codec_name = codec->long_name;
- bit_rate = codec_context->bit_rate;
- sample_rate = codec_context->sample_rate;
- bits_per_sample = codec_context->bits_per_raw_sample;
+ bit_rate = codecpar->bit_rate;
+ sample_rate = codecpar->sample_rate;
+ bits_per_sample = codecpar->bits_per_raw_sample;
if (!bits_per_sample) {
// APE uses bpcs, FLAC uses bprs.
- bits_per_sample = codec_context->bits_per_coded_sample;
+ bits_per_sample = codecpar->bits_per_coded_sample;
}
- if (codec_context->codec_id == AV_CODEC_ID_AAC ||
- codec_context->codec_id == AV_CODEC_ID_MUSEPACK8 ||
- codec_context->codec_id == AV_CODEC_ID_WMAV1 ||
- codec_context->codec_id == AV_CODEC_ID_WMAV2) {
+ if (codecpar->codec_id == AV_CODEC_ID_AAC ||
+ codecpar->codec_id == AV_CODEC_ID_MUSEPACK8 ||
+ codecpar->codec_id == AV_CODEC_ID_WMAV1 ||
+ codecpar->codec_id == AV_CODEC_ID_WMAV2) {
// These decoders set both bps and bitrate.
bits_per_sample = 0;
}
if (bits_per_sample) {
bit_rate = 0;
}
- channels = codec_context->channels;
+ channels = codecpar->channels;
if (avstream->duration != AV_NOPTS_VALUE) {
duration = avstream->duration * av_q2d(avstream->time_base);
@@ -158,12 +159,24 @@ std::unique_ptr<AudioFile> Audio::open(const std::string& file_name, int stream)
}
}
- if (!error && avcodec_open2(codec_context, codec, nullptr) < 0) {
+ AVCodecContext *codec_context = nullptr;
+ if (!error) {
error = AudioError::CANNOT_OPEN_DECODER;
+ // Allocate a codec context for the decoder.
+ codec_context = avcodec_alloc_context3(codec);
+ if (codec_context) {
+ // Copy codec parameters from input stream to output codec context.
+ if (avcodec_parameters_to_context(codec_context, codecpar) == 0) {
+ // Finally, init the decoder.
+ if (avcodec_open2(codec_context, codec, nullptr) == 0) {
+ error = AudioError::OK;
+ }
+ }
+ }
}
if (!error) {
- AVSampleFormat fmt = codec_context->sample_fmt;
+ AVSampleFormat fmt = (AVSampleFormat)codecpar->format;
if (fmt != AV_SAMPLE_FMT_S16 && fmt != AV_SAMPLE_FMT_S16P &&
fmt != AV_SAMPLE_FMT_S32 && fmt != AV_SAMPLE_FMT_S32P &&
fmt != AV_SAMPLE_FMT_FLT && fmt != AV_SAMPLE_FMT_FLTP &&
@@ -173,21 +186,21 @@ std::unique_ptr<AudioFile> Audio::open(const std::string& file_name, int stream)
}
return std::unique_ptr<AudioFile>(new AudioFileImpl(
- error, format_context, audio_stream,
- codec_name, bit_rate, sample_rate, bits_per_sample,
- streams, channels, duration
+ error, format_context, codec_context,
+ audio_stream, codec_name, bit_rate, sample_rate,
+ bits_per_sample, streams, channels, duration
));
}
AudioFileImpl::AudioFileImpl(
- AudioError error, AVFormatContext *format_context, int audio_stream,
- const std::string& codec_name, int bit_rate, int sample_rate, int bits_per_sample,
- int streams, int channels, double duration
+ AudioError error, AVFormatContext *format_context, AVCodecContext *codec_context,
+ int audio_stream, const std::string& codec_name, int bit_rate, int sample_rate,
+ int bits_per_sample, int streams, int channels, double duration
) :
- error(error), format_context(format_context), audio_stream(audio_stream),
- codec_name(codec_name), bit_rate(bit_rate),
- sample_rate(sample_rate), bits_per_sample(bits_per_sample),
- streams(streams), channels(channels), duration(duration)
+ error(error), format_context(format_context), codec_context(codec_context),
+ audio_stream(audio_stream), codec_name(codec_name), bit_rate(bit_rate),
+ sample_rate(sample_rate),
+ bits_per_sample(bits_per_sample), streams(streams), channels(channels), duration(duration)
{
av_init_packet(&this->packet);
this->packet.data = nullptr;
@@ -215,13 +228,10 @@ AudioFileImpl::~AudioFileImpl()
this->offset = 0;
av_packet_unref(&this->packet);
}
+ if (this->codec_context) {
+ avcodec_free_context(&codec_context);
+ }
if (this->format_context) {
- if (this->audio_stream >= 0) {
- auto codec_context = this->format_context->streams[this->audio_stream]->codec;
- if (codec_context) {
- avcodec_close(codec_context);
- }
- }
avformat_close_input(&this->format_context);
}
}
@@ -251,9 +261,10 @@ int AudioFileImpl::read()
for (;;) {
while (this->packet.size > 0) {
av_frame_unref(this->frame);
- auto codec_context = this->format_context->streams[this->audio_stream]->codec;
int got_frame = 0;
- int len = avcodec_decode_audio4(codec_context, this->frame, &got_frame, &this->packet);
+ int len = avcodec_decode_audio4(
+ this->codec_context, this->frame, &got_frame, &this->packet
+ );
if (len < 0) {
// Error, skip the frame.
break;