mirror of https://github.com/procxx/kepka.git
Fix GIFs with alpha display.
This commit is contained in:
parent
5937b24799
commit
c2f58d3ab5
|
@ -212,6 +212,7 @@ void PaintFrameInner(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
QRect to,
|
QRect to,
|
||||||
const QImage &original,
|
const QImage &original,
|
||||||
|
bool alpha,
|
||||||
int rotation) {
|
int rotation) {
|
||||||
const auto rotated = [](QRect rect, int rotation) {
|
const auto rotated = [](QRect rect, int rotation) {
|
||||||
switch (rotation) {
|
switch (rotation) {
|
||||||
|
@ -239,22 +240,32 @@ void PaintFrameInner(
|
||||||
if (rotation) {
|
if (rotation) {
|
||||||
p.rotate(rotation);
|
p.rotate(rotation);
|
||||||
}
|
}
|
||||||
p.drawImage(rotated(to, rotation), original);
|
const auto rect = rotated(to, rotation);
|
||||||
|
if (alpha) {
|
||||||
|
p.fillRect(rect, Qt::white);
|
||||||
|
}
|
||||||
|
p.drawImage(rect, original);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PaintFrameContent(
|
void PaintFrameContent(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const QImage &original,
|
const QImage &original,
|
||||||
|
bool alpha,
|
||||||
int rotation,
|
int rotation,
|
||||||
const FrameRequest &request) {
|
const FrameRequest &request) {
|
||||||
const auto full = request.outer;
|
const auto full = request.outer.isEmpty()
|
||||||
|
? original.size()
|
||||||
|
: request.outer;
|
||||||
|
const auto size = request.resize.isEmpty()
|
||||||
|
? original.size()
|
||||||
|
: request.resize;
|
||||||
const auto to = QRect(
|
const auto to = QRect(
|
||||||
(full.width() - request.resize.width()) / 2,
|
(full.width() - size.width()) / 2,
|
||||||
(full.height() - request.resize.height()) / 2,
|
(full.height() - size.height()) / 2,
|
||||||
request.resize.width(),
|
size.width(),
|
||||||
request.resize.height());
|
size.height());
|
||||||
PaintFrameOuter(p, to, full);
|
PaintFrameOuter(p, to, full);
|
||||||
PaintFrameInner(p, to, original, rotation);
|
PaintFrameInner(p, to, original, alpha, rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyFrameRounding(QImage &storage, const FrameRequest &request) {
|
void ApplyFrameRounding(QImage &storage, const FrameRequest &request) {
|
||||||
|
@ -267,17 +278,21 @@ void ApplyFrameRounding(QImage &storage, const FrameRequest &request) {
|
||||||
|
|
||||||
QImage PrepareByRequest(
|
QImage PrepareByRequest(
|
||||||
const QImage &original,
|
const QImage &original,
|
||||||
|
bool alpha,
|
||||||
int rotation,
|
int rotation,
|
||||||
const FrameRequest &request,
|
const FrameRequest &request,
|
||||||
QImage storage) {
|
QImage storage) {
|
||||||
Expects(!request.outer.isEmpty());
|
Expects(!request.outer.isEmpty() || alpha);
|
||||||
|
|
||||||
if (!FFmpeg::GoodStorageForFrame(storage, request.outer)) {
|
const auto outer = request.outer.isEmpty()
|
||||||
storage = FFmpeg::CreateFrameStorage(request.outer);
|
? original.size()
|
||||||
|
: request.outer;
|
||||||
|
if (!FFmpeg::GoodStorageForFrame(storage, outer)) {
|
||||||
|
storage = FFmpeg::CreateFrameStorage(outer);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPainter p(&storage);
|
QPainter p(&storage);
|
||||||
PaintFrameContent(p, original, rotation, request);
|
PaintFrameContent(p, original, alpha, rotation, request);
|
||||||
p.end();
|
p.end();
|
||||||
|
|
||||||
ApplyFrameRounding(storage, request);
|
ApplyFrameRounding(storage, request);
|
||||||
|
|
|
@ -60,6 +60,7 @@ struct Stream {
|
||||||
QImage storage);
|
QImage storage);
|
||||||
[[nodiscard]] QImage PrepareByRequest(
|
[[nodiscard]] QImage PrepareByRequest(
|
||||||
const QImage &original,
|
const QImage &original,
|
||||||
|
bool alpha,
|
||||||
int rotation,
|
int rotation,
|
||||||
const FrameRequest &request,
|
const FrameRequest &request,
|
||||||
QImage storage);
|
QImage storage);
|
||||||
|
|
|
@ -361,6 +361,7 @@ void VideoTrackObject::presentFrameIfNeeded() {
|
||||||
Expects(frame->position != kFinishedPosition);
|
Expects(frame->position != kFinishedPosition);
|
||||||
|
|
||||||
fillRequests(frame);
|
fillRequests(frame);
|
||||||
|
frame->alpha = (frame->decoded->format == AV_PIX_FMT_BGRA);
|
||||||
frame->original = ConvertFrame(
|
frame->original = ConvertFrame(
|
||||||
_stream,
|
_stream,
|
||||||
frame->decoded.get(),
|
frame->decoded.get(),
|
||||||
|
@ -982,7 +983,8 @@ QImage VideoTrack::frame(
|
||||||
unwrapped.updateFrameRequest(instance, useRequest);
|
unwrapped.updateFrameRequest(instance, useRequest);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (GoodForRequest(frame->original, _streamRotation, useRequest)) {
|
if (!frame->alpha
|
||||||
|
&& GoodForRequest(frame->original, _streamRotation, useRequest)) {
|
||||||
return frame->original;
|
return frame->original;
|
||||||
} else if (changed || none || i->second.image.isNull()) {
|
} else if (changed || none || i->second.image.isNull()) {
|
||||||
const auto j = none
|
const auto j = none
|
||||||
|
@ -1002,6 +1004,7 @@ QImage VideoTrack::frame(
|
||||||
}
|
}
|
||||||
j->second.image = PrepareByRequest(
|
j->second.image = PrepareByRequest(
|
||||||
frame->original,
|
frame->original,
|
||||||
|
frame->alpha,
|
||||||
_streamRotation,
|
_streamRotation,
|
||||||
useRequest,
|
useRequest,
|
||||||
std::move(j->second.image));
|
std::move(j->second.image));
|
||||||
|
@ -1025,7 +1028,8 @@ void VideoTrack::PrepareFrameByRequests(
|
||||||
const auto end = frame->prepared.end();
|
const auto end = frame->prepared.end();
|
||||||
for (auto i = begin; i != end; ++i) {
|
for (auto i = begin; i != end; ++i) {
|
||||||
auto &prepared = i->second;
|
auto &prepared = i->second;
|
||||||
if (!GoodForRequest(frame->original, rotation, prepared.request)) {
|
if (frame->alpha
|
||||||
|
|| !GoodForRequest(frame->original, rotation, prepared.request)) {
|
||||||
auto j = begin;
|
auto j = begin;
|
||||||
for (; j != i; ++j) {
|
for (; j != i; ++j) {
|
||||||
if (j->second.request == prepared.request) {
|
if (j->second.request == prepared.request) {
|
||||||
|
@ -1036,6 +1040,7 @@ void VideoTrack::PrepareFrameByRequests(
|
||||||
if (j == i) {
|
if (j == i) {
|
||||||
prepared.image = PrepareByRequest(
|
prepared.image = PrepareByRequest(
|
||||||
frame->original,
|
frame->original,
|
||||||
|
frame->alpha,
|
||||||
rotation,
|
rotation,
|
||||||
prepared.request,
|
prepared.request,
|
||||||
std::move(prepared.image));
|
std::move(prepared.image));
|
||||||
|
|
|
@ -83,6 +83,8 @@ private:
|
||||||
crl::time display = kTimeUnknown;
|
crl::time display = kTimeUnknown;
|
||||||
|
|
||||||
base::flat_map<const Instance*, Prepared> prepared;
|
base::flat_map<const Instance*, Prepared> prepared;
|
||||||
|
|
||||||
|
bool alpha = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Shared {
|
class Shared {
|
||||||
|
|
|
@ -1391,6 +1391,7 @@ QImage Pip::videoFrame(const FrameRequest &request) const {
|
||||||
if (state == ThumbState::Cover) {
|
if (state == ThumbState::Cover) {
|
||||||
_preparedCoverStorage = Streaming::PrepareByRequest(
|
_preparedCoverStorage = Streaming::PrepareByRequest(
|
||||||
_instance.info().video.cover,
|
_instance.info().video.cover,
|
||||||
|
false,
|
||||||
_instance.info().video.rotation,
|
_instance.info().video.rotation,
|
||||||
request,
|
request,
|
||||||
std::move(_preparedCoverStorage));
|
std::move(_preparedCoverStorage));
|
||||||
|
|
Loading…
Reference in New Issue