예제 #1
0
void CMTDHistory::SetPVector(const CSimpleVector<double>& pvector)
{
    unsigned int   curr_position = 0;
    CMTDBuffer*    p_buff = NULL;
    int            loc = 0;

    Deallocate();

    while(loc < pvector.GetLength()) {

        if((p_buff == NULL) || (curr_position >= MaxBufferSize)) {
            // allocate new buffer
            p_buff = GetNewBuffer(MaxBufferSize);
            curr_position = 0;
        }

        // now set height
        p_buff->SetHeight(curr_position,pvector[loc++]);

        for(unsigned int i=0; i < GetNumberOfCoords(); i++) {
            // set value and width
            p_buff->SetValue(curr_position,i,pvector[loc++]);
            p_buff->SetWidth(curr_position,i,pvector[loc++]);
        }
        p_buff->IncNumberOfHills();
        curr_position++;
    }
}
예제 #2
0
void CMTDHistory::AddMTDData(CXMLElement* p_ele)
{
    if(p_ele == NULL) {
        INVALID_ARGUMENT("p_ele is NULL");
    }

    CXMLElement* p_history = p_ele->GetFirstChildElement("HISTORY");
    if(p_history == NULL) {
        LOGIC_ERROR("unable to open HISTORY element");
    }

    unsigned int num_of_hills; // this is total number of hills

    if(p_history->GetAttribute("numofhills",num_of_hills) == false) {
        LOGIC_ERROR("unable to get number of hills");
    }

    if(num_of_hills == 0) return;   // there are no data in received history

    CXMLBinData* p_hele = p_history->GetFirstChildBinData("BUFFER");

    unsigned int control_num_of_hills = 0;

    while(p_hele != NULL) {
        unsigned int num_of_values;
        if(p_hele->GetAttribute("numofhills",num_of_values) == false) {
            LOGIC_ERROR("unable to get number of hills in buffer");
        }

        control_num_of_hills += num_of_values;

        // now allocate buffer
        CMTDBuffer* p_buffer = GetNewBuffer(num_of_values);
        p_buffer->ReadBufferData(p_hele);

        p_hele = p_hele->GetNextSiblingBinData("BUFFER");
    }

    if(control_num_of_hills != num_of_hills) {
        LOGIC_ERROR("mismatch in number of hills");
    }
}
예제 #3
0
////////////////////////////////////////////////////////////////////////////
///
/// Handle losing lock on the frame headers.
///
/// This function is called to handle the data that was spuriously accumulated
/// when the frame header was badly parsed.
///
/// In principle this function is quite simple. We allocate a new accumulation buffer and
/// use the currently accumulated data is the data source to run the elementary stream
/// state machine. There is however a little extra logic to get rid of recursion.
/// Specificially we change the error handling behaviour if this method is re-entered
/// so that there error is reported back to the already executing copy of the method.
///
/// \return Collator status code, CollatorNoError indicates success.
///
CollatorStatus_t Collator_PesAudio_c::HandleMissingNextFrameHeader(void)
{
	CollatorStatus_t Status;
	//
	// Mark the collator as having lost frame lock.
	// Yes! We really do want to do this before the re-entry checks.
	//
	CollatorState = SeekingSyncWord; // we really do want to do this before the re-entry checks
	AccumulatedFrameReady = false;
	//
	// Check for re-entry
	//
	if (AlreadyHandlingMissingNextFrameHeader)
	{
		COLLATOR_DEBUG("Re-entered the error recovery handler, initiating stack unwind\n");
		return CollatorUnwindStack;
	}
	//
	// Check whether the sub-class wants trivial or aggressive error recovery
	//
	if (!ReprocessAccumulatedDataDuringErrorRecovery)
	{
		DiscardAccumulatedData();
		return CollatorNoError;
	}
	//
	// Remember the original elementary stream pointers for when we return to 'normal' processing.
	//
	unsigned char *OldRemainingElementaryOrigin = RemainingElementaryOrigin;
	unsigned char *OldRemainingElementaryData = RemainingElementaryData;
	unsigned int OldRemainingElementaryLength = RemainingElementaryLength;
	//
	// Take ownership of the already accumulated data
	//
	Buffer_t ReprocessingDataBuffer = CodedFrameBuffer;
	unsigned char *ReprocessingData = BufferBase;
	unsigned int ReprocessingDataLength = AccumulatedDataSize;
	ReprocessingDataBuffer->SetUsedDataSize(ReprocessingDataLength);
	Status = ReprocessingDataBuffer->ShrinkBuffer(max(ReprocessingDataLength, 1));
	if (Status != BufferNoError)
	{
		COLLATOR_ERROR("Failed to shrink the reprocessing buffer to size (%08x).\n", Status);
		// not fatal - we're merely wasting memory
	}
	// At the time of writing GetNewBuffer() doesn't check for leaks. This is good because otherwise
	// we wouldn't have transfer the ownership of the ReprocessingDataBuffer by making this call.
	Status = GetNewBuffer();
	if (Status != CollatorNoError)
	{
		COLLATOR_ERROR("Cannot get new buffer during error recovery\n");
		return CollatorError;
	}
	//
	// Remember that we are re-processing the previously accumulated elementary stream
	//
	AlreadyHandlingMissingNextFrameHeader = true;
	//
	// WARNING: From this point on we own the ReprocessingDataBuffer, have set the recursion avoidance
	// marker and may have damaged the RemainingElementaryData pointer. There should be no
	// short-circuit exit paths used after this point otherwise we risk avoiding the clean up
	// at the bottom of the method.
	//
	while (ReprocessingDataLength > 1)
	{
		//
		// Remove the first byte from the recovery buffer (to avoid detecting again the same start code).
		//
		ReprocessingData += 1;
		ReprocessingDataLength -= 1;
		//
		// Search for a start code in the reprocessing data. This allows us to throw away data that we
		// know will never need reprocessing which makes the recursion avoidance code more efficient.
		//
		RemainingElementaryOrigin = ReprocessingData;
		RemainingElementaryData = ReprocessingData;
		RemainingElementaryLength = ReprocessingDataLength;
		int CodeOffset;
		PotentialFrameHeaderLength = 0; // ensure no (now voided) historic data is considered by sub-class
		Status = FindNextSyncWord(&CodeOffset);
		if (Status == CodecNoError)
		{
			COLLATOR_ASSERT(CodeOffset >= 0);
			COLLATOR_DEBUG("Found start code during error recovery (byte %d of %d)\n",
				       CodeOffset, ReprocessingDataLength);
			// We found a start code, snip off all preceding data
			ReprocessingData += CodeOffset;
			ReprocessingDataLength -= CodeOffset;
		}
		else
		{
			// We didn't find a start code, snip off everything except the last few bytes. This
			// final fragment may contain a partial start code so we want to pass if through the
			// elementary stream handler again.
			unsigned FinalBytes = min(ReprocessingDataLength, FrameHeaderLength - 1);
			COLLATOR_DEBUG("Found no start code during error recovery (processing final %d bytes of %d)\n",
				       ReprocessingDataLength, FinalBytes);
			ReprocessingData += ReprocessingDataLength;
			ReprocessingDataLength = FinalBytes;
			ReprocessingData -= ReprocessingDataLength;
		}
		//
		// Process the elementary stream
		//
		Status = HandleElementaryStream(ReprocessingDataLength, ReprocessingData);
		if (CollatorNoError == Status)
		{
			COLLATOR_DEBUG("Error recovery completed, returning to normal processing\n");
			// All data consumed and stored in the subsequent accumulation buffer
			break; // Success will propagate when we return Status
		}
		else if (CollatorUnwindStack == Status)
		{
			COLLATOR_DEBUG("Stack unwound successfully, re-trying error recovery\n");
			// We found a frame header but lost lock again... let's have another go
			AccumulatedDataSize = 0; // make sure no accumulated data is carried round the loop
			continue;
		}
		else
		{
			COLLATOR_ERROR("Error handling elementary stream during error recovery\n");
			break; // Failure will propagate when we return Status
		}
	}
	//
	// Free the buffer we just consumed and restore the original elementary stream pointers
	//
	RemainingElementaryOrigin = OldRemainingElementaryOrigin;
	RemainingElementaryData = OldRemainingElementaryData;
	RemainingElementaryLength = OldRemainingElementaryLength;
	(void) ReprocessingDataBuffer->DecrementReferenceCount(IdentifierCollator);
	AlreadyHandlingMissingNextFrameHeader = false;
	return Status;
}
예제 #4
0
CMTDBuffer* CMTDHistory::AddMTDDataAsSingleBuffer(CXMLElement* p_ele)
{
    if(p_ele == NULL) {
        INVALID_ARGUMENT("p_ele is NULL");
    }

    CXMLElement* p_history = p_ele->GetFirstChildElement("HISTORY");
    if(p_history == NULL) {
        LOGIC_ERROR("unable to open HISTORY element");
    }

    unsigned int num_of_hills; // this is total number of hills

    if(p_history->GetAttribute("numofhills",num_of_hills) == false) {
        LOGIC_ERROR("unable to get number of hills");
    }

    if(num_of_hills == 0) return(NULL);   // there are no data in received history

    CMTDBuffer* p_buffer = GetNewBuffer(num_of_hills);

    CXMLBinData* p_hele = p_history->GetFirstChildBinData("BUFFER");

    if(p_hele != NULL) {
        // set level and start from the first buffer
        unsigned int level_id;
        unsigned int start_id;
        if(p_hele->GetAttribute("level",level_id) == false) {
            LOGIC_ERROR("unable to get buffer level id");
        }
        if(p_hele->GetAttribute("start",start_id) == false) {
            LOGIC_ERROR("unable to get buffer start id");
        }
        p_buffer->SetLevel(level_id);
        p_buffer->SetStart(start_id);
    }

    unsigned int control_num_of_hills = 0;

    while(p_hele != NULL) {
        unsigned int num_of_values;
        if(p_hele->GetAttribute("numofhills",num_of_values) == false) {
            LOGIC_ERROR("unable to get number of hills in buffer");
        }

        unsigned int history_size = num_of_values*(1 + 2*NCoords)*sizeof(double);

        if((history_size == 0) || (history_size != p_hele->GetLength())) {
            LOGIC_ERROR("inconsistent history size");
        }

        double* src = (double*)p_hele->GetData();

        if(src == NULL) {
            LOGIC_ERROR("data array is NULL");
        }

        // copy data
        for(unsigned int i=0; i < num_of_values; i++) {
            p_buffer->SetHeight(control_num_of_hills+i,*src++);
            for(unsigned int j=0; j < NCoords; j++) {
                p_buffer->SetValue(control_num_of_hills+i,j,*src++);
                p_buffer->SetWidth(control_num_of_hills+i,j,*src++);
            }
            p_buffer->IncNumberOfHills();
        }

        control_num_of_hills += num_of_values;

        p_hele = p_hele->GetNextSiblingBinData("BUFFER");
    }

    if(control_num_of_hills != num_of_hills) {
        LOGIC_ERROR("mismatch in number of hills");
    }

    return(p_buffer);
}
예제 #5
0
void CMTDHistory::Load(FILE* fin)
{
    if( fin == NULL ) {
        INVALID_ARGUMENT("stream is not open");
    }

// read MTD accumulator header ------------------
    char mtd_id[4];
    char ver_id[3];
    int  numofcoords = 0;
    int  nr;

// first line can contain either two or four records for version 0
    char buffer[80];
    if( fgets(buffer,80,fin) == NULL ) {
        RUNTIME_ERROR("unable to read the first line");
    }

    nr = sscanf(buffer,"%3s %2s %d",mtd_id,ver_id,&numofcoords);
    if( nr != 3 ){
        RUNTIME_ERROR("wrong header");
    }

    mtd_id[3]='\0';
    ver_id[2]='\0';

// check ID string
    if(strcmp(mtd_id,"MTD") != 0) {
        CSmallString error;
        error << "'MTD' magic word was not found in the first line (line: " << buffer << ")";
        RUNTIME_ERROR(error);
    }
    if(strcmp(ver_id,"V3") != 0) {
        CSmallString error;
        error << "'illegal MTD history version (V3 expected) (line: " << buffer << ")";
        RUNTIME_ERROR(error);
    }

    if(numofcoords <= 0) {
        CSmallString error;
        error << "number of coordinates has to be greater than zero, but " << numofcoords << " was found";
        RUNTIME_ERROR(error);
    }

    SetNumberOfCoords(numofcoords);

   if( fin == NULL ) {
        INVALID_ARGUMENT("stream is not open");
    }

// read coordinate specification ----------------
    for(unsigned int i=0; i < NCoords; i++) {
        unsigned int    id = 0;
        char            type[11];
        char            name[51];
        double          min_value = 0.0;
        double          max_value = 0.0;
        int             nbins = 0;
        int             tr = 0;

        memset(type,0,11);
        memset(name,0,51);

        // read item
        tr = fscanf(fin,"%u %10s %lf %lf %d",&id,type,&min_value,&max_value,&nbins);
        if( tr != 5 ) {
            CSmallString error;
            error << "unable to read coordinate definition, id: " << i+1 << " (number of collums read: " << tr << ")";
            RUNTIME_ERROR(error);
        }

        // some tests
        if(id != i+1) {
            CSmallString error;
            error << "coordinate id does not match, read: " << id << ", expected: " << i+1;
            RUNTIME_ERROR(error);
        }
        if(max_value <= min_value) {
            CSmallString error;
            error << "min value is not smaller than max value, id: " << id;
            RUNTIME_ERROR(error);
        }
        if(nbins <= 0) {
            CSmallString error;
            error << "number of bins has to be grater than zero, id: " << id;
            RUNTIME_ERROR(error);
        }

        tr = fscanf(fin,"%u %55s",&id,name);
        if( tr != 2 ) {
            CSmallString error;
            error << "unable to read coordinate definition, id: " << i+1 << " (number of collums read: " << tr << ")";
            RUNTIME_ERROR(error);
        }

        // some tests
        if(id != i+1) {
            CSmallString error;
            error << "coordinate id does not match, read: " << id << ", expected: " << i+1;
            RUNTIME_ERROR(error);
        }
        // init coordinate
        SetCoordinate(i,name,type,min_value,max_value,nbins);
    }

// now read records -----------------------------

    unsigned int   curr_position = 0;
    unsigned int   position = 1;
    CMTDBuffer*    p_buff = NULL;

    while(feof(fin) == 0) {
        int nr,level,time;

        if((p_buff == NULL) || (curr_position >= MaxBufferSize)) {
            // allocate new buffer
            p_buff = GetNewBuffer(MaxBufferSize);
            if(p_buff == NULL) {
                CSmallString error;
                error << "unable to allocate new buffer (pos: " << position << ")";
                RUNTIME_ERROR(error);
            }
            curr_position = 0;
        }

        // read level and time
        nr = fscanf(fin,"%d %d",&level,&time);
        if(nr <= 0) break;      // end of file
        if(nr != 2) {
            CSmallString error;
            error << "level and time were not successfully read (pos: " << position << ")";
            RUNTIME_ERROR(error);
        }

        // now read height
        double height;
        nr = fscanf(fin,"%lf",&height);
        if(nr != 1) {
            CSmallString error;
            error << "unable to read height (pos: " << position << ")";
            RUNTIME_ERROR(error);
        }

        p_buff->SetHeight(curr_position,height);

        for(unsigned int i=0; i < GetNumberOfCoords(); i++) {
            double value,width;
            nr = fscanf(fin,"%lf %lf",&value,&width);
            if(nr != 2) {
                CSmallString error;
                error << "unable to read value and width (pos: " << position << ")";
                RUNTIME_ERROR(error);
            }
            // register value and width
            p_buff->SetValue(curr_position,i,value);
            p_buff->SetWidth(curr_position,i,width);
        }
        p_buff->IncNumberOfHills();
        curr_position++;
        position++;
    }
}