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})
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})
target_link_libraries(ffConv ${FFMPEG_LIBRARIES})

View File

@ -30,7 +30,9 @@ namespace ffcpp {
}
Codec::~Codec() {
//avcodec_close(_codecCtx);
if(_codecCtx) {
avcodec_close(_codecCtx);
}
}
Codec::operator AVCodecContext*() const {
@ -69,4 +71,16 @@ namespace ffcpp {
_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 setHeight(int height);
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);
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) {
int res = avformat_alloc_output_context2(&_formatCtx, nullptr, nullptr, src.c_str());
throwIfError(res, "cannot allocate format context");
@ -46,11 +50,11 @@ namespace ffcpp {
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) {
if(_formatCtx->streams[i]->codec->codec_type == type) {
if(curIndex == index) {
return Stream(_formatCtx->streams[i]);
return _streams[i];
} else {
curIndex++;
}
@ -60,11 +64,11 @@ namespace ffcpp {
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);
}
Stream MediaFile::audioStream(size_t index /* = 0 */) const {
Stream& MediaFile::audioStream(size_t index /* = 0 */) {
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);
if(!codec) throw std::runtime_error("cannot find codec");
@ -92,7 +96,8 @@ namespace ffcpp {
ctx->height = height;
ctx->pix_fmt = pixelFormat;
return Stream(stream, codec);
_streams.push_back(Stream(stream, codec));
return _streams.back();
}
void MediaFile::writeHeader() {

View File

@ -2,12 +2,14 @@
#define FFCONV_MEDIAFILE_H
#include "Stream.h"
#include "Packet.h"
extern "C" {
#include <libavformat/avformat.h>
}
#include <string>
#include <vector>
namespace ffcpp {
@ -20,6 +22,7 @@ namespace ffcpp {
private:
AVFormatContext* _formatCtx;
Mode _mode;
std::vector<Stream> _streams;
public:
MediaFile(const std::string& src, Mode mode);
@ -28,9 +31,10 @@ namespace ffcpp {
bool hasVideo() const;
bool hasAudio() const;
Stream videoStream(size_t index = 0) const;
Stream audioStream(size_t index = 0) const;
Stream addStream(AVCodecID codecID, int width, int height, AVPixelFormat pixelFormat);
Stream& videoStream(size_t index = 0);
Stream& audioStream(size_t index = 0);
Stream& addStream(AVCodecID codecID, int width, int height, AVPixelFormat pixelFormat);
void writeHeader();
void writeTrailer();
@ -39,7 +43,7 @@ namespace ffcpp {
private:
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 {
Stream::Stream() {
_stream = nullptr;
Stream::Stream(): _stream(nullptr) {
}
Stream::Stream(AVStream *stream) {
_stream = stream;
_codec = Codec(_stream->codec, CodecType::Decoder);
Stream::Stream(AVStream *stream): _stream(stream), _codec(_stream->codec, CodecType::Decoder) {
}
Stream::Stream(AVStream *stream, AVCodec* encoder) {
_stream = stream;
_codec = Codec(stream->codec, encoder);
Stream::Stream(AVStream *stream, AVCodec* encoder): _stream(stream), _codec(stream->codec, encoder) {
}
Stream::operator AVStream*() const {
return _stream;
}
Codec Stream::codec() const {
Codec& Stream::codec() {
return _codec;
}
@ -33,4 +31,15 @@ namespace ffcpp {
_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, AVCodec* encoder);
operator AVStream*() const;
Codec codec() const;
Codec& codec();
AVRational timeBase() const;
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 output(argv[2], ff::Mode::Write);
ff::Stream vStream;
if(input.hasVideo()) {
vStream = input.videoStream();
}
ff::Stream& vStream = input.videoStream();
ff::Codec vDecoder = vStream.codec();
ff::Stream outVStream = output.addStream(AV_CODEC_ID_H264, vDecoder.width(), vDecoder.height(), AV_PIX_FMT_YUV420P);
ff::Codec& vDecoder = vStream.codec();
ff::Stream& outVStream = output.addStream(AV_CODEC_ID_H264, vDecoder.width(), vDecoder.height(), AV_PIX_FMT_YUV420P);
outVStream.setTimeBase(vDecoder.timeBase());
ff::Codec vEncoder = outVStream.codec();
ff::Codec& vEncoder = outVStream.codec();
output.writeHeader();
AVFrame* frame = nullptr;