1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
|
/**********************************************************************
Audacity: A Digital Audio Editor
AVPacketWrapperImpl.inl
Dmitry Vedenko
**********************************************************************/
class AVPacketWrapperImpl : public AVPacketWrapper
{
public:
explicit
AVPacketWrapperImpl(const FFmpegFunctions& ffmpeg) noexcept
: AVPacketWrapper(ffmpeg)
{
if (mFFmpeg.av_packet_alloc != nullptr)
{
// A library defining one is assumed to define the other
// assert(ffmpeg->av_packet_free != nullptr);
mAVPacket = mFFmpeg.av_packet_alloc();
mUseAVFree = false;
}
else
{
mAVPacket =
static_cast<AVPacket*>(mFFmpeg.av_malloc(sizeof(AVPacket)));
mUseAVFree = true;
}
mFFmpeg.av_init_packet(mAVPacket);
}
AudacityAVBufferRef* GetBuf() const noexcept override
{
if (mAVPacket != nullptr)
return reinterpret_cast<AudacityAVBufferRef*>(mAVPacket->buf);
return {};
}
int64_t GetPresentationTimestamp() const noexcept override
{
if (mAVPacket != nullptr)
return mAVPacket->pts;
return {};
}
int64_t GetDecompressionTimestamp() const noexcept override
{
if (mAVPacket != nullptr)
return mAVPacket->dts;
return {};
}
uint8_t* GetData() const noexcept override
{
if (mAVPacket != nullptr)
return mAVPacket->data;
return {};
}
int GetSize() const noexcept override
{
if (mAVPacket != nullptr)
return mAVPacket->size;
return {};
}
bool OffsetPacket(size_t offset) noexcept override
{
if (mAVPacket == nullptr)
return false;
if (offset >= mAVPacket->size)
{
mAVPacket->data += mAVPacket->size;
mAVPacket->size = 0;
return false;
}
else
{
mAVPacket->data += offset;
mAVPacket->size -= offset;
return true;
}
}
void ResetData() noexcept override
{
if (mAVPacket == nullptr)
return;
mAVPacket->data = nullptr;
mAVPacket->size = 0;
}
void ResetTimestamps() noexcept override
{
if (mAVPacket == nullptr)
return;
mAVPacket->dts = AV_NOPTS_VALUE;
mAVPacket->pts = AV_NOPTS_VALUE;
}
int GetStreamIndex() const noexcept override
{
if (mAVPacket != nullptr)
return mAVPacket->stream_index;
return {};
}
void SetStreamIndex(int index) noexcept override
{
if (mAVPacket != nullptr)
mAVPacket->stream_index = index;
}
int GetFlags() const noexcept override
{
if (mAVPacket != nullptr)
return mAVPacket->flags;
return {};
}
int GetDuration() const noexcept override
{
if (mAVPacket != nullptr)
return mAVPacket->duration;
return {};
}
int64_t GetPos() const noexcept override
{
if (mAVPacket != nullptr)
return mAVPacket->pos;
return {};
}
int64_t GetConvergenceDuration() const noexcept override
{
if (mAVPacket != nullptr)
#if LIBAVFORMAT_VERSION_MAJOR <= 58
return mAVPacket->convergence_duration;
#else
// From FFmpeg docs: "Same as the duration field, but as int64_t."
// duration is int64_t now, convergence_duration is removed
return mAVPacket->duration;
#endif
return {};
}
std::unique_ptr<AVPacketWrapper> Clone() const noexcept override
{
// Guarantee non-null return, which is assumed elsewhere
auto copy = std::make_unique<AVPacketWrapperImpl>(mFFmpeg);
if (mAVPacket == nullptr)
// should happen only if mFFmpeg is null, and should result in
// a clone with null for mAVPacket too
return copy;
// Make mAVPacket in this and the clone share resources
mFFmpeg.av_packet_ref(copy->mAVPacket, mAVPacket);
return std::move(copy);
}
void RescalePresentationTimestamp(AudacityAVRational bq, AudacityAVRational cq)
noexcept override
{
if (mAVPacket == nullptr)
return;
mFFmpeg.av_rescale_q(mAVPacket->pts, { bq.num, bq.den }, { cq.num, cq.den });
}
void RescaleDecompressionTimestamp(AudacityAVRational bq, AudacityAVRational cq)
noexcept override
{
if (mAVPacket == nullptr)
return;
mFFmpeg.av_rescale_q(mAVPacket->dts, { bq.num, bq.den }, { cq.num, cq.den });
}
void RescaleDuration(AudacityAVRational bq, AudacityAVRational cq)
noexcept override
{
if (mAVPacket == nullptr)
return;
mFFmpeg.av_rescale_q(mAVPacket->duration, { bq.num, bq.den }, { cq.num, cq.den });
}
};
std::unique_ptr<AVPacketWrapper> CreateAVPacketWrapper(const FFmpegFunctions& fns)
{
return std::make_unique<AVPacketWrapperImpl>(fns);
}
|