implement encoding a part of the host video

This commit is contained in:
falsycat 2022-10-14 00:02:48 +09:00
parent 0fde521ffe
commit 8262bf29b2
2 changed files with 70 additions and 39 deletions

View File

@ -36,6 +36,15 @@ ValueFlag<int32_t> bh {
ValueFlag<int32_t> utime { ValueFlag<int32_t> utime {
parser, "10", "duration of each feature (frame)", {"utime"}, 10, parser, "10", "duration of each feature (frame)", {"utime"}, 10,
}; };
ValueFlag<int32_t> dur {
parser, "0", "number of features to be extracted (ut)", {"dur"}, 0,
};
ValueFlag<int32_t> offset {
parser, "0", "number of offset frames to start extraction", {"offset"}, 0,
};
Flag only_body {
parser, "only-body", "cut off head and tail that no feature is embedded", {"only-body"},
};
Flag uvfix { Flag uvfix {
parser, "uvfix", "fix UV values in feature", {"uvfix"}, parser, "uvfix", "fix UV values in feature", {"uvfix"},
@ -94,6 +103,8 @@ static void Exec() {
const auto bw = args::get(param::bw); const auto bw = args::get(param::bw);
const auto bh = args::get(param::bh); const auto bh = args::get(param::bh);
const auto ut = args::get(param::utime); const auto ut = args::get(param::utime);
const auto dur = args::get(param::dur);
const auto offset = args::get(param::offset);
Enforce(bw > 0 && bh > 0, "block size must be greater than 0"); Enforce(bw > 0 && bh > 0, "block size must be greater than 0");
Enforce(ut > 0, "utime must be greater than 0"); Enforce(ut > 0, "utime must be greater than 0");
@ -151,10 +162,10 @@ static void Exec() {
// calc params // calc params
const auto tscale = tra.timescale; const auto tscale = tra.timescale;
const auto dur = const auto dur_t =
(static_cast<uint64_t>(tra.duration_hi) << 32) | (static_cast<uint64_t>(tra.duration_hi) << 32) |
static_cast<uint64_t>(tra.duration_lo); static_cast<uint64_t>(tra.duration_lo);
const auto dursec = static_cast<float>(dur)/static_cast<float>(tscale); const auto dursec = static_cast<float>(dur_t)/static_cast<float>(tscale);
const float fps = static_cast<float>(tra.sample_count)/dursec; const float fps = static_cast<float>(tra.sample_count)/dursec;
const auto fps9 = static_cast<int>(90000/fps); const auto fps9 = static_cast<int>(90000/fps);
@ -218,10 +229,10 @@ static void Exec() {
// decode frame // decode frame
Frame bf = {}; Frame bf = {};
int32_t t = 0; int32_t fidx = 0;
for (size_t si = 0; si < tra.sample_count; ++si) { for (size_t si = 0; si < tra.sample_count; ++si) {
unsigned fsz, time, dur; unsigned fsz, ftime, fdur;
const auto off = MP4D_frame_offset(&dem, ti, si, &fsz, &time, &dur); const auto off = MP4D_frame_offset(&dem, ti, si, &fsz, &ftime, &fdur);
srcst.seekg(off); srcst.seekg(off);
Enforce(!!srcst, "NAL seek failure"); Enforce(!!srcst, "NAL seek failure");
@ -247,13 +258,23 @@ static void Exec() {
// handle decoded frame // handle decoded frame
if (frame.iBufferStatus) { if (frame.iBufferStatus) {
bool encode_frame = !param::only_body;
bool keep_frame = false;
// alter the frame if it's not the first // alter the frame if it's not the first
Frame cf = {yuv, frame}; Frame cf = {yuv, frame};
if (t%ut > 0) { if (offset <= fidx && (dur == 0 || fidx-offset < dur*ut)) {
Embed(t/ut, cf, bf); const auto t = (fidx-offset)/ut;
const auto tf = (fidx-offset)%ut;
if (tf > 0) {
Embed(t, cf, bf);
}
encode_frame = true;
keep_frame = (tf == 0);
} }
// encode // encode
if (encode_frame) {
SFrameBSInfo info; SFrameBSInfo info;
SSourcePicture pic = cf.GetSourcePic(); SSourcePicture pic = cf.GetSourcePic();
Enforce(cmResultSuccess == enc->EncodeFrame(&pic, &info), Enforce(cmResultSuccess == enc->EncodeFrame(&pic, &info),
@ -272,12 +293,13 @@ static void Exec() {
} }
} }
} }
}
// save the frame if it's the first // save the frame if it's the first
if (t%ut == 0) { if (keep_frame) {
bf = std::move(cf); bf = std::move(cf);
} }
++t; ++fidx;
} }
i += sz; i += sz;
} }

View File

@ -35,6 +35,12 @@ ValueFlag<int32_t> bh {
ValueFlag<int32_t> utime { ValueFlag<int32_t> utime {
parser, "10", "duration of each feature (frame)", {"utime"}, 10, parser, "10", "duration of each feature (frame)", {"utime"}, 10,
}; };
ValueFlag<int32_t> dur {
parser, "0", "number of features to be extracted (ut)", {"dur"}, 0,
};
ValueFlag<int32_t> offset {
parser, "0", "number of offset frames to start extraction", {"offset"}, 0,
};
ValueFlag<int32_t> bmix { ValueFlag<int32_t> bmix {
parser, "8", "x interval of blockmatch (px)", {"bm-ix"}, 8, parser, "8", "x interval of blockmatch (px)", {"bm-ix"}, 8,
@ -187,6 +193,8 @@ static void Exec() {
const auto bw = args::get(param::bw); const auto bw = args::get(param::bw);
const auto bh = args::get(param::bh); const auto bh = args::get(param::bh);
const auto ut = args::get(param::utime); const auto ut = args::get(param::utime);
const auto dur = args::get(param::dur);
const auto offset = args::get(param::offset);
Enforce(bw > 0 && bh > 0, "block size must be greater than 0"); Enforce(bw > 0 && bh > 0, "block size must be greater than 0");
Enforce(ut > 0, "utime must be greater than 0"); Enforce(ut > 0, "utime must be greater than 0");
@ -265,10 +273,10 @@ static void Exec() {
// decode frame // decode frame
Frame pf = {}; Frame pf = {};
size_t t = 0; int32_t fidx = 0;
for (size_t si = 0; si < tra.sample_count; ++si) { for (size_t si = 0; si < tra.sample_count; ++si) {
unsigned fsz, time, dur; unsigned fsz, ftime, fdur;
const auto off = MP4D_frame_offset(&dem, ti, si, &fsz, &time, &dur); const auto off = MP4D_frame_offset(&dem, ti, si, &fsz, &ftime, &fdur);
vst.seekg(off); vst.seekg(off);
Enforce(!!vst, "NAL seek failure"); Enforce(!!vst, "NAL seek failure");
@ -291,16 +299,17 @@ static void Exec() {
Enforce(ret == 0, "frame decode failure"); Enforce(ret == 0, "frame decode failure");
i += sz; i += sz;
if (offset <= fidx && (dur == 0 || fidx-offset < dur*ut)) {
Frame cf = {yuv, frame}; Frame cf = {yuv, frame};
if (cf.w == 0 || cf.h == 0) continue; if (cf.w == 0 || cf.h == 0) continue;
const auto utf = t%ut; const auto tf = (fidx-offset)%ut;
if (utf > 0) { if (tf > 0) {
EachFrame(utf, cf, pf); EachFrame(tf, cf, pf);
} }
pf = std::move(cf); pf = std::move(cf);
}
++t; ++fidx;
} }
} }
} }