Skip to content

Commit 3194748

Browse files
committed
Update to fit to FFmpeg 5.0 API
1 parent 5c3756b commit 3194748

24 files changed

+215
-99
lines changed

src/AvTranscoder/Library.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extern "C" {
1111
#else
1212
#include <libswresample/version.h>
1313
#endif
14+
#include <libavcodec/avcodec.h>
1415
#include <libavformat/avformat.h>
1516
#include <libavfilter/avfilter.h>
1617
}

src/AvTranscoder/codec/ICodec.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ class AvExport ICodec
5454
#ifndef SWIG
5555
AVCodecContext& getAVCodecContext() { return *_avCodecContext; }
5656
const AVCodecContext& getAVCodecContext() const { return *_avCodecContext; }
57-
AVCodec& getAVCodec() { return *_avCodec; }
5857
const AVCodec& getAVCodec() const { return *_avCodec; }
5958
#endif
6059

@@ -66,7 +65,7 @@ class AvExport ICodec
6665

6766
protected:
6867
AVCodecContext* _avCodecContext; ///< Full codec instance description (has ownership)
69-
AVCodec* _avCodec; ///< Codec abstract description
68+
const AVCodec* _avCodec; ///< Codec abstract description
7069
const bool _isCodecContextAllocated; ///< Is the AVCodecContext allocated by the class
7170

7271
ECodecType _type;

src/AvTranscoder/data/coded/CodedData.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ void CodedData::assign(const size_t size, const int value)
8787

8888
void CodedData::initAVPacket()
8989
{
90-
av_init_packet(&_packet);
90+
_packet = *av_packet_alloc();
9191
_packet.data = NULL;
9292
_packet.size = 0;
9393
}

src/AvTranscoder/decoder/AudioDecoder.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ bool AudioDecoder::decodeNextFrame(IFrame& frameBuffer)
8787
if(!_isSetup)
8888
setupDecoder();
8989

