def present(self, frame: QVideoFrame): print("present called") if frame.isValid(): clone_frame = QVideoFrame(frame) clone_frame.map(QAbstractVideoBuffer.ReadOnly) image = QImage(clone_frame.bits(), frame.width(), frame.height(), frame.bytesPerLine(), \ QVideoFrame.imageFormatFromPixelFormat(frame.pixelFormat())) clone_frame.unmap() self.frame_available.emit(image) if self.surfaceFormat().pixelFormat() != frame.pixelFormat() or \ self.surfaceFormat().frameSize() != frame.size(): self.setError(QAbstractVideoSurface.IncorrectFormatError) self.stop() print("present finished: Return False") return False else: self.current_frame = frame print("present finished: Return True") return True
def present(self, frame: QVideoFrame) -> bool: if not frame.isValid(): return False image_format = QVideoFrame.imageFormatFromPixelFormat(frame.pixelFormat()) if image_format == QVideoFrame.Format_Invalid: _logger.info(_('QR code scanner for video frame with invalid pixel format')) return False if not frame.map(QAbstractVideoBuffer.ReadOnly): _logger.info(_('QR code scanner failed to map video frame')) return False try: img = QImage(frame.bits(), frame.width(), frame.height(), image_format) # Check whether we need to flip the image on any axis surface_format = self.surfaceFormat() flip_x = surface_format.isMirrored() flip_y = surface_format.scanLineDirection() == QVideoSurfaceFormat.BottomToTop # Mirror the image if needed if flip_x or flip_y: img = img.mirrored(flip_x, flip_y) # Create a copy of the image so the original frame data can be freed img = img.copy() finally: frame.unmap() self.frame_available.emit(img) return True
def present(self, frame: QVideoFrame): """ Called by the video player :param frame: frame to present """ if frame.isValid(): clone_frame = QVideoFrame(frame) clone_frame.map(QAbstractVideoBuffer.ReadOnly) image = QImage( clone_frame.bits(), clone_frame.width(), clone_frame.height(), QVideoFrame.imageFormatFromPixelFormat( clone_frame.pixelFormat())) self.frameAvailable.emit(image) clone_frame.unmap() if self.surfaceFormat().pixelFormat() != frame.pixelFormat( ) or self.surfaceFormat().frameSize() != frame.size(): self.setError(self.IncorrectFormatError) self.stop() return False else: self.currentFrame = frame self.widget.repaint() return True
def present(self, frame): if frame.isValid(): cloneFrame = QVideoFrame(frame) cloneFrame.map(QAbstractVideoBuffer.ReadOnly) image = QImage(cloneFrame.bits(), cloneFrame.width(), cloneFrame.height(), QVideoFrame.imageFormatFromPixelFormat(cloneFrame.pixelFormat())) self.frameAvailable.emit(image) # this is very important cloneFrame.unmap() if self.surfaceFormat().pixelFormat() != frame.pixelFormat() or \ self.surfaceFormat().frameSize() != frame.size(): self.setError(QAbstractVideoSurface.IncorrectFormatError) self.stop() return False else: self.currentFrame = frame self.widget.repaint(self.targetRect) return True
class VideoWidgetSurface(QAbstractVideoSurface): def __init__(self, widget, parent=None): super(VideoWidgetSurface, self).__init__(parent) self.parent = parent self.widget = widget self.output = None self.t_const = None self.i = 0 self.imageFormat = QImage.Format_Invalid def supportedPixelFormats(self, handleType=QAbstractVideoBuffer.NoHandle): formats = [QVideoFrame.PixelFormat()] if handleType == QAbstractVideoBuffer.NoHandle: for f in [ QVideoFrame.Format_RGB32, QVideoFrame.Format_ARGB32, QVideoFrame.Format_ARGB32_Premultiplied, QVideoFrame.Format_RGB565, QVideoFrame.Format_RGB555 ]: formats.append(f) return formats def isFormatSupported(self, _format): imageFormat = QVideoFrame.imageFormatFromPixelFormat( _format.pixelFormat()) size = _format.frameSize() _bool = False if (imageFormat != QImage.Format_Invalid and not size.isEmpty() and _format.handleType() == QAbstractVideoBuffer.NoHandle): _bool = True return _bool def start(self, _format): imageFormat = QVideoFrame.imageFormatFromPixelFormat( _format.pixelFormat()) size = _format.frameSize() if (imageFormat != QImage.Format_Invalid and not size.isEmpty()): self.imageFormat = imageFormat self.imageSize = size self.sourceRect = _format.viewport() QAbstractVideoSurface.start(self, _format) self.widget.updateGeometry() self.updateVideoRect() return True else: return False def stop(self): self.currentFrame = QVideoFrame() self.targetRect = QRect() QAbstractVideoSurface.stop(self) self.widget.update() def present(self, frame): if self.surfaceFormat().pixelFormat() != frame.pixelFormat( ) or self.surfaceFormat().frameSize() != frame.size(): self.setError(QAbstractVideoSurface.IncorrectFormatError) self.stop() return False else: self.currentFrame = frame self.widget.repaint(self.targetRect) return True def videoRect(self): return self.targetRect def updateVideoRect(self): origin = self.surfaceFormat().sizeHint() scaled = origin.scaled(self.widget.size().boundedTo(origin), Qt.KeepAspectRatio) self.targetRect = QRect(QPoint(0, 0), scaled) self.targetRect.moveCenter(self.widget.rect().center()) if not origin.isEmpty(): self.ratio = scaled.width() / origin.width() self.refPoint = self.targetRect.topLeft() def transformed(self, obj): if type(obj) is QPolygonF: tranformed = QPolygonF() for i in range(obj.size()): tranformed << (obj.at(i) * self.ratio) + self.refPoint return tranformed else: top_left = (obj.topLeft() * self.ratio) + self.refPoint bottom_right = (obj.bottomRight() * self.ratio) + self.refPoint return QRectF(top_left, bottom_right) def paint(self, painter): try: if self.currentFrame.map(QAbstractVideoBuffer.ReadOnly): oldTransform = painter.transform() if (self.surfaceFormat().scanLineDirection() == QVideoSurfaceFormat.BottomToTop): painter.scale(1, -1) painter.translate(0, -self.widget.height()) image = QImage(self.currentFrame.bits(), self.currentFrame.width(), self.currentFrame.height(), self.currentFrame.bytesPerLine(), self.imageFormat) # print(self.parent.mediaPlayer.position()) self.i += 1 frame_id = int(self.parent.mediaPlayer.position() / self.t_const) painter.drawImage(self.targetRect, image, self.sourceRect) objects = self.output[frame_id]['cells'] for o_id, cell in objects.items(): # top, left, bottom, right = cell.bbox cell_box = self.transformed(cell) painter.setBrush(Qt.NoBrush) painter.setPen(Qt.red) if cell.isCounted(): painter.setPen(Qt.green) painter.drawText(cell_box.bottomRight(), "id {}".format(cell.getCountId())) painter.drawPoint(cell_box.center()) painter.drawRect(cell_box) area = self.output[frame_id]['area'] if area: area = self.transformed(area) painter.setPen(Qt.blue) painter.drawPolygon(area) painter.setTransform(oldTransform) self.currentFrame.unmap() except: pass
class VideoWidgetSurface(QAbstractVideoSurface): def __init__(self, widget, parent=None): super(VideoWidgetSurface, self).__init__(parent) self.widget = widget self.imageFormat = QImage.Format_Invalid def supportedPixelFormats(self, handleType=QAbstractVideoBuffer.NoHandle): formats = [QVideoFrame.PixelFormat()] if (handleType == QAbstractVideoBuffer.NoHandle): for f in [QVideoFrame.Format_RGB32, QVideoFrame.Format_ARGB32, QVideoFrame.Format_ARGB32_Premultiplied, QVideoFrame.Format_RGB565, QVideoFrame.Format_RGB555,QVideoFrame.Format_BGR24,QVideoFrame.Format_RGB24]: formats.append(f) return formats def isFormatSupported(self, _format): imageFormat = QVideoFrame.imageFormatFromPixelFormat(_format.pixelFormat()) size = _format.frameSize() _bool = False if (imageFormat != QImage.Format_Invalid and not size.isEmpty() and _format.handleType() == QAbstractVideoBuffer.NoHandle): _bool = True return _bool def start(self, _format): imageFormat = QVideoFrame.imageFormatFromPixelFormat(_format.pixelFormat()) size = _format.frameSize() if (imageFormat != QImage.Format_Invalid and not size.isEmpty()): self.imageFormat = imageFormat self.imageSize = size self.sourceRect = _format.viewport() QAbstractVideoSurface.start(self, _format) self.widget.updateGeometry() self.updateVideoRect() return True else: return False def stop(self): self.currentFrame = QVideoFrame() self.targetRect = QRect() QAbstractVideoSurface.stop(self) self.widget.update() def present(self, frame): global frameCounter if (self.surfaceFormat().pixelFormat() != frame.pixelFormat() or self.surfaceFormat().frameSize() != frame.size()): self.setError(QAbstractVideoSurface.IncorrectFormatError) self.stop() return False else: if frameCounter < player.message_count - 1: frameCounter += 1 self.currentFrame = frame self.widget.repaint(self.targetRect) return True def videoRect(self): return self.targetRect def updateVideoRect(self): size = self.surfaceFormat().sizeHint() size.scale(self.widget.size().boundedTo(size), Qt.KeepAspectRatio) self.targetRect = QRect(QPoint(0, 0), size); self.targetRect.moveCenter(self.widget.rect().center()) def paint(self, painter): if (self.currentFrame.map(QAbstractVideoBuffer.ReadOnly)): oldTransform = painter.transform() if (self.surfaceFormat().scanLineDirection() == QVideoSurfaceFormat.BottomToTop): painter.scale(1, -1); painter.translate(0, -self.widget.height()) image = QImage(self.currentFrame.bits(), self.currentFrame.width(), self.currentFrame.height(), self.currentFrame.bytesPerLine(), self.imageFormat ) painter.drawImage(self.targetRect, image, self.sourceRect) painter.setTransform(oldTransform) self.currentFrame.unmap()
class VideoWidgetSurface(QAbstractVideoSurface): def __init__(self, widget): ''' Constructor ''' super().__init__() self.widget = widget self.imageFormat = QImage.Format_Invalid self.image = None def supportedPixelFormats(self, handleType=QAbstractVideoBuffer.NoHandle): ''' Available Frames Format ''' formats = [QVideoFrame.PixelFormat()] if handleType == QAbstractVideoBuffer.NoHandle: for f in [QVideoFrame.Format_RGB32, QVideoFrame.Format_ARGB32, QVideoFrame.Format_ARGB32_Premultiplied, QVideoFrame.Format_RGB565, QVideoFrame.Format_RGB555 ]: formats.append(f) return formats def isFormatSupported(self, _format): ''' Check if is supported VideFrame format ''' imageFormat = QVideoFrame.imageFormatFromPixelFormat( _format.pixelFormat()) size = _format.frameSize() _bool = False if (imageFormat != QImage.Format_Invalid and not size.isEmpty() and _format.handleType() == QAbstractVideoBuffer.NoHandle): _bool = True return _bool def start(self, _format): ''' Start QAbstractVideoSurface ''' imageFormat = QVideoFrame.imageFormatFromPixelFormat( _format.pixelFormat()) size = _format.frameSize() if (imageFormat != QImage.Format_Invalid and not size.isEmpty()): self._sourceRect = _format.viewport() QAbstractVideoSurface.start(self, _format) self.imageFormat = imageFormat self.imageSize = size self.widget.updateGeometry() self.updateVideoRect() return True else: return False def stop(self): ''' Stop Video ''' self._currentFrame = QVideoFrame() self._targetRect = QRect() QAbstractVideoSurface.stop(self) self.widget.update() def present(self, frame): ''' Present Frame ''' if (self.surfaceFormat().pixelFormat() != frame.pixelFormat() or self.surfaceFormat().frameSize() != frame.size()): self.setError(QAbstractVideoSurface.IncorrectFormatError) # if is a hight quality frame is stopped and not call start function # self.stop() return False else: self._currentFrame = frame self.widget.update() return True def videoRect(self): ''' Get Video Rectangle ''' return self._targetRect def sourceRect(self): ''' Get Source Rectangle ''' return self._sourceRect def updateVideoRect(self): ''' Update video rectangle ''' size = self.surfaceFormat().sizeHint() size.scale(self.widget.size().boundedTo(size), Qt.KeepAspectRatio) self._targetRect = QRect(QPoint(0, 0), size) self._targetRect.moveCenter(self.widget.rect().center()) def paint(self, painter): ''' Paint Frame''' if (self._currentFrame.map(QAbstractVideoBuffer.ReadOnly)): oldTransform = painter.transform() painter.setTransform(oldTransform) self.image = QImage(self._currentFrame.bits(), self._currentFrame.width(), self._currentFrame.height(), self._currentFrame.bytesPerLine(), self.imageFormat ) if self.widget._filterSatate.grayColorFilter: self.image = filter.GrayFilter(self.image) if self.widget._filterSatate.MirroredHFilter: self.image = filter.MirrredFilter(self.image) if self.widget._filterSatate.monoFilter: self.image = filter.MonoFilter(self.image) if self.widget._filterSatate.invertColorFilter: self.image.invertPixels() # TODO : Test in other thread if self.widget._filterSatate.edgeDetectionFilter: try: self.image = filter.EdgeFilter(self.image) except Exception: None # TODO : Test in other thread if self.widget._filterSatate.contrastFilter: try: self.image = filter.AutoContrastFilter(self.image) except Exception: None # TODO : Test in other thread if self.widget._filterSatate.NDVI: try: self.image = filter.NDVIFilter(self.image) except Exception: None painter.drawImage(self._targetRect, self.image, self._sourceRect) self._currentFrame.unmap() return
class VideoFrameGrabber(QAbstractVideoSurface): frameAvailable = pyqtSignal(QImage) def __init__(self, widget: QWidget, parent: QObject): super().__init__(parent) self.widget = widget def supportedPixelFormats(self, handleType): return [ QVideoFrame.Format_ARGB32, QVideoFrame.Format_ARGB32_Premultiplied, QVideoFrame.Format_RGB32, QVideoFrame.Format_RGB24, QVideoFrame.Format_RGB565, QVideoFrame.Format_RGB555, QVideoFrame.Format_ARGB8565_Premultiplied, QVideoFrame.Format_BGRA32, QVideoFrame.Format_BGRA32_Premultiplied, QVideoFrame.Format_BGR32, QVideoFrame.Format_BGR24, QVideoFrame.Format_BGR565, QVideoFrame.Format_BGR555, QVideoFrame.Format_BGRA5658_Premultiplied, QVideoFrame.Format_AYUV444, QVideoFrame.Format_AYUV444_Premultiplied, QVideoFrame.Format_YUV444, QVideoFrame.Format_YUV420P, QVideoFrame.Format_YV12, QVideoFrame.Format_UYVY, QVideoFrame.Format_YUYV, QVideoFrame.Format_NV12, QVideoFrame.Format_NV21, QVideoFrame.Format_IMC1, QVideoFrame.Format_IMC2, QVideoFrame.Format_IMC3, QVideoFrame.Format_IMC4, QVideoFrame.Format_Y8, QVideoFrame.Format_Y16, QVideoFrame.Format_Jpeg, QVideoFrame.Format_CameraRaw, QVideoFrame.Format_AdobeDng ] def isFormatSupported(self, format): imageFormat = QVideoFrame.imageFormatFromPixelFormat( format.pixelFormat()) size = format.frameSize() return imageFormat != QImage.Format_Invalid and not size.isEmpty() and \ format.handleType() == QAbstractVideoBuffer.NoHandle def start(self, format: QVideoSurfaceFormat): imageFormat = QVideoFrame.imageFormatFromPixelFormat( format.pixelFormat()) size = format.frameSize() if imageFormat != QImage.Format_Invalid and not size.isEmpty(): self.imageFormat = imageFormat self.imageSize = size self.sourceRect = format.viewport() super().start(format) self.widget.updateGeometry() self.updateVideoRect() return True else: return False def stop(self): self.currentFrame = QVideoFrame() self.targetRect = QRect() super().stop() self.widget.update() def present(self, frame): if frame.isValid(): cloneFrame = QVideoFrame(frame) cloneFrame.map(QAbstractVideoBuffer.ReadOnly) image = QImage( cloneFrame.bits(), cloneFrame.width(), cloneFrame.height(), QVideoFrame.imageFormatFromPixelFormat( cloneFrame.pixelFormat())) self.frameAvailable.emit(image) # this is very important cloneFrame.unmap() if self.surfaceFormat().pixelFormat() != frame.pixelFormat() or \ self.surfaceFormat().frameSize() != frame.size(): self.setError(QAbstractVideoSurface.IncorrectFormatError) self.stop() return False else: self.currentFrame = frame self.widget.repaint(self.targetRect) return True def updateVideoRect(self): size = self.surfaceFormat().sizeHint() size.scale(self.widget.size().boundedTo(size), Qt.KeepAspectRatio) self.targetRect = QRect(QPoint(0, 0), size) self.targetRect.moveCenter(self.widget.rect().center()) def paint(self, painter): if self.currentFrame.map(QAbstractVideoBuffer.ReadOnly): oldTransform = self.painter.transform() if self.surfaceFormat().scanLineDirection( ) == QVideoSurfaceFormat.BottomToTop: self.painter.scale(1, -1) self.painter.translate(0, -self.widget.height()) image = QImage(self.currentFrame.bits(), self.currentFrame.width(), self.currentFrame.height(), self.currentFrame.bytesPerLine(), self.imageFormat) self.painter.drawImage(self.targetRect, image, self.sourceRect) self.painter.setTransform(oldTransform) self.currentFrame.unmap()
class VideoWidgetSurface(QAbstractVideoSurface): def __init__(self, widget, parent=None): ''' Constructor ''' super(VideoWidgetSurface, self).__init__(parent) self.widget = widget self.imageFormat = QImage.Format_Invalid self.image = None def supportedPixelFormats(self, handleType=QAbstractVideoBuffer.NoHandle): ''' Available Frames Format ''' formats = [QVideoFrame.PixelFormat()] if handleType == QAbstractVideoBuffer.NoHandle: for f in [ QVideoFrame.Format_RGB32, QVideoFrame.Format_ARGB32, QVideoFrame.Format_ARGB32_Premultiplied, QVideoFrame.Format_RGB565, QVideoFrame.Format_RGB555 ]: formats.append(f) return formats def isFormatSupported(self, _format): ''' Check if is supported VideFrame format ''' imageFormat = QVideoFrame.imageFormatFromPixelFormat( _format.pixelFormat()) size = _format.frameSize() _bool = False if (imageFormat != QImage.Format_Invalid and not size.isEmpty() and _format.handleType() == QAbstractVideoBuffer.NoHandle): _bool = True return _bool def start(self, _format): ''' Start QAbstractVideoSurface ''' imageFormat = QVideoFrame.imageFormatFromPixelFormat( _format.pixelFormat()) size = _format.frameSize() if (imageFormat != QImage.Format_Invalid and not size.isEmpty()): self.sourceRect = _format.viewport() QAbstractVideoSurface.start(self, _format) self.imageFormat = imageFormat self.imageSize = size self.widget.updateGeometry() self.updateVideoRect() return True else: return False def stop(self): ''' Stop Video ''' self.currentFrame = QVideoFrame() self.targetRect = QRect() QAbstractVideoSurface.stop(self) self.widget.update() def present(self, frame): ''' Present Frame ''' if (self.surfaceFormat().pixelFormat() != frame.pixelFormat() or self.surfaceFormat().frameSize() != frame.size()): self.setError(QAbstractVideoSurface.IncorrectFormatError) self.stop() return False else: self.currentFrame = frame self.widget.repaint(self.targetRect) return True def videoRect(self): ''' Get Video Rectangle ''' return self.targetRect def GetsourceRect(self): ''' Get Source Rectangle ''' return self.sourceRect def updateVideoRect(self): ''' Update video rectangle ''' size = self.surfaceFormat().sizeHint() size.scale(self.widget.size().boundedTo(size), Qt.KeepAspectRatio) self.targetRect = QRect(QPoint(0, 0), size) self.targetRect.moveCenter(self.widget.rect().center()) def paint(self, painter): ''' Paint Frame''' if (self.currentFrame.map(QAbstractVideoBuffer.ReadOnly)): oldTransform = painter.transform() if (self.surfaceFormat().scanLineDirection() == QVideoSurfaceFormat.BottomToTop): painter.scale(1, -1) painter.translate(0, -self.widget.height()) self.image = QImage(self.currentFrame.bits(), self.currentFrame.width(), self.currentFrame.height(), self.currentFrame.bytesPerLine(), self.imageFormat) if self.widget._filterSatate.grayColorFilter: self.image = filter.GrayFilter(self.image) if self.widget._filterSatate.MirroredHFilter: self.image = filter.MirrredFilter(self.image) if self.widget._filterSatate.monoFilter: self.image = filter.MonoFilter(self.image) # TODO : Probar en un thread distinto if self.widget._filterSatate.edgeDetectionFilter: try: self.image = filter.EdgeFilter(self.image) except Exception: None # TODO : Probar en un thread distinto if self.widget._filterSatate.contrastFilter: try: self.image = filter.AutoContrastFilter(self.image) except Exception: None if self.widget._filterSatate.invertColorFilter: self.image.invertPixels() painter.drawImage(self.targetRect, self.image, self.sourceRect) if self._interaction.objectTracking and self.widget._isinit: frame = convertQImageToMat(self.image) # Update tracker ok, bbox = self.widget.tracker.update(frame) # Draw bounding box if ok: # qgsu.showUserAndLogMessage( # "bbox : ", str(bbox), level=QGis.Warning) painter.setPen(Qt.blue) painter.drawRect( QRect(int(bbox[0]), int(bbox[1]), int(bbox[2]), int(bbox[3]))) else: qgsu.showUserAndLogMessage("Tracking failure detected ", "", level=QGis.Warning) painter.setTransform(oldTransform) self.currentFrame.unmap() return self.painter
class VideoWidgetSurface(QAbstractVideoSurface): def __init__(self, widget, parent=None): ''' Constructor ''' super(VideoWidgetSurface, self).__init__(parent) self.widget = widget self.imageFormat = QImage.Format_Invalid self.image = None self.zoomedrect = None def supportedPixelFormats(self, handleType=QAbstractVideoBuffer.NoHandle): ''' Available Frames Format ''' formats = [QVideoFrame.PixelFormat()] if handleType == QAbstractVideoBuffer.NoHandle: for f in [ QVideoFrame.Format_RGB32, QVideoFrame.Format_ARGB32, QVideoFrame.Format_ARGB32_Premultiplied, QVideoFrame.Format_RGB565, QVideoFrame.Format_RGB555 ]: formats.append(f) return formats def isFormatSupported(self, _format): ''' Check if is supported VideFrame format ''' imageFormat = QVideoFrame.imageFormatFromPixelFormat( _format.pixelFormat()) size = _format.frameSize() _bool = False if (imageFormat != QImage.Format_Invalid and not size.isEmpty() and _format.handleType() == QAbstractVideoBuffer.NoHandle): _bool = True return _bool def start(self, _format): ''' Start QAbstractVideoSurface ''' imageFormat = QVideoFrame.imageFormatFromPixelFormat( _format.pixelFormat()) size = _format.frameSize() if (imageFormat != QImage.Format_Invalid and not size.isEmpty()): self.imageFormat = imageFormat self.imageSize = size self.sourceRect = _format.viewport() QAbstractVideoSurface.start(self, _format) self.widget.updateGeometry() self.updateVideoRect() return True else: return False def stop(self): ''' Stop Video ''' self.currentFrame = QVideoFrame() self.targetRect = QRect() QAbstractVideoSurface.stop(self) self.widget.update() def present(self, frame): ''' Present Frame ''' if (self.surfaceFormat().pixelFormat() != frame.pixelFormat() or self.surfaceFormat().frameSize() != frame.size()): self.setError(QAbstractVideoSurface.IncorrectFormatError) self.stop() return False else: self.currentFrame = frame self.widget.repaint(self.targetRect) qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsVideo", 'Video : '), "Repaint Video", onlyLog=True) return True def videoRect(self): ''' Get Video Rectangle ''' return self.targetRect def GetsourceRect(self): ''' Get Source Rectangle ''' return self.sourceRect def updateVideoRect(self): ''' Update video rectangle ''' size = self.surfaceFormat().sizeHint() size.scale(self.widget.size().boundedTo(size), Qt.KeepAspectRatio) self.targetRect = QRect(QPoint(0, 0), size) self.targetRect.moveCenter(self.widget.rect().center()) def updateVideoZoomRect(self, rect): # TODO : Make this function size = self.surfaceFormat().sizeHint() size.scale(rect.width(), rect.height(), Qt.KeepAspectRatio) self.zoomedrect = rect self.zoomedrect.moveCenter(rect.center()) self.widget.update() def updatetest(self): return def paint(self, painter): ''' Paint Frame''' if (self.currentFrame.map(QAbstractVideoBuffer.ReadOnly)): oldTransform = painter.transform() if (self.surfaceFormat().scanLineDirection() == QVideoSurfaceFormat.BottomToTop): painter.scale(1, -1) painter.translate(0, -self.widget.height()) self.image = QImage(self.currentFrame.bits(), self.currentFrame.width(), self.currentFrame.height(), self.currentFrame.bytesPerLine(), self.imageFormat) if grayColorFilter: self.image = filter.GrayFilter(self.image) if monoFilter: self.image = filter.MonoFilter(self.image) if edgeDetectionFilter: self.image = filter.EdgeFilter(self.image) if contrastFilter: self.image = filter.AutoContrastFilter(self.image) if invertColorFilter: self.image.invertPixels() if zoomRect and self.zoomedrect is not None: painter.drawImage(self.sourceRect, self.image, self.zoomedrect) painter.setTransform(oldTransform) self.currentFrame.unmap() return painter.drawImage(self.targetRect, self.image, self.sourceRect) painter.setTransform(oldTransform) self.currentFrame.unmap() self.currentFrame.release()
class VideoFrameGrabber(QAbstractVideoSurface): """ This video surface can be used as a QMediaPlayer target but also allows access to the data """ frameAvailable = pyqtSignal(QImage) def __init__(self, widget, *args, **kwargs): super().__init__(widget, *args, **kwargs) self.imageFormat = QImage.Format_Invalid self.widget = widget self.targetRect = QRect() self.sourceRect = QRect() self.imageSize = QSize() self.currentFrame = None @staticmethod def _format_size_(surface_format): image_format = QVideoFrame.imageFormatFromPixelFormat( surface_format.pixelFormat()) size = surface_format.frameSize() return image_format, size def isFormatSupported(self, surface_format): """ True if format is supported :param surface_format: format """ image_format, size = self._format_size_(surface_format) return image_format != QImage.Format_Invalid and not size.isEmpty( ) and surface_format.handleType() == QAbstractVideoBuffer.NoHandle def start(self, surface_format): """ Start capturing :param surface_format: surface format """ image_format, size = self._format_size_(surface_format) if image_format != QImage.Format_Invalid and not size.isEmpty(): self.imageFormat = image_format self.imageSize = size self.sourceRect = surface_format.viewport() super().start(surface_format) self.widget.updateGeometry() self.update_video_rect() return True else: return False def stop(self): """ Stop capturing """ self.currentFrame = QVideoFrame() self.targetRect = QRect() super().stop() self.widget.update() def present(self, frame: QVideoFrame): """ Called by the video player :param frame: frame to present """ if frame.isValid(): clone_frame = QVideoFrame(frame) clone_frame.map(QAbstractVideoBuffer.ReadOnly) image = QImage( clone_frame.bits(), clone_frame.width(), clone_frame.height(), QVideoFrame.imageFormatFromPixelFormat( clone_frame.pixelFormat())) self.frameAvailable.emit(image) clone_frame.unmap() if self.surfaceFormat().pixelFormat() != frame.pixelFormat( ) or self.surfaceFormat().frameSize() != frame.size(): self.setError(self.IncorrectFormatError) self.stop() return False else: self.currentFrame = frame self.widget.repaint() return True def paint(self, painter: QPainter): """ Paint frame :param painter: painter to use """ if self.currentFrame.map(QAbstractVideoBuffer.ReadOnly): old_transform = painter.transform() if self.surfaceFormat().scanLineDirection( ) == QVideoSurfaceFormat.BottomToTop: painter.scale(1, -1) painter.translate(0, -self.widget.height()) image = QImage(self.currentFrame.bits(), self.currentFrame.width(), self.currentFrame.height(), self.currentFrame.bytesPerLine(), self.imageFormat) painter.drawImage(self.targetRect, image, self.sourceRect) painter.setTransform(old_transform) self.currentFrame.unmap() def update_video_rect(self): """ Update dimensions """ size = self.surfaceFormat().sizeHint() size.scale(self.widget.size().boundedTo(size), Qt.KeepAspectRatio) self.targetRect = QRect(QPoint(0, 0), size) self.targetRect.moveCenter(self.widget.rect().center()) def supportedPixelFormats(self, handle_type=None): """ Get all supported formats :param handle_type: handle_type """ return [ QVideoFrame.Format_ARGB32, QVideoFrame.Format_ARGB32_Premultiplied, QVideoFrame.Format_RGB32, QVideoFrame.Format_RGB24, QVideoFrame.Format_RGB565, QVideoFrame.Format_RGB555, QVideoFrame.Format_ARGB8565_Premultiplied, QVideoFrame.Format_BGRA32, QVideoFrame.Format_BGRA32_Premultiplied, QVideoFrame.Format_BGR32, QVideoFrame.Format_BGR24, QVideoFrame.Format_BGR565, QVideoFrame.Format_BGR555, QVideoFrame.Format_BGRA5658_Premultiplied, QVideoFrame.Format_AYUV444, QVideoFrame.Format_AYUV444_Premultiplied, QVideoFrame.Format_YUV444, QVideoFrame.Format_YUV420P, QVideoFrame.Format_YV12, QVideoFrame.Format_UYVY, QVideoFrame.Format_YUYV, QVideoFrame.Format_NV12, QVideoFrame.Format_NV21, QVideoFrame.Format_IMC1, QVideoFrame.Format_IMC2, QVideoFrame.Format_IMC3, QVideoFrame.Format_IMC4, QVideoFrame.Format_Y8, QVideoFrame.Format_Y16, QVideoFrame.Format_Jpeg, QVideoFrame.Format_CameraRaw, QVideoFrame.Format_AdobeDng ]