Fixed clang false warning on deprecated field of AVPacket.

This commit is contained in:
John Preston 2016-07-19 19:02:39 +03:00
parent 49f6431fca
commit 92f15a9ad3
6 changed files with 56 additions and 32 deletions

View File

@ -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);
}
}

View File

@ -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 <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libswresample/swresample.h>
} // extern "C"
#include "media/media_child_ffmpeg_loader.h"
class AudioPlayerLoader;
class ChildFFMpegLoader;
@ -65,7 +59,7 @@ private:
QMutex _fromVideoMutex;
uint64 _fromVideoPlayId;
QQueue<AVPacket> _fromVideoQueue;
QQueue<FFMpeg::AVPacketDataWrap> _fromVideoQueue;
SingleDelayedCall _fromVideoNotify;
void emitError(AudioMsgId::Type type);

View File

@ -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<AVPacket> &packets) {
void ChildFFMpegLoader::enqueuePackets(QQueue<FFMpeg::AVPacketDataWrap> &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);

View File

@ -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<AVPacket> &packets);
void enqueuePackets(QQueue<FFMpeg::AVPacketDataWrap> &packets);
uint64 playId() const {
return _videoPlayId;
@ -111,6 +129,6 @@ private:
AVFrame *_frame = nullptr;
SwrContext *_swrContext = nullptr;
QQueue<AVPacket> _queue;
QQueue<FFMpeg::AVPacketDataWrap> _queue;
};

View File

@ -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);
}
}

View File

@ -21,15 +21,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#pragma once
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libswscale/swscale.h>
}
} // 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<AVPacket> _packetQueue;
QQueue<FFMpeg::AVPacketDataWrap> _packetQueue;
AVPacket _packetNull; // for final decoding
int _packetStartedSize = 0;
uint8_t *_packetStartedData = nullptr;