fixed deinitialization behavior
This commit is contained in:
parent
d7f8c733ec
commit
3959e80e36
@ -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})
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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() {
|
||||||
|
|||||||
@ -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
10
ffcpp/Packet.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "Packet.h"
|
||||||
|
|
||||||
|
namespace ffcpp {
|
||||||
|
|
||||||
|
Packet::Packet() {
|
||||||
|
_packet.data = nullptr;
|
||||||
|
_packet.size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
20
ffcpp/Packet.h
Normal file
20
ffcpp/Packet.h
Normal 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
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
11
main.cpp
11
main.cpp
@ -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;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user