Files
fmviewer3/project/fm_viewer/fav/AVDecoder_p.h
2026-02-21 17:11:31 +09:00

148 lines
4.4 KiB
C++

/******************************************************************************
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2015 Wang Bin <wbsecg1@gmail.com>
* This file is part of QtAV
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
#ifndef QTAV_AVDECODER_P_H
#define QTAV_AVDECODER_P_H
#include <QtCore/QHash>
#include <QtCore/QSharedPointer>
#include <QtCore/QVector>
#include "_fav_constants.h"
#include "AVCompat.h"
namespace FAV {
// always define the class to avoid macro check when using it
class AVFrameBuffers {
#if QTAV_HAVE(AVBUFREF)
QVector<AVBufferRef*> buf;
#endif
public:
AVFrameBuffers(AVFrame* frame) {
Q_UNUSED(frame);
#if QTAV_HAVE(AVBUFREF)
if (!frame->buf[0]) { //not ref counted. duplicate data?
return;
}
buf.reserve(frame->nb_extended_buf + FF_ARRAY_ELEMS(frame->buf));
buf.resize(frame->nb_extended_buf + FF_ARRAY_ELEMS(frame->buf));
for (int i = 0; i < (int)FF_ARRAY_ELEMS(frame->buf); ++i) {
if (!frame->buf[i]) //so not use planes + nb_extended_buf!
continue;
buf[i] = av_buffer_ref(frame->buf[i]);
if (!buf[i]) {
qWarning("av_buffer_ref(frame->buf[%d]) error", i);
}
}
if (!frame->extended_buf)
return;
for (int i = 0; i < frame->nb_extended_buf; ++i) {
const int k = buf.size() + i - frame->nb_extended_buf;
buf[k] = av_buffer_ref(frame->extended_buf[i]);
if (!buf[k]) {
qWarning("av_buffer_ref(frame->extended_buf[%d]) error", i);
}
}
#endif //QTAV_HAVE(AVBUFREF)
}
~AVFrameBuffers() {
#if QTAV_HAVE(AVBUFREF)
foreach (AVBufferRef* b, buf) {
av_buffer_unref(&b);
}
#endif //QTAV_HAVE(AVBUFREF)
}
};
typedef QSharedPointer<AVFrameBuffers> AVFrameBuffersRef;
class Q_AV_PRIVATE_EXPORT AVDecoderPrivate : public DPtrPrivate<AVDecoder>
{
public:
static const char* getProfileName(AVCodecID id, int profile) {
AVCodec *c = avcodec_find_decoder(id);
if (!c)
return "Unknow";
return av_get_profile_name(c, profile);
}
static const char* getProfileName(const AVCodecContext* ctx) {
if (ctx->codec)
return av_get_profile_name(ctx->codec, ctx->profile);
return getProfileName(ctx->codec_id, ctx->profile);
}
AVDecoderPrivate():
codec_ctx(0)
, available(true)
, is_open(false)
, undecoded_size(0)
, dict(0)
{
codec_ctx = avcodec_alloc_context3(NULL);
}
virtual ~AVDecoderPrivate() {
if (dict) {
av_dict_free(&dict);
}
if (codec_ctx) {
avcodec_free_context(&codec_ctx);
}
}
virtual bool open() {return true;}
virtual void close() {}
virtual bool enableFrameRef() const { return true;}
void applyOptionsForDict();
void applyOptionsForContext();
AVCodecContext *codec_ctx; //set once and not change
bool available; //TODO: true only when context(and hw ctx) is ready
bool is_open;
int undecoded_size;
QString codec_name;
QVariantHash options;
AVDictionary *dict;
};
class AudioResampler;
class AudioDecoderPrivate : public AVDecoderPrivate
{
public:
AudioDecoderPrivate();
virtual ~AudioDecoderPrivate();
AudioResampler *resampler;
QByteArray decoded;
};
class Q_AV_PRIVATE_EXPORT VideoDecoderPrivate : public AVDecoderPrivate
{
public:
VideoDecoderPrivate():
AVDecoderPrivate()
{}
virtual ~VideoDecoderPrivate() {}
};
} //namespace FAV
Q_DECLARE_METATYPE(FAV::AVFrameBuffersRef)
#endif // QTAV_AVDECODER_P_H