mirror of https://github.com/procxx/kepka.git
Add limits on video frame size.
Any video that starts streaming is limited to 4K. Any in-chat streaming is limited to full hd. Any GIF panel animation is limited to 720p.
This commit is contained in:
parent
2c0b852dad
commit
01c79f917e
|
@ -40,6 +40,7 @@ namespace {
|
|||
|
||||
constexpr auto kMaxGifForwardedBarLines = 4;
|
||||
constexpr auto kUseNonBlurredThreshold = 240;
|
||||
constexpr auto kMaxInlineArea = 1920 * 1080;
|
||||
|
||||
int gifMaxStatusWidth(DocumentData *document) {
|
||||
auto result = st::normalFont->width(formatDownloadText(document->size, document->size));
|
||||
|
@ -47,6 +48,11 @@ int gifMaxStatusWidth(DocumentData *document) {
|
|||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool CanPlayInline(not_null<DocumentData*> document) {
|
||||
const auto dimensions = document->dimensions;
|
||||
return dimensions.width() * dimensions.height() <= kMaxInlineArea;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
struct Gif::Streamed {
|
||||
|
@ -261,7 +267,7 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
|
|||
const auto selected = (selection == FullSelection);
|
||||
const auto autoPaused = App::wnd()->sessionController()->isGifPausedAtLeastFor(Window::GifPauseReason::Any);
|
||||
const auto cornerDownload = downloadInCorner();
|
||||
const auto canBePlayed = _data->canBePlayed();
|
||||
const auto canBePlayed = _data->canBePlayed() && CanPlayInline(_data);
|
||||
const auto autoplay = autoplayEnabled() && canBePlayed;
|
||||
const auto activeRoundPlaying = activeRoundStreamed();
|
||||
const auto startPlay = autoplay
|
||||
|
@ -865,7 +871,7 @@ void Gif::drawGrouped(
|
|||
const auto autoPaused = App::wnd()->sessionController()->isGifPausedAtLeastFor(Window::GifPauseReason::Any);
|
||||
const auto fullFeatured = fullFeaturedGrouped(sides);
|
||||
const auto cornerDownload = fullFeatured && downloadInCorner();
|
||||
const auto canBePlayed = _data->canBePlayed();
|
||||
const auto canBePlayed = _data->canBePlayed() && CanPlayInline(_data);;
|
||||
const auto autoplay = fullFeatured && autoplayEnabled() && canBePlayed;
|
||||
const auto startPlay = autoplay && !_streamed;
|
||||
if (startPlay) {
|
||||
|
@ -1404,7 +1410,13 @@ void Gif::repaintStreamedContent() {
|
|||
}
|
||||
|
||||
void Gif::streamingReady(::Media::Streaming::Information &&info) {
|
||||
history()->owner().requestViewResize(_parent);
|
||||
if (info.video.size.width() * info.video.size.height()
|
||||
> kMaxInlineArea) {
|
||||
_data->dimensions = info.video.size;
|
||||
stopAnimation();
|
||||
} else {
|
||||
history()->owner().requestViewResize(_parent);
|
||||
}
|
||||
}
|
||||
|
||||
void Gif::stopAnimation() {
|
||||
|
|
|
@ -35,6 +35,13 @@ namespace internal {
|
|||
|
||||
using TextState = HistoryView::TextState;
|
||||
|
||||
constexpr auto kMaxInlineArea = 1280 * 720;
|
||||
|
||||
[[nodiscard]] bool CanPlayInline(not_null<DocumentData*> document) {
|
||||
const auto dimensions = document->dimensions;
|
||||
return dimensions.width() * dimensions.height() <= kMaxInlineArea;
|
||||
}
|
||||
|
||||
FileBase::FileBase(not_null<Context*> context, not_null<Result*> result)
|
||||
: ItemBase(context, result) {
|
||||
}
|
||||
|
@ -141,7 +148,10 @@ void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) cons
|
|||
document->automaticLoad(fileOrigin(), nullptr);
|
||||
|
||||
bool loaded = document->loaded(), loading = document->loading(), displayLoading = document->displayLoading();
|
||||
if (loaded && !_gif && !_gif.isBad()) {
|
||||
if (loaded
|
||||
&& !_gif
|
||||
&& !_gif.isBad()
|
||||
&& CanPlayInline(document)) {
|
||||
auto that = const_cast<Gif*>(this);
|
||||
that->_gif = Media::Clip::MakeReader(document, FullMsgId(), [that](Media::Clip::Notification notification) {
|
||||
that->clipCallback(notification);
|
||||
|
@ -371,9 +381,16 @@ void Gif::clipCallback(Media::Clip::Notification notification) {
|
|||
_gif.setBad();
|
||||
getShownDocument()->unload();
|
||||
} else if (_gif->ready() && !_gif->started()) {
|
||||
auto height = st::inlineMediaHeight;
|
||||
auto frame = countFrameSize();
|
||||
_gif->start(frame.width(), frame.height(), _width, height, ImageRoundRadius::None, RectPart::None);
|
||||
if (_gif->width() * _gif->height() > kMaxInlineArea) {
|
||||
getShownDocument()->dimensions = QSize(
|
||||
_gif->width(),
|
||||
_gif->height());
|
||||
unloadAnimation();
|
||||
} else {
|
||||
auto height = st::inlineMediaHeight;
|
||||
auto frame = countFrameSize();
|
||||
_gif->start(frame.width(), frame.height(), _width, height, ImageRoundRadius::None, RectPart::None);
|
||||
}
|
||||
} else if (_gif->autoPausedGif() && !context()->inlineItemVisible(this)) {
|
||||
unloadAnimation();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace internal {
|
|||
namespace {
|
||||
|
||||
constexpr auto kSkipInvalidDataPackets = 10;
|
||||
constexpr auto kMaxInlineArea = 1280 * 720;
|
||||
|
||||
// See https://github.com/telegramdesktop/tdesktop/issues/7225
|
||||
constexpr auto kAlignImageBy = 64;
|
||||
|
@ -59,6 +60,9 @@ ReaderImplementation::ReadResult FFMpegReaderImplementation::readNextFrame() {
|
|||
do {
|
||||
int res = avcodec_receive_frame(_codecContext, _frame.get());
|
||||
if (res >= 0) {
|
||||
if (_frame->width * _frame->height > kMaxInlineArea) {
|
||||
return ReadResult::Error;
|
||||
}
|
||||
processReadFrame();
|
||||
return ReadResult::Success;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Media {
|
|||
namespace Streaming {
|
||||
namespace {
|
||||
|
||||
constexpr auto kMaxFrameArea = 3840 * 2160; // usual 4K
|
||||
constexpr auto kDisplaySkipped = crl::time(-1);
|
||||
constexpr auto kFinishedPosition = std::numeric_limits<crl::time>::max();
|
||||
static_assert(kDisplaySkipped != kTimeUnknown);
|
||||
|
@ -511,6 +512,9 @@ bool VideoTrackObject::tryReadFirstFrame(FFmpeg::Packet &&packet) {
|
|||
}
|
||||
|
||||
bool VideoTrackObject::processFirstFrame() {
|
||||
if (_stream.frame->width * _stream.frame->height >= kMaxFrameArea) {
|
||||
return false;
|
||||
}
|
||||
auto frame = ConvertFrame(
|
||||
_stream,
|
||||
_stream.frame.get(),
|
||||
|
|
Loading…
Reference in New Issue