From 8262bf29b2cc0715f36e36b0c5ee94cca0cc7acb Mon Sep 17 00:00:00 2001 From: falsycat Date: Fri, 14 Oct 2022 00:02:48 +0900 Subject: [PATCH] implement encoding a part of the host video --- conv/block_stego.cc | 72 +++++++++++++++++++++++++++++---------------- conv/stego_aprob.cc | 37 ++++++++++++++--------- 2 files changed, 70 insertions(+), 39 deletions(-) diff --git a/conv/block_stego.cc b/conv/block_stego.cc index b434186..22da37e 100644 --- a/conv/block_stego.cc +++ b/conv/block_stego.cc @@ -36,6 +36,15 @@ ValueFlag bh { ValueFlag utime { parser, "10", "duration of each feature (frame)", {"utime"}, 10, }; +ValueFlag dur { + parser, "0", "number of features to be extracted (ut)", {"dur"}, 0, +}; +ValueFlag 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 { parser, "uvfix", "fix UV values in feature", {"uvfix"}, @@ -91,9 +100,11 @@ static void Embed(int32_t t, Frame& dst, const Frame& base) { } static void Exec() { - const auto bw = args::get(param::bw); - const auto bh = args::get(param::bh); - const auto ut = args::get(param::utime); + const auto bw = args::get(param::bw); + const auto bh = args::get(param::bh); + 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(ut > 0, "utime must be greater than 0"); @@ -151,10 +162,10 @@ static void Exec() { // calc params const auto tscale = tra.timescale; - const auto dur = + const auto dur_t = (static_cast(tra.duration_hi) << 32) | static_cast(tra.duration_lo); - const auto dursec = static_cast(dur)/static_cast(tscale); + const auto dursec = static_cast(dur_t)/static_cast(tscale); const float fps = static_cast(tra.sample_count)/dursec; const auto fps9 = static_cast(90000/fps); @@ -218,10 +229,10 @@ static void Exec() { // decode frame Frame bf = {}; - int32_t t = 0; + int32_t fidx = 0; for (size_t si = 0; si < tra.sample_count; ++si) { - unsigned fsz, time, dur; - const auto off = MP4D_frame_offset(&dem, ti, si, &fsz, &time, &dur); + unsigned fsz, ftime, fdur; + const auto off = MP4D_frame_offset(&dem, ti, si, &fsz, &ftime, &fdur); srcst.seekg(off); Enforce(!!srcst, "NAL seek failure"); @@ -247,37 +258,48 @@ static void Exec() { // handle decoded frame if (frame.iBufferStatus) { + bool encode_frame = !param::only_body; + bool keep_frame = false; + // alter the frame if it's not the first Frame cf = {yuv, frame}; - if (t%ut > 0) { - Embed(t/ut, cf, bf); + if (offset <= fidx && (dur == 0 || fidx-offset < dur*ut)) { + 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 - SFrameBSInfo info; - SSourcePicture pic = cf.GetSourcePic(); - Enforce(cmResultSuccess == enc->EncodeFrame(&pic, &info), - "encode failure"); + if (encode_frame) { + SFrameBSInfo info; + SSourcePicture pic = cf.GetSourcePic(); + Enforce(cmResultSuccess == enc->EncodeFrame(&pic, &info), + "encode failure"); - // write buffer - if (info.eFrameType != videoFrameTypeSkip) { - for (int li = 0; li < info.iLayerNum; ++li) { - const auto& l = info.sLayerInfo[li]; + // write buffer + if (info.eFrameType != videoFrameTypeSkip) { + for (int li = 0; li < info.iLayerNum; ++li) { + const auto& l = info.sLayerInfo[li]; - uint8_t* buf = l.pBsBuf; - for (int ni = 0; ni < l.iNalCount; ++ni) { - mp4_h26x_write_nal( - &writer, buf, l.pNalLengthInByte[ni], fps9); - buf += l.pNalLengthInByte[ni]; + uint8_t* buf = l.pBsBuf; + for (int ni = 0; ni < l.iNalCount; ++ni) { + mp4_h26x_write_nal( + &writer, buf, l.pNalLengthInByte[ni], fps9); + buf += l.pNalLengthInByte[ni]; + } } } } // save the frame if it's the first - if (t%ut == 0) { + if (keep_frame) { bf = std::move(cf); } - ++t; + ++fidx; } i += sz; } diff --git a/conv/stego_aprob.cc b/conv/stego_aprob.cc index 0cfbe3f..7d7e17f 100644 --- a/conv/stego_aprob.cc +++ b/conv/stego_aprob.cc @@ -35,6 +35,12 @@ ValueFlag bh { ValueFlag utime { parser, "10", "duration of each feature (frame)", {"utime"}, 10, }; +ValueFlag dur { + parser, "0", "number of features to be extracted (ut)", {"dur"}, 0, +}; +ValueFlag offset { + parser, "0", "number of offset frames to start extraction", {"offset"}, 0, +}; ValueFlag bmix { parser, "8", "x interval of blockmatch (px)", {"bm-ix"}, 8, @@ -184,9 +190,11 @@ static void EachFrame(int32_t t, const Frame& cf, const Frame& pf) { } static void Exec() { - const auto bw = args::get(param::bw); - const auto bh = args::get(param::bh); - const auto ut = args::get(param::utime); + const auto bw = args::get(param::bw); + const auto bh = args::get(param::bh); + 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(ut > 0, "utime must be greater than 0"); @@ -265,10 +273,10 @@ static void Exec() { // decode frame Frame pf = {}; - size_t t = 0; + int32_t fidx = 0; for (size_t si = 0; si < tra.sample_count; ++si) { - unsigned fsz, time, dur; - const auto off = MP4D_frame_offset(&dem, ti, si, &fsz, &time, &dur); + unsigned fsz, ftime, fdur; + const auto off = MP4D_frame_offset(&dem, ti, si, &fsz, &ftime, &fdur); vst.seekg(off); Enforce(!!vst, "NAL seek failure"); @@ -291,16 +299,17 @@ static void Exec() { Enforce(ret == 0, "frame decode failure"); i += sz; - Frame cf = {yuv, frame}; - if (cf.w == 0 || cf.h == 0) continue; + if (offset <= fidx && (dur == 0 || fidx-offset < dur*ut)) { + Frame cf = {yuv, frame}; + if (cf.w == 0 || cf.h == 0) continue; - const auto utf = t%ut; - if (utf > 0) { - EachFrame(utf, cf, pf); + const auto tf = (fidx-offset)%ut; + if (tf > 0) { + EachFrame(tf, cf, pf); + } + pf = std::move(cf); } - pf = std::move(cf); - - ++t; + ++fidx; } } }