📄 framebuffer.c
字号:
/************************************************** * * buffer.c * * CVS ID: $Id: framebuffer.c,v 1.35 2007/09/21 05:26:11 hara Exp $ * Author: Raffaele Belardi [RB] - STM) * Date: $Date: 2007/09/21 05:26:11 $ * Revision: $Revision: 1.35 $ * * Description: * * API for FrameBuffer access * *************************************************** * * COPYRIGHT (C) ST Microelectronics 2005 * All Rights Reserved * **************************************************** * * STM CVS Log: * * $Log: framebuffer.c,v $ * Revision 1.35 2007/09/21 05:26:11 hara * Initial implementation for WMDRM feature into A+. * * Revision 1.34 2006/12/05 17:49:21 belardi * Removed unused variable * * Revision 1.33 2006/12/04 16:53:22 chlapik * FB handling modified: * - always ask max 1 element * - startOffset modify only if there are non zero amount of data * - subcode or - ed if element was once filled * * Revision 1.32 2006/10/17 09:51:20 trubac * FB init bug fixed * * Revision 1.31 2006/09/27 19:48:59 belardi * Removed (global) unused variables * * Revision 1.30 2006/09/18 09:55:21 belardi * Corrected CVS keyword usage * * Revision 1.29 2006/09/18 09:23:02 belardi * Added Log CVS keyword into file header * * ***************************************************/#include "gendef.h"#include "osal.h"//#include "wmadefs.h"#include "decoder_task.h"#include "controller.h"#include "framebuffer.h"#include "tag_defs.h" // [RB] for MAX_STRINGS_SIZE //[LL] id3tag_defs.h moved#include "xfile.h"#include <string.h> // memset,...//int cc = 0; //ok - testuint32 decoderReadBytes; // number of read (acquired by decoder) bytes in current fileuint32 decoderDecodedBytes; // number of decoded bytes in current file#ifdef BITSTREAM_ARRAY //#include "input3.h" //O.K. input WMA bitstream //#include "input_16_16_long.h" #include "input.h" //mp3 unsigned long long g_current_read; //O.K. - where to read from input bitstream buffer#endifunsigned char g_FB_writeTo; // FrameBuffer Element # to be filled inunsigned char g_FB_readFrom; // Lastly read out FrameBuffer Element #int g_FBempty; // number of empty elements in FB#if (0 != HAVE_WMDRM_LARGE_BUFFER)FrameBufferElement FrameBuffer[FrameBufferSdramElements+1]; /* FrameBufferSdramElements : Big elements number for FrameBuffer in SDRAM */uint16 FrameBufferElements = FrameBufferInternalElements;unsigned char FrameBufferDataBuffer[FRAME_BUFFER_ELEMENT_LENGTH*(FrameBufferInternalElements) + MAX_DATA_REQUESTED];#elseFrameBufferElement FrameBuffer[FrameBufferElements+1];unsigned char FrameBufferDataBuffer[FRAME_BUFFER_ELEMENT_LENGTH*(FrameBufferElements) + MAX_DATA_REQUESTED];#endif/*************************************************** * FrameBufferInit() * * *************************************************/void FrameBufferInit(uint32 sz){ uint8 i; // Create the buffers of dimension multiple of 4 to limit // alignment problems in DMA //uint32 req_dim = (sz*(FrameBufferElements) + MAX_DATA_REQUESTED) & 0xFFFFFFFC; //req_dim += 4; // & !!! should be there ??? // memset((char *) &(FrameBuffer), 0, sizeof(FrameBufferElement) * (FrameBufferElements+1) ); //tmpP = (int *) malloc(req_dim); // 32 bit aligned //Data = (unsigned char *) tmpP; #if (0 != HAVE_WMDRM_LARGE_BUFFER) FrameBufferElements = FrameBufferInternalElements;#endif g_FB_writeTo = 1; g_FB_readFrom = 0; g_FBempty = FrameBufferElements; FrameBuffer[0].en = 0; FrameBuffer[0].status = fbEmpty; FrameBuffer[0].data = FrameBufferDataBuffer; for (i = 1; i < FrameBufferElements + 1; i++) { FrameBuffer[i].en = i; FrameBuffer[i].status = fbEmpty; FrameBuffer[i].data = FrameBufferDataBuffer + MAX_DATA_REQUESTED + (i - 1)*FRAME_BUFFER_ELEMENT_LENGTH; //to guarantee continuos buffer //FrameBuffer[i].data = (char *) pseudoMalloc(req_dim); } } #if (0 != HAVE_WMDRM_LARGE_BUFFER)/*************************************************** * FrameBufferSdramInit() * * *************************************************/void FrameBufferSdramInit(uint32 sz){ uint8 i; uint8 *pFrameBufferDataBuffer; FrameBufferElements = FrameBufferSdramElements; pFrameBufferDataBuffer = cap_input_buffer_SDRAM; g_FB_writeTo = 1; g_FB_readFrom = 0; g_FBempty = FrameBufferSdramElements; FrameBuffer[0].en = 0; FrameBuffer[0].status = fbEmpty; FrameBuffer[0].data = pFrameBufferDataBuffer; /* Re-use shockproof buffer for Big Frame buffer. */ for (i = 1; i < FrameBufferSdramElements + 1; i++) { FrameBuffer[i].en = i; FrameBuffer[i].status = fbEmpty; FrameBuffer[i].data = pFrameBufferDataBuffer + MAX_DATA_REQUESTED + (i - 1)*FRAME_BUFFER_ELEMENT_LENGTH; //to guarantee continuos buffer } } #endif/*************************************************** * FrameBufferStartTransfer() * * Programs DMA to copy data from the CHANNEL_ITF into the * FrameBuffer. * * *************************************************//* void FrameBufferStartTransfer(ElementFlagType FBflag, FILE_STRUCT *File, FAT_PRIVATE_STRUCT *FAT_private){ int copiedDataLength; int i; ElementFlagType FBflag2 = FBflag;#ifdef BITSTREAM_ARRAY for(i=0;i<FRAME_BUFFER_ELEMENT_LENGTH;i++) (FrameBuffer[g_FB_writeTo].data)[i] = (g_bitstream + g_current_read)[i]; //memmove(FrameBuffer[g_FB_writeTo].data, g_bitstream + g_current_read, FRAME_BUFFER_ELEMENT_LENGTH); g_current_read += FRAME_BUFFER_ELEMENT_LENGTH; copiedDataLength = FRAME_BUFFER_ELEMENT_LENGTH; #endif#ifdef FS_ARRAY if (cc == 47) cc++; copiedDataLength = FileRead_FAT(FAT_private,File,FrameBuffer[g_FB_writeTo].data,FRAME_BUFFER_ELEMENT_LENGTH,0); if (copiedDataLength < FRAME_BUFFER_ELEMENT_LENGTH) { FBflag2 = last; if (copiedDataLength < 0) copiedDataLength = 0; }#endif FrameBuffer[g_FB_writeTo].status = fbTransferInProgress; { // Following part of the code should be executed // after successful filling of FrameBuffer (i.e. after DMA transfer) } FrameBuffer[g_FB_writeTo].ElementFlag = FBflag2; FrameBufferTransferDone(copiedDataLength);} *//*************************************************** * FrameBufferTransferDone() * * Sets flags after DMA transfer is done. * Called from DMA interrupt * * *************************************************//* void FrameBufferTransferDone(int copiedDataLength){ g_FBempty--; // decrement number of empty elements FrameBuffer[g_FB_writeTo].availableDataLength = copiedDataLength; FrameBuffer[g_FB_writeTo].status = 3; // fbTransferComplete; FrameBuffer[g_FB_writeTo].EndOfFile = cc++;} *//*************************************************** * FillFrameBuffer() * * Provides data from FB to Decoder (if data are ready) * * *************************************************/FrameBufferStatus FrameBufferGetData(FrameBufferElement *pBufferElement, uint8 update){ unsigned char tmp_readFrom = (g_FB_readFrom%FrameBufferElements) + 1; if (FrameBuffer[tmp_readFrom].status == fbDataReady) { *pBufferElement = FrameBuffer[tmp_readFrom]; if (update) { g_FB_readFrom = tmp_readFrom; decoderReadBytes = FrameBuffer[tmp_readFrom].startOffset; } return fbDataReady; } else { return fbEmpty; // ? fbTransferInProgress } }/*************************************************** * * SetEmptyFBE() * * Sets FB Elements as fbEmpty * * *************************************************/void SetEmptyFBE(unsigned char From, unsigned char To){ unsigned char c; for (c = From; c != To; c ++) //= (c%FrameBufferElements)+1) { //FrameBuffer[c].ElementFlag = FT_MIDDLE; if(FrameBuffer[c].status != fbEmpty) { FrameBuffer[c].status = fbEmpty; g_FBempty++; } } if (g_FBempty > FrameBufferElements) { g_FBempty = FrameBufferElements; } if ((g_FBempty > FB_EMPTY_RATIO) && (!decoderStopRequest())) { // request new data from controller event_req_set_decoder(READY); //controller_update_status(CONTROLLER_NEW_DECODER_DATA_REQUEST_EVENT); } }/*************************************************** * * SetEmptyFBECycle() * * Sets FB Elements as fbEmpty in Circular buffer * * Clears both From and To including (!) * * *************************************************/void SetEmptyFBECycle(unsigned char From, unsigned char To){ unsigned char c; if (To == 0) { To = FrameBufferElements; } for (c = From; c != To; c = (c%FrameBufferElements)+1) { if(FrameBuffer[c].status != fbEmpty) { FrameBuffer[c].status = fbEmpty; g_FBempty++; } FrameBuffer[c].ElementFlag = FT_MIDDLE; } if(FrameBuffer[c].status != fbEmpty) { FrameBuffer[c].status = fbEmpty; g_FBempty++; } FrameBuffer[c].ElementFlag = FT_MIDDLE; if (g_FBempty > FrameBufferElements) { g_FBempty = FrameBufferElements; } if ((g_FBempty > FB_EMPTY_RATIO) && (!decoderStopRequest())) { // request new data from controller event_req_set_decoder(READY); //controller_update_status(CONTROLLER_NEW_DECODER_DATA_REQUEST_EVENT);#if (1 == HAVE_WMDRM) /* To perform Frame Buffer filling as soon as possible, after 1 frame buffer element is empty. */ event_out_shedule(DECODER_REQ_EVENT); #endif } }/*************************************************** * * GetElementNumber() * * According to *pBuffer sets ElementNumber * If 0 then return 1 * * *************************************************/unsigned char GetElementNumber(unsigned char *pBuffer){ int element; if (pBuffer < (FrameBuffer[2].data)) element = 1; else element = 1 + ((pBuffer - (FrameBuffer[1].data)) / FRAME_BUFFER_ELEMENT_LENGTH); return element;}/*void SetEmptyAllFBE(void){ int i; for (i = 1; i < FrameBufferElements + 1; i++) { FrameBuffer[i].status = fbEmpty; }}*//*************************************************** * * GetNextFBElement() * * * *************************************************/#if 0 // [RB] commente out to reduce ROM spaceunsigned char *GetNextFBElement(void){ return (FrameBuffer[(g_FB_readFrom%FrameBufferElements) + 1].data);}#endifuint8* FBM_GetFreeElement(uint16 *bytes_free){ uint8* ret = NULL; if (FrameBuffer[g_FB_writeTo].status == fbEmpty) { ret = FrameBuffer[g_FB_writeTo].data; *bytes_free = FRAME_BUFFER_ELEMENT_LENGTH; if (FrameBuffer[g_FB_writeTo].ElementFlag & FT_UNFINISHED) { ret += FrameBuffer[g_FB_writeTo].availableDataLength; // update destination pointer *bytes_free -= FrameBuffer[g_FB_writeTo].availableDataLength; } } return ret; }void FBM_SetFullElement(tQsubcode_event *subcode, ElementFlagType FBflag_last, uint16 copiedDataLength, uint32 startOffset){ uint16 copiedBytes; copiedBytes = copiedDataLength; if (FrameBuffer[g_FB_writeTo].ElementFlag & FT_UNFINISHED) { copiedBytes += FrameBuffer[g_FB_writeTo].availableDataLength; FrameBuffer[g_FB_writeTo].ElementFlag &= ~FT_UNFINISHED; } if ((copiedBytes > 0) || (!copiedDataLength)) { FrameBuffer[g_FB_writeTo].ElementFlag = FBflag_last; FrameBuffer[g_FB_writeTo].availableDataLength = copiedBytes; //handling of startOffset if(copiedDataLength) { //if some data provided, update startOffset FrameBuffer[g_FB_writeTo].startOffset = startOffset; // set offset from the begining of song } else { //no data provided if(!copiedBytes) { //last element is full, next one will be empty FrameBuffer[g_FB_writeTo].startOffset = 0; } } //handling of subcode if(copiedDataLength) { //only if some data provided if (subcode != NULL) { //if subcode exists if(copiedBytes == copiedDataLength) { //we fill this element first time FrameBuffer[g_FB_writeTo].subcode = *subcode; } else { //we fill this element not first time (FrameBuffer[g_FB_writeTo].subcode.event_type) |= (subcode->event_type); } } } if ((FBflag_last == FT_LAST) || (FBflag_last == FT_FSLAST)) { FrameBuffer[g_FB_writeTo].status = fbDataReady; g_FBempty--; // decrement number of empty elements g_FB_writeTo = (g_FB_writeTo%FrameBufferElements) + 1; } else { if (copiedBytes == FRAME_BUFFER_ELEMENT_LENGTH) { FrameBuffer[g_FB_writeTo].status = fbDataReady; g_FBempty--; // decrement number of empty elements g_FB_writeTo = (g_FB_writeTo%FrameBufferElements) + 1; } else { FrameBuffer[g_FB_writeTo].ElementFlag |= FT_UNFINISHED; } } } }uint32 GetDecodedBytes(void){ return decoderDecodedBytes;}void SetDecodedBytes(uint32 unprocessedData){ decoderDecodedBytes = decoderReadBytes - unprocessedData;} void SetDecodedBytesWMA(uint32 offset){ decoderDecodedBytes = offset;} void FB_clearWriteToElement(void){ FrameBuffer[g_FB_writeTo].ElementFlag = FT_MIDDLE;}void FB_clearAll(void){ // clears all uint8 c; #if (1 == HAVE_WMDRM_LARGE_BUFFER) for (c = 1; c <= FrameBufferSdramElements; c++)#else for (c = 1; c <= FrameBufferElements; c++)#endif { FrameBuffer[c].status = fbEmpty; FrameBuffer[c].ElementFlag = FT_MIDDLE; } g_FBempty = FrameBufferElements; // reset FB pointers g_FB_writeTo = 1; g_FB_readFrom = 0;}void ClearFBElement(uint8 ElementNumber){ if(FrameBuffer[ElementNumber].status != fbEmpty) { FrameBuffer[ElementNumber].status = fbEmpty; g_FBempty++; } FrameBuffer[ElementNumber].ElementFlag = FT_MIDDLE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -