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