fixed deinitialization behavior

This commit is contained in:
Selim Mustafaev 2016-09-01 00:32:30 +03:00
parent d7f8c733ec
commit 3959e80e36
10 changed files with 96 additions and 29 deletions

View File

@ -11,6 +11,6 @@ link_directories(${FFMPEG_LIBRARY_DIRS})
#message(FATAL_ERROR ${FFMPEG_LIBRARIES}) #message(FATAL_ERROR ${FFMPEG_LIBRARIES})
set(SOURCE_FILES main.cpp ffcpp/MediaFile.cpp ffcpp/MediaFile.h ffcpp/ffcpp.cpp ffcpp/ffcpp.h ffcpp/Stream.cpp ffcpp/Stream.h ffcpp/Codec.cpp ffcpp/Codec.h) set(SOURCE_FILES main.cpp ffcpp/MediaFile.cpp ffcpp/MediaFile.h ffcpp/ffcpp.cpp ffcpp/ffcpp.h ffcpp/Stream.cpp ffcpp/Stream.h ffcpp/Codec.cpp ffcpp/Codec.h ffcpp/Packet.cpp ffcpp/Packet.h)
add_executable(ffConv ${SOURCE_FILES}) add_executable(ffConv ${SOURCE_FILES})
target_link_libraries(ffConv ${FFMPEG_LIBRARIES}) target_link_libraries(ffConv ${FFMPEG_LIBRARIES})

View File

@ -30,7 +30,9 @@ namespace ffcpp {
} }
Codec::~Codec() { Codec::~Codec() {
//avcodec_close(_codecCtx); if(_codecCtx) {
avcodec_close(_codecCtx);
}
} }
Codec::operator AVCodecContext*() const { Codec::operator AVCodecContext*() const {
@ -69,4 +71,16 @@ namespace ffcpp {
_codecCtx->pix_fmt = pixelFormat; _codecCtx->pix_fmt = pixelFormat;
} }
Codec::Codec(Codec&& c) {
*this = std::move(c);
}
Codec& Codec::operator=(Codec&& c) {
_codec = c._codec;
_codecCtx = c._codecCtx;
c._codec = nullptr;
c._codecCtx = nullptr;
return *this;
}
} }

View File

@ -34,6 +34,10 @@ 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);
public:
Codec(Codec&& c);
Codec& operator=(Codec&& c);
}; };
} }

View File

