From 92f15a9ad3fe5c11fb2efd776d81b41e8fb840c8 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 19 Jul 2016 19:02:39 +0300 Subject: [PATCH] Fixed clang false warning on deprecated field of AVPacket. --- .../SourceFiles/media/media_audio_loaders.cpp | 6 +++-- .../SourceFiles/media/media_audio_loaders.h | 10 ++----- .../media/media_child_ffmpeg_loader.cpp | 11 +++++--- .../media/media_child_ffmpeg_loader.h | 22 +++++++++++++-- .../SourceFiles/media/media_clip_ffmpeg.cpp | 27 ++++++++++++------- .../SourceFiles/media/media_clip_ffmpeg.h | 12 ++++----- 6 files changed, 56 insertions(+), 32 deletions(-) diff --git a/Telegram/SourceFiles/media/media_audio_loaders.cpp b/Telegram/SourceFiles/media/media_audio_loaders.cpp index 83ec07544..5b1805b93 100644 --- a/Telegram/SourceFiles/media/media_audio_loaders.cpp +++ b/Telegram/SourceFiles/media/media_audio_loaders.cpp @@ -34,7 +34,7 @@ void AudioPlayerLoaders::feedFromVideo(VideoSoundPart &&part) { { QMutexLocker lock(&_fromVideoMutex); if (_fromVideoPlayId == part.videoPlayId) { - _fromVideoQueue.enqueue(*part.packet); + _fromVideoQueue.enqueue(FFMpeg::dataWrapFromPacket(*part.packet)); invoke = true; } else { FFMpeg::freePacket(part.packet); @@ -76,7 +76,9 @@ AudioPlayerLoaders::~AudioPlayerLoaders() { void AudioPlayerLoaders::clearFromVideoQueue() { auto queue = createAndSwap(_fromVideoQueue); - for (auto &packet : queue) { + for (auto &packetData : queue) { + AVPacket packet; + FFMpeg::packetFromDataWrap(packet, packetData); FFMpeg::freePacket(&packet); } } diff --git a/Telegram/SourceFiles/media/media_audio_loaders.h b/Telegram/SourceFiles/media/media_audio_loaders.h index 1aaebd514..50a282b59 100644 --- a/Telegram/SourceFiles/media/media_audio_loaders.h +++ b/Telegram/SourceFiles/media/media_audio_loaders.h @@ -22,13 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "media/media_child_ffmpeg_loader.h" #include "media/media_audio.h" - -extern "C" { -#include -#include -#include -#include -} // extern "C" +#include "media/media_child_ffmpeg_loader.h" class AudioPlayerLoader; class ChildFFMpegLoader; @@ -65,7 +59,7 @@ private: QMutex _fromVideoMutex; uint64 _fromVideoPlayId; - QQueue _fromVideoQueue; + QQueue _fromVideoQueue; SingleDelayedCall _fromVideoNotify; void emitError(AudioMsgId::Type type); diff --git a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp index 4ec96b1c1..5016b1b4f 100644 --- a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp +++ b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp @@ -120,7 +120,10 @@ AudioPlayerLoader::ReadResult ChildFFMpegLoader::readMore(QByteArray &result, in av_frame_unref(_frame); int got_frame = 0; int res = 0; - auto packet = _queue.dequeue(); + + AVPacket packet; + FFMpeg::packetFromDataWrap(packet, _queue.dequeue()); + _eofReached = FFMpeg::isNullPacket(packet); if (_eofReached) { return ReadResult::EndOfFile; @@ -172,14 +175,16 @@ AudioPlayerLoader::ReadResult ChildFFMpegLoader::readMore(QByteArray &result, in return ReadResult::Ok; } -void ChildFFMpegLoader::enqueuePackets(QQueue &packets) { +void ChildFFMpegLoader::enqueuePackets(QQueue &packets) { _queue += std_::move(packets); packets.clear(); } ChildFFMpegLoader::~ChildFFMpegLoader() { auto queue = createAndSwap(_queue); - for (auto &packet : queue) { + for (auto &packetData : queue) { + AVPacket packet; + FFMpeg::packetFromDataWrap(packet, packetData); FFMpeg::freePacket(&packet); } if (_swrContext) swr_free(&_swrContext); diff --git a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.h b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.h index 903893c1d..69926bfb8 100644 --- a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.h +++ b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.h @@ -45,6 +45,24 @@ struct VideoSoundPart { namespace FFMpeg { +// AVPacket has a deprecated field, so when you copy an AVPacket +// variable (e.g. inside QQueue), a compile warning is emited. +// We wrap full AVPacket data in a new AVPacketDataWrap struct. +// All other fields are copied from AVPacket without modifications. +struct AVPacketDataWrap { + char __data[sizeof(AVPacket)]; +}; + +inline void packetFromDataWrap(AVPacket &packet, const AVPacketDataWrap &data) { + memcpy(&packet, &data, sizeof(data)); +} + +inline AVPacketDataWrap dataWrapFromPacket(const AVPacket &packet) { + AVPacketDataWrap data; + memcpy(&data, &packet, sizeof(data)); + return data; +} + inline bool isNullPacket(const AVPacket &packet) { return packet.data == nullptr && packet.size == 0; } @@ -84,7 +102,7 @@ public: } ReadResult readMore(QByteArray &result, int64 &samplesAdded) override; - void enqueuePackets(QQueue &packets); + void enqueuePackets(QQueue &packets); uint64 playId() const { return _videoPlayId; @@ -111,6 +129,6 @@ private: AVFrame *_frame = nullptr; SwrContext *_swrContext = nullptr; - QQueue _queue; + QQueue _queue; }; diff --git a/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp b/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp index ab29e6975..8e321eb16 100644 --- a/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp +++ b/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp @@ -56,12 +56,13 @@ ReaderImplementation::ReadResult FFMpegReaderImplementation::readNextFrame() { startPacket(); int got_frame = 0; - int decoded = 0; auto packet = &_packetNull; + AVPacket tempPacket; if (!_packetQueue.isEmpty()) { - packet = &_packetQueue.head(); - decoded = packet->size; + FFMpeg::packetFromDataWrap(tempPacket, _packetQueue.head()); + packet = &tempPacket; } + int decoded = packet->size; int res = 0; if ((res = avcodec_decode_video2(_codecContext, _frame, &got_frame, packet)) < 0) { @@ -427,7 +428,7 @@ void FFMpegReaderImplementation::processPacket(AVPacket *packet) { _lastReadPacketMs = countPacketMs(packet); if (videoPacket) { - _packetQueue.enqueue(*packet); + _packetQueue.enqueue(FFMpeg::dataWrapFromPacket(*packet)); } else if (audioPacket) { // queue packet to audio player VideoSoundPart part; @@ -457,18 +458,22 @@ FFMpegReaderImplementation::PacketResult FFMpegReaderImplementation::readAndProc void FFMpegReaderImplementation::startPacket() { if (!_packetStarted && !_packetQueue.isEmpty()) { - _packetStartedSize = _packetQueue.head().size; - _packetStartedData = _packetQueue.head().data; + AVPacket packet; + FFMpeg::packetFromDataWrap(packet, _packetQueue.head()); + _packetStartedSize = packet.size; + _packetStartedData = packet.data; _packetStarted = true; } } void FFMpegReaderImplementation::finishPacket() { if (_packetStarted) { - _packetQueue.head().size = _packetStartedSize; - _packetQueue.head().data = _packetStartedData; + AVPacket packet; + FFMpeg::packetFromDataWrap(packet, _packetQueue.head()); + packet.size = _packetStartedSize; + packet.data = _packetStartedData; _packetStarted = false; - av_packet_unref(&_packetQueue.head()); + av_packet_unref(&packet); _packetQueue.dequeue(); } } @@ -476,7 +481,9 @@ void FFMpegReaderImplementation::finishPacket() { void FFMpegReaderImplementation::clearPacketQueue() { finishPacket(); auto packets = createAndSwap(_packetQueue); - for (auto &packet : packets) { + for (auto &packetData : packets) { + AVPacket packet; + FFMpeg::packetFromDataWrap(packet, packetData); av_packet_unref(&packet); } } diff --git a/Telegram/SourceFiles/media/media_clip_ffmpeg.h b/Telegram/SourceFiles/media/media_clip_ffmpeg.h index 7a9abbe9a..c73fdc8ac 100644 --- a/Telegram/SourceFiles/media/media_clip_ffmpeg.h +++ b/Telegram/SourceFiles/media/media_clip_ffmpeg.h @@ -21,15 +21,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once extern "C" { -#include -#include -#include + #include -} + +} // extern "C" #include "media/media_clip_implementation.h" - -struct VideoSoundData; +#include "media/media_child_ffmpeg_loader.h" namespace Media { namespace Clip { @@ -96,7 +94,7 @@ private: uint64 _playId = 0; int64 _lastReadPacketMs = 0; - QQueue _packetQueue; + QQueue _packetQueue; AVPacket _packetNull; // for final decoding int _packetStartedSize = 0; uint8_t *_packetStartedData = nullptr;