Example #1
0
void loadCircular(CircularBuffer *cb) {
	
	int i;
	data *value;
	value = (data *)malloc(sizeof(data));
	/*
	for(i=0;i<MAX_LINE;i++) {
		
		value->ch = a_data1[i];
		
		BufferWrite(cb, value);
		
	}
	*/
	for(i=0;i<MAX_LINE;i++) {
			
		value->ch = b_data1[i];
			
		BufferWrite(cb, value);
			
	}
	for(i=0;i<MAX_LINE;i++) {
			
		value->ch = pbdata[i];
			
		BufferWrite(cb, value);
			
	}
}
Example #2
0
void DataFlash_APM1::WriteByte(byte data)
{
  if (!df_Stop_Write)
    {
    BufferWrite(df_BufferNum,df_BufferIdx,data);
    df_BufferIdx++;
    if (df_BufferIdx >= df_PageSize)  // End of buffer?
      {
      df_BufferIdx=4;		//(4 bytes for FileNumber, FilePage)
	  BufferToPage(df_BufferNum,df_PageAdr,0);  // Write Buffer to memory, NO WAIT
      df_PageAdr++;
	  if (OVERWRITE_DATA==1)
	    {
        if (df_PageAdr>DF_LAST_PAGE)  // If we reach the end of the memory, start from the begining
		  df_PageAdr = 1;
	    }
      else
	    {
        if (df_PageAdr>DF_LAST_PAGE)  // If we reach the end of the memory, stop here
		  df_Stop_Write=1;
	    }

      if (df_BufferNum==1)  // Change buffer to continue writing...
        df_BufferNum=2;
      else
        df_BufferNum=1;
      // We are starting a new page - write FileNumber and FilePage
		BufferWrite(df_BufferNum,0,df_FileNumber>>8);   // High byte
		BufferWrite(df_BufferNum,1,df_FileNumber&0xFF); // Low byte
		df_FilePage++;
		BufferWrite(df_BufferNum,2,df_FilePage>>8);   // High byte
		BufferWrite(df_BufferNum,3,df_FilePage&0xFF); // Low byte
      }
Example #3
0
// *** DATAFLASH PUBLIC FUNCTIONS ***
void DataFlash_APM1::StartWrite(int16_t PageAdr)
{
  df_BufferNum=1;
  df_BufferIdx=4;
  df_PageAdr=PageAdr;
  df_Stop_Write=0;
  WaitReady();
      // We are starting a new page - write FileNumber and FilePage
		BufferWrite(df_BufferNum,0,df_FileNumber>>8);   // High byte
		BufferWrite(df_BufferNum,1,df_FileNumber&0xFF); // Low byte
		BufferWrite(df_BufferNum,2,df_FilePage>>8);   // High byte
		BufferWrite(df_BufferNum,3,df_FilePage&0xFF); // Low byte
}
Example #4
0
static int Process(amrwb* p, const packet* Packet, const flowstate* State)
{
	int Size;
	if (Packet)
	{
		if (Packet->RefTime >= 0)
			p->Codec.Packet.RefTime = Packet->RefTime;

		// add new packet to buffer
		BufferPack(&p->Buffer,0);
		BufferWrite(&p->Buffer,Packet->Data[0],Packet->Length,256);
	}
	else
		p->Codec.Packet.RefTime = TIME_UNKNOWN;

	if (p->Buffer.WritePos - p->Buffer.ReadPos < 1)
		return ERR_NEED_MORE_DATA;

	if (p->Buffer.Data[p->Buffer.ReadPos] == '#' &&
		p->Buffer.WritePos - p->Buffer.ReadPos > 9 &&
		memcmp(p->Buffer.Data+p->Buffer.ReadPos,"#!AMR-WB\n",9)==0)
		p->Buffer.ReadPos += 9;

	Size = block_size[(p->Buffer.Data[p->Buffer.ReadPos] >> 3) & 0xF];

	if (p->Buffer.WritePos - p->Buffer.ReadPos < Size)
		return ERR_NEED_MORE_DATA;

    D_IF_decode(p->Decoder, p->Buffer.Data+p->Buffer.ReadPos, p->Synth, _good_frame);
	p->Buffer.ReadPos += Size;
	p->Codec.Packet.Length = sizeof(p->Synth);
	p->Codec.Packet.Data[0] = p->Synth;
	return ERR_NONE;
}
Example #5
0
DWORD WINAPI threadAvsDec(LPVOID id)
{
	BYTE pUVrow[info->width];
	for (int f = 0; f < info->num_frames; f++)
	{
		while (BufferIsFull(frameBuffer))
			Sleep(250); // only bad if encodes more than 1000fps, then decrease

		AVS_VideoFrame *frame = avs_get_frame(clip, f);

        const BYTE *pYplane = avs_get_read_ptr_p(frame, AVS_PLANAR_Y);
        const BYTE *pUplane = avs_get_read_ptr_p(frame, AVS_PLANAR_U);
		const BYTE *pVplane = avs_get_read_ptr_p(frame, AVS_PLANAR_V);
		BYTE *frameData  = (BYTE*) malloc(hostPtrSize);

		BYTE *pBuf = frameData;

        // Y plane
        unsigned int pitch = avs_get_pitch_p(frame, AVS_PLANAR_Y);
		for (int h = 0; h < info->height; h++)
		{
			memcpy(pBuf, pYplane, info->width);
			pBuf += alignedSurfaceWidth;
			pYplane += pitch;
		}

		// UV planes
		unsigned int uiHalfHeight = info->height >> 1;
		unsigned int uiHalfWidth  = info->width >> 1; //chromaWidth
		unsigned int pos = 0;
		for (unsigned int h = 0; h < uiHalfHeight; h++)
		{
			for (unsigned int i = 0; i < uiHalfWidth; ++i)
			{
				pUVrow[i*2]     = pUplane[pos + i];
				pUVrow[i*2 + 1] = pVplane[pos + i];
			}
			memcpy(pBuf, pUVrow, info->width);
			pBuf += alignedSurfaceWidth;
			pos += uiHalfWidth;
		}

		BufferWrite(frameBuffer, (BufferType)frameData);

        // not sure release is needed, but it doesn't cause an error
        avs_release_frame(frame);
	}
	return 0;
}
Example #6
0
/** @brief Flush all buffers for the active volume in the given range of blocks.

    @param ulBlockStart Starting block number to flush.
    @param ulBlockCount Count of blocks, starting at @p ulBlockStart, to flush.
                        Must not be zero.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
    @retval -RED_EINVAL Invalid parameters.
*/
REDSTATUS RedBufferFlush(
    uint32_t    ulBlockStart,
    uint32_t    ulBlockCount)
{
    REDSTATUS   ret = 0;

    if(    (ulBlockStart >= gpRedVolume->ulBlockCount)
        || ((gpRedVolume->ulBlockCount - ulBlockStart) < ulBlockCount)
        || (ulBlockCount == 0U))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else
    {
        uint8_t bIdx;

        for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++)
        {
            BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];

            if(    (pHead->bVolNum == gbRedVolNum)
                && (pHead->ulBlock != BBLK_INVALID)
                && ((pHead->uFlags & BFLAG_DIRTY) != 0U)
                && (pHead->ulBlock >= ulBlockStart)
                && (pHead->ulBlock < (ulBlockStart + ulBlockCount)))
            {
                ret = BufferWrite(bIdx);

                if(ret == 0)
                {
                    pHead->uFlags &= (~BFLAG_DIRTY);
                }
                else
                {
                    break;
                }
            }
        }
    }

    return ret;
}
Example #7
0
static int Process( ffmpeg_video* p, const packet* Packet, const flowstate* State )
{
	int Picture;
	int Len;

	if (Packet)
	{
		if (State->DropLevel)
		{
			if (State->DropLevel>1)
			{
				p->SkipToKey = 1;
				p->DropToKey = 1;
				p->Dropping = 1;
				p->Context->hurry_up = 5;
			}
			else
				p->Context->hurry_up = 1;
			if (!SupportDrop(p))
				p->Context->hurry_up = 0;
		}
		else
			p->Context->hurry_up = 0;

		if (!Packet->Key && p->DropToKey)
		{
			if (p->Dropping)
			{
				flowstate DropState;
				DropState.CurrTime = TIME_UNKNOWN;
				DropState.DropLevel = 1;
				p->Codec.Out.Process(p->Codec.Out.Pin.Node,NULL,&DropState);
			}
			if (SupportDrop(p))
				avcodec_flush_buffers(p->Context);
			return ERR_DROPPING;
		}

		if (p->DropToKey)
			p->DropToKey = 0;

		if (Packet->RefTime >= 0)
			p->Codec.Packet.RefTime = Packet->RefTime;

		BufferPack(&p->Buffer,0);
		if(p->Codec.In.Pin.Node->Class==FOURCC('R','V','_','0')&&
			(p->Codec.In.Format.Format.Video.Pixel.FourCC == FOURCC('R','V','1','0')||
			p->Codec.In.Format.Format.Video.Pixel.FourCC == FOURCC('R','V','2','0')||
			p->Codec.In.Format.Format.Video.Pixel.FourCC == FOURCC('R','V','3','0')||
			p->Codec.In.Format.Format.Video.Pixel.FourCC == FOURCC('R','V','4','0')))
		{
		
				int32_t ret = rm_assemble_video_frame(p,Packet);
				if(ret != ERR_NONE)
					return ERR_NEED_MORE_DATA;
		}
		else
		{
			BufferWrite(&p->Buffer,Packet->Data[0],Packet->Length,2048);
		}
	}
	else
	{
		if (p->FrameTime<0)
			p->Codec.Packet.RefTime = TIME_UNKNOWN;
		else
		if (!State)
			p->Codec.Packet.RefTime += p->FrameTime;

		if (!State && p->Buffer.WritePos == p->Buffer.ReadPos)
			return ERR_NEED_MORE_DATA;
	}

	if (p->SkipToKey)
		p->Picture->pict_type = 0;

	Len = avcodec_decode_video(p->Context, p->Picture, &Picture, p->Buffer.Data + p->Buffer.ReadPos, 
		p->Buffer.WritePos - p->Buffer.ReadPos);

	if (Len < 0)
	{
		BufferDrop(&p->Buffer);
		return ERR_INVALID_DATA;
	}

	p->Buffer.ReadPos += Len;

	if (!Picture)
	{
		if (p->SkipToKey>1 && p->Picture->pict_type)
			--p->SkipToKey;

		return ERR_NEED_MORE_DATA;
	}

	if (p->SkipToKey>0)
	{
		if ((!p->Picture->key_frame && p->Picture->pict_type) || p->SkipToKey>1)
		{
			if (p->SkipToKey>1)
				--p->SkipToKey;
			if (p->Dropping)
			{
				flowstate DropState;
				DropState.CurrTime = TIME_UNKNOWN;
				DropState.DropLevel = 1;
				p->Codec.Out.Process(p->Codec.Out.Pin.Node,NULL,&DropState);
			}
			return ERR_DROPPING;
		}
		p->SkipToKey = 0;
	}

	if (p->Context->pix_fmt != p->PixelFormat ||
		p->Context->sample_aspect_ratio.num != p->Aspect.num ||
		p->Context->sample_aspect_ratio.den != p->Aspect.den ||
		p->Context->width != p->Codec.Out.Format.Format.Video.Width ||
		p->Context->height != p->Codec.Out.Format.Format.Video.Height ||
		p->Picture->linesize[0] != p->Codec.Out.Format.Format.Video.Pitch)
	{
		if (!BuildOutputFormat(p))
			return ERR_INVALID_DATA;

		ConnectionUpdate(&p->Codec.Node,CODEC_OUTPUT,p->Codec.Out.Pin.Node,p->Codec.Out.Pin.No);
	}

	p->Codec.Packet.Data[0] = p->Picture->data[0];
	p->Codec.Packet.Data[1] = p->Picture->data[1];
	p->Codec.Packet.Data[2] = p->Picture->data[2];
	return ERR_NONE;
}
Example #8
0
static int rm_assemble_video_frame(ffmpeg_video* p,const packet* Packet)
{
    int32_t hdr, seq, pic_num, len2, pos;
    int32_t type;
	uint8_t* buf = (uint8_t*)Packet->Data[0];
	int32_t len = Packet->Length;
	int32_t used=0;
	RMVideo* rm = &p->rm;

    hdr = *buf++; len--;
    type = hdr >> 6;
    switch(type)
	{
    case 0: // slice
    case 2: // last slice
        seq = *buf++; len--;
		
        len2 = get_num(p,buf, &used);
		buf+=used;
		len-=used;

		used=0;
        pos = get_num(p,buf, &used);
		buf+=used;
		len-=used;

        pic_num = *buf++; len--;

        break;
    case 1: //whole frame
        {
			uint8_t addbuf[9]={0,1,1,1,1,0,0,0,0};
			seq = *buf++; len--;

			BufferWrite(&p->Buffer,addbuf,9,1);
			BufferWrite(&p->Buffer,buf,len,2048);
		}
        return ERR_NONE;
    case 3: //frame as a part of packet
		{
			uint8_t addbuf[9]={0,1,1,1,1,0,0,0,0};
			
			len2 = get_num(p,buf, &used);
			buf+=used;
			len-=used;

			used=0;
			pos = get_num(p,buf, &used);
			buf+=used;
			len-=used;

			pic_num = *buf++; len--;

			BufferWrite(&p->Buffer,addbuf,9,1);
			BufferWrite(&p->Buffer,buf,len2,2048);
		}
        return ERR_NONE;
    }
    //now we have to deal with single slice
	
    if((seq & 0x7F) == 1 || rm->curpic_num != pic_num)
	{
        rm->slices = ((hdr & 0x3F) << 1) + 1;
        rm->videobufsize = len2 + 8*rm->slices + 1;
        av_free(rm->videobuf);
        if(!(rm->videobuf = av_malloc(rm->videobufsize)))
            return ERR_OUT_OF_MEMORY;
        rm->videobufpos = 8*rm->slices + 1;
        rm->cur_slice = 0;
        rm->curpic_num = pic_num;
    }
    if(type == 2)
        len = FFMIN(len, pos);
	
    if(++rm->cur_slice > rm->slices)
        return ERR_OUT_OF_MEMORY;

    AV_WL32(rm->videobuf - 7 + 8*rm->cur_slice, 1);
    AV_WL32(rm->videobuf - 3 + 8*rm->cur_slice, rm->videobufpos - 8*rm->slices - 1);

    if(rm->videobufpos + len > rm->videobufsize)
        return ERR_OUT_OF_MEMORY;

	memcpy(rm->videobuf+rm->videobufpos,buf,len);

    rm->videobufpos += len;
    rm->remaining_len-= len;
	
    if(type == 2 || (rm->videobufpos) == rm->videobufsize)
	{
		rm->videobuf[0] = rm->cur_slice-1;

		BufferWrite(&p->Buffer,rm->videobuf,1 + 8*rm->cur_slice,1);
		BufferWrite(&p->Buffer,rm->videobuf + 1 + 8*rm->slices,rm->videobufpos - 1 - 8*rm->slices,2048);

		return ERR_NONE;
    }
	
    return ERR_NEED_MORE_DATA;
}
Example #9
0
File: ogg.c Project: Erikhht/TCPMP
static int FillQueue(ogg* p,format_reader* Reader)
{
	for (;;)
	{
		int Bytes = ogg_sync_pageseek(p->OggSync,&p->OggPage);

		if (Bytes == 0) // need more data
		{
			int Result;
			format_buffer* Buffer;

			if (!Reader->BufferAvailable && (!p->Format.SyncMode || p->Format.SyncRead<=0))
				return ERR_NEED_MORE_DATA;

			Buffer = Format_BufferRemove(Reader);
			if (!Buffer && p->Format.SyncMode && p->Format.SyncRead>0 && Format_ReadBuffer(Reader,0))
				Buffer = Format_BufferRemove(Reader);

			Result = AddBuffer(p,Buffer);
			if (Result != ERR_NONE)
				return Result;
		}
		else		
		if (Bytes < 0)
			Reader->FilePos -= Bytes;
		else
		if (Bytes > 0)
		{
			int StreamNo;
			oggstream* s;
			int Id;
			
			Reader->FilePos += Bytes;

			Id = ogg_page_serialno(&p->OggPage);
		
			DEBUG_MSG4(DEBUG_FORMAT,T("OGG Page id:%d size:%d gran:%d filepos:%d"),Id,p->OggPage.body_len,(int)ogg_page_granulepos(&p->OggPage),Reader->FilePos - Bytes);

			for (StreamNo=0;StreamNo<p->Format.StreamCount;++StreamNo)
				if (p->Format.Streams[StreamNo]->Id == Id)
					break;

			if (StreamNo==p->Format.StreamCount)
			{
				// check for restarted audio http streaming (comments changed)
				if (p->Format.StreamCount==1 && 
					p->Format.Streams[0]->Format.Type == PACKET_AUDIO &&
					p->Format.Streams[0]->LastTime>0)
				{
					StreamNo = 0;
					s = (oggstream*) p->Format.Streams[0];
					if (s->Vorbis)
					{
						// vorbis decoder have to release s->Info
						s->Stream.Format.Extra = NULL;
						s->Stream.Format.ExtraLength = 0;
						ConnectionUpdate((node*)&p->Format,FORMAT_STREAM+0,s->Stream.Pin.Node,s->Stream.Pin.No);
					}
					FreeStream(p,s);
				}
				else
				{
					s = (oggstream*) Format_AddStream(&p->Format,sizeof(oggstream));
					if (!s)	continue;
				}

				// init stream
				s->Stream.Id = Id;
				s->OggStream = ogg_stream_create(Id);
				s->NeedMorePage = 1;
				s->MediaTime = 0;
				s->Invalid = 0;
				s->Vorbis = 0;
				s->Native = 0;
				s->PacketNo = 0;

				vorbis_info_init(&s->Info);
				vorbis_comment_init(&s->Comment);
			}

			s = (oggstream*) p->Format.Streams[StreamNo];

			if (s->Invalid) // drop invalid streams
				continue;

			if (s->PacketNo>=3)
			{
				if (!s->Stream.Pin.Node) // drop unused streams
					continue;

				if (p->Format.InSeek)
				{
					// reftime needed for SeekByPacket
					if ((s->MediaTime = ogg_page_granulepos(&p->OggPage)) != -1)
					{
						// no need for GlobalOffset here
						s->Stream.LastTime = (tick_t)(s->MediaTime * s->MediaRateDen / s->MediaRateNum);
						if (s->Stream.Format.Type == PACKET_AUDIO)
						{
							s->Stream.LastTime += p->Format.AVOffset;
							if (s->Stream.LastTime < 0)
								s->Stream.LastTime = 0;
						}
					}
				}
			}

			// add page to stream
			if (ogg_stream_pagein(s->OggStream,&p->OggPage) >= 0)
			{
				if (s->PacketNo<3) // header packet needed?
				{
					int i = ogg_stream_packetout(s->OggStream,&s->OggPacket);
					if (i == 0) // stream needs more pages
						continue;
					
					if (++s->PacketNo==1) // first packet?
					{
						ogg_reference* Ref;
						const void* Data;
						int Length;

						if (i < 0)
						{
							// first header packet is a must have
							s->Invalid = 1;
							continue;
						}

						if (p->Format.UseBufferBlock)
						{
							for (Length=0,Ref=s->OggPacket.packet;Ref;Ref=Ref->next)
								Length += Ref->length;

							if (s->Stream.BufferBlockLength<Length && !Format_AllocBufferBlock(&p->Format,&s->Stream,Length))
							{
								Length = 0;
								Data = NULL;
							}
							else
							{
								for (Length=0,Ref=s->OggPacket.packet;Ref;Ref=Ref->next)
								{
									WriteBlock(&s->Stream.BufferBlock,Length,Ref->buffer->data + Ref->begin,Ref->length);
									Length += Ref->length;
								}
								Data = s->Stream.BufferBlock.Ptr;
							}
						}
						else
						{
							BufferDrop(&s->Stream.BufferMem);
							for (Ref=s->OggPacket.packet;Ref;Ref=Ref->next)
								BufferWrite(&s->Stream.BufferMem,Ref->buffer->data + Ref->begin, Ref->length, 16384);
							Data = s->Stream.BufferMem.Data;
							Length = s->Stream.BufferMem.WritePos;
						}

						if (OGMHeader(p,s,(char*)Data,Length) || SpeexHeader(p,s,(char*)Data,Length))
						{
							PacketFormatDefault(&s->Stream.Format);
							s->PacketNo = 3; // no more headers
						}
						else
						if (!VorbisHeader(p,s))
						{
							s->Invalid = 1;
							continue;
						}

						while (s->MediaRateNum > (1<<30))
						{
							s->MediaRateDen >>= 1;
							s->MediaRateNum >>= 1;
						}

						Format_PrepairStream(&p->Format,&s->Stream);
						continue;
					}
					else
					{
						assert(s->Vorbis);

						// error in second or third header packet will not cause fatal error
						vorbis_synthesis_headerin(&s->Info,&s->Comment,&s->OggPacket); 

						if (s->PacketNo == 3)
						{
							// got the three header packets: reinit codec with vorbis_info
							s->Stream.Format.Extra = &s->Info;
							s->Stream.Format.ExtraLength = -1;
							ConnectionUpdate((node*)&p->Format,FORMAT_STREAM+StreamNo,s->Stream.Pin.Node,s->Stream.Pin.No);
							SendComments(s);
						}
						continue;
					}
				}
Example #10
0
/** @brief Acquire a buffer.

    @param ulBlock  Block number to acquire.
    @param uFlags   BFLAG_ values for the operation.
    @param ppBuffer On success, populated with the acquired buffer.

    @return A negated ::REDSTATUS code indicating the operation result.

    @retval 0           Operation was successful.
    @retval -RED_EIO    A disk I/O error occurred.
    @retval -RED_EINVAL Invalid parameters.
    @retval -RED_EBUSY  All buffers are referenced.
*/
REDSTATUS RedBufferGet(
    uint32_t    ulBlock,
    uint16_t    uFlags,
    void      **ppBuffer)
{
    REDSTATUS   ret = 0;
    uint8_t     bIdx;

    if((ulBlock >= gpRedVolume->ulBlockCount) || ((uFlags & BFLAG_MASK) != uFlags) || (ppBuffer == NULL))
    {
        REDERROR();
        ret = -RED_EINVAL;
    }
    else
    {
        if(BufferFind(ulBlock, &bIdx))
        {
            /*  Error if the buffer exists and BFLAG_NEW was specified, since
                the new flag is used when a block is newly allocated/created, so
                the block was previously free and and there should never be an
                existing buffer for a free block.

                Error if the buffer exists but does not have the same type as
                was requested.
            */
            if(    ((uFlags & BFLAG_NEW) != 0U)
                || ((uFlags & BFLAG_META_MASK) != (gBufCtx.aHead[bIdx].uFlags & BFLAG_META_MASK)))
            {
                CRITICAL_ERROR();
                ret = -RED_EFUBAR;
            }
        }
        else if(gBufCtx.uNumUsed == REDCONF_BUFFER_COUNT)
        {
            /*  The MINIMUM_BUFFER_COUNT is supposed to ensure that no operation
                ever runs out of buffers, so this should never happen.
            */
            CRITICAL_ERROR();
            ret = -RED_EBUSY;
        }
        else
        {
            BUFFERHEAD *pHead;

            /*  Search for the least recently used buffer which is not
                referenced.
            */
            for(bIdx = (uint8_t)(REDCONF_BUFFER_COUNT - 1U); bIdx > 0U; bIdx--)
            {
                if(gBufCtx.aHead[gBufCtx.abMRU[bIdx]].bRefCount == 0U)
                {
                    break;
                }
            }

            bIdx = gBufCtx.abMRU[bIdx];
            pHead = &gBufCtx.aHead[bIdx];

            if(pHead->bRefCount == 0U)
            {
                /*  If the LRU buffer is valid and dirty, write it out before
                    repurposing it.
                */
                if(((pHead->uFlags & BFLAG_DIRTY) != 0U) && (pHead->ulBlock != BBLK_INVALID))
                {
                  #if REDCONF_READ_ONLY == 1
                    CRITICAL_ERROR();
                    ret = -RED_EFUBAR;
                  #else
                    ret = BufferWrite(bIdx);
                  #endif
                }
            }
            else
            {
                /*  All the buffers are used, which should have been caught by
                    checking gBufCtx.uNumUsed.
                */
                CRITICAL_ERROR();
                ret = -RED_EBUSY;
            }

            if(ret == 0)
            {
                if((uFlags & BFLAG_NEW) == 0U)
                {
                    /*  Invalidate the LRU buffer.  If the read fails, we do not
                        want the buffer head to continue to refer to the old
                        block number, since the read, even if it fails, may have
                        partially overwritten the buffer data (consider the case
                        where block size exceeds sector size, and some but not
                        all of the sectors are read successfully), and if the
                        buffer were to be used subsequently with its partially
                        erroneous contents, bad things could happen.
                    */
                    pHead->ulBlock = BBLK_INVALID;

                    ret = RedIoRead(gbRedVolNum, ulBlock, 1U, gBufCtx.b.aabBuffer[bIdx]);

                    if((ret == 0) && ((uFlags & BFLAG_META) != 0U))
                    {
                        if(!BufferIsValid(gBufCtx.b.aabBuffer[bIdx], uFlags))
                        {
                            /*  A corrupt metadata node is usually a critical
                                error.  The master block is an exception since
                                it might be invalid because the volume is not
                                mounted; that condition is expected and should
                                not result in an assertion.
                            */
                            CRITICAL_ASSERT((uFlags & BFLAG_META_MASTER) == BFLAG_META_MASTER);
                            ret = -RED_EIO;
                        }
                    }

                  #ifdef REDCONF_ENDIAN_SWAP
                    if(ret == 0)
                    {
                        BufferEndianSwap(gBufCtx.b.aabBuffer[bIdx], uFlags);
                    }
                  #endif
                }
                else
                {
                    RedMemSet(gBufCtx.b.aabBuffer[bIdx], 0U, REDCONF_BLOCK_SIZE);
                }
            }

            if(ret == 0)
            {
                pHead->bVolNum = gbRedVolNum;
                pHead->ulBlock = ulBlock;
                pHead->uFlags = 0U;
            }
        }

        /*  Reference the buffer, update its flags, and promote it to MRU.  This
            happens both when BufferFind() found an existing buffer for the
            block and when the LRU buffer was repurposed to create a buffer for
            the block.
        */
        if(ret == 0)
        {
            BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];

            pHead->bRefCount++;

            if(pHead->bRefCount == 1U)
            {
                gBufCtx.uNumUsed++;
            }

            /*  BFLAG_NEW tells this function to zero the buffer instead of
                reading it from disk; it has no meaning later on, and thus is
                not saved.
            */
            pHead->uFlags |= (uFlags & (~BFLAG_NEW));

            BufferMakeMRU(bIdx);

            *ppBuffer = gBufCtx.b.aabBuffer[bIdx];
        }
    }

    return ret;
}
Example #11
0
File: idct.c Project: Jsoucek/q3ce
static int Process(codecidct* p, const packet* Packet, const flowstate* State)
{
	int Result;
	idct* IDCT = p->IDCT.Ptr;

	if (p->IDCT.Count<=0 && p->IDCT.Width>0 && p->IDCT.Height>0)
		return ERR_INVALID_DATA;

	p->State.CurrTime = State->CurrTime;
	if (State->DropLevel > 1)
		Discontinuity(p);

	if (p->Show>=0) // pending frame?
	{
		Result = IDCT->Send(IDCT,p->RefTime,&p->State);
		if (Result == ERR_BUFFER_FULL)
			return Result;
		p->Show = -1;
	}

	if (!Packet) // end of file or dropped
		return IDCT->Null(IDCT,State,0);

	if ((p->In.Format.Video.Pixel.Flags & PF_FRAGMENTED) && p->FindNext)
	{
		bool_t Processed = 0;

		if (p->RefTime >= 0)
			p->RefTime += p->FrameTime; 

		for (;;)
		{
			if (!p->FindNext(p))
			{
				if (Processed)
				{
					Result = ERR_NEED_MORE_DATA;
					break;
				}

				p->FrameEnd -= p->Buffer.ReadPos;
				BufferPack(&p->Buffer,0);
				BufferWrite(&p->Buffer,Packet->Data[0],Packet->Length,32768);
				Processed = 1;

				if (Packet->RefTime >= 0)
				{
					p->RefTime = Packet->RefTime;
//					if (p->IDCT.Count >= 3 && p->FrameTime>0 && p->RefTime >= p->FrameTime)
//						p->RefTime -= p->FrameTime;
				}
			}
			else
			{
				p->State.DropLevel = p->RefTime >= 0 && State->CurrTime >= 0 &&
				                     p->RefTime < (State->CurrTime - p->DropTolerance);

				if (State->DropLevel > 1)
				{
					p->IDCT.Ptr->Null(p->IDCT.Ptr,NULL,0);
					Result = ERR_NONE;
				}
				else
					Result = p->Frame(p,p->Buffer.Data+p->Buffer.ReadPos,p->FrameEnd-p->Buffer.ReadPos); 

				p->Buffer.ReadPos = p->FrameEnd;

				if (Result==ERR_NONE && p->Show>=0)
				{
					if (!Processed)
						Result = ERR_BUFFER_FULL; // resend packet next time
					break;
				}
			}
		}
	}
	else
	{
		if (State->DropLevel > 1)
		{
			p->IDCT.Ptr->Null(p->IDCT.Ptr,NULL,0);
			Result = ERR_NONE;
		}
		else
		{
			p->State.DropLevel = State->DropLevel;
			p->RefTime = Packet->RefTime;
//			if (p->IDCT.Count >= 3 && p->FrameTime>0 && p->RefTime >= p->FrameTime)
//				p->RefTime -= p->FrameTime;
			Result = p->Frame(p,Packet->Data[0],Packet->Length);
		}
	}

	if (p->Show>=0 && IDCT->Send(IDCT,p->RefTime,&p->State) != ERR_BUFFER_FULL)
		p->Show = -1;

	return Result;
}
Example #12
0
/// Allocate a new buffer or reuse a free one.
BufferWrite BufferPool::alloc(Allocator* allocator, size_t size, bool strict)
{
	if (size == 0)
		return allocator->alloc(0);

	ipc::ScopedMTLock locker(globalLock, "alloc");

	++nbrequests;

	if (size != currentBufferSize)
	{ // remove all current references
		buffers.clear();
		freeBuffers.clear();
		currentBufferSize = size;
	}

	if (freeBuffers.empty() && !buffers.empty())
	{ // search for any newly free buffers
		BufferList::iterator it = buffers.begin();
		while (it != buffers.end())
		{
			if (it->unique())
			{ // this buffer is free
				BufferList::iterator old = it;
				freeBuffers.push_back(*it);
				++it;
				buffers.erase(old);
			}
			else
				++it;
		}
	}
	BufferWrite buf;
	if(freeBuffers.empty())
	{
		if( buffers.size() >= maxBuffers)
		{
#ifdef DEBUG
			std::cerr << "Warning: buffer pool overflow ("<<buffers.size()<<")."<<std::endl;
#endif
			if (strict)
				return BufferWrite();
			else
				buffers.pop_front();
		}
		// allocate a new buffer
		++nballocs;
		buf = allocator->alloc(currentBufferSize);
		if (buf.getSize() != size)
			std::cerr << "BufferPool: alloc failure for requested size "
					<< size << std::endl;
	}
	else
	{ // use the first free buffer
		buf = freeBuffers.front();
		freeBuffers.pop_front(); // this is not a free buffer anymore
		if (buf.getSize() != size)
			std::cerr << "BufferPool: reuse failure for requested size "
					<< size << std::endl;
	}
	if (buf.getSize() == size)
		buffers.push_back(buf);
	return buf;
}
Example #13
0
void ParserDataFeed(parser* p,const void* Ptr,size_t Len)
{
	BufferWrite(&p->Buffer,Ptr,Len,4096);
}