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; } } }