mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 04:50:29 -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_horizontalCount(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"); | ||||
| 
 | ||||
| @ -59,6 +63,7 @@ ATVMod::ATVMod() : | ||||
| 
 | ||||
| ATVMod::~ATVMod() | ||||
| { | ||||
| 	if (m_video.isOpened()) m_video.release(); | ||||
| } | ||||
| 
 | ||||
| void ATVMod::configure(MessageQueue* messageQueue, | ||||
| @ -171,10 +176,48 @@ void ATVMod::pullVideo(Real& sample) | ||||
|             m_lineCount++; | ||||
|             if (m_lineCount > (m_nbLines/2)) m_evenImage = !m_evenImage; | ||||
|         } | ||||
|         else | ||||
|         else // new image
 | ||||
|         { | ||||
|             m_lineCount = 0; | ||||
|             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; | ||||
| @ -342,7 +385,7 @@ void ATVMod::applyStandard() | ||||
|         m_nbImageLines2    = 255; | ||||
|         m_interlaced       = true; | ||||
|         m_nbHorizPoints    = 64 * m_pointsPerTU; // full line
 | ||||
|         m_nbSyncLinesH     = 5; | ||||
|         m_nbSyncLinesHead  = 5; | ||||
|         m_nbBlankLines     = 15; // yields 480 lines (255 - 15) * 2
 | ||||
|         m_pointsPerHBar    = m_pointsPerImgLine / m_nbBars; | ||||
|         m_linesPerVBar     = m_nbImageLines2  / m_nbBars; | ||||
| @ -364,7 +407,7 @@ void ATVMod::applyStandard() | ||||
|         m_nbImageLines2    = 305; | ||||
|         m_interlaced       = true; | ||||
|         m_nbHorizPoints    = 64 * m_pointsPerTU; // full line
 | ||||
|         m_nbSyncLinesH     = 5; | ||||
|         m_nbSyncLinesHead  = 5; | ||||
|         m_nbBlankLines     = 17; // yields 576 lines (305 - 17) * 2
 | ||||
|         m_pointsPerHBar    = m_pointsPerImgLine / m_nbBars; | ||||
|         m_linesPerVBar     = m_nbImageLines2 / m_nbBars; | ||||
| @ -377,6 +420,12 @@ void ATVMod::applyStandard() | ||||
|     { | ||||
|         resizeImage(); | ||||
|     } | ||||
| 
 | ||||
|     if (m_videoOK) | ||||
|     { | ||||
|     	calculateVideoSizes(); | ||||
|     	resizeVideo(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ATVMod::openImage(const QString& fileName) | ||||
| @ -392,6 +441,8 @@ void ATVMod::openImage(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)); | ||||
| 
 | ||||
|     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_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); | ||||
|         calculateVideoSizes(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -410,3 +462,19 @@ void ATVMod::resizeImage() | ||||
|     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); | ||||
| } | ||||
| 
 | ||||
| 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_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_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
 | ||||
|     float    m_hBarIncrement;    //!< video level increment at each horizontal bar increment
 | ||||
|     float    m_vBarIncrement;    //!< video level increment at each vertical bar increment
 | ||||
| @ -240,10 +240,16 @@ private: | ||||
|     bool m_imageOK; | ||||
| 
 | ||||
|     cv::VideoCapture m_video;    //!< current video capture
 | ||||
|     cv::Mat m_frame;             //!< current frame
 | ||||
|     float m_videoFPS; | ||||
|     int m_videoWidth; | ||||
|     int m_videoHeight; | ||||
|     cv::Mat m_frameOriginal;     //!< current frame from video
 | ||||
|     cv::Mat m_frame;             //!< current displayable video frame
 | ||||
|     float m_videoFPS;            //!< current video FPS rate
 | ||||
|     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; | ||||
| 
 | ||||
|     static const float m_blackLevel; | ||||
| @ -260,6 +266,8 @@ private: | ||||
|     void openImage(const QString& fileName); | ||||
|     void openVideo(const QString& fileName); | ||||
|     void resizeImage(); | ||||
|     void calculateVideoSizes(); | ||||
|     void resizeVideo(); | ||||
| 
 | ||||
|     inline void pullImageLine(Real& sample) | ||||
|     { | ||||
| @ -276,7 +284,7 @@ private: | ||||
|             int pointIndex = m_horizontalCount - (m_pointsPerSync + m_pointsPerBP); | ||||
|             int iLine = m_lineCount % m_nbLines2; | ||||
|             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) | ||||
|             { | ||||
| @ -296,16 +304,41 @@ private: | ||||
|                 sample = ((iLine -5) / (float) m_nbImageLines2) * m_spanLevel + m_blackLevel; | ||||
|                 break; | ||||
|             case ATVModInputImage: | ||||
|                 if (!m_imageOK || (iLineImage < 0)) | ||||
|                 if (!m_imageOK || (iLineImage < 0) || m_image.empty()) | ||||
|                 { | ||||
|                     sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel; | ||||
|                 } | ||||
|                 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; | ||||
|                 } | ||||
|                 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: | ||||
|             default: | ||||
|                 sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel; | ||||
|  | ||||
| @ -69,7 +69,7 @@ void ATVModGUI::resetToDefaults() | ||||
| { | ||||
| 	blockApplySettings(true); | ||||
| 
 | ||||
| 	ui->rfBW->setValue(12); | ||||
| 	ui->rfBW->setValue(10); | ||||
| 	ui->uniformLevel->setValue(35); | ||||
| 	ui->volume->setValue(10); | ||||
| 	ui->standard->setCurrentIndex(0); | ||||
|  | ||||
| @ -390,6 +390,11 @@ | ||||
|           <string>Image</string> | ||||
|          </property> | ||||
|         </item> | ||||
|         <item> | ||||
|          <property name="text"> | ||||
|           <string>Video</string> | ||||
|          </property> | ||||
|         </item> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user