diff --git a/src/QtAV/VideoFrame.h b/src/QtAV/VideoFrame.h index 6f29271a..c97bd1bf 100644 --- a/src/QtAV/VideoFrame.h +++ b/src/QtAV/VideoFrame.h @@ -1,6 +1,6 @@ /****************************************************************************** QtAV: Media play library based on Qt and FFmpeg - Copyright (C) 2012-2015 Wang Bin + Copyright (C) 2012-2016 Wang Bin * This file is part of QtAV @@ -56,13 +56,13 @@ public: //set planes and linesize manually or call init QTAV_DEPRECATED VideoFrame(const QByteArray& data, int width, int height, const VideoFormat& format); VideoFrame(const QVector& textures, int width, int height, const VideoFormat& format); - VideoFrame(const QImage& image); // does not copy the image data + VideoFrame(const QImage& image); VideoFrame(const VideoFrame &other); - virtual ~VideoFrame(); + ~VideoFrame(); VideoFrame &operator =(const VideoFrame &other); - virtual int channelCount() const; + int channelCount() const Q_DECL_OVERRIDE; /*! * Deep copy. Given the format, width and height, plane addresses and line sizes. */ @@ -96,13 +96,14 @@ public: /*! * \brief toImage * Return a QImage of current video frame, with given format, image size and region of interest. + * If VideoFrame is constructed from an QImage, the target format, size and roi are the same, then no data copy. * \param dstSize result image size * \param roi NOT implemented! */ QImage toImage(QImage::Format fmt = QImage::Format_ARGB32, const QSize& dstSize = QSize(), const QRectF& roi = QRect()) const; /*! * \brief to - * The result frame data is always on host memory. + * The result frame data is always on host memory. If video frame data is already in host memory, and the target parameters are the same, then return the current frame. * \param pixfmt target pixel format * \param dstSize target frame size * \param roi interested region of source frame diff --git a/src/VideoFrame.cpp b/src/VideoFrame.cpp index 0d2c2daf..d19a57e6 100644 --- a/src/VideoFrame.cpp +++ b/src/VideoFrame.cpp @@ -1,6 +1,6 @@ /****************************************************************************** QtAV: Media play library based on Qt and FFmpeg - Copyright (C) 2012-2015 Wang Bin + Copyright (C) 2012-2016 Wang Bin * This file is part of QtAV @@ -146,6 +146,7 @@ public: float displayAspectRatio; VideoFormat format; QVector textures; + QScopedPointer qt_image; VideoSurfaceInteropPtr surface_interop; }; @@ -181,6 +182,7 @@ VideoFrame::VideoFrame(const QImage& image) { setBits((uchar*)image.constBits(), 0); setBytesPerLine(image.bytesPerLine(), 0); + d_func()->qt_image.reset(new QImage(image)); } /*! @@ -352,6 +354,13 @@ int VideoFrame::effectiveBytesPerLine(int plane) const QImage VideoFrame::toImage(QImage::Format fmt, const QSize& dstSize, const QRectF &roi) const { + Q_D(const VideoFrame); + if (!d->qt_image.isNull() + && fmt == d->qt_image->format() + && dstSize == d->qt_image->size() + && (!roi.isValid() || roi == d->qt_image->rect())) { + return *d->qt_image.data(); + } VideoFrame f(to(VideoFormat(VideoFormat::pixelFormatFromImageFormat(fmt)), dstSize, roi)); if (!f) return QImage();