Commit 1ffe45e7 authored by Linshizhi's avatar Linshizhi

Implement IOCtx.

parent 1e0a94a7
......@@ -31,6 +31,7 @@ ExternalProject_Add(
--disable-ffmpeg --disable-ffprobe --disable-ffplay --prefix=${PROJECT_SOURCE_DIR}/lib/
BUILD_COMMAND make -j
INSTALL_COMMAND make install
UPDATE_COMMAND ""
)
set(SRC ${ROOT}/src)
......
#include "ioctx.h"
namespace IOCtx {
///////////////////////////////////////////////////////////////////////////////
// InCtx //
///////////////////////////////////////////////////////////////////////////////
InCtx::InCtx(std::string path, CustomProto proto):
fmt(nullptr) {
// Build AVIOContex for custom proto
AVIOContext *customIO = nullptr;
fmt = Utils::makeInAVFormat(path, customIO);
}
void InCtx::readFrame(AVPacket *packet) {
if (av_read_frame(fmt.get(), packet) < 0)
throw IO_ERROR();
}
bool InCtx::isReady() noexcept {
return fmt.get() != nullptr;
}
///////////////////////////////////////////////////////////////////////////////
// OutCtx //
///////////////////////////////////////////////////////////////////////////////
OutCtx::OutCtx(std::string path, CustomProto proto):
fmt(nullptr) {
}
}
#include <string>
#include <stdexcept>
#include "utils.h"
extern "C" {
#include <libavformat/avformat.h>
}
#ifndef IOCTX_H
#define IOCTX_H
namespace IOCtx {
// Forward Declarations
class InCtx;
class OutCtx;
// Extra support custom protos
enum CustomProto {
SHARED_MEMORY
};
class END_OF_FILE: public std::runtime_error {
public:
END_OF_FILE(): std::runtime_error("") {}
};
class IO_ERROR: public std::runtime_error {
public:
IO_ERROR(): std::runtime_error("") {}
};
class InCtx {
// OutCtx require parameters of InCtx
// to initialize.
friend OutCtx;
public:
InCtx(std::string path):
fmt(Utils::makeInAVFormat(path, nullptr)) {}
InCtx(std::string path, CustomProto proto);
void readFrame(AVPacket*);
bool isReady() noexcept;
private:
Utils::AVFormatContextShared fmt;
};
class OutCtx {
public:
OutCtx(std::string path):
fmt(Utils::makeOutAVFormat(path, nullptr)) {}
OutCtx(std::string path, CustomProto proto);
void writeFrame(AVPacket*);
bool isReady() noexcept;
private:
Utils::AVFormatContextShared fmt;
};
}
#endif /* IOCTX_H */
#include "utils.h"
namespace Utils {
static AVFormatContext* AVFormatInputContextConstructor(
std::string path, AVIOContext *customIO) {
AVFormatContext *ctx = customIO == nullptr ? nullptr : avformat_alloc_context();
ctx->pb = customIO;
if (avformat_open_input(&ctx, path.c_str(), nullptr, nullptr) < 0) {
return nullptr;
}
if (avformat_find_stream_info(ctx, nullptr) < 0) {
avformat_close_input(&ctx);
return nullptr;
}
return ctx;
}
static void AVFormatInputContextDestructor(AVFormatContext *ctx) {
avformat_close_input(&ctx);
}
AVFormatContextShared makeInAVFormat(std::string path, AVIOContext *customIO) {
AVFormatContextShared ioCtx {
AVFormatInputContextConstructor(path, customIO),
AVFormatInputContextDestructor
};
return ioCtx;
}
static AVFormatContext* AVFormatOutputContextConstructor(
std::string path, AVIOContext *customIO) {
AVFormatContext *ctx = customIO == nullptr ? nullptr : avformat_alloc_context();
ctx->pb = customIO;
if (avformat_open_input(&ctx, path.c_str(), nullptr, nullptr) < 0) {
return nullptr;
}
return ctx;
}
static void AVFormatOutputContextDestructor(AVFormatContext *ctx) {
avformat_close_input(&ctx);
}
AVFormatContextShared makeOutAVFormat(std::string path, AVIOContext *customIO) {
AVFormatContextShared ioCtx {
AVFormatOutputContextConstructor(path, customIO),
AVFormatOutputContextDestructor
};
return ioCtx;
}
}
#include <string>
#include <memory>
extern "C" {
#include <libavformat/avformat.h>
}
#ifndef UTILS_H
#define UTILS_H
namespace Utils {
using AVFormatContextShared = std::shared_ptr<AVFormatContext>;
AVFormatContextShared makeInAVFormat(std::string, AVIOContext*);
AVFormatContextShared makeOutAVFormat(std::string, AVIOContext*);
/* To check that is video specified by path valid
*
* This function require that ffmpeg is installed on
* running envrionment */
bool isVideoValid(std::string path);
}
#endif /* UTILS_H */
#include <gtest/gtest.h>
#include <string>
#include "ioctx.h"
#include "utils.h"
extern "C" {
#include <libavformat/avformat.h>
}
class IOCTX_With_Default_Proto_Fixture: public ::testing::Test {
protected:
void SetUp() override {
oCtx = OutCtx(outFilePath, iCtx);
}
std::string inFilePath = "./resources/sample.mp4";
std::string outFilePath = "./resources/sample_out.mp4";
InCtx iCtx { inFilePath };
OutCtx oCtx;
};
class IOCTX_With_SharedMemory_Proto_Fixture: public ::testing::Test {
protected:
void SetUp() override {
}
InCtx iCtx;
OutCtx oCtx;
};
TEST_F(IOCTX_With_Default_Proto_Fixture, Description) {
AVPacket packet;
iCtx.readFrame(&packet);
oCtx.writeFrame(&packet);
ASSERT_TRUE(Utils::isVideoValid(outFilePath));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment