Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
frametype.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include "all.h"
00045 #include "prototypes.h"
00046 #include "frames.h"
00047 #include "frame.h"
00048 #include "param.h"
00049
00050
00051 static FrameTable *frameTable=NULL;
00052 static boolean use_cache = FALSE;
00053 static int firstI = 0;
00054
00055
00056
00057
00058
00059 boolean forceEncodeLast = FALSE;
00060 extern int framePatternLen;
00061 extern char *framePattern;
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 int
00080 FType_Type(frameNum)
00081 int frameNum;
00082 {
00083 if (use_cache) return (int)frameTable[frameNum].typ;
00084
00085 if ( forceEncodeLast && (frameNum+1 == numInputFiles) ) {
00086 int result;
00087
00088 result = framePattern[frameNum % framePatternLen];
00089 if ( result == 'b' ) return 'i';
00090 else return result;
00091 } else {
00092 if (specificsOn) {
00093 static int lastI = -1;
00094 int newtype;
00095
00096 if (lastI > frameNum) lastI = -1;
00097 newtype = SpecTypeLookup(frameNum);
00098 switch (newtype) {
00099 case 1:
00100 lastI = frameNum;
00101 return 'i';
00102 case 2:
00103 return 'p';
00104 case 3:
00105 return 'b';
00106 default:
00107 if (lastI != -1) return framePattern[(frameNum-lastI+firstI) % framePatternLen];
00108 else return framePattern[frameNum % framePatternLen];
00109 }
00110 } else return framePattern[frameNum % framePatternLen];
00111 }
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 int
00127 FType_FutureRef(currFrameNum)
00128 int currFrameNum;
00129 {
00130 int index;
00131 int futureIndex;
00132 int result;
00133
00134 if (use_cache) {
00135 return frameTable[currFrameNum].next->number;
00136 } else {
00137 index = currFrameNum % framePatternLen;
00138 futureIndex = frameTable[index].next->number;
00139
00140 result = currFrameNum +
00141 (((futureIndex-index)+framePatternLen) % framePatternLen);
00142
00143 if ( (result >= numInputFiles) && forceEncodeLast ) {
00144 return numInputFiles-1;
00145 } else {
00146 return result;
00147 }
00148 }
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 int
00164 FType_PastRef(currFrameNum)
00165 int currFrameNum;
00166 {
00167 int index;
00168 int pastIndex;
00169
00170 if (use_cache) {
00171 return frameTable[currFrameNum].prev->number;
00172 } else {
00173 index = currFrameNum % framePatternLen;
00174 pastIndex = frameTable[index].prev->number;
00175
00176 return currFrameNum -
00177 (((index-pastIndex)+framePatternLen) % framePatternLen);
00178 }
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 #define SIMPLE_ASCII_UPPER(x) (((x)>='a') ? ((x)-'a'+'A') : (x))
00194 void
00195 SetFramePattern(pattern)
00196 char *pattern;
00197 {
00198 int len = strlen(pattern);
00199 char *buf;
00200 int index;
00201
00202 if ( ! pattern ) {
00203 fprintf(stderr, "pattern cannot be NULL\n");
00204 exit(1);
00205 }
00206
00207 if ( SIMPLE_ASCII_UPPER(pattern[0]) != 'I' ) {
00208 for (index=0; index < len; index++) {
00209
00210 if (SIMPLE_ASCII_UPPER(pattern[index]) == 'I') {
00211 break;
00212 } else if (SIMPLE_ASCII_UPPER(pattern[index]) == 'P') {
00213 fprintf(stderr, "first reference frame must be 'i'\n");
00214 exit(1);
00215 }
00216 }
00217 }
00218
00219 buf = (char *)malloc(sizeof(char)*(len+1));
00220 ERRCHK(buf, "malloc");
00221
00222 firstI = -1;
00223 for ( index = 0; index < len; index++ ) {
00224 switch( SIMPLE_ASCII_UPPER(pattern[index]) ) {
00225 case 'I':
00226 buf[index] = 'i';
00227 if (firstI == -1) firstI = index;
00228 break;
00229 case 'P':
00230 buf[index] = 'p';
00231 break;
00232 case 'B':
00233 buf[index] = 'b';
00234 break;
00235 default:
00236 fprintf(stderr, "Frame type '%c' not supported.\n", pattern[index]);
00237 exit(1);
00238 }
00239 }
00240 buf[len] = 0;
00241
00242 if (firstI == -1) {
00243 fprintf(stderr, "Must have an I-frame in PATTERN\n");
00244 exit(1);
00245 }
00246
00247 framePattern = buf;
00248 framePatternLen = len;
00249
00250
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 void
00266 ComputeFrameTable()
00267 {
00268 register int index;
00269 FrameTable *lastI, *lastIP, *firstB, *secondIP;
00270 FrameTable *ptr;
00271 char typ;
00272 int table_size;
00273
00274 if (!stdinUsed) {
00275 table_size = numInputFiles;
00276 } else {
00277 table_size = framePatternLen;
00278 }
00279
00280 frameTable = (FrameTable *) malloc((1+table_size)*sizeof(FrameTable));
00281 ERRCHK(frameTable, "malloc");
00282
00283 lastI = NULL;
00284 lastIP = NULL;
00285 firstB = NULL;
00286 secondIP = NULL;
00287 for ( index = 0; index < table_size; index++ ) {
00288 frameTable[index].number = index;
00289 typ = FType_Type(index);
00290 frameTable[index].typ = typ;
00291 switch( typ ) {
00292 case 'i':
00293 ptr = firstB;
00294 while ( ptr != NULL ) {
00295 ptr->next = &(frameTable[index]);
00296 ptr = ptr->nextOutput;
00297 }
00298 frameTable[index].nextOutput = firstB;
00299 frameTable[index].prev = lastIP;
00300 if ( lastIP != NULL ) {
00301 lastIP->next = &(frameTable[index]);
00302 if ( secondIP == NULL ) {
00303 secondIP = &(frameTable[index]);
00304 }
00305 }
00306 lastIP = &(frameTable[index]);
00307 firstB = NULL;
00308 break;
00309 case 'p':
00310 ptr = firstB;
00311 while ( ptr != NULL ) {
00312 ptr->next = &(frameTable[index]);
00313 ptr = ptr->nextOutput;
00314 }
00315 frameTable[index].nextOutput = firstB;
00316 frameTable[index].prev = lastIP;
00317 if ( lastIP != NULL ) {
00318 lastIP->next = &(frameTable[index]);
00319 if ( secondIP == NULL ) {
00320 secondIP = &(frameTable[index]);
00321 }
00322 }
00323 lastIP = &(frameTable[index]);
00324 firstB = NULL;
00325 break;
00326 case 'b':
00327 if ( (index+1 == framePatternLen) ||
00328 (FType_Type(index+1) != 'b') ) {
00329 frameTable[index].nextOutput = NULL;
00330 } else {
00331 frameTable[index].nextOutput = &(frameTable[index+1]);
00332 }
00333 frameTable[index].prev = lastIP;
00334 if ( firstB == NULL ) {
00335 firstB = &(frameTable[index]);
00336 }
00337 break;
00338 default:
00339 fprintf(stderr, "Programmer Error in ComputeFrameTable (%d)\n",
00340 framePattern[index]);
00341 exit(1);
00342 break;
00343 }
00344 }
00345
00346
00347 frameTable[table_size].number = framePatternLen;
00348 ptr = firstB;
00349 while ( ptr != NULL ) {
00350 ptr->next = &(frameTable[table_size]);
00351 ptr = ptr->nextOutput;
00352 }
00353 frameTable[table_size].nextOutput = firstB;
00354 frameTable[table_size].prev = lastIP;
00355 if ( secondIP == NULL )
00356 frameTable[table_size].next = &(frameTable[0]);
00357 else
00358 frameTable[table_size].next = secondIP;
00359
00360 frameTable[0].prev = lastIP;
00361 if ( lastIP != NULL ) {
00362 lastIP->next = &(frameTable[table_size]);
00363 }
00364
00365 if (!stdinUsed) {
00366 use_cache = TRUE;
00367 }
00368 }
00369