Skip to content

Commit 13df9ed

Browse files
committed
replace libpostproc deinterlacer with internal implementation
* Mod: drop LinearBlend and Median deinterlacer * Mod: drop libpostproc dependency * Fix: Bob/LinearBob/CubicBob supports all pixel format now * Fix: top and button pixels was blinking with Bob/LinearBob/CubicBob
1 parent 1408d4b commit 13df9ed

File tree

12 files changed

+110
-132
lines changed

12 files changed

+110
-132
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ You have to prepare next libraries, too:
2828
* libavcodec >= 55.34.1 (*)
2929
* libavutil >= 52.48.101 (*)
3030
* libavfilter (*)
31-
* libpostproc (*)
3231
* libswresample (*)
3332
* libswscale (*)
3433
* chardet (*)

build-ffmpeg

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
args="--prefix=`pwd`/build --enable-gpl --disable-debug --disable-shared --enable-static \
44
--enable-runtime-cpudetect --disable-doc --disable-programs --enable-gnutls \
5-
--disable-avdevice --enable-avfilter --enable-swresample \
6-
--disable-avresample --enable-pthreads --enable-postproc \
5+
--disable-avdevice --enable-avfilter --enable-swresample --disable-avresample --enable-pthreads \
76
--disable-encoders --disable-muxers --disable-devices --enable-filters"
87

98
kern=`uname -s`

configure

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ if has_arg "developer"; then
429429
transdir=$(pwd)/src/bomi/translations
430430
fi
431431

432-
check_pkg_or_exit ffmpeg "libavformat >= 55.12.0" "libavutil >= 52.48.101" "libavcodec >= 55.34.1" "libswresample" "libswscale" "libavfilter" "libpostproc"
432+
check_pkg_or_exit ffmpeg "libavformat >= 55.12.0" "libavutil >= 52.48.101" "libavcodec >= 55.34.1" "libswresample" "libswscale" "libavfilter"
433433
check_pkg_or_exit "libmpg123"
434434
check_pkg_or_exit "libass"
435435
check_pkg_or_exit "dvdread"

src/bomi/enum/deintmethod.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
#include "deintmethod.hpp"
22

