improved bad gif handling in autoplay, replaced av_free_packet with av_packet_unref

This commit is contained in:
John Preston 2015-12-25 16:10:13 +03:00
parent f0a08a8713
commit 972e78ae7a
5 changed files with 46 additions and 23 deletions

View File

@ -1289,7 +1289,7 @@ public:
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
LOG(("Audio Error: Unable to avcodec_decode_audio4() file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
av_free_packet(&avpkt);
av_packet_unref(&avpkt);
if (res == AVERROR_INVALIDDATA) return 0; // try to skip bad packet
return -1;
}
@ -1306,7 +1306,7 @@ public:
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
av_free_packet(&avpkt);
av_packet_unref(&avpkt);
return -1;
}
}
@ -1314,7 +1314,7 @@ public:
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
LOG(("Audio Error: Unable to swr_convert for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
av_free_packet(&avpkt);
av_packet_unref(&avpkt);
return -1;
}
int32 resultLen = av_samples_get_buffer_size(0, _toChannels, res, _toFormat, 1);
@ -1326,7 +1326,7 @@ public:
}
}
}
av_free_packet(&avpkt);
av_packet_unref(&avpkt);
return 1;
}

View File

@ -161,6 +161,7 @@ ClipReader::ClipReader(const FileLocation &location, const QByteArray &data) : _
, _currentDisplayed(1)
, _paused(0)
, _lastDisplayMs(getms())
, _autoplay(false)
, _private(0) {
if (_clipThreads.size() < ClipThreadsCount) {
_threadIndex = _clipThreads.size();
@ -619,7 +620,7 @@ private:
_avpkt.size = _packetSize;
_avpkt.data = _packetData;
_packetWas = false;
av_free_packet(&_avpkt);
av_packet_unref(&_avpkt);
}
}

View File

