mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 13:00:26 -04:00 
			
		
		
		
	ATV Modulator: transmit video interim state (1)
This commit is contained in:
		
							parent
							
								
									870f44a51b
								
							
						
					
					
						commit
						2a64878d7f
					
				| @ -37,7 +37,11 @@ ATVMod::ATVMod() : | |||||||
|     m_settingsMutex(QMutex::Recursive), |     m_settingsMutex(QMutex::Recursive), | ||||||
|     m_horizontalCount(0), |     m_horizontalCount(0), | ||||||
|     m_lineCount(0), |     m_lineCount(0), | ||||||
| 	m_imageOK(false) | 	m_imageOK(false), | ||||||
|  | 	m_videoFPSq(1.0f), | ||||||
|  |     m_videoFPSCount(0.0f), | ||||||
|  | 	m_videoPrevFPSCount(0), | ||||||
|  | 	m_videoOK(false) | ||||||
| { | { | ||||||
|     setObjectName("ATVMod"); |     setObjectName("ATVMod"); | ||||||
| 
 | 
 | ||||||
| @ -59,6 +63,7 @@ ATVMod::ATVMod() : | |||||||
| 
 | 
 | ||||||
| ATVMod::~ATVMod() | ATVMod::~ATVMod() | ||||||
| { | { | ||||||
|  | 	if (m_video.isOpened()) m_video.release(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ATVMod::configure(MessageQueue* messageQueue, | void ATVMod::configure(MessageQueue* messageQueue, | ||||||
| @ -171,10 +176,48 @@ void ATVMod::pullVideo(Real& sample) | |||||||
|             m_lineCount++; |             m_lineCount++; | ||||||
|             if (m_lineCount > (m_nbLines/2)) m_evenImage = !m_evenImage; |             if (m_lineCount > (m_nbLines/2)) m_evenImage = !m_evenImage; | ||||||
|         } |         } | ||||||
|         else |         else // new image
 | ||||||
|         { |         { | ||||||
|             m_lineCount = 0; |             m_lineCount = 0; | ||||||
|             m_evenImage = !m_evenImage; |             m_evenImage = !m_evenImage; | ||||||
|  | 
 | ||||||
|  |             if (m_running.m_atvModInput == ATVModInputVideo) | ||||||
|  |             { | ||||||
|  |             	int grabOK; | ||||||
|  |             	int fpsIncrement = (int) m_videoFPSCount - m_videoPrevFPSCount; | ||||||
|  | 
 | ||||||
|  |             	// move a number of frames according to increment
 | ||||||
|  |             	// use grab to test for EOF then retrieve to preserve last valid frame as the current original frame
 | ||||||
|  |             	// TODO: handle pause (no move)
 | ||||||
|  |             	for (int i = 0; i < fpsIncrement; i++) | ||||||
|  |             	{ | ||||||
|  |             		grabOK = m_video.grab(); | ||||||
|  |             		if (!grabOK) break; | ||||||
|  |             	} | ||||||
|  | 
 | ||||||
|  |             	if (grabOK) | ||||||
|  |             	{ | ||||||
|  |             		cv::Mat colorFrame; | ||||||
|  |             		m_video.retrieve(colorFrame); | ||||||
|  |             		cv::cvtColor(colorFrame, m_frameOriginal, CV_BGR2GRAY); | ||||||
|  |             		resizeVideo(); | ||||||
|  |             	} | ||||||
|  |             	else | ||||||
|  |             	{ | ||||||
|  |             		// TODO: handle play loop
 | ||||||
|  |             	} | ||||||
|  | 
 | ||||||
|  |             	if (m_videoFPSCount < m_videoFPS) | ||||||
|  |             	{ | ||||||
|  |             		m_videoPrevFPSCount = (int) m_videoFPSCount; | ||||||
|  |                 	m_videoFPSCount += m_videoFPSq; | ||||||
|  |             	} | ||||||
|  |             	else | ||||||
|  |             	{ | ||||||
|  |             		m_videoPrevFPSCount = 0; | ||||||
|  |             		m_videoFPSCount = m_videoFPSq; | ||||||
|  |             	} | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         m_horizontalCount = 0; |         m_horizontalCount = 0; | ||||||
| @ -342,7 +385,7 @@ void ATVMod::applyStandard() | |||||||
|         m_nbImageLines2    = 255; |         m_nbImageLines2    = 255; | ||||||
|         m_interlaced       = true; |         m_interlaced       = true; | ||||||
|         m_nbHorizPoints    = 64 * m_pointsPerTU; // full line
 |         m_nbHorizPoints    = 64 * m_pointsPerTU; // full line
 | ||||||
|         m_nbSyncLinesH     = 5; |         m_nbSyncLinesHead  = 5; | ||||||
|         m_nbBlankLines     = 15; // yields 480 lines (255 - 15) * 2
 |         m_nbBlankLines     = 15; // yields 480 lines (255 - 15) * 2
 | ||||||
|         m_pointsPerHBar    = m_pointsPerImgLine / m_nbBars; |         m_pointsPerHBar    = m_pointsPerImgLine / m_nbBars; | ||||||
|         m_linesPerVBar     = m_nbImageLines2  / m_nbBars; |         m_linesPerVBar     = m_nbImageLines2  / m_nbBars; | ||||||
| @ -364,7 +407,7 @@ void ATVMod::applyStandard() | |||||||
|         m_nbImageLines2    = 305; |         m_nbImageLines2    = 305; | ||||||
|         m_interlaced       = true; |         m_interlaced       = true; | ||||||
|         m_nbHorizPoints    = 64 * m_pointsPerTU; // full line
 |         m_nbHorizPoints    = 64 * m_pointsPerTU; // full line
 | ||||||
|         m_nbSyncLinesH     = 5; |         m_nbSyncLinesHead  = 5; | ||||||
|         m_nbBlankLines     = 17; // yields 576 lines (305 - 17) * 2
 |         m_nbBlankLines     = 17; // yields 576 lines (305 - 17) * 2
 | ||||||
|         m_pointsPerHBar    = m_pointsPerImgLine / m_nbBars; |         m_pointsPerHBar    = m_pointsPerImgLine / m_nbBars; | ||||||
|         m_linesPerVBar     = m_nbImageLines2 / m_nbBars; |         m_linesPerVBar     = m_nbImageLines2 / m_nbBars; | ||||||
| @ -377,6 +420,12 @@ void ATVMod::applyStandard() | |||||||
|     { |     { | ||||||
|         resizeImage(); |         resizeImage(); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     if (m_videoOK) | ||||||
|  |     { | ||||||
|  |     	calculateVideoSizes(); | ||||||
|  |     	resizeVideo(); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ATVMod::openImage(const QString& fileName) | void ATVMod::openImage(const QString& fileName) | ||||||
| @ -392,6 +441,8 @@ void ATVMod::openImage(const QString& fileName) | |||||||
| 
 | 
 | ||||||
| void ATVMod::openVideo(const QString& fileName) | void ATVMod::openVideo(const QString& fileName) | ||||||
| { | { | ||||||
|  | 	//if (m_videoOK && m_video.isOpened()) m_video.release(); should be done by OpenCV in open method
 | ||||||
|  | 
 | ||||||
|     m_videoOK = m_video.open(qPrintable(fileName)); |     m_videoOK = m_video.open(qPrintable(fileName)); | ||||||
| 
 | 
 | ||||||
|     if (m_videoOK) |     if (m_videoOK) | ||||||
| @ -400,6 +451,7 @@ void ATVMod::openVideo(const QString& fileName) | |||||||
|         m_videoWidth = (int) m_video.get(CV_CAP_PROP_FRAME_WIDTH); |         m_videoWidth = (int) m_video.get(CV_CAP_PROP_FRAME_WIDTH); | ||||||
|         m_videoHeight = (int) m_video.get(CV_CAP_PROP_FRAME_HEIGHT); |         m_videoHeight = (int) m_video.get(CV_CAP_PROP_FRAME_HEIGHT); | ||||||
|         qDebug("ATVMod::openVideo(: FPS: %f size: %d x %d", m_videoFPS, m_videoWidth, m_videoHeight); |         qDebug("ATVMod::openVideo(: FPS: %f size: %d x %d", m_videoFPS, m_videoWidth, m_videoHeight); | ||||||
|  |         calculateVideoSizes(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -410,3 +462,19 @@ void ATVMod::resizeImage() | |||||||
|     cv::resize(m_imageOriginal, m_image, cv::Size(), fx, fy); |     cv::resize(m_imageOriginal, m_image, cv::Size(), fx, fy); | ||||||
|     qDebug("ATVMod::resizeImage: %d x %d -> %d x %d", m_imageOriginal.cols, m_imageOriginal.rows, m_image.cols, m_image.rows); |     qDebug("ATVMod::resizeImage: %d x %d -> %d x %d", m_imageOriginal.cols, m_imageOriginal.rows, m_image.cols, m_image.rows); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void ATVMod::calculateVideoSizes() | ||||||
|  | { | ||||||
|  | 	m_videoFy = (m_nbImageLines - 2*m_nbBlankLines) / (float) m_videoHeight; | ||||||
|  | 	m_videoFx = m_pointsPerImgLine / (float) m_videoWidth; | ||||||
|  | 	m_videoFPSq = m_videoFPS / m_fps; | ||||||
|  | 
 | ||||||
|  | 	qDebug("ATVMod::resizeVideo: factors: %f x %f FPSq: %f", m_videoFx, m_videoFy, m_videoFPSq); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ATVMod::resizeVideo() | ||||||
|  | { | ||||||
|  | 	if (!m_frameOriginal.empty()) { | ||||||
|  | 		cv::resize(m_frameOriginal, m_frame, cv::Size(), m_videoFx, m_videoFy); // resize current frame
 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
| @ -219,7 +219,7 @@ private: | |||||||
|     uint32_t m_nbImageLines;     //!< number of image lines excluding synchronization lines
 |     uint32_t m_nbImageLines;     //!< number of image lines excluding synchronization lines
 | ||||||
|     uint32_t m_nbImageLines2;    //!< same number as above (non interlaced) or half the number above (interlaced)
 |     uint32_t m_nbImageLines2;    //!< same number as above (non interlaced) or half the number above (interlaced)
 | ||||||
|     uint32_t m_nbHorizPoints;    //!< number of line points per horizontal line
 |     uint32_t m_nbHorizPoints;    //!< number of line points per horizontal line
 | ||||||
|     uint32_t m_nbSyncLinesH;     //!< number of header sync lines
 |     uint32_t m_nbSyncLinesHead;  //!< number of header sync lines
 | ||||||
|     uint32_t m_nbBlankLines;     //!< number of lines in a frame (full or half) that are blanked (black) at the top of the image
 |     uint32_t m_nbBlankLines;     //!< number of lines in a frame (full or half) that are blanked (black) at the top of the image
 | ||||||
|     float    m_hBarIncrement;    //!< video level increment at each horizontal bar increment
 |     float    m_hBarIncrement;    //!< video level increment at each horizontal bar increment
 | ||||||
|     float    m_vBarIncrement;    //!< video level increment at each vertical bar increment
 |     float    m_vBarIncrement;    //!< video level increment at each vertical bar increment
 | ||||||
| @ -240,10 +240,16 @@ private: | |||||||
|     bool m_imageOK; |     bool m_imageOK; | ||||||
| 
 | 
 | ||||||
|     cv::VideoCapture m_video;    //!< current video capture
 |     cv::VideoCapture m_video;    //!< current video capture
 | ||||||
|     cv::Mat m_frame;             //!< current frame
 |     cv::Mat m_frameOriginal;     //!< current frame from video
 | ||||||
|     float m_videoFPS; |     cv::Mat m_frame;             //!< current displayable video frame
 | ||||||
|     int m_videoWidth; |     float m_videoFPS;            //!< current video FPS rate
 | ||||||
|     int m_videoHeight; |     int m_videoWidth;            //!< current video frame width
 | ||||||
|  |     int m_videoHeight;           //!< current video frame height
 | ||||||
|  |     float m_videoFx;             //!< current video horizontal scaling factor
 | ||||||
|  |     float m_videoFy;             //!< current video vertictal scaling factor
 | ||||||
|  |     float m_videoFPSq;           //!< current video FPS sacaling factor
 | ||||||
|  |     float m_videoFPSCount;       //!< current video FPS fractional counter
 | ||||||
|  |     int m_videoPrevFPSCount;     //!< current video FPS previous integer counter
 | ||||||
|     bool m_videoOK; |     bool m_videoOK; | ||||||
| 
 | 
 | ||||||
|     static const float m_blackLevel; |     static const float m_blackLevel; | ||||||
| @ -260,6 +266,8 @@ private: | |||||||
|     void openImage(const QString& fileName); |     void openImage(const QString& fileName); | ||||||
|     void openVideo(const QString& fileName); |     void openVideo(const QString& fileName); | ||||||
|     void resizeImage(); |     void resizeImage(); | ||||||
|  |     void calculateVideoSizes(); | ||||||
|  |     void resizeVideo(); | ||||||
| 
 | 
 | ||||||
|     inline void pullImageLine(Real& sample) |     inline void pullImageLine(Real& sample) | ||||||
|     { |     { | ||||||
| @ -276,7 +284,7 @@ private: | |||||||
|             int pointIndex = m_horizontalCount - (m_pointsPerSync + m_pointsPerBP); |             int pointIndex = m_horizontalCount - (m_pointsPerSync + m_pointsPerBP); | ||||||
|             int iLine = m_lineCount % m_nbLines2; |             int iLine = m_lineCount % m_nbLines2; | ||||||
|             int oddity = m_lineCount < m_nbLines2 ? 0 : 1; |             int oddity = m_lineCount < m_nbLines2 ? 0 : 1; | ||||||
|             int iLineImage = iLine - m_nbSyncLinesH - m_nbBlankLines; |             int iLineImage = iLine - m_nbSyncLinesHead - m_nbBlankLines; | ||||||
| 
 | 
 | ||||||
|             switch(m_running.m_atvModInput) |             switch(m_running.m_atvModInput) | ||||||
|             { |             { | ||||||
| @ -296,16 +304,41 @@ private: | |||||||
|                 sample = ((iLine -5) / (float) m_nbImageLines2) * m_spanLevel + m_blackLevel; |                 sample = ((iLine -5) / (float) m_nbImageLines2) * m_spanLevel + m_blackLevel; | ||||||
|                 break; |                 break; | ||||||
|             case ATVModInputImage: |             case ATVModInputImage: | ||||||
|                 if (!m_imageOK || (iLineImage < 0)) |                 if (!m_imageOK || (iLineImage < 0) || m_image.empty()) | ||||||
|                 { |                 { | ||||||
|                     sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel; |                     sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel; | ||||||
|                 } |                 } | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|                     unsigned char pixv = m_image.at<unsigned char>(2*iLineImage+ oddity, pointIndex); // row (y), col (x)
 |                 	unsigned char pixv; | ||||||
|  | 
 | ||||||
|  |                 	if (m_interlaced) { | ||||||
|  |                         pixv = m_image.at<unsigned char>(2*iLineImage + oddity, pointIndex); // row (y), col (x)
 | ||||||
|  |                 	} else { | ||||||
|  |                         pixv = m_image.at<unsigned char>(iLineImage, pointIndex); // row (y), col (x)
 | ||||||
|  |                 	} | ||||||
|  | 
 | ||||||
|                     sample = (pixv / 256.0f) * m_spanLevel + m_blackLevel; |                     sample = (pixv / 256.0f) * m_spanLevel + m_blackLevel; | ||||||
|                 } |                 } | ||||||
|                 break; |                 break; | ||||||
|  |             case ATVModInputVideo: | ||||||
|  |                 if (!m_videoOK || (iLineImage < 0) || m_frame.empty()) | ||||||
|  |                 { | ||||||
|  |                     sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel; | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                 	unsigned char pixv; | ||||||
|  | 
 | ||||||
|  |                 	if (m_interlaced) { | ||||||
|  |                         pixv = m_frame.at<unsigned char>(2*iLineImage + oddity, pointIndex); // row (y), col (x)
 | ||||||
|  |                 	} else { | ||||||
|  |                         pixv = m_frame.at<unsigned char>(iLineImage, pointIndex); // row (y), col (x)
 | ||||||
|  |                 	} | ||||||
|  | 
 | ||||||
|  |                     sample = (pixv / 256.0f) * m_spanLevel + m_blackLevel; | ||||||
|  |                 } | ||||||
|  |             	break; | ||||||
|             case ATVModInputUniform: |             case ATVModInputUniform: | ||||||
|             default: |             default: | ||||||
|                 sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel; |                 sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel; | ||||||
|  | |||||||
| @ -69,7 +69,7 @@ void ATVModGUI::resetToDefaults() | |||||||
| { | { | ||||||
| 	blockApplySettings(true); | 	blockApplySettings(true); | ||||||
| 
 | 
 | ||||||
| 	ui->rfBW->setValue(12); | 	ui->rfBW->setValue(10); | ||||||
| 	ui->uniformLevel->setValue(35); | 	ui->uniformLevel->setValue(35); | ||||||
| 	ui->volume->setValue(10); | 	ui->volume->setValue(10); | ||||||
| 	ui->standard->setCurrentIndex(0); | 	ui->standard->setCurrentIndex(0); | ||||||
|  | |||||||
| @ -390,6 +390,11 @@ | |||||||
|           <string>Image</string> |           <string>Image</string> | ||||||
|          </property> |          </property> | ||||||
|         </item> |         </item> | ||||||
|  |         <item> | ||||||
|  |          <property name="text"> | ||||||
|  |           <string>Video</string> | ||||||
|  |          </property> | ||||||
|  |         </item> | ||||||
|        </widget> |        </widget> | ||||||
|       </item> |       </item> | ||||||
|       <item> |       <item> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user