@ -12,6 +12,10 @@ namespace ffcpp {
res = avformat_find_stream_info(_formatCtx, nullptr); res = avformat_find_stream_info(_formatCtx, nullptr);
throwIfError(res, "cannot find stream info"); throwIfError(res, "cannot find stream info");
for(size_t i = 0; i < _formatCtx->nb_streams; ++i) {
_streams.push_back(Stream(_formatCtx->streams[i]));
}
} else if(mode == Mode::Write) { } else if(mode == Mode::Write) {
int res = avformat_alloc_output_context2(&_formatCtx, nullptr, nullptr, src.c_str()); int res = avformat_alloc_output_context2(&_formatCtx, nullptr, nullptr, src.c_str());
throwIfError(res, "cannot allocate format context"); throwIfError(res, "cannot allocate format context");
@ -46,11 +50,11 @@ namespace ffcpp {
return hasStream(AVMEDIA_TYPE_AUDIO); return hasStream(AVMEDIA_TYPE_AUDIO);
} }
Stream MediaFile::getStream(AVMediaType type, size_t index) const { Stream& 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]->codec->codec_type == type) {
if(curIndex == index) { if(curIndex == index) {
return Stream(_formatCtx->streams[i]); return _streams[i];
} else { } else {
curIndex++; curIndex++;
} }
@ -60,11 +64,11 @@ namespace ffcpp {
throw std::runtime_error("cannot find stream"); throw std::runtime_error("cannot find stream");
} }
Stream MediaFile::videoStream(size_t index /* = 0 */) const { Stream& MediaFile::videoStream(size_t index /* = 0 */) {
return getStream(AVMEDIA_TYPE_VIDEO, index); return getStream(AVMEDIA_TYPE_VIDEO, index);
} }
Stream MediaFile::audioStream(size_t index /* = 0 */) const { Stream& MediaFile::audioStream(size_t index /* = 0 */) {
return getStream(AVMEDIA_TYPE_AUDIO, index); return getStream(AVMEDIA_TYPE_AUDIO, index);
} }
@ -80,7 +84,7 @@ namespace ffcpp {
} }
} }
Stream MediaFile::addStream(AVCodecID codecID, int width, int height, AVPixelFormat pixelFormat) { Stream& MediaFile::addStream(AVCodecID codecID, int width, int height, AVPixelFormat pixelFormat) {
AVCodec* codec = avcodec_find_encoder(codecID); AVCodec* codec = avcodec_find_encoder(codecID);
if(!codec) throw std::runtime_error("cannot find codec"); if(!codec) throw std::runtime_error("cannot find codec");
@ -92,7 +96,8 @@ namespace ffcpp {
ctx->height = height; ctx->height = height;
ctx->pix_fmt = pixelFormat; ctx->pix_fmt = pixelFormat;
return Stream(stream, codec); _streams.push_back(Stream(stream, codec));
return _streams.back();
} }
void MediaFile::writeHeader() { void MediaFile::writeHeader() {

View File

@ -2,12 +2,14 @@
#define FFCONV_MEDIAFILE_H #define FFCONV_MEDIAFILE_H
#include "Stream.h" #include "Stream.h"
#include "Packet.h"
extern "C" { extern "C" {
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
} }
#include <string> #include <string>
#include <vector>
namespace ffcpp { namespace ffcpp {
@ -20,6 +22,7 @@ namespace ffcpp {
private: private:
AVFormatContext* _formatCtx; AVFormatContext* _formatCtx;
Mode _mode; Mode _mode;
std::vector<Stream> _streams;
public: public:
MediaFile(const std::string& src, Mode mode); MediaFile(const std::string& src, Mode mode);
@ -28,9 +31,10 @@ namespace ffcpp {
bool hasVideo() const; bool hasVideo() const;
bool hasAudio() const; bool hasAudio() const;
Stream videoStream(size_t index = 0) const; Stream& videoStream(size_t index = 0);
Stream audioStream(size_t index = 0) const; Stream& audioStream(size_t index = 0);
Stream addStream(AVCodecID codecID, int width, int height, AVPixelFormat pixelFormat); Stream& addStream(AVCodecID codecID, int width, int height, AVPixelFormat pixelFormat);
void writeHeader(); void writeHeader();
void writeTrailer(); void writeTrailer();
@ -39,7 +43,7 @@ namespace ffcpp {
private: private:
bool hasStream(AVMediaType type) const; bool hasStream(AVMediaType type) const;
Stream getStream(AVMediaType type, size_t index) const; Stream& getStream(AVMediaType type, size_t index);
}; };
} }

10
ffcpp/Packet.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "Packet.h"
namespace ffcpp {
Packet::Packet() {
_packet.data = nullptr;
_packet.size = 0;
}
}

20
ffcpp/Packet.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef FFCONV_PACKET_H
#define FFCONV_PACKET_H
extern "C" {
#include <libavformat/avformat.h>
}
namespace ffcpp {
class Packet {
private:
AVPacket _packet;
public:
Packet();
};
}
#endif //FFCONV_PACKET_H

View File

@ -3,25 +3,23 @@
namespace ffcpp { namespace ffcpp {
Stream::Stream() { Stream::Stream(): _stream(nullptr) {
_stream = nullptr;
} }
Stream::Stream(AVStream *stream) { Stream::Stream(AVStream *stream): _stream(stream), _codec(_stream->codec, CodecType::Decoder) {
_stream = stream;
_codec = Codec(_stream->codec, CodecType::Decoder);
} }
Stream::Stream(AVStream *stream, AVCodec* encoder) { Stream::Stream(AVStream *stream, AVCodec* encoder): _stream(stream), _codec(stream->codec, encoder) {
_stream = stream;
_codec = Codec(stream->codec, encoder);
} }
Stream::operator AVStream*() const { Stream::operator AVStream*() const {
return _stream; return _stream;
} }
Codec Stream::codec() const { Codec& Stream::codec() {
return _codec; return _codec;
} }
@ -33,4 +31,15 @@ namespace ffcpp {
_stream->time_base = timeBase; _stream->time_base = timeBase;
} }
Stream::Stream(Stream&& stream) {
*this = std::move(stream);
}
Stream& Stream::operator=(Stream&& stream) {
_codec = std::move(stream._codec);
_stream = stream._stream;
stream._stream = nullptr;
return *this;
}
} }

View File

@ -19,10 +19,14 @@ namespace ffcpp {
Stream(AVStream* stream); Stream(AVStream* stream);
Stream(AVStream* stream, AVCodec* encoder); Stream(AVStream* stream, AVCodec* encoder);
operator AVStream*() const; operator AVStream*() const;
Codec codec() const; Codec& codec();
AVRational timeBase() const; AVRational timeBase() const;
void setTimeBase(AVRational timeBase); void setTimeBase(AVRational timeBase);
public:
Stream(Stream&& stream);
Stream& operator=(Stream&& stream);
}; };
} }

View File

@ -23,15 +23,12 @@ int main(int argc, char** argv) {
ff::MediaFile input(argv[1], ff::Mode::Read); ff::MediaFile input(argv[1], ff::Mode::Read);
ff::MediaFile output(argv[2], ff::Mode::Write); ff::MediaFile output(argv[2], ff::Mode::Write);
ff::Stream vStream; ff::Stream& vStream = input.videoStream();
if(input.hasVideo()) {
vStream = input.videoStream();
}
ff::Codec vDecoder = vStream.codec(); ff::Codec& vDecoder = vStream.codec();
ff::Stream outVStream = output.addStream(AV_CODEC_ID_H264, vDecoder.width(), vDecoder.height(), AV_PIX_FMT_YUV420P); ff::Stream& outVStream = output.addStream(AV_CODEC_ID_H264, vDecoder.width(), vDecoder.height(), AV_PIX_FMT_YUV420P);
outVStream.setTimeBase(vDecoder.timeBase()); outVStream.setTimeBase(vDecoder.timeBase());
ff::Codec vEncoder = outVStream.codec(); ff::Codec& vEncoder = outVStream.codec();
output.writeHeader(); output.writeHeader();
AVFrame* frame = nullptr; AVFrame* frame = nullptr;