90-
int got_frame = 0;
90+
bool got_frame = false;
9191
while(!got_frame)
9292
{
9393
CodedData data;
@@ -98,18 +98,27 @@ bool AudioDecoder::decodeNextFrame(IFrame& frameBuffer)
9898
// decoding
9999
// @note could be called several times to return the remaining frames (last call with an empty packet)
100100
// @see CODEC_CAP_DELAY
101-
int ret = avcodec_decode_audio4(&_inputStream->getAudioCodec().getAVCodecContext(), &frameBuffer.getAVFrame(),
102-
&got_frame, &data.getAVPacket());
101+
int ret = avcodec_send_packet(&_inputStream->getAudioCodec().getAVCodecContext(), &data.getAVPacket());
102+
103103
if(ret < 0)
104104
{
105-
throw std::runtime_error("An error occurred during audio decoding: " + getDescriptionFromErrorCode(ret));
105+
throw std::runtime_error("An error occurred sending audio packet to decoder: " + getDescriptionFromErrorCode(ret));
106106
}
107107

108+
ret = avcodec_receive_frame(&_inputStream->getAudioCodec().getAVCodecContext(), &frameBuffer.getAVFrame());
109+
110+
if (ret == 0)
111+
got_frame = true;
112+
else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
113+
got_frame = false;
114+
else
115+
throw std::runtime_error("An error occurred receiving audio packet from decoder: " + getDescriptionFromErrorCode(ret));
116+
108117
// fixed channel layout value after decoding
109118
frameBuffer.getAVFrame().channel_layout = channelLayout;
110119

111120
// if no frame could be decompressed
112-
if(!nextPacketRead && ret == 0 && got_frame == 0)
121+
if(!nextPacketRead && got_frame == 0)
113122
decodeNextFrame = false;
114123
else
115124
decodeNextFrame = true;

src/AvTranscoder/decoder/VideoDecoder.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,22 @@ bool VideoDecoder::decodeNextFrame(IFrame& frameBuffer)
9494
// decoding
9595
// @note could be called several times to return the remaining frames (last call with an empty packet)
9696
// @see CODEC_CAP_DELAY
97-
const int ret = avcodec_decode_video2(&_inputStream->getVideoCodec().getAVCodecContext(), &frameBuffer.getAVFrame(),
98-
&got_frame, &data.getAVPacket());
97+
int ret = avcodec_send_packet(&_inputStream->getVideoCodec().getAVCodecContext(), &data.getAVPacket());
98+
9999
if(ret < 0)
100100
{
101-
throw std::runtime_error("An error occurred during video decoding: " + getDescriptionFromErrorCode(ret));
101+
throw std::runtime_error("An error occurred sending video packet to decoder: " + getDescriptionFromErrorCode(ret));
102102
}
103103

104+
ret = avcodec_receive_frame(&_inputStream->getAudioCodec().getAVCodecContext(), &frameBuffer.getAVFrame());
105+
106+
if (ret == 0)
107+
got_frame = true;
108+
else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
109+
got_frame = false;
110+
else
111+
throw std::runtime_error("An error occurred receiving video packet from decoder: " + getDescriptionFromErrorCode(ret));
112+
104113
// if no frame could be decompressed
105114
if(!nextPacketRead && ret == 0 && got_frame == 0)
106115
decodeNextFrame = false;

src/AvTranscoder/encoder/AudioEncoder.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ extern "C" {
77
}
88

99
#include <stdexcept>
10+
#include <libavcodec/avcodec.h>
1011

1112
namespace avtranscoder
1213
{
@@ -93,8 +94,6 @@ void AudioEncoder::setupEncoder(const ProfileLoader::Profile& profile)
9394

9495
bool AudioEncoder::encodeFrame(const IFrame& sourceFrame, CodedData& codedFrame)
9596
{
96-
AVCodecContext& avCodecContext = _codec.getAVCodecContext();
97-
9897
AVPacket& packet = codedFrame.getAVPacket();
9998
const AVFrame& srcAvFrame = sourceFrame.getAVFrame();
10099
if(srcAvFrame.pts != (int)AV_NOPTS_VALUE)
@@ -121,7 +120,24 @@ bool AudioEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData)
121120
encodedData.data = NULL;
122121

123122
AVCodecContext& avCodecContext = _codec.getAVCodecContext();
124-
#if LIBAVCODEC_VERSION_MAJOR > 53
123+
#if LIBAVCODEC_VERSION_MAJOR > 58
124+
int ret = avcodec_send_frame(&avCodecContext, decodedData);
125+
if(ret != 0)
126+
{
127+
throw std::runtime_error("Error sending audio frame to encoder: " + getDescriptionFromErrorCode(ret));
128+
}
129+
130+
ret = avcodec_receive_packet(&avCodecContext, &encodedData);
131+
132+
if (ret == 0)
133+
return true;
134+
135+
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
136+
return false;
137+
138+
throw std::runtime_error("Error receiving audio frame from encoder: " + getDescriptionFromErrorCode(ret));
139+
140+
#elif LIBAVCODEC_VERSION_MAJOR > 53
125141
int gotPacket = 0;
126142
const int ret = avcodec_encode_audio2(&avCodecContext, &encodedData, decodedData, &gotPacket);
127143
if(ret != 0)

src/AvTranscoder/encoder/VideoEncoder.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,6 @@ void VideoEncoder::setupEncoder(const ProfileLoader::Profile& profile)
110110

111111
bool VideoEncoder::encodeFrame(const IFrame& sourceFrame, CodedData& codedFrame)
112112
{
113-
AVCodecContext& avCodecContext = _codec.getAVCodecContext();
114-
115113
AVPacket& packet = codedFrame.getAVPacket();
116114
const AVFrame& srcAvFrame = sourceFrame.getAVFrame();
117115
if(srcAvFrame.pts != (int)AV_NOPTS_VALUE)
@@ -138,14 +136,37 @@ bool VideoEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData)
138136
encodedData.data = NULL;
139137

140138
AVCodecContext& avCodecContext = _codec.getAVCodecContext();
141-
#if LIBAVCODEC_VERSION_MAJOR > 53
139+
#if LIBAVCODEC_VERSION_MAJOR > 58
140+
int ret = avcodec_send_frame(&avCodecContext, decodedData);
141+
if(ret != 0)
142+
{
143+
throw std::runtime_error("Error sending video frame to encoder: " + getDescriptionFromErrorCode(ret));
144+
}
145+
146+
ret = avcodec_receive_packet(&avCodecContext, &encodedData);
147+
148+
if (ret == 0)
149+
{
150+
return true;
151+
}
152+
else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
153+
{
154+
return false;
155+
}
156+
else
157+
{
158+
throw std::runtime_error("Error receiving video frame from encoder: " + getDescriptionFromErrorCode(ret));
159+
}
160+
161+
#elif LIBAVCODEC_VERSION_MAJOR > 53
142162
int gotPacket = 0;
143163
const int ret = avcodec_encode_video2(&avCodecContext, &encodedData, decodedData, &gotPacket);
144164
if(ret != 0)
145165
{
146166
throw std::runtime_error("Encode video frame error: avcodec encode video frame - " +
147167
getDescriptionFromErrorCode(ret));
148168
}
169+
149170
return gotPacket == 1;
150171
#else
151172
const int ret = avcodec_encode_video(&avCodecContext, encodedData.data, encodedData.size, decodedData);

src/AvTranscoder/file/FormatContext.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ FormatContext::~FormatContext()
4646
if(!_avFormatContext)
4747
return;
4848

49-
// free the streams added
50-
for(std::vector<AVStream*>::iterator it = _avStreamAllocated.begin(); it != _avStreamAllocated.end(); ++it)
51-
avcodec_close((*it)->codec);
52-
5349
// free the format context
5450
if(_isOpen)
5551
avformat_close_input(&_avFormatContext);
@@ -151,7 +147,7 @@ AVStream& FormatContext::addAVStream(const AVCodec& avCodec)
151147

152148
bool FormatContext::seek(const uint64_t position, const int flag)
153149
{
154-
LOG_INFO("Seek in '" << _avFormatContext->filename << "' at " << position << " with flag '" << flag << "'")
150+
LOG_INFO("Seek in '" << _avFormatContext->url << "' at " << position << " with flag '" << flag << "'")
155151
const int err = av_seek_frame(_avFormatContext, -1, position, flag);
156152
if(err < 0)
157153
{
@@ -186,12 +182,13 @@ AVStream& FormatContext::getAVStream(size_t index) const
186182

187183
void FormatContext::setFilename(const std::string& filename)
188184
{
189-
strcpy(&_avFormatContext->filename[0], filename.c_str());
185+
_avFormatContext->url = (char*)av_malloc(filename.size());
186+
strcpy(_avFormatContext->url, filename.c_str());
190187
}
191188

192189
void FormatContext::setOutputFormat(const std::string& filename, const std::string& shortName, const std::string& mimeType)
193190
{
194-
AVOutputFormat* oformat = av_guess_format(shortName.c_str(), filename.c_str(), mimeType.c_str());
191+
const AVOutputFormat* oformat = av_guess_format(shortName.c_str(), filename.c_str(), mimeType.c_str());
195192
if(!oformat)
196193
{
197194
std::string msg("Unable to find format for ");

src/AvTranscoder/file/FormatContext.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ class AvExport FormatContext
113113

114114
#ifndef SWIG
115115
AVFormatContext& getAVFormatContext() const { return *_avFormatContext; }
116-
AVOutputFormat& getAVOutputFormat() const { return *_avFormatContext->oformat; }
117-
AVInputFormat& getAVInputFormat() const { return *_avFormatContext->iformat; }
116+
const AVOutputFormat& getAVOutputFormat() const { return *_avFormatContext->oformat; }
117+
const AVInputFormat& getAVInputFormat() const { return *_avFormatContext->iformat; }
118118
AVIOContext& getAVIOContext() const { return *_avFormatContext->pb; }
119119
AVDictionary& getAVMetaData() const { return *_avFormatContext->metadata; }
120120
AVStream& getAVStream(size_t index) const;

src/AvTranscoder/file/OutputFile.cpp

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <AvTranscoder/util.hpp>
44

55
#include <stdexcept>
6+
#include <libavutil/channel_layout.h>
67

78
#ifndef FF_INPUT_BUFFER_PADDING_SIZE
89
#define FF_INPUT_BUFFER_PADDING_SIZE 16
@@ -35,31 +36,29 @@ IOutputStream& OutputFile::addVideoStream(const VideoCodec& videoDesc)
3536
{
3637
AVStream& stream = _formatContext.addAVStream(videoDesc.getAVCodec());
3738

38-
stream.codec->width = videoDesc.getAVCodecContext().width;
39-
stream.codec->height = videoDesc.getAVCodecContext().height;
40-
stream.codec->bit_rate = videoDesc.getAVCodecContext().bit_rate;
41-
stream.codec->pix_fmt = videoDesc.getAVCodecContext().pix_fmt;
42-
stream.codec->profile = videoDesc.getAVCodecContext().profile;
43-
stream.codec->level = videoDesc.getAVCodecContext().level;
44-
stream.codec->field_order = videoDesc.getAVCodecContext().field_order;
39+
stream.codecpar->width = videoDesc.getAVCodecContext().width;
40+
stream.codecpar->height = videoDesc.getAVCodecContext().height;
41+
stream.codecpar->bit_rate = videoDesc.getAVCodecContext().bit_rate;
42+
stream.codecpar->format = videoDesc.getAVCodecContext().pix_fmt;
43+
stream.codecpar->profile = videoDesc.getAVCodecContext().profile;
44+
stream.codecpar->level = videoDesc.getAVCodecContext().level;
45+
stream.codecpar->field_order = videoDesc.getAVCodecContext().field_order;
4546

46-
stream.codec->colorspace = videoDesc.getAVCodecContext().colorspace;
47-
stream.codec->color_primaries = videoDesc.getAVCodecContext().color_primaries;
48-
stream.codec->color_range = videoDesc.getAVCodecContext().color_range;
49-
stream.codec->color_trc = videoDesc.getAVCodecContext().color_trc;
50-
stream.codec->chroma_sample_location = videoDesc.getAVCodecContext().chroma_sample_location;
47+
stream.codecpar->color_space = videoDesc.getAVCodecContext().colorspace;
48+
stream.codecpar->color_primaries = videoDesc.getAVCodecContext().color_primaries;
49+
stream.codecpar->color_range = videoDesc.getAVCodecContext().color_range;
50+
stream.codecpar->color_trc = videoDesc.getAVCodecContext().color_trc;
51+
stream.codecpar->chroma_location = videoDesc.getAVCodecContext().chroma_sample_location;
5152

5253
setOutputStream(stream, videoDesc);
5354

5455
// need to set the time_base on the AVCodecContext and the AVStream
5556
// compensating the frame rate with the ticks_per_frame and keeping
5657
// a coherent reading speed.
57-
av_reduce(&stream.codec->time_base.num, &stream.codec->time_base.den,
58+
av_reduce(&stream.time_base.num, &stream.time_base.den,
5859
videoDesc.getAVCodecContext().time_base.num * videoDesc.getAVCodecContext().ticks_per_frame,
5960
videoDesc.getAVCodecContext().time_base.den, INT_MAX);
6061

61-
stream.time_base = stream.codec->time_base;
62-
6362
OutputStream* outputStream = new OutputStream(*this, _formatContext.getNbStreams() - 1);
6463
_outputStreams.push_back(outputStream);
6564

@@ -70,16 +69,16 @@ IOutputStream& OutputFile::addAudioStream(const AudioCodec& audioDesc)
7069
{
7170
AVStream& stream = _formatContext.addAVStream(audioDesc.getAVCodec());
7271

73-
stream.codec->sample_rate = audioDesc.getAVCodecContext().sample_rate;
74-
stream.codec->channels = audioDesc.getAVCodecContext().channels;
75-
stream.codec->channel_layout = audioDesc.getAVCodecContext().channel_layout;
76-
stream.codec->sample_fmt = audioDesc.getAVCodecContext().sample_fmt;
77-
stream.codec->frame_size = audioDesc.getAVCodecContext().frame_size;
72+
stream.codecpar->sample_rate = audioDesc.getAVCodecContext().sample_rate;
73+
stream.codecpar->channels = audioDesc.getAVCodecContext().channels;
74+
stream.codecpar->channel_layout = audioDesc.getAVCodecContext().channel_layout;
75+
stream.codecpar->format = audioDesc.getAVCodecContext().sample_fmt;
76+
stream.codecpar->frame_size = audioDesc.getAVCodecContext().frame_size;
7877

7978
setOutputStream(stream, audioDesc);
8079

8180
// need to set the time_base on the AVCodecContext of the AVStream
82-
av_reduce(&stream.codec->time_base.num, &stream.codec->time_base.den, audioDesc.getAVCodecContext().time_base.num,
81+
av_reduce(&stream.time_base.num, &stream.time_base.den, audioDesc.getAVCodecContext().time_base.num,
8382
audioDesc.getAVCodecContext().time_base.den, INT_MAX);
8483

8584
OutputStream* outputStream = new OutputStream(*this, _formatContext.getNbStreams() - 1);
@@ -92,14 +91,14 @@ IOutputStream& OutputFile::addCustomStream(const ICodec& iCodecDesc)
9291
{
9392
AVStream& stream = _formatContext.addAVStream(iCodecDesc.getAVCodec());
9493

95-
stream.codec->sample_rate = 48000;
96-
stream.codec->channels = 1;
97-
stream.codec->channel_layout = AV_CH_LAYOUT_MONO;
98-
stream.codec->sample_fmt = AV_SAMPLE_FMT_S32;
99-
stream.codec->frame_size = 1920;
94+
stream.codecpar->sample_rate = 48000;
95+
stream.codecpar->channels = 1;
96+
stream.codecpar->channel_layout = AV_CH_LAYOUT_MONO;
97+
stream.codecpar->format = AV_SAMPLE_FMT_S32;
98+
stream.codecpar->frame_size = 1920;
10099

101100
// need to set the time_base on the AVCodecContext of the AVStream
102-
av_reduce(&stream.codec->time_base.num, &stream.codec->time_base.den, 1, 1, INT_MAX);
101+
av_reduce(&stream.time_base.num, &stream.time_base.den, 1, 1, INT_MAX);
103102

104103
OutputStream* outputStream = new OutputStream(*this, _formatContext.getNbStreams() - 1);
105104
_outputStreams.push_back(outputStream);
@@ -136,7 +135,7 @@ IOutputStream& OutputFile::getStream(const size_t streamIndex)
136135

137136
std::string OutputFile::getFilename() const
138137
{
139-
return std::string(_formatContext.getAVFormatContext().filename);
138+
return std::string(_formatContext.getAVFormatContext().url);
140139
}
141140

142141
std::string OutputFile::getFormatName() const
@@ -194,8 +193,7 @@ IOutputStream::EWrappingStatus OutputFile::wrap(const CodedData& data, const siz
194193
<< _frameCount.at(streamIndex) << ")")
195194

196195
// Packet to wrap
197-
AVPacket packet;
198-
av_init_packet(&packet);
196+
AVPacket packet = *av_packet_alloc();
199197
packet.stream_index = streamIndex;
200198
packet.data = (uint8_t*)data.getData();
201199
packet.size = data.getSize();
@@ -348,6 +346,7 @@ void OutputFile::setupRemainingWrappingOptions()
348346

349347
void OutputFile::setOutputStream(AVStream& avStream, const ICodec& codec)
350348
{
349+
#if LIBAVCODEC_VERSION_MAJOR < 59
351350
// depending on the format, place global headers in extradata instead of every keyframe
352351
if(_formatContext.getAVOutputFormat().flags & AVFMT_GLOBALHEADER)
353352
{
@@ -368,13 +367,14 @@ void OutputFile::setOutputStream(AVStream& avStream, const ICodec& codec)
368367
LOG_WARN("This codec is considered experimental by libav/ffmpeg:" << codec.getCodecName());
369368
avStream.codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
370369
}
370+
#endif
371371

372372
// some codecs need/can use extradata to decode
373373
uint8_t* srcExtradata = codec.getAVCodecContext().extradata;
374374
const int srcExtradataSize = codec.getAVCodecContext().extradata_size;
375-
avStream.codec->extradata = (uint8_t*)av_malloc(srcExtradataSize + FF_INPUT_BUFFER_PADDING_SIZE);
376-
memcpy(avStream.codec->extradata, srcExtradata, srcExtradataSize);
377-
memset(((uint8_t*)avStream.codec->extradata) + srcExtradataSize, 0, FF_INPUT_BUFFER_PADDING_SIZE);
378-
avStream.codec->extradata_size = codec.getAVCodecContext().extradata_size;
375+
avStream.codecpar->extradata = (uint8_t*)av_malloc(srcExtradataSize + FF_INPUT_BUFFER_PADDING_SIZE);
376+
memcpy(avStream.codecpar->extradata, srcExtradata, srcExtradataSize);
377+
memset(((uint8_t*)avStream.codecpar->extradata) + srcExtradataSize, 0, FF_INPUT_BUFFER_PADDING_SIZE);
378+
avStream.codecpar->extradata_size = codec.getAVCodecContext().extradata_size;
379379
}
380380
}

src/AvTranscoder/filter/FilterGraph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ bool FilterGraph::areInputFrameSizesEqual(const std::vector<IFrame*>& inputs)
211211
if(!inputs.size() || inputs.size() == 1)
212212
return true;
213213

214-
const int frameSize = inputs.at(0)->getDataSize();
214+
size_t frameSize = inputs.at(0)->getDataSize();
215215
for(size_t index = 1; index < inputs.size(); ++index)
216216
{
217217
if(frameSize != inputs.at(index)->getDataSize())

src/AvTranscoder/log.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void Logger::log(const int level, const std::string& msg)
5656
logMessage += "\n";
5757

5858
// send message
59-
av_log(NULL, level, logMessage.c_str());
59+
av_log(NULL, level, "%s", logMessage.c_str());
6060
}
6161

6262
void Logger::logInFile()

0 commit comments

Comments
 (0)