Changeset 898
- Timestamp:
- 05/24/08 13:43:22 (6 months ago)
- Files:
-
- trunk/FFusionCodec.c (modified) (11 diffs)
- trunk/FrameBuffer.c (modified) (6 diffs)
- trunk/FrameBuffer.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/FFusionCodec.c
r882 r898 252 252 static void DumpFrameDropStats(FFusionGlobals glob) 253 253 { 254 #ifdef DEBUG_BUILD 254 255 static const char types[4] = {'?', 'I', 'P', 'B'}; 256 #endif 255 257 int i; 256 258 … … 260 262 261 263 for (i = 0; i < 4; i++) { 264 #ifdef DEBUG_BUILD 262 265 struct per_frame_decode_stats *f = &glob->stats.type[i]; 266 #endif 263 267 264 268 Codecprintf(glob->fileLog, "%c\t| %d\t\t| %d\t\t| %d\t\t| %d/%f%%\t\t| %d/%f%%\n", types[i], f->begin_calls, f->decode_calls, f->draw_calls, … … 358 362 // we allocate some space for copying the frame data since we need some padding at the end 359 363 // for ffmpeg's optimized bitstream readers. Size doesn't really matter, it'll grow if need be 360 FFusionDataSetup(&(glob->data), 256, 64*1024);364 FFusionDataSetup(&(glob->data), 256, 1024*1024); 361 365 FFusionRunUpdateCheck(); 362 366 } … … 977 981 /* Reset context, safe marking in such a case */ 978 982 glob->begin.lastFrameType = FF_I_TYPE; 979 glob->data.unparsedFrames.dataSize = 0;983 FFusionDataReadUnparsed(&(glob->data)); 980 984 glob->begin.lastPFrameData = NULL; 981 985 redisplayFirstFrame = 1; … … 1019 1023 glob->packedType = PACKED_DELAY_BY_ONE_FRAME; 1020 1024 1021 if(FFusionCreateDataBuffer(&(glob->data), (uint8_t *)drp->codecData, parsedBufSize)) 1022 myDrp->frameData = FFusionDataAppend(&(glob->data), parsedBufSize, type); 1025 myDrp->frameData = FFusionDataAppend(&(glob->data), (uint8_t *)drp->codecData, parsedBufSize, type); 1023 1026 if(type != FF_I_TYPE) 1024 1027 myDrp->frameData->prereqFrame = glob->begin.lastPFrameData; … … 1065 1068 glob->begin.lastPFrameData->nextFrame = myDrp->frameData; 1066 1069 glob->begin.lastPFrameData = myDrp->frameData; 1067 if(FFusionCreateDataBuffer(&(glob->data), buffer, parsedBufSize)) 1068 myDrp->frameData = FFusionDataAppend(&(glob->data), parsedBufSize, type); 1070 myDrp->frameData = FFusionDataAppend(&(glob->data), buffer, parsedBufSize, type); 1069 1071 myDrp->frameData->prereqFrame = glob->begin.lastPFrameData; 1070 1072 buffer += parsedBufSize; … … 1074 1076 FFusionDataSetUnparsed(&(glob->data), buffer, bufferSize); 1075 1077 else 1076 glob->data.unparsedFrames.dataSize = 0;1078 FFusionDataReadUnparsed(&(glob->data)); 1077 1079 } 1078 1080 else 1079 glob->data.unparsedFrames.dataSize = 0;1081 FFusionDataReadUnparsed(&(glob->data)); 1080 1082 myDrp->bufferSize = 0; 1081 1083 } … … 1169 1171 #endif 1170 1172 glob->decode.futureBuffer = NULL; 1171 FFusionDataMarkRead( &(glob->data),myDrp->frameData);1173 FFusionDataMarkRead(myDrp->frameData); 1172 1174 glob->decode.lastFrame = myDrp->frameNumber; 1173 1175 return err; … … 1200 1202 /* data is already set up properly for us */ 1201 1203 dataSize = myDrp->bufferSize; 1202 FFusionCreateDataBuffer(&(glob->data), (uint8_t *)drp->codecData, dataSize); 1203 dataPtr = glob->data.buffer; 1204 dataPtr = FFusionCreateEntireDataBuffer(&(glob->data), (uint8_t *)drp->codecData, dataSize); 1204 1205 } 1205 1206 ICMDataProcRecordPtr dataProc = drp->dataProcRecord.dataProc ? &drp->dataProcRecord : NULL; … … 1227 1228 if (myDrp->buffer) myDrp->buffer->returnedFrame = tempFrame; 1228 1229 1229 FFusionDataMarkRead( &(glob->data),frameData);1230 FFusionDataMarkRead(frameData); 1230 1231 1231 1232 FFusionDebugPrint("%p DecodeBand decoded #%d.\n", glob, glob->decode.lastFrame); … … 1367 1368 pascal ComponentResult FFusionCodecEndBand(FFusionGlobals glob, ImageSubCodecDecompressRecord *drp, OSErr result, long flags) 1368 1369 { 1370 #ifdef DEBUG_BUILD 1369 1371 FFusionDecompressRecord *myDrp = (FFusionDecompressRecord *)drp->userDecompressRecord; 1372 #endif 1370 1373 glob->stats.type[drp->frameType].end_calls++; 1371 1374 FFusionDebugPrint("%p EndBand #%d.\n", glob, myDrp->frameNumber); trunk/FrameBuffer.c
r806 r898 10 10 #include "FrameBuffer.h" 11 11 #include "avcodec.h" 12 #include <sys/param.h> 12 13 13 14 void FFusionDataSetup(FFusionData *data, int dataSize, int bufferSize) 14 15 { 15 data->read = 0; 16 data->write = 0; 17 data->frames = malloc(sizeof(FrameData *) * dataSize); 16 memset(data, 0, sizeof(FFusionData)); 17 int framesSize = sizeof(FrameData) * dataSize; 18 data->frames = malloc(framesSize); 19 memset(data->frames, 0, framesSize); 18 20 19 21 int i; 20 22 for(i=0; i<dataSize; i++) 21 23 { 22 FrameData *fdata = malloc(sizeof(FrameData)); 23 data->frames[i] = fdata; 24 fdata->buffer = av_malloc(bufferSize); 25 fdata->bufferSize = bufferSize; 24 FrameData *fdata = data->frames + i; 25 fdata->buffer = NULL; 26 fdata->data = data; 26 27 } 27 data-> size = dataSize;28 data->buffer = av_malloc(bufferSize); 29 data-> bufferSize = bufferSize;30 data-> startBufferSize = bufferSize;28 data->frameSize = dataSize; 29 30 data->ringBuffer = av_malloc(bufferSize); 31 data->ringSize = bufferSize; 31 32 } 32 33 33 34 void FFusionDataFree(FFusionData *data) 34 35 { 35 int i;36 for(i=0; i<data->size; i++)36 free(data->frames); 37 if(data->previousData != NULL) 37 38 { 38 av_free(data->frames[i]->buffer);39 free(data-> frames[i]);39 FFusionDataFree(data->previousData); 40 free(data->previousData); 40 41 } 41 free(data->frames);42 av_free(data->buffer);43 42 } 44 43 45 int FFusionCreateDataBuffer(FFusionData *data, uint8_t *buffer, int bufferSize)44 static void expansion(FFusionData *data, int dataSize) 46 45 { 47 data->buffer = av_fast_realloc(data->buffer, &data->bufferSize, bufferSize + FF_INPUT_BUFFER_PADDING_SIZE); 48 if (data->buffer) { 49 uint8_t *dataPtr = data->buffer; 46 FFusionData *prev = malloc(sizeof(FFusionData)); 47 memcpy(prev, data, sizeof(FFusionData)); 48 int i; 49 for(i=0; i<data->frameSize; i++) 50 data->frames[i].data = prev; 51 52 int newRingSize = MAX(dataSize * 10, data->ringSize * 2); 53 FFusionDataSetup(data, data->frameSize * 2, newRingSize); 54 data->previousData = prev; 55 } 56 57 uint8_t *FFusionCreateEntireDataBuffer(FFusionData *data, uint8_t *buffer, int bufferSize) 58 { 59 data->ringBuffer = av_fast_realloc(data->ringBuffer, &(data->ringSize), bufferSize + FF_INPUT_BUFFER_PADDING_SIZE); 60 if (data->ringBuffer) { 61 uint8_t *dataPtr = data->ringBuffer; 50 62 memcpy(dataPtr, buffer, bufferSize); 51 63 memset(dataPtr + bufferSize, 0, FF_INPUT_BUFFER_PADDING_SIZE); 52 64 } 53 return data-> buffer != NULL;65 return data->ringBuffer; 54 66 } 55 67 56 FrameData *FFusionDataAppend(FFusionData *data, int dataSize, int type)68 static uint8_t *createBuffer(FFusionData *data, int dataSize) 57 69 { 58 if( (data->write + 1) % data->size == data->read)70 if(data->ringWrite >= data->ringRead) 59 71 { 60 int newSize = data->size * 2; 61 FrameData * *newData = malloc(sizeof(FrameData *) * newSize); 62 memcpy(newData, data->frames + data->read, (data->size - data->read) * sizeof(FrameData)); 63 if(data->read != 0) 64 memcpy(newData + (data->size - data->read), data->frames, data->read * sizeof(FrameData)); 65 66 int i; 67 for(i=data->size; i<newSize; i++) 72 //Write is after read 73 if(data->ringWrite + dataSize + FF_INPUT_BUFFER_PADDING_SIZE < data->ringSize) 68 74 { 69 FrameData *newFrame = malloc(sizeof(FrameData));70 newData[i] = newFrame;71 newFrame->buffer = av_malloc(data->startBufferSize);72 newFrame->bufferSize = data->startBufferSize;75 //Found at end 76 int offset = data->ringWrite; 77 data->ringWrite = offset + dataSize; 78 return data->ringBuffer + offset; 73 79 } 74 data->read = 0; 75 data->write = data->size; 76 data->size = newSize; 77 free(data->frames); 78 data->frames = newData; 80 else 81 //Can't fit at end, loop 82 data->ringWrite = 0; 83 } 84 if(data->ringWrite + dataSize + FF_INPUT_BUFFER_PADDING_SIZE < data->ringRead) 85 { 86 //Found at write 87 int offset = data->ringWrite; 88 data->ringWrite = offset + dataSize; 89 return data->ringBuffer + offset; 90 } 91 else 92 { 93 expansion(data, dataSize); 94 return data->ringBuffer; 95 } 96 } 97 98 static uint8_t *insertIntoBuffer(FFusionData *data, uint8_t *buffer, int dataSize) 99 { 100 uint8_t *ret = createBuffer(data, dataSize); 101 memcpy(ret, buffer, dataSize); 102 memset(ret + dataSize, 0, FF_INPUT_BUFFER_PADDING_SIZE); 103 return ret; 104 } 105 106 FrameData *FFusionDataAppend(FFusionData *data, uint8_t *buffer, int dataSize, int type) 107 { 108 if((data->frameWrite + 1) % data->frameSize == data->frameRead) 109 { 110 expansion(data, dataSize); 79 111 } 80 112 81 FrameData *dest = data->frames[data->write]; 82 uint8_t *tbuff = dest->buffer; 83 dest->buffer = data->buffer; 84 data->buffer = tbuff; 113 FrameData *dest = data->frames + data->frameWrite; 85 114 86 unsigned int tsize = dest->bufferSize; 87 dest->bufferSize = data->bufferSize; 88 data->bufferSize = tsize; 89 115 uint8_t *saveBuffer = insertIntoBuffer(data, buffer, dataSize); 116 dest->buffer = saveBuffer; 90 117 dest->dataSize = dataSize; 91 118 dest->type = type; … … 94 121 dest->nextFrame = NULL; 95 122 96 data-> write = (data->write + 1) % data->size;123 data->frameWrite = (data->frameWrite + 1) % data->frameSize; 97 124 return dest; 98 125 } … … 102 129 FrameData *unparsed = &(data->unparsedFrames); 103 130 104 unparsed->buffer = av_fast_realloc(unparsed->buffer, &unparsed->bufferSize, bufferSize);131 unparsed->buffer = insertIntoBuffer(data, buffer, bufferSize); 105 132 if (unparsed->buffer) { 106 133 memcpy(unparsed->buffer, buffer, bufferSize); 107 134 unparsed->dataSize = bufferSize; 108 135 } 136 } 137 138 void FFusionDataReadUnparsed(FFusionData *data) 139 { 140 data->ringWrite -= data->unparsedFrames.dataSize; 141 data->unparsedFrames.dataSize = 0; 109 142 } 110 143 … … 117 150 } 118 151 119 void FFusionDataMarkRead(F FusionData *data, FrameData *toData)152 void FFusionDataMarkRead(FrameData *toData) 120 153 { 121 154 if(toData == NULL) … … 125 158 return; 126 159 127 int i; 128 for(i=data->read; i!=data->write; i = (i + 1) % data->size) 160 FFusionData *data = toData->data; 161 data->frameRead = toData - data->frames + 1; 162 data->ringRead = toData->buffer + toData->dataSize - data->ringBuffer; 163 if(data->previousData != NULL) 129 164 { 130 if(data->frames[i] == toData) 131 { 132 data->read = (i + 1) % data->size; 133 break; 134 } 165 FFusionDataFree(data->previousData); 166 data->previousData = NULL; 135 167 } 136 168 } … … 139 171 { 140 172 int i; 141 for(i=data-> read; i!=data->write; i = (i + 1) % data->size)173 for(i=data->frameRead; i!=data->frameWrite; i = (i + 1) % data->frameSize) 142 174 { 143 if(data->frames[i] ->frameNumber == frameNumber)144 return data->frames [i];175 if(data->frames[i].frameNumber == frameNumber) 176 return data->frames + i; 145 177 } 178 if(data->previousData != NULL) 179 return FFusionDataFind(data->previousData, frameNumber); 180 146 181 return NULL; 147 182 } trunk/FrameBuffer.h
r641 r898 9 9 10 10 typedef struct FrameData_s FrameData; 11 typedef struct FFusionData_s FFusionData; 12 11 13 struct FrameData_s 12 14 { … … 20 22 FrameData *prereqFrame; /* This is the frame's data which must be decoded to fully display this frame */ 21 23 FrameData *nextFrame; /* This is the next frame to decode if this one is already decoded. This is for predictive decoding */ 22 /* private */ 23 unsigned int bufferSize; 24 FFusionData *data; 24 25 }; 25 26 26 typedef struct 27 typedef struct DataRingBuffer_s { 28 } DataRingBuffer; 29 30 struct FFusionData_s 27 31 { 28 uint8_t *buffer;29 unsigned int bufferSize;30 32 FrameData unparsedFrames; 31 33 /* private */ 32 unsigned int size; 33 unsigned int read; 34 unsigned int write; 35 unsigned int startBufferSize; 36 FrameData * *frames; 37 } FFusionData; 34 unsigned int frameSize; 35 unsigned int frameRead; 36 unsigned int frameWrite; 37 FrameData *frames; 38 unsigned int ringSize; 39 unsigned int ringRead; 40 unsigned int ringWrite; 41 uint8_t *ringBuffer; 42 FFusionData *previousData; 43 }; 38 44 39 45 void FFusionDataSetup(FFusionData *data, int dataSize, int bufferSize); 40 46 void FFusionDataFree(FFusionData *data); 41 int FFusionCreateDataBuffer(FFusionData *data, uint8_t *buffer, int bufferSize);42 FrameData *FFusionDataAppend(FFusionData *data, int dataSize, int type);47 uint8_t *FFusionCreateEntireDataBuffer(FFusionData *data, uint8_t *buffer, int bufferSize); 48 FrameData *FFusionDataAppend(FFusionData *data, uint8_t *buffer, int dataSize, int type); 43 49 void FFusionDataSetUnparsed(FFusionData *data, uint8_t *buffer, int bufferSize); 44 void FFusionDataMarkRead(F FusionData *data, FrameData *toData);50 void FFusionDataMarkRead(FrameData *toData); 45 51 FrameData *FFusionDataFind(FFusionData *data, int frameNumber); 46 52
