From adec05d76155ee3c471af3120faaf207c423497c Mon Sep 17 00:00:00 2001 From: wang-bin Date: Wed, 15 Nov 2017 14:10:53 +0800 Subject: [PATCH] videotoolbox: sw fallback if hw is not supported #998 --- src/VideoThread.cpp | 4 ++-- src/codec/video/VideoDecoderFFmpeg.cpp | 23 +------------------- src/codec/video/VideoDecoderFFmpegBase.cpp | 23 ++++++++++++++++++-- src/codec/video/VideoDecoderFFmpegBase.h | 3 ++- src/codec/video/VideoDecoderVideoToolbox.cpp | 8 ++++++- 5 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/VideoThread.cpp b/src/VideoThread.cpp index e77a81b85..a86f08d78 100644 --- a/src/VideoThread.cpp +++ b/src/VideoThread.cpp @@ -1,6 +1,6 @@ /****************************************************************************** QtAV: Multimedia framework based on Qt and FFmpeg - Copyright (C) 2012-2016 Wang Bin + Copyright (C) 2012-2017 Wang Bin * This file is part of QtAV @@ -488,7 +488,7 @@ void VideoThread::run() dec->setOptions(*dec_opt); if (!dec->decode(pkt)) { d.pts_history.push_back(d.pts_history.back()); - qWarning("Decode video failed. undecoded: %d/%d", dec->undecodedSize(), pkt.data.size()); + //qWarning("Decode video failed. undecoded: %d/%d", dec->undecodedSize(), pkt.data.size()); if (pkt.isEOF()) { Q_EMIT eofDecoded(); qDebug("video decode eof done. d.render_pts0: %.3f", d.render_pts0); diff --git a/src/codec/video/VideoDecoderFFmpeg.cpp b/src/codec/video/VideoDecoderFFmpeg.cpp index 85eba6c10..a5acd3366 100644 --- a/src/codec/video/VideoDecoderFFmpeg.cpp +++ b/src/codec/video/VideoDecoderFFmpeg.cpp @@ -1,6 +1,6 @@ /****************************************************************************** QtAV: Multimedia framework based on Qt and FFmpeg - Copyright (C) 2012-2016 Wang Bin + Copyright (C) 2012-2017 Wang Bin * This file is part of QtAV (from 2013) @@ -147,7 +147,6 @@ class VideoDecoderFFmpeg : public VideoDecoderFFmpegBase .arg(patch>=100?QStringLiteral("FFmpeg"):QStringLiteral("Libav")) .arg(QTAV_VERSION_MAJOR(avcodec_version())).arg(QTAV_VERSION_MINOR(avcodec_version())).arg(patch); } - virtual VideoFrame frame() Q_DECL_OVERRIDE Q_DECL_FINAL; // TODO: av_opt_set in setter void setSkipLoopFilter(DiscardType value); @@ -283,26 +282,6 @@ VideoDecoderId VideoDecoderFFmpeg::id() const return VideoDecoderId_FFmpeg; } -VideoFrame VideoDecoderFFmpeg::frame() -{ - DPTR_D(VideoDecoderFFmpeg); - if (d.frame->width <= 0 || d.frame->height <= 0 || !d.codec_ctx) - return VideoFrame(); - // it's safe if width, height, pixfmt will not change, only data change - VideoFrame frame(d.frame->width, d.frame->height, VideoFormat((int)d.codec_ctx->pix_fmt)); - frame.setDisplayAspectRatio(d.getDAR(d.frame)); - frame.setBits(d.frame->data); - frame.setBytesPerLine(d.frame->linesize); - // in s. TODO: what about AVFrame.pts? av_frame_get_best_effort_timestamp? move to VideoFrame::from(AVFrame*) - frame.setTimestamp((double)d.frame->pkt_pts/1000.0); - frame.setMetaData(QStringLiteral("avbuf"), QVariant::fromValue(AVFrameBuffersRef(new AVFrameBuffers(d.frame)))); - d.updateColorDetails(&frame); - if (frame.format().hasPalette()) { - frame.setMetaData(QStringLiteral("pallete"), QByteArray((const char*)d.frame->data[1], 256*4)); - } - return frame; -} - void VideoDecoderFFmpeg::setSkipLoopFilter(DiscardType value) { DPTR_D(VideoDecoderFFmpeg); diff --git a/src/codec/video/VideoDecoderFFmpegBase.cpp b/src/codec/video/VideoDecoderFFmpegBase.cpp index 4012c521d..e344c5cbc 100644 --- a/src/codec/video/VideoDecoderFFmpegBase.cpp +++ b/src/codec/video/VideoDecoderFFmpegBase.cpp @@ -1,6 +1,6 @@ /****************************************************************************** QtAV: Multimedia framework based on Qt and FFmpeg - Copyright (C) 2012-2016 Wang Bin + Copyright (C) 2012-2017 Wang Bin * This file is part of QtAV (from 2014) @@ -132,7 +132,7 @@ bool VideoDecoderFFmpegBase::decode(const Packet &packet) //qDebug("pic_type=%c", av_get_picture_type_char(d.frame->pict_type)); d.undecoded_size = qMin(packet.data.size() - ret, packet.data.size()); if (ret < 0) { - qWarning("[VideoDecoderFFmpegBase] %s", av_err2str(ret)); + //qWarning("[VideoDecoderFFmpegBase] %s", av_err2str(ret)); return false; } if (!got_frame_ptr) { @@ -148,4 +148,23 @@ bool VideoDecoderFFmpegBase::decode(const Packet &packet) return true; } +VideoFrame VideoDecoderFFmpegBase::frame() +{ + DPTR_D(VideoDecoderFFmpegBase); + if (d.frame->width <= 0 || d.frame->height <= 0 || !d.codec_ctx) + return VideoFrame(); + // it's safe if width, height, pixfmt will not change, only data change + VideoFrame frame(d.frame->width, d.frame->height, VideoFormat((int)d.codec_ctx->pix_fmt)); + frame.setDisplayAspectRatio(d.getDAR(d.frame)); + frame.setBits(d.frame->data); + frame.setBytesPerLine(d.frame->linesize); + // in s. TODO: what about AVFrame.pts? av_frame_get_best_effort_timestamp? move to VideoFrame::from(AVFrame*) + frame.setTimestamp((double)d.frame->pkt_pts/1000.0); + frame.setMetaData(QStringLiteral("avbuf"), QVariant::fromValue(AVFrameBuffersRef(new AVFrameBuffers(d.frame)))); + d.updateColorDetails(&frame); + if (frame.format().hasPalette()) { + frame.setMetaData(QStringLiteral("pallete"), QByteArray((const char*)d.frame->data[1], 256*4)); + } + return frame; +} } //namespace QtAV diff --git a/src/codec/video/VideoDecoderFFmpegBase.h b/src/codec/video/VideoDecoderFFmpegBase.h index 57948751b..f59e97a65 100644 --- a/src/codec/video/VideoDecoderFFmpegBase.h +++ b/src/codec/video/VideoDecoderFFmpegBase.h @@ -1,6 +1,6 @@ /****************************************************************************** QtAV: Multimedia framework based on Qt and FFmpeg - Copyright (C) 2012-2016 Wang Bin + Copyright (C) 2012-2017 Wang Bin * This file is part of QtAV (from 2014) @@ -35,6 +35,7 @@ class VideoDecoderFFmpegBase : public VideoDecoder DPTR_DECLARE_PRIVATE(VideoDecoderFFmpegBase) public: virtual bool decode(const Packet& packet) Q_DECL_OVERRIDE; + virtual VideoFrame frame() Q_DECL_OVERRIDE; protected: VideoDecoderFFmpegBase(VideoDecoderFFmpegBasePrivate &d); private: diff --git a/src/codec/video/VideoDecoderVideoToolbox.cpp b/src/codec/video/VideoDecoderVideoToolbox.cpp index 44976f388..a72947434 100755 --- a/src/codec/video/VideoDecoderVideoToolbox.cpp +++ b/src/codec/video/VideoDecoderVideoToolbox.cpp @@ -1,6 +1,6 @@ /****************************************************************************** QtAV: Multimedia framework based on Qt and FFmpeg - Copyright (C) 2012-2016 Wang Bin + Copyright (C) 2012-2017 Wang Bin * This file is part of QtAV (from 2015) @@ -148,7 +148,9 @@ static const char* cv_err_str(int err) VideoDecoderVideoToolbox::VideoDecoderVideoToolbox() : VideoDecoderFFmpegHW(*new VideoDecoderVideoToolboxPrivate()) { +#if 1//!AV_MODULE_CHECK(LIBAVCODEC, 57, 30, 1, 89, 100) // ffmpeg3.3 setProperty("threads", 1); // to avoid crash at av_videotoolbox_alloc_context/av_videotoolbox_default_free. I have no idea how the are called +#endif // dynamic properties about static property details. used by UI setProperty("detail_format", tr("Output pixel format from decoder. Performance NV12 > UYVY > BGRA > YUV420P > YUYV.\nOSX < 10.7 only supports UYVY, BGRA and YUV420p")); setProperty("detail_interop" @@ -174,6 +176,9 @@ QString VideoDecoderVideoToolbox::description() const VideoFrame VideoDecoderVideoToolbox::frame() { DPTR_D(VideoDecoderVideoToolbox); + if (!d.codec_ctx->hwaccel_context) { + return VideoDecoderFFmpegBase::frame(); + } CVPixelBufferRef cv_buffer = (CVPixelBufferRef)d.frame->data[3]; if (!cv_buffer) { qDebug("Frame buffer is empty."); @@ -286,6 +291,7 @@ void* VideoDecoderVideoToolboxPrivate::setup(AVCodecContext *avctx) bool VideoDecoderVideoToolboxPrivate::getBuffer(void **opaque, uint8_t **data) { + qDebug("vt getbuffer"); *data = (uint8_t *)1; // dummy. it's AVFrame.data[0], must be non null required by ffmpeg Q_UNUSED(opaque); return true;