PonyPlayer
forward.hpp
浏览该文件的文档.
1//
2// Created by ColorsWind on 2022/5/1.
3//
4#pragma once
5
6#include "decoders.hpp"
7
8template<IDemuxDecoder::DecoderType type>
9class DecoderImpl : public DecoderContext, public IDemuxDecoder {
10protected:
12public:
14 : DecoderContext(vs), frameQueue(queue) {}
15
16 PONY_THREAD_SAFE double duration() override {
17 return static_cast<double>(stream->duration) * av_q2d(stream->time_base);
18 }
19
20 PONY_GUARD_BY(DECODER) bool accept(AVPacket *pkt, std::atomic<bool> &interrupt) override {
21 if (!frameQueue->isEnable())
22 return true;
23 int ret = avcodec_send_packet(codecCtx, pkt);
24 if (ret < 0) {
25 qWarning() << "Error avcodec_send_packet:" << ffmpegErrToString(ret);
26 return false;
27 }
28 while(ret >= 0 && !interrupt) {
29 ret = avcodec_receive_frame(codecCtx, frameBuf);
30 if (ret >= 0) {
31 if(!frameQueue->push(frameBuf)) {
32 frameQueue->clear([](AVFrame *frame) { av_frame_free(&frame); });
33 av_frame_unref(frameBuf);
34 return false;
35 }
36 frameBuf = av_frame_alloc();
37 } else if (ret == AVERROR(EAGAIN)) {
38 return true;
39 } else if (ret == ERROR_EOF) {
40 frameQueue->push(nullptr);
41 return false;
42 } else {
43 frameQueue->push(nullptr);
44 qWarning() << "Error avcodec_receive_frame:" << ffmpegErrToString(ret);
45 return false;
46 }
47 }
48 return false;
49 }
50
51 PONY_THREAD_SAFE VideoFrameRef getPicture() override { NOT_IMPLEMENT_YET }
52
53 PONY_THREAD_SAFE AudioFrame getSample() override { NOT_IMPLEMENT_YET }
54
56
57 void setOutputFormat(const PonyAudioFormat &format) override { NOT_IMPLEMENT_YET }
58
59
60 PONY_THREAD_SAFE qreal viewFront() override {
61 return frameQueue->viewFront<qreal>([this](AVFrame * frame) {
62 if (frame) {
63 return static_cast<qreal>(frame->pts) * av_q2d(stream->time_base);
64 } else {
65 return std::numeric_limits<qreal>::quiet_NaN();
66 }
67 });
68 }
69
70 PONY_THREAD_SAFE int skip(const std::function<bool(qreal)> &predicate) override {
71 return frameQueue->skip([this, predicate](AVFrame *frame){
72 return frame && predicate(static_cast<qreal>(frame->pts) * av_q2d(stream->time_base));
73 }, [](AVFrame *frame) { av_frame_free(&frame); });
74 }
75
76 PONY_THREAD_SAFE void setEnable(bool b) override {
77 frameQueue->setEnable(b);
78 }
79
81 avcodec_flush_buffers(codecCtx);
82 }
83
84};
85
89template<> class DecoderImpl<Audio>: public DecoderImpl<Common> {
90 SwrContext *swrCtx = nullptr;
91 uint8_t *audioOutBuf = nullptr;
92 AVFrame * sampleFrameBuf = nullptr;
94
95public:
96 DecoderImpl(AVStream *vs, TwinsBlockQueue<AVFrame *> *queue) : DecoderImpl<Common>(vs, queue) {
97 if (!(audioOutBuf = static_cast<uint8_t *>(av_malloc(2 * MAX_AUDIO_FRAME_SIZE)))) {
98 throw std::runtime_error("Cannot alloc audioOutBuf");
99 }
100 sampleFrameBuf = av_frame_alloc();
101 }
102
103 virtual ~DecoderImpl() override {
104 if (sampleFrameBuf) { av_frame_free(&sampleFrameBuf); }
105 if (audioOutBuf) { av_freep(&audioOutBuf); }
106 if (swrCtx) { swr_free(&swrCtx); }
107 }
108
109
110 PONY_THREAD_SAFE AudioFrame getSample() override {
111 if (!frameQueue->isEnable()) {
112 ILLEGAL_STATE("forward: getSample is disabled");
113 }
114
115 AVFrame *frame = frameQueue->remove(true);
116 if (!frame) { return {}; }
117 double pts = static_cast<double>(frame->pts) * av_q2d(stream->time_base);
118 int len = swr_convert(swrCtx, &audioOutBuf, 2 * MAX_AUDIO_FRAME_SIZE,
119 const_cast<const uint8_t **>(frame->data), frame->nb_samples);
120
121 int out_size = av_samples_get_buffer_size(nullptr, targetFmt.getChannelCount(),
122 len,
123 targetFmt.getSampleFormatForFFmpeg(),
124 1);
125 av_frame_free(&frame);
126 return {reinterpret_cast<std::byte *>(audioOutBuf), out_size, pts};
127 }
128
130 return {PonyPlayer::valueOf(codecCtx->sample_fmt), codecCtx->sample_rate, codecCtx->channels};
131 }
132
133 void setOutputFormat(const PonyAudioFormat& format) override {
134 targetFmt = format;
135 if (swrCtx) { swr_free(&swrCtx); }
136 this->swrCtx = swr_alloc_set_opts(swrCtx, av_get_default_channel_layout(format.getChannelCount()),
137 format.getSampleFormatForFFmpeg(), format.getSampleRate(),
138 static_cast<int64_t>(codecCtx->channel_layout), codecCtx->sample_fmt,
139 codecCtx->sample_rate, 0, nullptr);
140
141 if (!swrCtx || swr_init(swrCtx) < 0) {
142 throw std::runtime_error("Cannot initialize swrCtx");
143 }
144 }
145
146};
147
151template<> class DecoderImpl<Video>: public DecoderImpl<Common> {
152private:
156 std::atomic<AVFrame *> stillVideoFrame = nullptr;
157public:
158 DecoderImpl(AVStream *vs, TwinsBlockQueue<AVFrame *> *queue) : DecoderImpl<Common>(vs, queue) {}
159
160
162 if (stillVideoFrame != nullptr) { return {stillVideoFrame, true, -1}; }
163 AVFrame *frame = frameQueue->remove(true);
164 if (!frame) { return {}; }
165 if (frame->pts < 0) {
166 stillVideoFrame = frame;
167 return {frame, true, -9};
168 } else {double pts = static_cast<double>(frame->pts) * av_q2d(stream->time_base);
169 return {frame, true, pts};
170 }
171 }
172
173
174 ~DecoderImpl() override {
175 auto *frame = stillVideoFrame.load();
176 if (frame) { av_frame_free(&frame); }
177 }
178
179
180};
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
PonyAudioFormat getInputFormat() override
Definition: forward.hpp:129
void setOutputFormat(const PonyAudioFormat &format) override
Definition: forward.hpp:133
DecoderImpl(AVStream *vs, TwinsBlockQueue< AVFrame * > *queue)
Definition: forward.hpp:96
virtual ~DecoderImpl() override
Definition: forward.hpp:103
PONY_THREAD_SAFE AudioFrame getSample() override
Definition: forward.hpp:110
~DecoderImpl() override
Definition: forward.hpp:174
VideoFrameRef getPicture() override
Definition: forward.hpp:161
DecoderImpl(AVStream *vs, TwinsBlockQueue< AVFrame * > *queue)
Definition: forward.hpp:158
Definition: forward.hpp:9
PONY_THREAD_SAFE AudioFrame getSample() override
Definition: forward.hpp:53
PONY_THREAD_SAFE double duration() override
Definition: forward.hpp:16
PonyAudioFormat getInputFormat() override
Definition: forward.hpp:55
PONY_THREAD_SAFE int skip(const std::function< bool(qreal)> &predicate) override
Definition: forward.hpp:70
PONY_GUARD_BY(DECODER) void flushFFmpegBuffers() override
Definition: forward.hpp:80
TwinsBlockQueue< AVFrame * > * frameQueue
Definition: forward.hpp:11
int ret
Definition: forward.hpp:23
PONY_GUARD_BY(DECODER) bool accept(AVPacket *pkt
PONY_THREAD_SAFE void setEnable(bool b) override
Definition: forward.hpp:76
PONY_THREAD_SAFE VideoFrameRef getPicture() override
Definition: forward.hpp:51
void setOutputFormat(const PonyAudioFormat &format) override
Definition: forward.hpp:57
PONY_THREAD_SAFE qreal viewFront() override
Definition: forward.hpp:60
DecoderImpl(AVStream *vs, TwinsBlockQueue< AVFrame * > *queue)
Definition: forward.hpp:13
Definition: decoders.hpp:22
virtual bool accept(AVPacket *pkt, std::atomic< bool > &interrupt)=0
virtual void flushFFmpegBuffers()=0
Definition: audioformat.hpp:97
int getChannelCount() const
Definition: audioformat.hpp:142
AVSampleFormat getSampleFormatForFFmpeg() const
Definition: audioformat.hpp:118
int getSampleRate() const
Definition: audioformat.hpp:138
联动队列. 用于单生产者多队列, 单消费者通信.
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
constexpr PonyThread DECODER
Definition: ponyplayer.h:46
const PonySampleFormat Int16
Definition: audioformat.hpp:160
#define ILLEGAL_STATE(msg)
Definition: ponyplayer.h:40
#define NOT_IMPLEMENT_YET
Definition: ponyplayer.h:39