diff --git a/src/AVDecoder.cpp b/src/AVDecoder.cpp index f8183a04..8aa40ab8 100644 --- a/src/AVDecoder.cpp +++ b/src/AVDecoder.cpp @@ -54,6 +54,32 @@ AVCodecContext* AVDecoder::codecContext() const return d_func().codec_ctx; } +void AVDecoder::setLowResolution(int lowres) +{ + d_func().low_resolution = lowres; +} + +int AVDecoder::lowResolution() const +{ + return d_func().low_resolution; +} + +void AVDecoder::setDecodeThreads(int threads) +{ + DPTR_D(AVDecoder); + d.threads = threads > 0 ? threads : av_cpu_count(); +} + +int AVDecoder::decodeThreads() const +{ + return d_func().threads; +} + +void AVDecoder::setThreadSlice(bool s) +{ + d_func().thread_slice = s; +} + bool AVDecoder::isAvailable() const { return d_func().codec_ctx != 0; @@ -61,6 +87,21 @@ bool AVDecoder::isAvailable() const bool AVDecoder::prepare() { + DPTR_D(AVDecoder); + if (!d.codec_ctx) { + qWarning("call this after AVCodecContext is set!"); + return false; + } + qDebug("Decoding threads count: %d", d.threads); + d.codec_ctx->thread_count = d.threads; + if (d.threads > 1) + d.codec_ctx->thread_type = d.thread_slice ? FF_THREAD_SLICE : FF_THREAD_FRAME; + else + d.codec_ctx->thread_type = 0; //FF_THREAD_FRAME:1, FF_THREAD_SLICE:2 + + //? !CODEC_ID_H264 && !CODEC_ID_VP8 + d.codec_ctx->lowres = d.low_resolution; + return true; } diff --git a/src/AVDemuxer.cpp b/src/AVDemuxer.cpp index f0fc35a2..47867abc 100644 --- a/src/AVDemuxer.cpp +++ b/src/AVDemuxer.cpp @@ -727,13 +727,6 @@ bool AVDemuxer::findAVCodec() if (type == AVMEDIA_TYPE_VIDEO && video_stream < 0) { video_stream = i; v_codec_context = format_context->streams[video_stream]->codec; - //if !vaapi - if (v_codec_context->codec_id == CODEC_ID_H264) { - v_codec_context->thread_type = FF_THREAD_FRAME; //FF_THREAD_SLICE; - v_codec_context->thread_count = QThread::idealThreadCount(); - } else { - //v_codec_context->lowres = 0; - } } else if (type == AVMEDIA_TYPE_AUDIO && audio_stream < 0) { audio_stream = i; a_codec_context = format_context->streams[audio_stream]->codec; diff --git a/src/QtAV/AVDecoder.h b/src/QtAV/AVDecoder.h index 4524579c..5397a385 100644 --- a/src/QtAV/AVDecoder.h +++ b/src/QtAV/AVDecoder.h @@ -40,6 +40,13 @@ public: void flush(); void setCodecContext(AVCodecContext* codecCtx); //protected AVCodecContext* codecContext() const; + //? low resolution decoding, 0: normal, 1-> 1/2 size, 2->1/4 size + void setLowResolution(int lowres); + int lowResolution() const; + // 0: auto detect by av_cpu_count() + void setDecodeThreads(int threads); + int decodeThreads() const; + void setThreadSlice(bool s); /*not available if AVCodecContext == 0*/ bool isAvailable() const; virtual bool prepare(); //if resampler or image converter set, call it diff --git a/src/QtAV/QtAV_Compat.h b/src/QtAV/QtAV_Compat.h index 0a8dbe47..4f22b7eb 100644 --- a/src/QtAV/QtAV_Compat.h +++ b/src/QtAV/QtAV_Compat.h @@ -33,6 +33,7 @@ extern "C" #include #include #include //AV_ROUND_UP, av_rescale_rnd for libav +#include #include #include #include diff --git a/src/QtAV/VideoDecoder.h b/src/QtAV/VideoDecoder.h index 6598a863..6d2074ab 100644 --- a/src/QtAV/VideoDecoder.h +++ b/src/QtAV/VideoDecoder.h @@ -42,6 +42,7 @@ public: VideoDecoder(); virtual ~VideoDecoder(); //virtual bool prepare(); + virtual bool prepare(); virtual bool decode(const QByteArray &encoded); //TODO: new api: originalVideoSize()(inSize()), decodedVideoSize()(outSize()) //size: the decoded(actually then resized in ImageConverter) frame size diff --git a/src/QtAV/private/AVDecoder_p.h b/src/QtAV/private/AVDecoder_p.h index 6107eb89..15d22637 100644 --- a/src/QtAV/private/AVDecoder_p.h +++ b/src/QtAV/private/AVDecoder_p.h @@ -33,8 +33,12 @@ class Q_EXPORT AVDecoderPrivate : public DPtrPrivate public: AVDecoderPrivate(): codec_ctx(0) + , available(true) , frame(0) , got_frame_ptr(0) + , threads(av_cpu_count()) + , thread_slice(1) + , low_resolution(0) { frame = avcodec_alloc_frame(); } @@ -46,10 +50,14 @@ public: } AVCodecContext *codec_ctx; //set once and not change + bool available; AVFrame *frame; //set once and not change QByteArray decoded; int got_frame_ptr; QMutex mutex; + int threads; + bool thread_slice; + int low_resolution; }; } //namespace QtAV diff --git a/src/VideoDecoder.cpp b/src/VideoDecoder.cpp index 2d120142..d3eb2520 100644 --- a/src/VideoDecoder.cpp +++ b/src/VideoDecoder.cpp @@ -53,6 +53,11 @@ VideoDecoder::~VideoDecoder() { } +bool VideoDecoder::prepare() +{ + return AVDecoder::prepare(); +} + //TODO: use ipp, cuda decode and yuv functions. is sws_scale necessary? bool VideoDecoder::decode(const QByteArray &encoded) {