feat(app): add mk-moshable

This commit is contained in:
Jonas Röger 2025-11-24 01:22:23 +01:00
parent 6e07b36f02
commit ce0b64d24f
Signed by: jonas
GPG Key ID: 4000EB35E1AE0F07
2 changed files with 97 additions and 1 deletions

View File

@ -18,8 +18,15 @@ target_link_libraries(mosh-me avcpp::avcpp spdlog::spdlog)
target_compile_features(mosh-me PUBLIC cxx_std_23) target_compile_features(mosh-me PUBLIC cxx_std_23)
target_include_directories(mosh-me PRIVATE ${PROJECT_SOURCE_DIR}/include) target_include_directories(mosh-me PRIVATE ${PROJECT_SOURCE_DIR}/include)
add_executable(mk-moshable
${PROJECT_SOURCE_DIR}/app/mk-moshable.cpp
)
target_link_libraries(mk-moshable avcpp::avcpp spdlog::spdlog)
target_compile_features(mk-moshable PUBLIC cxx_std_23)
target_include_directories(mk-moshable PRIVATE ${PROJECT_SOURCE_DIR}/include)
install(TARGETS mosh-me mosh-me)
install(TARGETS mosh-me mk-moshable)
################################################################################ ################################################################################

89
app/mk-moshable.cpp Normal file
View File

@ -0,0 +1,89 @@
#include <avcpp/av.h>
#include <avcpp/codeccontext.h>
#include <avcpp/formatcontext.h>
#include <avcpp/stream.h>
#include <spdlog/spdlog.h>
int main(int argc, char *argv[]) {
if (argc < 3) {
spdlog::error("Please invoke with {} <ifile> <ofile>", argv[0]);
}
av::init();
try {
av::FormatContext ictx;
ictx.openInput(argv[1]);
ictx.findStreamInfo();
off_t v_istream_ix = -1;
for (off_t i = 0; i < ictx.streamsCount(); i++) {
auto stream = ictx.stream(i);
if (stream.isVideo() && stream.isValid()) {
v_istream_ix = i;
}
}
if (v_istream_ix == -1) {
spdlog::error("No video stream found in {}", argv[1]);
return 1;
}
av::VideoDecoderContext decoder(ictx.stream(v_istream_ix));
decoder.open();
av::FormatContext octx;
av::OutputFormat ofmt;
ofmt.setFormat("", argv[2]);
octx.setFormat(ofmt);
auto ocodec = av::findEncodingCodec("libxvid");
av::VideoEncoderContext encoder(ocodec);
encoder.setPixelFormat(decoder.pixelFormat());
encoder.setWidth(decoder.width());
encoder.setHeight(decoder.height());
encoder.setGopSize(1000);
encoder.setMaxBFrames(0);
encoder.setGlobalQuality(1);
encoder.raw()->qmin = 1;
encoder.raw()->qmax = 1;
encoder.setFlags(AV_CODEC_FLAG_QPEL | AV_CODEC_FLAG_4MV);
encoder.setTimeBase({1, 1000});
encoder.open();
auto ostream = octx.addStream(encoder);
ostream.setFrameRate(ictx.stream(v_istream_ix).frameRate());
octx.openOutput(argv[2]);
octx.writeHeader();
for (;;) {
auto pkt = ictx.readPacket();
if (pkt.isNull()) {
break;
}
if (pkt.streamIndex() != v_istream_ix) {
continue;
}
auto frame = decoder.decode(pkt);
if (frame) {
frame.setTimeBase(encoder.timeBase());
frame.setStreamIndex(0);
frame.setPictureType();
auto opkt = encoder.encode(frame);
if (opkt) {
opkt.setStreamIndex(0);
octx.writePacket(opkt);
}
}
}
octx.writeTrailer();
octx.flush();
} catch (const av::Exception &e) {
spdlog::error("{}", e.what());
}
}