Commit 9fe2e5d4 authored by Linshizhi's avatar Linshizhi

MovMemProto pass unittests.

parent 2c730355
......@@ -41,7 +41,8 @@ set(SRC_Files
${SRC}/utils.cc
${SRC}/proto/proto.cc
${SRC}/proto/sharedMemProto.cc
${SRC}/proto/transientMemProto.cc)
${SRC}/proto/transientMemProto.cc
${SRC}/proto/movMemProto.cc)
add_library(smp ${SRC_Files})
# Tests
......
......@@ -55,6 +55,13 @@ void InCtx::readFrame(AVPacket *packet) {
}
}
int InCtx::readFrame_(AVPacket *packet) {
auto fmt_ = fmt.get();
if (fmt_ == nullptr) {
return -100;
}
return av_read_frame(fmt_, packet);
}
///////////////////////////////////////////////////////////////////////////////
// OutCtx //
......
......@@ -83,6 +83,7 @@ public:
}
void readFrame(AVPacket*);
int readFrame_(AVPacket*);
};
......
......@@ -45,7 +45,7 @@ int MovMemProto::read_packet_internal(void *priv, uint8_t *buf, int bufSize) {
trans.remain = 0;
}
return sizeToRead;
return sizeToRead == 0 ? AVERROR(EAGAIN) : sizeToRead;
}
int MovMemProto::write_packet_internal(void *priv, uint8_t *buf, int bufSize) {
......@@ -53,7 +53,7 @@ int MovMemProto::write_packet_internal(void *priv, uint8_t *buf, int bufSize) {
}
int64_t MovMemProto::seek_packet_internal(void *opaque, int64_t offset, int whence) {
throw std::runtime_error("MovMemProto not support seek");
return 0;
}
void MovMemProto::close_internal() {
......
......@@ -40,8 +40,12 @@ public:
void close_internal();
void push(MemPiece data) {
s.push(data);
void push(uint8_t *data, size_t size) {
s.push(MemPiece{ std::shared_ptr<uint8_t>(data), size });
}
void eof() {
s.push(MemPiece{ nullptr, 0 });
}
private:
......
......@@ -68,9 +68,11 @@ public:
[](void *priv, uint8_t *buf, int bufSize) -> int {
return static_cast<T*>(priv)->write_packet(priv, buf, bufSize);
},
[](void *priv, int64_t offset, int whence) -> int64_t {
return static_cast<T*>(priv)->seek_packet(priv, offset, whence);
});
nullptr
//[](void *priv, int64_t offset, int whence) -> int64_t {
// return static_cast<T*>(priv)->seek_packet(priv, offset, whence);
//}
);
}
return io;
......
......@@ -3,10 +3,14 @@
#include "ioctx.h"
#include "utils.h"
#include "proto/transientMemProto.h"
#include "proto/movMemProto.h"
#include <thread>
extern "C" {
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libavcodec/avcodec.h>
#include <malloc.h>
}
......@@ -63,6 +67,7 @@ protected:
IOCtx::OutCtx oCtx { outFilePath };
};
TEST_F(IOCTX_With_Default_Proto_Fixture, Description) {
AVPacket packet;
......@@ -159,3 +164,134 @@ TEST_F(IOCTX_With_TransientMem_Proto_Fixture, Description) {
ASSERT_TRUE(Utils::isVideoValid(outFilePath));
}
class IOCTX_With_MovMem_Proto_Fixture: public ::testing::Test {
protected:
std::string outFilePath = "./resources/small_bunny_1080p_60fps_out_MM.mp4";
IOCtx::InCtx *inCtxMM;
IOCtx::OutCtx oCtx { outFilePath };
};
TEST_F(IOCTX_With_MovMem_Proto_Fixture, Initialize) {
// Prepare MM InCtx;
IOProto::MovMemProto::MovMemProto *mmProto =
new IOProto::MovMemProto::MovMemProto(nullptr, IOProto::read);
std::thread t1([mmProto]() {
AVPacket packet;
std::string inFilePath = "./resources/small_bunny_1080p_60fps.mp4";
IOCtx::InCtx inCtx { inFilePath };
AVBSFContext *bsCtx = NULL;
const AVBitStreamFilter *h264toannexb = av_bsf_get_by_name("h264_mp4toannexb");
av_bsf_alloc(h264toannexb, &bsCtx);
if (bsCtx == NULL) {
abort();
}
AVStream *s = inCtx.getStream([](AVStream *s) {
return s->codecpar->codec_type == AVMEDIA_TYPE_VIDEO;
});
avcodec_parameters_copy(bsCtx->par_in, s->codecpar);
avcodec_parameters_copy(bsCtx->par_out, s->codecpar);
if (av_bsf_init(bsCtx) < 0) {
printf("failed to init\n");
abort();
}
int i = 0;
uint8_t *mem;
while (true) {
int ret = inCtx.readFrame_(&packet);
if (ret < 0) break;
/* Packet need to do bitstream modification
* before sending */
ret = av_bsf_send_packet(bsCtx, &packet);
if (ret < 0) {
printf("failed to send packet to bs filter");
abort();
}
ret = av_bsf_receive_packet(bsCtx, &packet);
if (ret < 0) {
printf("Failed to receive packet from bs filter");
abort();
}
mem = (uint8_t*)malloc(packet.size);
memcpy(mem, packet.data, packet.size);
mmProto->push(mem, packet.size);
++i;
av_packet_unref(&packet);
}
mmProto->eof();
});
t1.detach();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
inCtxMM = new IOCtx::InCtx("", mmProto);
AVStream *s = inCtxMM->getStream([](AVStream *s) {
return s->codecpar->codec_type == AVMEDIA_TYPE_VIDEO;
});
if (s == NULL) {
abort();
}
if (oCtx.newStream(s->codecpar) == IOCtx::ERROR)
throw std::runtime_error("Failed to init fixture");
oCtx.writeHeader();
bool init = false;
int timescale = 90000;
int fps = 30;
AVRational tb = av_make_q(1, timescale);
int duration = timescale/fps;
int lastPTS = 0, lastDTS = 0;
while (true) {
AVPacket packet;
int ret = inCtxMM->readFrame_(&packet);
if (ret < 0) {
if (ret == -100)
FAIL();
break;
};
if (init == false) {
packet.pts = 0;
packet.dts = -duration;
packet.duration = duration;
lastPTS = packet.pts;
lastDTS = packet.dts;
init = true;
} else {
packet.pts = lastPTS + duration;
packet.dts = lastDTS + duration;
lastPTS += duration;
lastDTS += duration;
}
packet.stream_index = 0;
packet.pos = -1;
oCtx.writeFrame(&packet);
av_packet_unref(&packet);
}
oCtx.writeTrailer();
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