Example #1
0
void TcpMpegDecoder::startDecoding(ThreadSafeQueue<Image>& queuePtr, Stream &stream, unsigned int imageCount)
{
	char* prevBytePtr = NULL;
	char* curBytePtr = NULL;
	_bDecodeEnable = true;
	_bStillProcessing = true;

	while(_bDecodeEnable)
	{
		if(_iDecodedImageCount >= imageCount)
		{
			_bStillProcessing = false;
			break;
		}
		ReceivedDataStruct* dataStructPtr = (*_pHttpClientPtr).readBytes();

		ostringstream strOtherThanImageData;
		size_t i = 0;
		while(i < (*dataStructPtr).length)
		{
			curBytePtr = (*dataStructPtr).dataPtr + i;
			if (prevBytePtr != NULL && (*prevBytePtr) == -1 && (*curBytePtr) == -40) //start of jpeg
			{
				string metaDataStr = strOtherThanImageData.str();
				extractStreamHeaderData(metaDataStr);

				if(_iCurrentContentLength > ((*dataStructPtr).length - i))
				{
					_vCurrentImageData.insert(_vCurrentImageData.end(), prevBytePtr, (prevBytePtr + (*dataStructPtr).length - i + 1));
					i = (*dataStructPtr).length;
				}
				else
				{
					_vCurrentImageData.insert(_vCurrentImageData.end(), prevBytePtr, (prevBytePtr + _iCurrentContentLength));
					i += _iCurrentContentLength - 1;
				}
			}
			else if (_vCurrentImageData.size() > 0)
			{
				if(_vCurrentImageData.size() < _iCurrentContentLength)
				{
					if(((*dataStructPtr).length - i) <= (_iCurrentContentLength - _vCurrentImageData.size()))
					{
						_vCurrentImageData.insert(_vCurrentImageData.end(), curBytePtr, (curBytePtr + ((*dataStructPtr).length - i - 1 + 1)));
						i = (*dataStructPtr).length;
					}
					else
					{
						_vCurrentImageData.insert(_vCurrentImageData.end(), curBytePtr, (curBytePtr + (_iCurrentContentLength - _vCurrentImageData.size() - 1 + 1)));
						i += (_iCurrentContentLength - _vCurrentImageData.size());
					}
				}
				else if(_vCurrentImageData.size() == _iCurrentContentLength)
				{
					if(_vCurrentImageData[_iCurrentContentLength - 2] == -1 && _vCurrentImageData[_iCurrentContentLength - 1] == -39) //end of jpeg
					{
						//got jpeg
						_iDecodedImageCount++;
						Image image(stream.getWidth(), stream.getHeight(), _vCurrentImageData, stream.getId(), _sCurrentImageTimeStamp, "");
						queuePtr.push(image);
						//cout << "TcpMpegDecoder::startDecoding: Produced image from stream " << stream.getId() << " at " << _sCurrentImageTimeStamp << endl;
					}
					else //error
					{
						cerr << "TcpMpegDecoder:startDecoding: Error in decoding Mpeg stream." << std::endl;
					}
					_vCurrentImageData.clear();
				}
			}
			else if(_vCurrentImageData.size() == 0)
			{
				strOtherThanImageData << *curBytePtr;
				i++;
			}
			else
			{
				cerr << "TcpMpegDecoder:startDecoding: Error - cannot reach this part of the program." << std::endl;
			}
			prevBytePtr = curBytePtr;
		}
	}
}
void MpegDecoder::startDecoding(opencctv::ConcurrentQueue<opencctv::Image>* pQueue)
{
	unsigned char* prevBytePtr = NULL;
	unsigned char* curBytePtr = NULL;
	//char readBytes[2048];
	unsigned char readBytes[2048];
	size_t length = 0;
	_bStillProcessing = true;

	if(_pHttpClientPtr)
	{
		_bDecodeEnable = true;
	}

	while(_bDecodeEnable)
	{
		try
		{
			length = (*_pHttpClientPtr).read(readBytes);

		}catch(opencctv::Exception &e)
		{
			_bStillProcessing = false;
			_bDecodeEnable = false;
			throw e;
		}

		ostringstream strOtherThanImageData;
		size_t i = 0;
		while(i < length)
		{
			//curBytePtr = ((unsigned char*) &readBytes[0]) + i;
			curBytePtr = readBytes + i;
			if (prevBytePtr != NULL && (*prevBytePtr) == 255 && (*curBytePtr) == 216) //start of jpeg 0xFF 0xD8
			{
				string metaDataStr = strOtherThanImageData.str();

				if(extractStreamHeaderData(metaDataStr)) //Copy the data only if the image headers are properly extracted
				{
					if(_iCurrentContentLength > (length - i))
					{
						_vCurrentImageData.insert(_vCurrentImageData.end(), prevBytePtr, (prevBytePtr + length - i + 1));
						i = length;
					}
					else
					{
						_vCurrentImageData.insert(_vCurrentImageData.end(), prevBytePtr, (prevBytePtr + _iCurrentContentLength));
						i += _iCurrentContentLength - 1;
					}
				}

				strOtherThanImageData.clear();
			}
			else if (_vCurrentImageData.size() > 0)
			{
				if(_vCurrentImageData.size() < _iCurrentContentLength)
				{
					if((length - i) <= (_iCurrentContentLength - _vCurrentImageData.size()))
					{
						_vCurrentImageData.insert(_vCurrentImageData.end(), curBytePtr, (curBytePtr + (length - i - 1 + 1)));
						i = length;
					}
					else
					{
						_vCurrentImageData.insert(_vCurrentImageData.end(), curBytePtr, (curBytePtr + (_iCurrentContentLength - _vCurrentImageData.size() - 1 + 1)));
						i += (_iCurrentContentLength - _vCurrentImageData.size());
					}
				}
				else if(_vCurrentImageData.size() == _iCurrentContentLength)
				{
					if(_vCurrentImageData[_iCurrentContentLength - 2] == 255 && _vCurrentImageData[_iCurrentContentLength - 1] == 217) //end of jpeg 0xFF 0xD9
					{
						//got jpeg
						_iDecodedImageCount++;
						opencctv::Image* pImage = new opencctv::Image();
						pImage->setImageData(_vCurrentImageData);
						pImage->setTimestamp(_sCurrentImageTimeStamp);
						pQueue->push(pImage);
						//cout << "Decoded image no : " << _iDecodedImageCount << endl;
					}
					else //error
					{
						cerr << "ZoneMinder:MpegDecoder:startDecoding: Error - in decoding Mpeg stream." << std::endl;
					}
					_vCurrentImageData.clear();
				}
			}
			else if(_vCurrentImageData.size() == 0)
			{
				strOtherThanImageData << *curBytePtr;
				i++;
			}
			else
			{
				cerr << "ZoneMinder:MpegDecoder:startDecoding: Error - cannot reach this part of the program." << std::endl;
			}
			prevBytePtr = curBytePtr;
		}
	}
}