PonyPlayer
previewer.hpp
浏览该文件的文档.
1//
2// Created by kurisu on 2022/5/8.
3//
4
5#ifndef PONYPLAYER_PREVIEW_H
6#define PONYPLAYER_PREVIEW_H
7#include "dispatcher.hpp"
8#include <QImage>
9
10INCLUDE_FFMPEG_BEGIN
11#include <libswscale/swscale.h>
13
15 Q_OBJECT
16private:
17 int videoStreamIndex{-1};
18 AVStream *videoStream{};
19 DecoderContext* ctx{};
20 AVPacket *pkt{};
21
22public:
23
24 explicit Previewer(const std::string &fn, QObject *parent) : DemuxDispatcherBase(fn, parent) {
25 for (StreamIndex i = 0; i < fmtCtx->nb_streams; ++i) {
26 if (fmtCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
27 videoStreamIndex = static_cast<int>(i);
28 videoStream = fmtCtx->streams[i];
29 ctx = new DecoderContext(videoStream);
30 pkt = av_packet_alloc();
31 return;
32 }
33 }
34 qWarning() << "Previewer: can not find video stream";
35 }
36
38 delete ctx;
39 if (pkt) av_packet_free(&pkt);
40 }
41
48 if (!videoStream)
49 return {};
50 int ret = 0;
51 // 每次preview,都要先清空内部buffer,然后seek
52 avcodec_flush_buffers(ctx->codecCtx);
53 ret = av_seek_frame(fmtCtx, -1,
54 static_cast<int64_t>(pos * AV_TIME_BASE), AVSEEK_FLAG_BACKWARD);
55 if (ret < 0) {
56 qWarning() << "Previewer: av_seek_frame failed";
57 return {};
58 }
59
60 while (true) {
61 ret = av_read_frame(fmtCtx, pkt);
62 if (ret < 0) {
63 qWarning() << "Previewer: reach eof, no available picture";
64 break;
65 }
66 if (pkt->stream_index == videoStreamIndex) {
67 ret = avcodec_send_packet(ctx->codecCtx, pkt);
68 if (ret < 0) {
69 qWarning() << "avcodec_send_packet: " << ffmpegErrToString(ret);
70 break;
71 }
72 while ((ret = avcodec_receive_frame(ctx->codecCtx, ctx->frameBuf)) >= 0) {
73 double pts = static_cast<double>(ctx->frameBuf->pts) * av_q2d(videoStream->time_base);
74 if (pts < pos) {
75 av_frame_unref(ctx->frameBuf);
76 } else {
77 auto *frame = ctx->frameBuf;
78 ctx->frameBuf = av_frame_alloc();
79 av_packet_unref(pkt);
80// m_lifeManager->pop();
81 return {frame, true, pts};
82 }
83 }
84 if (ret < 0) {
85 if (ret == AVERROR(EAGAIN) || ret == ERROR_EOF);
86 else {
87 qWarning() << "avcodec_receive_frame: " << ffmpegErrToString(ret);
88 break;
89 }
90 }
91 }
92 av_packet_unref(pkt);
93 }
94 return {};
95 }
96
98
100
102};
103
104#endif //PONYPLAYER_PREVIEW_H
Definition: decoders.hpp:105
AVFrame * frameBuf
Definition: decoders.hpp:110
AVCodecContext * codecCtx
Definition: decoders.hpp:109
Definition: dispatcher.hpp:81
AVFormatContext * fmtCtx
Definition: dispatcher.hpp:86
Definition: audioformat.hpp:97
Definition: previewer.hpp:14
~Previewer()
Definition: previewer.hpp:37
VideoFrameRef previewRequest(qreal pos)
Definition: previewer.hpp:47
Previewer(const std::string &fn, QObject *parent)
Definition: previewer.hpp:24
PonyAudioFormat getAudioInputFormat() override
Definition: previewer.hpp:97
void setAudioOutputFormat(PonyAudioFormat format) override
Definition: previewer.hpp:99
void test_onWork() override
Definition: previewer.hpp:101
Definition: frame.hpp:47
unsigned int StreamIndex
Definition: dispatcher.hpp:75
const int ERROR_EOF
Definition: helper.hpp:14
QString ffmpegErrToString(int err)
Definition: helper.hpp:21
#define INCLUDE_FFMPEG_END
Definition: ponyplayer.h:26
#define NOT_IMPLEMENT_YET
Definition: ponyplayer.h:39