fixed deprecated code

This commit is contained in:
selim mustafaev 2017-11-20 01:48:31 +03:00
parent e22a2678da
commit 51c7109193
6 changed files with 122 additions and 62 deletions

View File

@ -27,12 +27,14 @@ namespace ffcpp {
public: public:
Codec(); Codec();
Codec(AVCodecContext* ctx, CodecType type); Codec(AVCodecID codecId, CodecType type, AVCodecParameters* params = nullptr);
Codec(AVCodecContext* ctx, AVCodec* codec); Codec(AVCodecContext* ctx, AVCodec* codec);
~Codec(); ~Codec();
operator AVCodecContext*() const; operator AVCodecContext*() const;
const AVCodec* nativeCodecPtr() const;
int width() const; int width() const;
int height() const; int height() const;
AVRational timeBase() const; AVRational timeBase() const;
@ -47,6 +49,13 @@ namespace ffcpp {
void setWidth(int width); void setWidth(int width);
void setHeight(int height); void setHeight(int height);
void setPixelFormat(AVPixelFormat pixelFormat); void setPixelFormat(AVPixelFormat pixelFormat);
void setTimeBase(AVRational timeBase);
void setSampleFormat(AVSampleFormat sampleFormat);
void setGlobalQuality(int quality);
void setChannelCount(int channels);
void setChannelLayout(uint64_t layout);
void setSampleRate(int sampleRate);
void setStdCompliance(int compliance);
FramePtr decode(Packet& packet); FramePtr decode(Packet& packet);
Packet encode(FramePtr frame); Packet encode(FramePtr frame);

View File

@ -21,7 +21,7 @@ namespace ffcpp {
public: public:
Stream(); Stream();
Stream(AVStream* stream); Stream(AVStream* stream);
Stream(AVStream* stream, AVCodec* encoder); Stream(AVStream* stream, CodecPtr codec);
operator AVStream*() const; operator AVStream*() const;
CodecPtr codec(); CodecPtr codec();

View File

@ -1,8 +1,6 @@
project(ffcpp) project(ffcpp)
find_package(FFMPEG REQUIRED) find_package(FFMPEG REQUIRED)
# FIXME: FFMPEG_INCLUDE_DIR is incorrect and causes errors
# http://stackoverflow.com/questions/35982639/ctime-std-namespace-conflict
include_directories(${FFMPEG_INCLUDE_DIR}) include_directories(${FFMPEG_INCLUDE_DIR})
link_directories(${FFMPEG_LIBRARY_DIRS}) link_directories(${FFMPEG_LIBRARY_DIRS})

View File

@ -8,15 +8,23 @@ namespace ffcpp {
} }
Codec::Codec(AVCodecContext *ctx, CodecType type): _codecCtx(ctx) { Codec::Codec(AVCodecID codecId, CodecType type, AVCodecParameters* params /* = nullptr */) {
if(type == CodecType::Encoder) { if(type == CodecType::Encoder) {
_codec = avcodec_find_encoder(ctx->codec_id); _codec = avcodec_find_encoder(codecId);
} else { } else {
_codec = avcodec_find_decoder(ctx->codec_id); _codec = avcodec_find_decoder(codecId);
} }
if(!_codec) throw std::runtime_error("cannot find codec"); if(!_codec) throw std::runtime_error("cannot find codec");
_codecCtx = avcodec_alloc_context3(_codec);
if(!_codecCtx) throw std::runtime_error("cannot allocate codec context");
if(params) {
int res = avcodec_parameters_to_context(_codecCtx, params);
if(res < 0) throwIfError(res, "cannot copy codec papameters from stream");
}
int res = avcodec_open2(_codecCtx, _codec, nullptr); int res = avcodec_open2(_codecCtx, _codec, nullptr);
throwIfError(res, "cannot open codec"); throwIfError(res, "cannot open codec");
} }
@ -35,6 +43,11 @@ namespace ffcpp {
} }
} }
const AVCodec *Codec::nativeCodecPtr() const
{
return _codec;
}
Codec::operator AVCodecContext*() const { Codec::operator AVCodecContext*() const {
return _codecCtx; return _codecCtx;
} }
@ -88,8 +101,50 @@ namespace ffcpp {
} }
void Codec::setPixelFormat(AVPixelFormat pixelFormat) { void Codec::setPixelFormat(AVPixelFormat pixelFormat) {
if(pixelFormat == AV_PIX_FMT_NONE) {
_codecCtx->pix_fmt = _codec->pix_fmts[0];
} else {
_codecCtx->pix_fmt = pixelFormat; _codecCtx->pix_fmt = pixelFormat;
} }
}
void Codec::setTimeBase(AVRational timeBase) {
_codecCtx->time_base = timeBase;
}
void Codec::setSampleFormat(AVSampleFormat sampleFormat)
{
if(sampleFormat == AV_SAMPLE_FMT_NONE) {
_codecCtx->sample_fmt = _codec->sample_fmts[0];
} else {
_codecCtx->sample_fmt = sampleFormat;
}
}
void Codec::setGlobalQuality(int quality)
{
_codecCtx->global_quality = quality;
}
void Codec::setChannelCount(int channels)
{
_codecCtx->channels = channels;
}
void Codec::setChannelLayout(uint64_t layout)
{
_codecCtx->channel_layout = layout;
}
void Codec::setSampleRate(int sampleRate)
{
_codecCtx->sample_rate = sampleRate;
}
void Codec::setStdCompliance(int compliance)
{
_codecCtx->strict_std_compliance = compliance;
}
Codec::Codec(Codec&& c) noexcept { Codec::Codec(Codec&& c) noexcept {
*this = std::move(c); *this = std::move(c);
@ -105,12 +160,17 @@ namespace ffcpp {
FramePtr Codec::decode(Packet &packet) { FramePtr Codec::decode(Packet &packet) {
FramePtr frame = std::make_shared<Frame>(); FramePtr frame = std::make_shared<Frame>();
int gotPicture = 0;
auto decFunc = (_codecCtx->codec_type == AVMEDIA_TYPE_VIDEO ? avcodec_decode_video2 : avcodec_decode_audio4);
while(!gotPicture) { int res = avcodec_send_packet(_codecCtx, packet);
int res = decFunc(_codecCtx, frame->nativePtr(), &gotPicture, packet);
if(res < 0) throw std::runtime_error("cannot decode packet"); if(res < 0) throw std::runtime_error("cannot decode packet");
while (res >= 0) {
res = avcodec_receive_frame(_codecCtx, frame->nativePtr());
if(res == AVERROR(EAGAIN) || res == AVERROR_EOF) {
break;
} else if(res < 0) {
throw std::runtime_error("cannot decode packet");
}
} }
if(_codecCtx->codec_type == AVMEDIA_TYPE_VIDEO) { if(_codecCtx->codec_type == AVMEDIA_TYPE_VIDEO) {
@ -124,12 +184,19 @@ namespace ffcpp {
Packet Codec::encode(FramePtr frame) { Packet Codec::encode(FramePtr frame) {
Packet packet; Packet packet;
int gotPacket = 0;
auto encFunc = (_codecCtx->codec_type == AVMEDIA_TYPE_VIDEO ? avcodec_encode_video2 : avcodec_encode_audio2);
int res = encFunc(_codecCtx, packet, frame ? frame->nativePtr() : nullptr, &gotPacket); int res = avcodec_send_frame(_codecCtx, frame->nativePtr());
if(res < 0) throw std::runtime_error("cannot encode frame"); if(res < 0) throw std::runtime_error("cannot encode frame");
while (res >= 0) {
res = avcodec_receive_packet(_codecCtx, packet);
if(res == AVERROR(EAGAIN) || res == AVERROR_EOF) {
break;
} else if(res < 0) {
throw std::runtime_error("cannot encode frame");
}
}
return packet; return packet;
} }

View File

@ -16,7 +16,7 @@ namespace ffcpp {
_streams.reserve(_formatCtx->nb_streams); _streams.reserve(_formatCtx->nb_streams);
for(size_t i = 0; i < _formatCtx->nb_streams; ++i) { for(size_t i = 0; i < _formatCtx->nb_streams; ++i) {
auto codecType = _formatCtx->streams[i]->codec->codec_type; auto codecType = _formatCtx->streams[i]->codecpar->codec_type;
if(codecType != AVMEDIA_TYPE_VIDEO && codecType != AVMEDIA_TYPE_AUDIO) if(codecType != AVMEDIA_TYPE_VIDEO && codecType != AVMEDIA_TYPE_AUDIO)
continue; continue;
@ -45,7 +45,7 @@ namespace ffcpp {
bool MediaFile::hasStream(AVMediaType type) const { bool MediaFile::hasStream(AVMediaType type) const {
for(size_t i = 0; i < _formatCtx->nb_streams; ++i) { for(size_t i = 0; i < _formatCtx->nb_streams; ++i) {
if(_formatCtx->streams[i]->codec->codec_type == type) { if(_formatCtx->streams[i]->codecpar->codec_type == type) {
return true; return true;
} }
} }
@ -63,7 +63,7 @@ namespace ffcpp {
StreamPtr MediaFile::getStream(AVMediaType type, size_t index) { StreamPtr MediaFile::getStream(AVMediaType type, size_t index) {
for(size_t i = 0, curIndex = 0; i < _formatCtx->nb_streams; ++i) { for(size_t i = 0, curIndex = 0; i < _formatCtx->nb_streams; ++i) {
if(_formatCtx->streams[i]->codec->codec_type == type) { if(_formatCtx->streams[i]->codecpar->codec_type == type) {
if(curIndex == index) { if(curIndex == index) {
return _streams[i]; return _streams[i];
} else { } else {
@ -98,22 +98,15 @@ namespace ffcpp {
} }
StreamPtr MediaFile::addVideoStream(AVCodecID codecID, int width, int height, AVRational timeBase, AVPixelFormat pixelFormat) { StreamPtr MediaFile::addVideoStream(AVCodecID codecID, int width, int height, AVRational timeBase, AVPixelFormat pixelFormat) {
AVCodec* codec = avcodec_find_encoder(codecID); CodecPtr codec = std::make_shared<Codec>(codecID, CodecType::Encoder);
if(!codec) throw std::runtime_error("cannot find codec");
AVStream* stream = avformat_new_stream(_formatCtx, codec); AVStream* stream = avformat_new_stream(_formatCtx, codec->nativeCodecPtr());
if(!stream) throw std::runtime_error("cannot create stream"); if(!stream) throw std::runtime_error("cannot create stream");
AVCodecContext* ctx = stream->codec; codec->setWidth(width);
ctx->width = width; codec->setHeight(height);
ctx->height = height; codec->setTimeBase(timeBase);
ctx->time_base = timeBase; codec->setPixelFormat(pixelFormat);
if(pixelFormat == AV_PIX_FMT_NONE) {
ctx->pix_fmt = codec->pix_fmts[0];
} else {
ctx->pix_fmt = pixelFormat;
}
auto sPtr = std::make_shared<Stream>(stream, codec); auto sPtr = std::make_shared<Stream>(stream, codec);
_streams.emplace_back(sPtr); _streams.emplace_back(sPtr);
@ -121,24 +114,18 @@ namespace ffcpp {
} }
StreamPtr MediaFile::addAudioStream(AVCodecID codecID, int channels, int sampleRate, AVSampleFormat sampleFormat) { StreamPtr MediaFile::addAudioStream(AVCodecID codecID, int channels, int sampleRate, AVSampleFormat sampleFormat) {
AVCodec* codec = avcodec_find_encoder(codecID); CodecPtr codec = std::make_shared<Codec>(codecID, CodecType::Encoder);
if(!codec) throw std::runtime_error("cannot find codec");
AVStream* stream = avformat_new_stream(_formatCtx, codec); AVStream* stream = avformat_new_stream(_formatCtx, codec->nativeCodecPtr());
if(!stream) throw std::runtime_error("cannot create stream"); if(!stream) throw std::runtime_error("cannot create stream");
AVCodecContext* ctx = stream->codec; codec->setSampleFormat(sampleFormat);
if(sampleFormat == AV_SAMPLE_FMT_NONE) { codec->setGlobalQuality(10);
ctx->sample_fmt = codec->sample_fmts[0]; codec->setChannelCount(channels);
} else { codec->setChannelLayout(av_get_default_channel_layout(channels));
ctx->sample_fmt = sampleFormat; codec->setSampleRate(sampleRate);
} codec->setTimeBase(AVRational {1, sampleRate});
ctx->global_quality = 10; codec->setStdCompliance(FF_COMPLIANCE_EXPERIMENTAL);
ctx->channels = channels;
ctx->channel_layout = (uint64_t)av_get_default_channel_layout(channels);
ctx->sample_rate = sampleRate;
ctx->time_base = AVRational {1, sampleRate};
ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
auto sPtr = std::make_shared<Stream>(stream, codec); auto sPtr = std::make_shared<Stream>(stream, codec);
_streams.emplace_back(sPtr); _streams.emplace_back(sPtr);
@ -154,7 +141,7 @@ namespace ffcpp {
} }
AVMediaType MediaFile::packetType(const Packet &packet) { AVMediaType MediaFile::packetType(const Packet &packet) {
return _formatCtx->streams[packet.streamIndex()]->codec->codec_type; return _formatCtx->streams[packet.streamIndex()]->codecpar->codec_type;
} }
void MediaFile::writeHeader() { void MediaFile::writeHeader() {

View File

@ -7,11 +7,10 @@ namespace ffcpp {
} }
Stream::Stream(AVStream *stream): _stream(stream) { Stream::Stream(AVStream *stream): _stream(stream) {
_codec = std::make_shared<Codec>(_stream->codec, CodecType::Decoder); _codec = std::make_shared<Codec>(_stream->codecpar->codec_id, CodecType::Decoder);
} }
Stream::Stream(AVStream *stream, AVCodec* encoder): _stream(stream) { Stream::Stream(AVStream *stream, CodecPtr codec): _stream(stream), _codec(codec) {
_codec = std::make_shared<Codec>(_stream->codec, encoder);
} }
Stream::operator AVStream*() const { Stream::operator AVStream*() const {