VideoFrame VideoFrame::to(const VideoFormat &fmt, const QSize& dstSize, const QRectF& roi) const { if (!isValid() || !constBits(0)) {// hw surface. map to host. only supports rgb packed formats now Q_D(const VideoFrame); const QVariant v = d->metadata.value(QStringLiteral("surface_interop")); if (!v.isValid()) return VideoFrame(); VideoSurfaceInteropPtr si = v.value<VideoSurfaceInteropPtr>(); if (!si) return VideoFrame(); VideoFrame f; f.setDisplayAspectRatio(displayAspectRatio()); f.setTimestamp(timestamp()); if (si->map(HostMemorySurface, fmt, &f)) { if ((!dstSize.isValid() ||dstSize == QSize(width(), height())) && (!roi.isValid() || roi == QRectF(0, 0, width(), height()))) //roi is not supported now return f; return f.to(fmt, dstSize, roi); } return VideoFrame(); } const int w = dstSize.width() > 0 ? dstSize.width() : width(); const int h = dstSize.height() > 0 ? dstSize.height() : height(); if (fmt.pixelFormatFFmpeg() == pixelFormatFFmpeg() && w == width() && h == height() // TODO: roi check. ) return *this; Q_D(const VideoFrame); ImageConverterSWS conv; conv.setInFormat(pixelFormatFFmpeg()); conv.setOutFormat(fmt.pixelFormatFFmpeg()); conv.setInSize(width(), height()); conv.setOutSize(w, h); conv.setInRange(colorRange()); if (!conv.convert(d->planes.constData(), d->line_sizes.constData())) { qWarning() << "VideoFrame::to error: " << format() << "=>" << fmt; return VideoFrame(); } VideoFrame f(w, h, fmt, conv.outData()); f.setBits(conv.outPlanes()); f.setBytesPerLine(conv.outLineSizes()); if (fmt.isRGB()) { f.setColorSpace(fmt.isPlanar() ? ColorSpace_GBR : ColorSpace_RGB); } else { f.setColorSpace(ColorSpace_Unknown); } // TODO: color range f.setTimestamp(timestamp()); f.setDisplayAspectRatio(displayAspectRatio()); f.d_ptr->metadata = d->metadata; // need metadata? return f; }
int VideoFrame::allocate() { Q_D(VideoFrame); if (pixelFormatFFmpeg() == QTAV_PIX_FMT_C(NONE) || width() <=0 || height() <= 0) { qWarning("Not valid format(%s) or size(%dx%d)", qPrintable(format().name()), width(), height()); return 0; } #if 0 const int align = 16; int bytes = av_image_get_buffer_size((AVPixelFormat)d->format.pixelFormatFFmpeg(), width(), height(), align); d->data.resize(bytes); av_image_fill_arrays(d->planes.data(), d->line_sizes.data() , (const uint8_t*)d->data.constData() , (AVPixelFormat)d->format.pixelFormatFFmpeg() , width(), height(), align); return bytes; #endif int bytes = avpicture_get_size((AVPixelFormat)pixelFormatFFmpeg(), width(), height()); if (d->data.size() < bytes) { d->data = QByteArray(bytes, 0); } init(); return bytes; }