VideoFrame VideoFrame::clone() const { Q_D(const VideoFrame); if (!d->format.isValid()) return VideoFrame(); int bytes = 0; for (int i = 0; i < d->format.planeCount(); ++i) { bytes += bytesPerLine(i)*planeHeight(i); } QByteArray buf(bytes, 0); char *dst = buf.data(); //must before buf is shared, otherwise data will be detached. VideoFrame f(buf, width(), height(), d->format); for (int i = 0; i < d->format.planeCount(); ++i) { f.setBits((quint8*)dst, i); f.setBytesPerLine(bytesPerLine(i), i); const int plane_size = bytesPerLine(i)*planeHeight(i); memcpy(dst, bits(i), plane_size); dst += plane_size; } f.d_ptr->metadata = d->metadata; // need metadata? f.setTimestamp(d->timestamp); f.setDisplayAspectRatio(d->displayAspectRatio); //f.setImageConverter(d->conv); return f; }
VideoFrame VideoFrame::clone() const { Q_D(const VideoFrame); if (!d->format.isValid()) return VideoFrame(); // data may be not set (ff decoder) if (d->planes.isEmpty() || !d->planes.at(0)) {//d->data.size() < width()*height()) { // at least width*height // maybe in gpu memory, then bits() is not set qDebug("frame data not valid. size: %d", d->data.size()); VideoFrame f(width(), height(), d->format); f.d_ptr->metadata = d->metadata; // need metadata? f.setTimestamp(d->timestamp); f.setDisplayAspectRatio(d->displayAspectRatio); return f; } int bytes = 0; for (int i = 0; i < d->format.planeCount(); ++i) { bytes += bytesPerLine(i)*planeHeight(i); } QByteArray buf(bytes, 0); char *dst = buf.data(); //must before buf is shared, otherwise data will be detached. VideoFrame f(width(), height(), d->format, buf); const int nb_planes = d->format.planeCount(); for (int i = 0; i < nb_planes; ++i) { f.setBits((quint8*)dst, i); f.setBytesPerLine(bytesPerLine(i), i); const int plane_size = bytesPerLine(i)*planeHeight(i); memcpy(dst, constBits(i), plane_size); dst += plane_size; } f.d_ptr->metadata = d->metadata; // need metadata? f.setTimestamp(d->timestamp); f.setDisplayAspectRatio(d->displayAspectRatio); f.setColorSpace(d->color_space); f.setColorRange(d->color_range); return f; }
void* VideoFrame::createInteropHandle(void* handle, SurfaceType type, int plane) { Q_D(VideoFrame); const QVariant v = d->metadata.value(QStringLiteral("surface_interop")); if (!v.isValid()) return 0; d->surface_interop = v.value<VideoSurfaceInteropPtr>(); if (!d->surface_interop) return 0; if (plane > planeCount()) return 0; return d->surface_interop->createHandle(handle, type, format(), plane, planeWidth(plane), planeHeight(plane)); }