viewfinderwrapper.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include "viewfinderwrapper.h"
  2. #include <QDebug>
  3. ViewFinderWrapper::ViewFinderWrapper(QDeclarativeItem *parent) :
  4. QDeclarativeItem(parent),
  5. m_camera(0), m_cameraStatus(QCamera::UnloadedStatus), m_cameraError(QCamera::NoError),
  6. m_cameraActive(false), m_viewFinderActive(false),
  7. m_receivedFrameCounter(0), m_processedFrameCounter(0), m_skippedFrameCounter(0),
  8. m_processor(0)
  9. {
  10. m_currentFrame = QPixmap();
  11. // Set flags to get our QML-element to draw
  12. setFlag(QGraphicsItem::ItemHasNoContents, false);
  13. // Connect surface to our slot
  14. connect(&m_surface, SIGNAL(frameAvailable()), this, SLOT(frameReady()));
  15. }
  16. ViewFinderWrapper::~ViewFinderWrapper()
  17. {
  18. m_processor->deleteLater();
  19. stopViewFinder();
  20. stopCamera();
  21. }
  22. int ViewFinderWrapper::cameraStatus() const
  23. {
  24. return m_cameraStatus;
  25. }
  26. int ViewFinderWrapper::cameraError() const
  27. {
  28. return m_cameraError;
  29. }
  30. long ViewFinderWrapper::frameCount() const
  31. {
  32. return m_receivedFrameCounter;
  33. }
  34. long ViewFinderWrapper::processedCount() const
  35. {
  36. return m_processedFrameCounter;
  37. }
  38. long ViewFinderWrapper::skippedCount() const
  39. {
  40. return m_skippedFrameCounter;
  41. }
  42. bool ViewFinderWrapper::running() const
  43. {
  44. return m_viewFinderActive;
  45. }
  46. void ViewFinderWrapper::startCamera()
  47. {
  48. Q_ASSERT(!m_camera);
  49. Q_ASSERT(!m_processor);
  50. m_processor = new ProcessingThread(this);
  51. connect(m_processor, SIGNAL(frameProcessed()), this, SLOT(onFrameProcessed()));
  52. connect(m_processor, SIGNAL(queueFull()), this, SLOT(onFrameSkipped()));
  53. m_processor->start();
  54. m_camera = new QCamera(this);
  55. if (m_camera) {
  56. connect(m_camera, SIGNAL(stateChanged(QCamera::State)), this, SLOT(onStateChanged(QCamera::State)));
  57. connect(m_camera, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(onStatusChanged(QCamera::Status)));
  58. connect(m_camera, SIGNAL(error(QCamera::Error)), this, SLOT(onCameraError(QCamera::Error)));
  59. m_camera->start();
  60. m_cameraActive = true;
  61. }
  62. }
  63. void ViewFinderWrapper::stopCamera()
  64. {
  65. Q_ASSERT(m_camera);
  66. // Stop processing thread
  67. m_processor->stop();
  68. m_processor->deleteLater();
  69. m_processor = 0;
  70. // Stop viewfinder
  71. stopViewFinder();
  72. // Stop camera
  73. m_cameraActive = false;
  74. m_camera->stop();
  75. delete m_camera;
  76. m_camera = 0;
  77. // Reset state
  78. reset();
  79. }
  80. void ViewFinderWrapper::reset()
  81. {
  82. m_cameraStatus = QCamera::UnloadedStatus;
  83. m_cameraError = QCamera::NoError;
  84. m_currentFrame = QPixmap();
  85. m_receivedFrameCounter = 0;
  86. m_processedFrameCounter = 0;
  87. m_skippedFrameCounter = 0;
  88. update();
  89. }
  90. void ViewFinderWrapper::startViewFinder()
  91. {
  92. if (!m_viewFinderActive)
  93. {
  94. m_camera->setViewfinder( static_cast<QAbstractVideoSurface*>( &m_surface ) );
  95. m_viewFinderActive = true;
  96. emit runningChanged();
  97. }
  98. }
  99. void ViewFinderWrapper::stopViewFinder()
  100. {
  101. if (m_viewFinderActive)
  102. {
  103. m_receivedFrameCounter = 0;
  104. m_viewFinderActive = false;
  105. m_camera->setViewfinder( static_cast<QAbstractVideoSurface*>( 0 ) );
  106. emit runningChanged();
  107. }
  108. }
  109. void ViewFinderWrapper::onStateChanged(QCamera::State state)
  110. {
  111. }
  112. void ViewFinderWrapper::onStatusChanged(QCamera::Status status)
  113. {
  114. m_cameraStatus = status;
  115. if (m_cameraStatus == QCamera::ActiveStatus) {
  116. startViewFinder();
  117. }
  118. emit cameraStatusChanged(m_cameraStatus);
  119. }
  120. void ViewFinderWrapper::onCameraError(QCamera::Error error)
  121. {
  122. m_cameraError = error;
  123. emit cameraErrorChanged(m_cameraError);
  124. }
  125. void ViewFinderWrapper::frameReady()
  126. {
  127. m_receivedFrameCounter++;
  128. emit frameCountChanged(m_receivedFrameCounter);
  129. // Get the current frame from the video surface
  130. QImage frame = m_surface.frame();
  131. // Add received frame to processing thread for processing
  132. if (m_processor) {
  133. m_processor->addFrameToProcessingQueue(frame);
  134. }
  135. // And take a copy for ourselves for drawing it on the screen
  136. m_currentFrame = QPixmap::fromImage(frame);
  137. // Update the UI
  138. update();
  139. }
  140. void ViewFinderWrapper::onFrameProcessed()
  141. {
  142. m_processedFrameCounter++;
  143. emit processedCountChanged(m_processedFrameCounter);
  144. update();
  145. }
  146. void ViewFinderWrapper::onFrameSkipped()
  147. {
  148. m_skippedFrameCounter++;
  149. emit skippedCountChanged(m_skippedFrameCounter);
  150. update();
  151. }
  152. void ViewFinderWrapper::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
  153. {
  154. Q_UNUSED(widget);
  155. if (painter)
  156. {
  157. QRect rect = option->rect;
  158. if (m_currentFrame.isNull()) {
  159. painter->fillRect(rect, Qt::lightGray);
  160. } else {
  161. painter->drawPixmap(rect, m_currentFrame);
  162. }
  163. }
  164. }