3-
const std::array<DeintMethodInfo::Item, 7> DeintMethodInfo::info{{
3+
const std::array<DeintMethodInfo::Item, 5> DeintMethodInfo::info{{
44
{DeintMethod::None, u"None"_q, u""_q, (int)0},
55
{DeintMethod::Bob, u"Bob"_q, u""_q, (int)1},
66
{DeintMethod::LinearBob, u"LinearBob"_q, u""_q, (int)2},
77
{DeintMethod::CubicBob, u"CubicBob"_q, u""_q, (int)3},
8-
{DeintMethod::Median, u"Median"_q, u""_q, (int)4},
9-
{DeintMethod::LinearBlend, u"LinearBlend"_q, u""_q, (int)5},
10-
{DeintMethod::Yadif, u"Yadif"_q, u""_q, (int)6}
8+
{DeintMethod::Yadif, u"Yadif"_q, u""_q, (int)4}
119
}};

src/bomi/enum/deintmethod.hpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ enum class DeintMethod : int {
99
Bob = (int)1,
1010
LinearBob = (int)2,
1111
CubicBob = (int)3,
12-
Median = (int)4,
13-
LinearBlend = (int)5,
14-
Yadif = (int)6
12+
Yadif = (int)4
1513
};
1614

1715
Q_DECLARE_METATYPE(DeintMethod)
@@ -51,9 +49,9 @@ class EnumInfo<DeintMethod> {
5149
QString name, key;
5250
QVariant data;
5351
};
54-
using ItemList = std::array<Item, 7>;
52+
using ItemList = std::array<Item, 5>;
5553
static constexpr auto size() -> int
56-
{ return 7; }
54+
{ return 5; }
5755
static constexpr auto typeName() -> const char*
5856
{ return "DeintMethod"; }
5957
static constexpr auto typeKey() -> const char*
@@ -77,8 +75,6 @@ class EnumInfo<DeintMethod> {
7775
case Enum::Bob: return qApp->translate("EnumInfo", "");
7876
case Enum::LinearBob: return qApp->translate("EnumInfo", "");
7977
case Enum::CubicBob: return qApp->translate("EnumInfo", "");
80-
case Enum::Median: return qApp->translate("EnumInfo", "");
81-
case Enum::LinearBlend: return qApp->translate("EnumInfo", "");
8278
case Enum::Yadif: return qApp->translate("EnumInfo", "");
8379
default: return QString();
8480
}

src/bomi/prebuild/enum-list

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,6 @@ ${ return EnumFlags<SpeakerId>((int)lhs | (int)rhs); }
137137
-Bob
138138
-LinearBob
139139
-CubicBob
140-
-Median
141-
-LinearBlend
142140
-Yadif
143141

144142
+Interpolator[:QByteArray:]

src/bomi/video/deintcaps.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ auto DeintCaps::list() -> const QList<DeintCaps>&
2727
push(DeintMethod::Bob , true , true, true );
2828
push(DeintMethod::LinearBob , true , true, true );
2929
push(DeintMethod::CubicBob , true , true, true );
30-
push(DeintMethod::LinearBlend , true , true, false);
3130
push(DeintMethod::Yadif , true , true, true );
32-
push(DeintMethod::Median , true , true, true );
3331
return caps;
3432
}
3533

src/bomi/video/ffmpegfilters.cpp

Lines changed: 86 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -137,56 +137,101 @@ auto FFmpegFilterGraph::release() -> void
137137

138138
/******************************************************************************/
139139

140-
auto FFmpegPostProc::process(MpImage &di, const MpImage&si) const -> bool
140+
auto BobDeinterlacer::field(DeintMethod method, const MpImage &src, bool top) const -> MpImage
141141
{
142-
if (!m_context)
143-
return false;
144-
const uint8_t *src[3] = {si->planes[0], si->planes[1], si->planes[2]};
145-
uint8_t *dst[3] = {di->planes[0], di->planes[1], di->planes[2]};
146-
const int srcStride[3] = {si->stride[0], si->stride[1], si->stride[2]};
147-
const int dstStride[3] = {di->stride[0], di->stride[1], di->stride[2]};
148-
pp_postprocess(src, srcStride, dst, dstStride, si->w, si->h,
149-
nullptr, 0, m_mode, m_context, si->pict_type);
150-
return true;
151-
}
142+
if (src->num_planes < 1)
143+
return src;
144+
const int h = src->plane_h[0];
145+
if (h < 4)
146+
return src;
152147

153-
auto FFmpegPostProc::initialize(const QString &option, const QSize &size,
154-
mp_imgfmt imgfmt) -> bool
155-
{
156-
if (m_option == option && m_size == size && m_imgfmt == imgfmt)
157-
return m_context;
158-
release();
159-
m_option = option;
160-
m_size = size;
161-
m_imgfmt = imgfmt;
162-
if (m_option.isEmpty() || m_size.isEmpty())
163-
return false;
164-
int flags = PP_CPU_CAPS_AUTO;
165-
switch (imgfmt) {
166-
case IMGFMT_420P:
167-
flags |= PP_FORMAT_420;
148+
MpImage dst = std::move(newImage(src));
149+
const int stride = src->stride[0];
150+
auto in = src->planes[0], out = dst->planes[0];
151+
auto copy = [=] (int src, int dst)
152+
{ memcpy(out + dst * stride, in + src * stride, stride); };
153+
154+
switch (method) {
155+
case DeintMethod::Bob: {
156+
const int srcOffset = !top;
157+
const int count = src->plane_h[0] / 2;
158+
for (int i = 0; i < count ; ++i) {
159+
auto src = in + srcOffset * stride;
160+
memcpy(out, src, stride);
161+
out += stride;
162+
memcpy(out, src, stride);
163+
out += stride;
164+
in += 2 * stride;
165+
}
168166
break;
169-
case IMGFMT_411P:
170-
flags |= PP_FORMAT_411;
167+
} case DeintMethod::LinearBob: {
168+
const int count = h / 2 - 1;
169+
170+
if (top) {
171+
copy(h - 2, h - 1);
172+
copy(h - 2, h - 2);
173+
} else {
174+
copy(1, 0);
175+
copy(h - 1, h - 1);
176+
in += stride;
177+
out += stride;
178+
}
179+
180+
for (int i = 0; i < count ; ++i) {
181+
memcpy(out, in, stride);
182+
out += stride;
183+
auto in1 = in;
184+
auto in2 = in += stride * 2;
185+
for (int x = 0; x < stride; ++x)
186+
*out++ = (*in1++ + *in2++) / 2 ;
187+
}
171188
break;
172-
case IMGFMT_422P:
173-
flags |= PP_FORMAT_422;
189+
} case DeintMethod::CubicBob: {
190+
const int count = h / 2 - 2;
191+
192+
if (top) {
193+
copy(0, 0);
194+
copy(0, 1);
195+
copy(h - 2, h - 1);
196+
copy(h - 2, h - 2);
197+
in += stride * 2;
198+
out += stride * 2;
199+
} else {
200+
copy(1, 0);
201+
copy(1, 1);
202+
copy(3, 2);
203+
copy(h - 1, h - 1);
204+
in += stride * 3;
205+
out += stride * 3;
206+
}
207+
208+
for (int i = 0; i < count ; ++i) {
209+
memcpy(out, in, stride);
210+
out += stride;
211+
auto in0 = in - stride * 2;
212+
auto in1 = in;
213+
auto in2 = in += stride * 2;
214+
auto in3 = in + stride * 2;
215+
for (int x = 0; x < stride; ++x) {
216+
const int p0 = *in0++, p1 = *in1++, p2 = *in2++, p3 = *in3++;
217+
const auto a = -p0 + 3*p1 - 3*p2 + p3;
218+
const auto b = 2*p0 - 5*p1 + 4*p2 - p3;
219+
const auto c = -p0 + p2;
220+
const auto d = 2*p1;
221+
*out++ = (uchar)qBound(0, (a + 2*b + 4*c + 8*d)/16, 255);
222+
}
223+
}
174224
break;
175-
case IMGFMT_444P:
176-
flags |= PP_FORMAT_444;
225+
} default:
226+
memcpy(dst->planes[0], src->planes[0], src->plane_h[0]*src->stride[0]);
177227
break;
178-
default:
179-
return false;
180228
}
181-
m_mode = pp_get_mode_by_name_and_quality(m_option.toLatin1().constData(),
182-
PP_QUALITY_MAX);
183-
if (!m_mode)
184-
return false;
185-
m_context = pp_get_context(size.width(), size.height(), flags);
186-
return m_context;
229+
for (int i = 1; i < src->num_planes; ++i)
230+
memcpy(dst->planes[i], src->planes[i], src->plane_h[i]*src->stride[i]);
231+
return dst;
187232
}
188233

189-
auto FFmpegPostProc::newImage(const MpImage &mpi) const -> MpImage
234+
auto BobDeinterlacer::newImage(const MpImage &mpi) const -> MpImage
190235
{
191236
auto tmp = mp_image_pool_get(m_pool, mpi->imgfmt, mpi->stride[0], mpi->h);
192237
auto img = mp_image_new_ref(tmp);
@@ -200,11 +245,3 @@ auto FFmpegPostProc::newImage(const MpImage &mpi) const -> MpImage
200245
mp_image_copy_attributes(img, (mp_image*)mpi.data());
201246
return MpImage::wrap(img);
202247
}
203-
204-
auto FFmpegPostProc::release() -> void
205-
{
206-
if (m_context)
207-
pp_free_context(m_context);
208-
if (m_mode)
209-
pp_free_mode(m_mode);
210-
}

src/bomi/video/ffmpegfilters.hpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33

44
#include <QString>
55
#include <QSize>
6-
76
extern "C" {
87
#include <video/mp_image_pool.h>
98
#include <video/img_format.h>
109
#include <libavfilter/avfiltergraph.h>
1110
#include <libpostproc/postprocess.h>
1211
}
12+
#include "enum/deintmethod.hpp"
1313
#include "mpimage.hpp"
1414

1515
#ifdef bool
@@ -34,22 +34,13 @@ class FFmpegFilterGraph {
3434
AVFilterContext *m_src = nullptr, *m_sink = nullptr;
3535
};
3636

37-
class FFmpegPostProc {
37+
class BobDeinterlacer {
3838
public:
39-
FFmpegPostProc() { m_pool = mp_image_pool_new(10); }
40-
~FFmpegPostProc() { release(); mp_image_pool_clear(m_pool); }
41-
auto process(MpImage &dst, const MpImage &src) const -> bool;
42-
auto initialize(const QString &opt, const QSize &s, mp_imgfmt fmt) -> bool;
43-
auto initialize(const QString &opt, const MpImage &mpi) -> bool
44-
{ return initialize(opt, {mpi->w, mpi->h}, mpi->imgfmt); }
45-
auto newImage(const MpImage &mpi) const -> MpImage;
39+
BobDeinterlacer() { m_pool = mp_image_pool_new(10); }
40+
~BobDeinterlacer() { mp_image_pool_clear(m_pool); }
41+
auto field(DeintMethod method, const MpImage &src, bool top) const -> MpImage;
4642
private:
47-
auto release() -> void;
48-
QString m_option;
49-
mp_imgfmt m_imgfmt = IMGFMT_NONE;
50-
QSize m_size = {0, 0};
51-
pp_context *m_context = nullptr;
52-
pp_mode *m_mode = nullptr;
43+
auto newImage(const MpImage &mpi) const -> MpImage;
5344
mp_image_pool *m_pool = nullptr;
5445
};
5546

src/bomi/video/softwaredeinterlacer.cpp

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,16 @@ struct SoftwareDeinterlacer::Data {
99
bool rebuild = true, pass = false;
1010
DeintOption deint;
1111
FFmpegFilterGraph graph;
12-
FFmpegPostProc pp;
12+
BobDeinterlacer bob;
1313
Type type = Pass;
1414
MpImage input;
1515
int processed = 0, count = 1;
1616
mutable int i_pts = 0;
1717
double pts = MP_NOPTS_VALUE, prev = MP_NOPTS_VALUE;
1818
std::deque<MpImage> queue;
1919

20-
auto topField() const -> MpImage
21-
{
22-
auto out = pp.newImage(input);
23-
pp.process(out, input);
24-
return out;
25-
}
26-
auto bottomField() const -> MpImage
27-
{
28-
auto inm = const_cast<MpImage&>(input);
29-
auto out = pp.newImage(input);
30-
inm->planes[0] += inm->stride[0];
31-
out->planes[0] += out->stride[0];
32-
inm->h -= 2;
33-
out->h -= 2;
34-
pp.process(out, inm);
35-
out->planes[0] -= out->stride[0];
36-
inm->planes[0] -= inm->stride[0];
37-
out->h += 2;
38-
inm->h += 2;
39-
return out;
40-
}
41-
20+
auto bobField(bool top) const -> MpImage
21+
{ return bob.field(deint.method, input, top); }
4222
auto step(int split) const -> double
4323
{
4424
if (pts == MP_NOPTS_VALUE || prev == MP_NOPTS_VALUE)
@@ -86,18 +66,16 @@ auto SoftwareDeinterlacer::push(MpImage &&mpi) -> void
8666
d->processed = 0;
8767
d->pass = true;
8868
if (d->input->fields & MP_IMGFIELD_INTERLACED) {
69+
d->pass = false;
8970
switch (d->type) {
90-
case Mark: {
91-
d->pass = false;
71+
case Mark: case Bob:
9272
break;
93-
} case Graph:
73+
case Graph:
9474
if (!(d->pass = !d->graph.initialize(d->option, d->input)))
9575
d->graph.push(d->input);
9676
break;
97-
case PP:
98-
d->pass = !d->pp.initialize(d->option, d->input);
99-
break;
10077
default:
78+
d->pass = true;
10179
break;
10280
}
10381
}
@@ -129,12 +107,9 @@ auto SoftwareDeinterlacer::pop() -> MpImage
129107
ret->pts = d->nextPts();
130108
}
131109
break;
132-
} case PP: {
110+
} case Bob: {
133111
const bool topFirst = d->input->fields & MP_IMGFIELD_TOP_FIRST;
134-
if (d->processed == 0)
135-
ret = topFirst ? d->topField() : d->bottomField();
136-
else if (d->processed == 1)
137-
ret = topFirst ? d->bottomField() : d->topField();
112+
ret = d->bobField(topFirst == !d->processed);
138113
break;
139114
} default:
140115
break;
@@ -162,20 +137,11 @@ auto SoftwareDeinterlacer::setOption(const DeintOption &deint) -> void
162137
} else if (deint.processor == Processor::GPU) {
163138
d->type = Mark;
164139
} else {
165-
d->type = PP;
166140
switch (d->deint.method) {
167141
case DeintMethod::Bob:
168142
case DeintMethod::LinearBob:
169-
d->option = u"li"_q;
170-
break;
171-
case DeintMethod::LinearBlend:
172-
d->option = u"lb"_q;
173-
break;
174143
case DeintMethod::CubicBob:
175-
d->option = u"ci"_q;
176-
break;
177-
case DeintMethod::Median:
178-
d->option = u"md"_q;
144+
d->type = Bob;
179145
break;
180146
case DeintMethod::Yadif:
181147
d->option = "yadif"_a % (d->deint.doubler ? "=mode=1"_a : ""_a);

0 commit comments

Comments
 (0)