/* ******************************************************************************* * INCLUDE ******************************************************************************* */ #include "Packet.h" #include "Logger.h" #include namespace Video { namespace Core { /* ******************************************************************************* * CLASS DEFINE ******************************************************************************* */ const uint32_t Packet::FLAG_IS_VIDEO = 0x80000000; const uint32_t Packet::FLAG_IS_KEY = 0x00000001; const uint32_t Packet::FLAG_IS_AAC_HEADER = 0x00000002; const uint32_t Packet::FLAG_IS_SEI = 0x04000000; Packet::Packet(): _flags(0), _pts(0), _dts(0), _pData(nullptr), _length(0), _pAVPacket(nullptr) { } Packet::Packet(const SerialCode& code, uint32_t flags, uint8_t* data, uint32_t length, int64_t pts, int64_t dts) : _code(code), _flags(flags), _pts(pts), _dts(dts), _pData(data), _length(length), _pAVPacket(nullptr) { } #if defined(USING_FFMPEG) Packet::Packet(const SerialCode& code, bool isVideo, AVPacket** packet) : _code(code), _pts((*packet)->pts), _dts((*packet)->dts), _pData(nullptr), _length((*packet)->size), _pAVPacket(*packet) { _flags = 0; if ((*packet)->flags & AV_PKT_FLAG_KEY) _flags |= Packet::FLAG_IS_KEY; if (isVideo) _flags |= Packet::FLAG_IS_VIDEO; *packet = nullptr; } #endif Packet::Packet(const Packet& other) { _code = other._code; _flags = other._flags; _pData = other._pData; _length = other._length; _pts = other._pts; _dts = other._dts; #if defined(USING_FFMPEG) if (other._pAVPacket) _pAVPacket = av_packet_clone(other._pAVPacket); else _pAVPacket = nullptr; #endif } Packet::~Packet() { #if defined(USING_FFMPEG) if (_pAVPacket) av_packet_free(&_pAVPacket); #endif } #if defined(USING_FFMPEG) void Packet::moveTo(AVPacket** packet) { if (_pAVPacket) { *packet = _pAVPacket; _pData = nullptr; _length = 0; _pAVPacket = nullptr; } else { *packet = buildAVPacket(); _pData = nullptr; _length = 0; } } #endif const uint8_t* Packet::data() { #if defined(USING_FFMPEG) if (_pAVPacket) return _pAVPacket->data; #endif return _pData.get(); } #if defined(USING_FFMPEG) AVPacket* Packet::buildAVPacket() { AVPacket* pPacket = av_packet_alloc(); pPacket->pts = _pts; pPacket->dts = _dts; if (_flags & FLAG_IS_KEY) pPacket->flags |= AV_PKT_FLAG_KEY; else pPacket->flags &= ~AV_PKT_FLAG_KEY; convertToAVPacket(pPacket); return pPacket; } void Packet::convertToAVPacket(AVPacket* pPacket) { if (_pData != nullptr) { uint8_t* data = (uint8_t*)av_malloc(_length); memcpy(data, _pData, _length); int rc = av_packet_from_data(pPacket, data, _length); if (rc < 0) { logger().error("Create av-packet FAIL!"); av_free(data); } _pData.reset(); } else throw Poco::DataException("Media::Packet::buildAVPacket: No source data"); } #endif } }