PonyPlayer
backward.hpp
浏览该文件的文档.
1//
2// Created by ColorsWind on 2022/5/18.
3//
4
5#pragma once
6
11template<IDemuxDecoder::DecoderType type>
13protected:
14 const qreal interval = 5.0;
16 std::vector<AVFrame*> *frameStack;
18 qreal lastPts{-1.0};
19 qreal from;
20 qreal next{-1.0};
21
22public:
24 DecoderContext(vs), frameQueue(queue), frameStack(new std::vector<AVFrame*>) {
25 from = static_cast<double>(stream->duration) * av_q2d(stream->time_base);
26 }
27
28 void setFollower(IDemuxDecoder* follower) override {
29 m_follower = follower;
30 }
31
32 void pushFrameStack() override {
33 while (!frameStack->empty()) {
34 frameQueue->push(frameStack->back());
35 frameStack->pop_back();
36 }
37 }
38
39 qreal getLastPts() override {
40 return lastPts;
41 }
42
43 void clearFrameStack() override {
44 if (frameStack) {
45 for (auto frame: *frameStack) {
46 if (frame) av_frame_free(&frame);
47 }
48 frameStack->clear();
49 }
50 }
51
52 void setStart(qreal secs) override {
53 from = secs;
54 lastPts = -1.0;
56 }
57
58 qreal nextSegment() override {
59 auto res = next;
60 next = -1.0;
61 return res;
62 }
63
64 double duration() override {
65 return static_cast<double>(stream->duration) * av_q2d(stream->time_base);
66 }
67
69 if (frameStack) {
70 for (auto frame: *frameStack) {
71 if (frame) av_frame_free(&frame);
72 }
73 delete frameStack;
74 }
75 }
76
77 bool accept(AVPacket *pkt, std::atomic<bool> &interrupt) override {
78 int ret = avcodec_send_packet(codecCtx, pkt);
79 if (ret < 0) {
80 qWarning() << "Error avcodec_send_packet:" << ffmpegErrToString(ret);
81 return false;
82 }
83 while(ret >= 0 && !interrupt) {
84 ret = avcodec_receive_frame(codecCtx, frameBuf);
85 if (ret >= 0) {
86 lastPts = av_q2d(stream->time_base) * static_cast<double>(frameBuf->pts);
87 if (lastPts < from-interval) {
88 av_frame_unref(frameBuf);
89 continue;
90 }
91 else if (lastPts >= from){
92 //std::cerr << "push to queue"<< std::endl;
93 //qDebug() << "push to queue";
94 av_frame_unref(frameBuf);
95 // 只有leader有权决定跳转
96 if (m_follower && m_follower->getLastPts() >= from) {
97 //std::cerr << "push to queue"<< std::endl;
100 if (from < interval)
101 from = 0;
102 else
103 from -= interval;
104 next = from;
105 return true;
106 }
107 }
108 else {
109 frameStack->push_back(frameBuf);
110 frameBuf = av_frame_alloc();
111 }
112 } else if (ret == AVERROR(EAGAIN)) {
113 return true;
114 } else if (ret == ERROR_EOF) {
115 return false;
116 } else {
117 qWarning() << "Error avcodec_receive_frame:" << ffmpegErrToString(ret);
118 return false;
119 }
120 }
121 return false;
122 }
123
124 void flushFFmpegBuffers() override {
125 avcodec_flush_buffers(codecCtx);
126 }
127
130 }
131
134 }
135
136 PONY_THREAD_SAFE void setEnable(bool b) override {
138 }
139
140 qreal viewFront() override {
142 }
143
145
146 void setOutputFormat(const PonyAudioFormat &format) override { NOT_IMPLEMENT_YET }
147
148 int skip(const std::function<bool(qreal)> &predicate) override { NOT_IMPLEMENT_YET }
149};
150
154template<>
156public:
158 : ReverseDecoderImpl<Common>(vs, queue) {}
159
161 AVFrame *frame = frameQueue->remove(true);
162 if (!frame) {
163 qDebug() << "getPicture: get EOF";
164 return {};
165 }
166// m_lifeCycleManager->pop();
167 double pts = static_cast<double>(frame->pts) * av_q2d(stream->time_base);
168 return {frame, true, pts};
169 }
170
171 qreal viewFront() override {
172 return frameQueue->viewFront<qreal>([this](AVFrame * frame) {
173 if (frame) {
174 return static_cast<qreal>(frame->pts) * av_q2d(stream->time_base);
175 } else {
176 return std::numeric_limits<qreal>::quiet_NaN();
177 }
178 });
179 }
180
181 int skip(const std::function<bool(qreal)> &predicate) override {
182 return frameQueue->skip([this, predicate](AVFrame *frame){
183 return frame && predicate(static_cast<qreal>(frame->pts) * av_q2d(stream->time_base));
184 }, [](AVFrame *frame) { av_frame_free(&frame); });
185 }
186
187};
188
189template<> class ReverseDecoderImpl<Audio>: public ReverseDecoderImpl<Common> {
190 SwrContext *swrCtx = nullptr;
191 uint8_t *audioOutBuf = nullptr;
192 AVFrame * sampleFrameBuf = nullptr;
194public:
196 : ReverseDecoderImpl<Common>(vs, queue) {
197 if (!(audioOutBuf = static_cast<uint8_t *>(av_malloc(2 * MAX_AUDIO_FRAME_SIZE)))) {
198 throw std::runtime_error("Cannot alloc audioOutBuf");
199 }
200 sampleFrameBuf = av_frame_alloc();
201 }
202
204 if (sampleFrameBuf) { av_frame_free(&sampleFrameBuf); }
205 if (audioOutBuf) { av_freep(&audioOutBuf); }
206 if (swrCtx) { swr_free(&swrCtx); }
207 }
208
209 void reverseSample(uint8_t *samples, int len) {
210 int sampleSize = targetFmt.getBytesPerSampleChannels();
211 int left = 0, right = len-sampleSize;
212 while (left < right) {
213 for (int i = 0; i < sampleSize; i++)
214 std::swap(samples[left+i], samples[right+i]);
215 left += sampleSize;
216 right -= sampleSize;
217 }
218 }
219
220 PONY_THREAD_SAFE AudioFrame getSample() override {
221 if (!frameQueue->isEnable()) {
222 ILLEGAL_STATE("forward: getSample is disabled");
223 }
224 auto *frame = std::forward<AVFrame *>(frameQueue->remove(true)); // suppress warning
225 if (!frame) {
226 qDebug() << "getSample: get EOF";
227 return {};
228 }
229 int len = swr_convert(swrCtx, &audioOutBuf, 2 * MAX_AUDIO_FRAME_SIZE,
230 const_cast<const uint8_t **>(frame->data), frame->nb_samples);
231
232 int out_size = av_samples_get_buffer_size(nullptr, targetFmt.getChannelCount(),
233 len,
234 targetFmt.getSampleFormatForFFmpeg(),
235 1);
236 double pts = static_cast<double>(frame->pts) * av_q2d(stream->time_base) +
237 static_cast<double>(len)/44100;
238 reverseSample(audioOutBuf, out_size);
239 pts += static_cast<double>(len)/targetFmt.getSampleRate();
240 av_frame_free(&frame);
241 return {reinterpret_cast<std::byte *>(audioOutBuf), out_size, pts};
242 }
243
245 return {PonyPlayer::valueOf(codecCtx->sample_fmt), codecCtx->sample_rate, codecCtx->channels};
246 }
247
248 void setOutputFormat(const PonyAudioFormat& format) override {
249 targetFmt = format;
250 if (swrCtx) { swr_free(&swrCtx); }
251 this->swrCtx = swr_alloc_set_opts(swrCtx, av_get_default_channel_layout(format.getChannelCount()),
252 format.getSampleFormatForFFmpeg(), format.getSampleRate(),
253 static_cast<int64_t>(codecCtx->channel_layout), codecCtx->sample_fmt,
254 codecCtx->sample_rate, 0, nullptr);
255
256 if (!swrCtx || swr_init(swrCtx) < 0) {
257 throw std::runtime_error("Cannot initialize swrCtx");
258 }
259 }
260
261};
262
Definition: frame.hpp:145
Definition: decoders.hpp:105
AVFrame * frameBuf
Definition: decoders.hpp:110
AVCodecContext * codecCtx
Definition: decoders.hpp:109
AVStream * stream
Definition: decoders.hpp:108
Definition: decoders.hpp:22
virtual qreal getLastPts()
Definition: decoders.hpp:88
virtual void pushFrameStack()
Definition: decoders.hpp:86
Definition: audioformat.hpp:97
int getChannelCount() const
Definition: audioformat.hpp:142
AVSampleFormat getSampleFormatForFFmpeg() const
Definition: audioformat.hpp:118
int getBytesPerSampleChannels() const
Definition: audioformat.hpp:134
int getSampleRate() const
Definition: audioformat.hpp:138
void reverseSample(uint8_t *samples, int len)
Definition: backward.hpp:209
void setOutputFormat(const PonyAudioFormat &format) override
Definition: backward.hpp:248
~ReverseDecoderImpl() override
Definition: backward.hpp:203
PonyAudioFormat getInputFormat() override
Definition: backward.hpp:244
ReverseDecoderImpl(AVStream *vs, TwinsBlockQueue< AVFrame * > *queue)
Definition: backward.hpp:195
PONY_THREAD_SAFE AudioFrame getSample() override
Definition: backward.hpp:220
ReverseDecoderImpl(AVStream *vs, TwinsBlockQueue< AVFrame * > *queue)
Definition: backward.hpp:157
qreal viewFront() override
Definition: backward.hpp:171
int skip(const std::function< bool(qreal)> &predicate) override
Definition: backward.hpp:181
VideoFrameRef getPicture() override
Definition: backward.hpp:160
Definition: backward.hpp:12
ReverseDecoderImpl(AVStream *vs, TwinsBlockQueue< AVFrame * > *queue)
Definition: backward.hpp:23
void pushFrameStack() override
Definition: backward.hpp:32
bool accept(AVPacket *pkt, std::atomic< bool > &interrupt) override
Definition: backward.hpp:77
qreal from
Definition: backward.hpp:19
qreal viewFront() override
Definition: backward.hpp:140
~ReverseDecoderImpl() override
Definition: backward.hpp:68
qreal nextSegment() override
Definition: backward.hpp:58
qreal next
Definition: backward.hpp:20
qreal lastPts
Definition: backward.hpp:18
void flushFFmpegBuffers() override
Definition: backward.hpp:124
void clearFrameStack() override
Definition: backward.hpp:43
void setOutputFormat(const PonyAudioFormat &format) override
Definition: backward.hpp:146
PONY_THREAD_SAFE void setEnable(bool b) override
Definition: backward.hpp:136
int skip(const std::function< bool(qreal)> &predicate) override
Definition: backward.hpp:148
qreal getLastPts() override
Definition: backward.hpp:39
AudioFrame getSample() override
Definition: backward.hpp:132
TwinsBlockQueue< AVFrame * > * frameQueue
Definition: backward.hpp:15
void setStart(qreal secs) override
Definition: backward.hpp:52
std::vector< AVFrame * > * frameStack
Definition: backward.hpp:16
VideoFrameRef getPicture() override
Definition: backward.hpp:128
const qreal interval
Definition: backward.hpp:14
IDemuxDecoder * m_follower
Definition: backward.hpp:17
void setFollower(IDemuxDecoder *follower) override
Definition: backward.hpp:28
double duration() override
Definition: backward.hpp:64
PonyAudioFormat getInputFormat() override
Definition: backward.hpp:144
联动队列. 用于单生产者多队列, 单消费者通信.
Definition: twins_queue.hpp:17
Definition: frame.hpp:47
constexpr auto Common
Definition: decoders.hpp:141
constexpr auto Video
Definition: decoders.hpp:140
constexpr auto Audio
Definition: decoders.hpp:139
const int MAX_AUDIO_FRAME_SIZE
Definition: helper.hpp:15
const int ERROR_EOF
Definition: helper.hpp:14
QString ffmpegErrToString(int err)
Definition: helper.hpp:21
const PonySampleFormat Int16
Definition: audioformat.hpp:160
#define ILLEGAL_STATE(msg)
Definition: ponyplayer.h:40
#define NOT_IMPLEMENT_YET
Definition: ponyplayer.h:39