File indexing completed on 2025-01-19 03:57:03
0001 /********************************************************* 0002 * Copyright (C) 2020, Val Doroshchuk <valbok@gmail.com> * 0003 * * 0004 * This file is part of QtAVPlayer. * 0005 * Free Qt Media Player based on FFmpeg. * 0006 *********************************************************/ 0007 0008 #include "qavcodec_p.h" 0009 #include "qavcodec_p_p.h" 0010 0011 #include <QDebug> 0012 0013 extern "C" { 0014 #include <libavutil/opt.h> 0015 #include <libavcodec/avcodec.h> 0016 #include <libavformat/avformat.h> 0017 } 0018 0019 QT_BEGIN_NAMESPACE 0020 0021 QAVCodec::QAVCodec() 0022 : QAVCodec(*new QAVCodecPrivate) 0023 { 0024 } 0025 0026 QAVCodec::QAVCodec(QAVCodecPrivate &d) 0027 : d_ptr(&d) 0028 { 0029 d_ptr->avctx = avcodec_alloc_context3(nullptr); 0030 } 0031 0032 QAVCodec::~QAVCodec() 0033 { 0034 Q_D(QAVCodec); 0035 if (d->avctx) 0036 avcodec_free_context(&d->avctx); 0037 } 0038 0039 void QAVCodec::setCodec(const AVCodec *c) 0040 { 0041 d_func()->codec = c; 0042 } 0043 0044 bool QAVCodec::open(AVStream *stream) 0045 { 0046 Q_D(QAVCodec); 0047 0048 if (!stream) 0049 return false; 0050 0051 int ret = avcodec_parameters_to_context(d->avctx, stream->codecpar); 0052 if (ret < 0) { 0053 qWarning() << "Failed avcodec_parameters_to_context:" << ret; 0054 return false; 0055 } 0056 0057 d->avctx->pkt_timebase = stream->time_base; 0058 d->avctx->framerate = stream->avg_frame_rate; 0059 if (!d->codec) 0060 d->codec = avcodec_find_decoder(d->avctx->codec_id); 0061 if (!d->codec) { 0062 qWarning() << "No decoder could be found for codec"; 0063 return false; 0064 } 0065 0066 d->avctx->codec_id = d->codec->id; 0067 0068 av_opt_set_int(d->avctx, "refcounted_frames", true, 0); 0069 av_opt_set_int(d->avctx, "threads", 1, 0); 0070 ret = avcodec_open2(d->avctx, d->codec, nullptr); 0071 if (ret < 0) { 0072 qWarning() << "Could not open the codec:" << d->codec->name << ret; 0073 return false; 0074 } 0075 0076 stream->discard = AVDISCARD_DEFAULT; 0077 d->stream = stream; 0078 0079 return true; 0080 } 0081 0082 AVCodecContext *QAVCodec::avctx() const 0083 { 0084 return d_func()->avctx; 0085 } 0086 0087 const AVCodec *QAVCodec::codec() const 0088 { 0089 return d_func()->codec; 0090 } 0091 0092 void QAVCodec::flushBuffers() 0093 { 0094 Q_D(QAVCodec); 0095 if (!d->avctx) 0096 return; 0097 avcodec_flush_buffers(d->avctx); 0098 } 0099 QT_END_NAMESPACE