@ -466,6 +466,13 @@ public:
ClipReader(const FileLocation &location, const QByteArray &data);
void setAutoplay() {
_autoplay = true;
}
bool autoplay() const {
return _autoplay;
}
void start(int32 framew, int32 frameh, int32 outerw, int32 outerh, bool rounded);
QPixmap current(int32 framew, int32 frameh, int32 outerw, int32 outerh, uint64 ms);
QImage frameOriginal() const {
@ -506,12 +513,16 @@ private:
Atomic<uint64> _lastDisplayMs;
int32 _threadIndex;
bool _autoplay;
friend class ClipReadManager;
ClipReaderPrivate *_private;
};
static ClipReader * const BadClipReader = reinterpret_cast<ClipReader * const>(&SharedMemoryLocation0);
enum ClipProcessResult {
ClipProcessError,
ClipProcessStarted,

View File

@ -4302,7 +4302,7 @@ HistoryGif::HistoryGif(DocumentData *document) : HistoryFileMedia()
, _thumbw(1)
, _thumbh(1)
, _gif(0) {
setLinks(new DocumentOpenLink(_data), new GifOpenLink(_data), new DocumentCancelLink(_data));
setLinks(new GifOpenLink(_data), new GifOpenLink(_data), new DocumentCancelLink(_data));
setStatusSize(FileStatusSizeReady);
@ -4314,7 +4314,7 @@ HistoryGif::HistoryGif(const HistoryGif &other) : HistoryFileMedia()
, _thumbw(other._thumbw)
, _thumbh(other._thumbh)
, _gif(0) {
setLinks(new DocumentOpenLink(_data), new GifOpenLink(_data), new DocumentCancelLink(_data));
setLinks(new GifOpenLink(_data), new GifOpenLink(_data), new DocumentCancelLink(_data));
setStatusSize(other._statusSize);
}
@ -4322,14 +4322,16 @@ HistoryGif::HistoryGif(const HistoryGif &other) : HistoryFileMedia()
void HistoryGif::initDimensions(const HistoryItem *parent) {
bool bubble = parent->hasBubble();
int32 tw = 0, th = 0;
if (_gif && _gif->state() == ClipError) {
Ui::showLayer(new InformBox(lang(lng_gif_error)));
if (gif() && _gif->state() == ClipError) {
if (!_gif->autoplay()) {
Ui::showLayer(new InformBox(lang(lng_gif_error)));
}
App::unregGifItem(_gif);
delete _gif;
_gif = 0;
_gif = BadClipReader;
}
if (_gif && _gif->ready()) {
if (gif() && _gif->ready()) {
tw = convertScale(_gif->width());
th = convertScale(_gif->height());
} else {
@ -4354,7 +4356,7 @@ void HistoryGif::initDimensions(const HistoryItem *parent) {
_thumbh = th;
_maxw = qMax(tw, int32(st::minPhotoSize));
_minh = qMax(th, int32(st::minPhotoSize));
if (!_gif || !_gif->ready()) {
if (!gif() || !_gif->ready()) {
_maxw = qMax(_maxw, parent->infoWidth() + 2 * int32(st::msgDateImgDelta + st::msgDateImgPadding.x()));
_maxw = qMax(_maxw, gifMaxStatusWidth(_data) + 2 * int32(st::msgDateImgDelta + st::msgDateImgPadding.x()));
}
@ -4368,7 +4370,7 @@ int32 HistoryGif::resize(int32 width, const HistoryItem *parent) {
bool bubble = parent->hasBubble();
int32 tw = 0, th = 0;
if (_gif && _gif->ready()) {
if (gif() && _gif->ready()) {
tw = convertScale(_gif->width());
th = convertScale(_gif->height());
} else {
@ -4402,7 +4404,7 @@ int32 HistoryGif::resize(int32 width, const HistoryItem *parent) {
_width = qMax(tw, int32(st::minPhotoSize));
_height = qMax(th, int32(st::minPhotoSize));
if (_gif && _gif->ready()) {
if (gif() && _gif->ready()) {
if (!_gif->started()) {
_gif->start(_thumbw, _thumbh, _width, _height, true);
}
@ -4423,15 +4425,16 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
_data->automaticLoad(parent);
bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
if (loaded && !_gif) {
if (loaded && !gif() && _gif != BadClipReader) {
const_cast<HistoryGif*>(this)->playInline(const_cast<HistoryItem*>(parent));
if (gif()) _gif->setAutoplay();
}
int32 skipx = 0, skipy = 0, width = _width, height = _height;
bool bubble = parent->hasBubble();
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
bool animating = (_gif && _gif->started());
bool animating = (gif() && _gif->started());
if (!animating || _data->uploading()) {
if (displayLoading) {
@ -4465,7 +4468,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
if (radial || (!_gif && !loaded && !_data->loading())) {
if (radial || (!_gif && !loaded && !_data->loading()) || (_gif == BadClipReader)) {
float64 radialOpacity = radial ? _animation->radial.opacity() : 1;
QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
p.setPen(Qt::NoPen);
@ -4534,7 +4537,7 @@ void HistoryGif::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x,
if (x >= skipx && y >= skipy && x < skipx + width && y < skipy + height) {
if (_data->uploading()) {
lnk = _cancell;
} else if (!_gif) {
} else if (!gif()) {
lnk = _data->loaded() ? _openl : (_data->loading() ? _cancell : _savel);
}
if (parent->getMedia() == this) {
@ -4598,7 +4601,7 @@ ImagePtr HistoryGif::replyPreview() {
}
bool HistoryGif::playInline(HistoryItem *parent) {
if (_gif) {
if (gif()) {
stopInline(parent);
} else {
_gif = new ClipReader(_data->location(), _data->data());
@ -4608,9 +4611,11 @@ bool HistoryGif::playInline(HistoryItem *parent) {
}
void HistoryGif::stopInline(HistoryItem *parent) {
App::unregGifItem(_gif);
delete _gif;
_gif = 0;
if (gif()) {
App::unregGifItem(_gif);
delete _gif;
_gif = 0;
}
parent->initDimensions();
Notify::historyItemResized(parent);
@ -4618,7 +4623,7 @@ void HistoryGif::stopInline(HistoryItem *parent) {
}
HistoryGif::~HistoryGif() {
if (_gif) {
if (gif()) {
App::unregGifItem(_gif);
delete _gif;
setBadPointer(_gif);

View File

@ -1621,6 +1621,12 @@ private:
DocumentData *_data;
int32 _thumbw, _thumbh;
ClipReader *_gif;
ClipReader *gif() {
return (_gif == BadClipReader) ? 0 : _gif;
}
const ClipReader *gif() const {
return (_gif == BadClipReader) ? 0 : _gif;
}
void setStatusSize(int32 newSize) const;
void updateStatusText(const HistoryItem *parent) const;