File indexing completed on 2024-06-16 04:38:28
0001 /* 0002 SPDX-FileCopyrightText: 2003 Fabrice Bellard 0003 SPDX-FileCopyrightText: 2020-2022 Mladen Milinkovic <max@smoothware.net> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "decoder.h" 0009 0010 #include "videoplayer/backend/ffplayer.h" 0011 #include "videoplayer/backend/packetqueue.h" 0012 #include "videoplayer/backend/framequeue.h" 0013 0014 #include <QWaitCondition> 0015 0016 0017 using namespace SubtitleComposer; 0018 0019 Decoder::Decoder(QObject *parent) 0020 : QThread(parent), 0021 m_reorderPts(-1), 0022 m_pkt(nullptr), 0023 m_queue(nullptr), 0024 m_frameQueue(nullptr), 0025 m_avCtx(nullptr), 0026 m_pktSerial(0), 0027 m_finished(0), 0028 m_emptyQueueCond(nullptr), 0029 m_startPts(0) 0030 { 0031 memset(&m_pkt, 0, sizeof(m_pkt)); 0032 } 0033 0034 void 0035 Decoder::init(AVCodecContext *avctx, PacketQueue *pq, FrameQueue *fq, QWaitCondition *emptyQueueCond) 0036 { 0037 m_queue = pq; 0038 m_frameQueue = fq; 0039 m_avCtx = avctx; 0040 m_pktSerial = -1; 0041 m_finished = 0; 0042 av_packet_free(&m_pkt); 0043 m_emptyQueueCond = emptyQueueCond; 0044 m_startPts = AV_NOPTS_VALUE; 0045 } 0046 0047 void 0048 Decoder::start() 0049 { 0050 m_queue->start(); 0051 QThread::start(); 0052 } 0053 0054 int 0055 Decoder::decodeFrame(AVFrame *frame, AVSubtitle *sub) 0056 { 0057 int ret = AVERROR(EAGAIN); 0058 0059 for(;;) { 0060 if(m_queue->m_serial == m_pktSerial) { 0061 do { 0062 if(m_queue->m_abortRequest) 0063 return -1; 0064 0065 switch(m_avCtx->codec_type) { 0066 case AVMEDIA_TYPE_VIDEO: 0067 ret = avcodec_receive_frame(m_avCtx, frame); 0068 if(ret >= 0) { 0069 if(m_reorderPts == -1) 0070 frame->pts = frame->best_effort_timestamp; 0071 else if(!m_reorderPts) 0072 frame->pts = frame->pkt_dts; 0073 } 0074 break; 0075 case AVMEDIA_TYPE_AUDIO: 0076 ret = avcodec_receive_frame(m_avCtx, frame); 0077 if(ret >= 0) { 0078 AVRational tb = AVRational{ 1, frame->sample_rate }; 0079 if(frame->pts != AV_NOPTS_VALUE) 0080 frame->pts = av_rescale_q(frame->pts, m_avCtx->pkt_timebase, tb); 0081 else if(m_nextPts != AV_NOPTS_VALUE) 0082 frame->pts = av_rescale_q(m_nextPts, m_nextPtsTb, tb); 0083 if(frame->pts != AV_NOPTS_VALUE) { 0084 m_nextPts = frame->pts + frame->nb_samples; 0085 m_nextPtsTb = tb; 0086 } 0087 } 0088 break; 0089 default: 0090 break; 0091 } 0092 if(ret == AVERROR_EOF) { 0093 m_finished = m_pktSerial; 0094 avcodec_flush_buffers(m_avCtx); 0095 return 0; 0096 } 0097 if(ret >= 0) 0098 return 1; 0099 } while(ret != AVERROR(EAGAIN)); 0100 } 0101 0102 AVPacket *pkt = nullptr; 0103 for(;;) { 0104 if(m_queue->m_nbPackets == 0) 0105 m_emptyQueueCond->wakeOne(); 0106 if(m_pkt) { 0107 pkt = m_pkt; 0108 m_pkt = nullptr; 0109 } else if(m_queue->get(&pkt, 1, &m_pktSerial) < 0) { 0110 return -1; 0111 } 0112 if(m_queue->m_serial == m_pktSerial) 0113 break; 0114 av_packet_free(&pkt); 0115 } 0116 0117 if(pkt->data == FFPlayer::flushPkt()) { 0118 avcodec_flush_buffers(m_avCtx); 0119 m_finished = 0; 0120 m_nextPts = m_startPts; 0121 m_nextPtsTb = m_startPtsTb; 0122 } else if(m_avCtx->codec_type == AVMEDIA_TYPE_SUBTITLE) { 0123 int gotFrame = 0; 0124 ret = avcodec_decode_subtitle2(m_avCtx, sub, &gotFrame, pkt); 0125 if(ret < 0) { 0126 ret = AVERROR(EAGAIN); 0127 } else if(gotFrame) { 0128 ret = 0; 0129 if(!pkt->data) { 0130 m_pkt = pkt; 0131 pkt = nullptr; 0132 } 0133 } else { 0134 ret = pkt->data ? AVERROR(EAGAIN) : AVERROR_EOF; 0135 } 0136 } else if(avcodec_send_packet(m_avCtx, pkt) == AVERROR(EAGAIN)) { 0137 av_log(m_avCtx, AV_LOG_ERROR, "Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n"); 0138 m_pkt = pkt; 0139 pkt = nullptr; 0140 } 0141 av_packet_free(&pkt); 0142 } 0143 } 0144 0145 void 0146 Decoder::destroy() 0147 { 0148 av_packet_free(&m_pkt); 0149 avcodec_free_context(&m_avCtx); 0150 } 0151 0152 void 0153 Decoder::abort() 0154 { 0155 m_queue->abort(); 0156 if(m_frameQueue) 0157 m_frameQueue->signal(); 0158 requestInterruption(); 0159 wait(); 0160 m_queue->flush(); 0161 }