1// cc -o /tmp/gtf -g gtf.c -Wall 2 3 4#include <mach/mach.h> 5#include <mach/thread_switch.h> 6#include <sys/file.h> 7#include <sys/stat.h> 8#include <math.h> 9#include <unistd.h> 10#include <string.h> 11#include <stdio.h> 12#include <stdlib.h> 13 14 15__private_extern__ float 16ratioOver( float a, float b ) 17{ 18 if( a > b) 19 return( a / b ); 20 else 21 return( b / a ); 22} 23 24static int 25IODisplayGetCVTSyncWidth( int horizontalActive, int verticalActive ) 26{ 27 // CVT Table 2 28 enum { 29 kCVTAspect4By3 = 4, 30 kCVTAspect16By9 = 5, 31 kCVTAspect16By10 = 6, 32 kCVTAspect5By4 = 7, 33 kCVTAspect15By9 = 7, 34 kCVTAspectUnknown = 10 35 }; 36 37 float ratio = ((float) horizontalActive) / ((float) verticalActive); 38 39 if (ratioOver(ratio, 4.0 / 3.0) <= 1.03125) 40 return (kCVTAspect4By3); 41 42 if (ratioOver(ratio, 16.0 / 9.0) <= 1.03125) 43 return (kCVTAspect16By9); 44 45 if (ratioOver(ratio, 16.0 / 10.0) <= 1.03125) 46 return (kCVTAspect16By10); 47 48 if (ratioOver(ratio, 5.0 / 4.0) <= 1.03125) 49 return (kCVTAspect5By4); 50 51 if (ratioOver(ratio, 15.0 / 9.0) <= 1.03125) 52 return (kCVTAspect15By9); 53 54 return (kCVTAspectUnknown); 55} 56 57//FromRefreshRate 58// 7.3 59void GenTiming ( int requestedWidth, int requestedHeight, 60 float frameRate, boolean_t needInterlace, 61 int genType ) 62{ 63 int charSize = 8; 64 65 float m = 600; // % / kHz; 66 float c = 40; // % 67 float k = 128; 68 float j = 20; // % 69 70 float cPrime = ((c - j) * k / 256) + j; 71 float mPrime = k / 256 * m; 72 73 float fieldRate; // V_FIELD_RATE_RQD 74 // 7. 75 float interlace = needInterlace ? 0.5 : 0.0; 76 float interlaceFactor = needInterlace ? 2.0 : 1.0; 77 78 // 1. 79 fieldRate = frameRate * interlaceFactor; 80 81 // 3. 82 int leftMargin = 0; 83 int rightMargin = 0; 84 // 4. 85 int horizontalActive = roundf(requestedWidth / charSize) * charSize 86 + leftMargin + rightMargin; // TOTAL_ACTIVE_PIXELS 87 88 // 5. 89 int verticalActive = roundf(requestedHeight / interlaceFactor); // V_LINES_RND 90 // 6. 91 int topMargin = 0; 92 int bottomMargin = 0; 93 94 int verticalSyncWidth; // V_SYNC_RND 95 int verticalSyncAndBackPorch; // V_SYNC_BP 96 int verticalSyncFrontPorch; 97 int horizontalTotal; // TOTAL_PIXELS 98 int horizontalBlanking; // H_BLANK 99 int horizontalSyncWidth; // H_SYNC_PIXELS 100 101 102 if (0 == genType) 103 verticalSyncWidth = 3; 104 else 105 verticalSyncWidth = IODisplayGetCVTSyncWidth(horizontalActive, verticalActive * interlaceFactor); 106 107 if (0 == genType) /******************************* GTF */ 108 109 { 110 float horizontalSyncPercent = 8.0/100.0; // H_SYNC_PER 111 float verticalSyncAndBackPorchTime = 550e-6; // MIN_VSYNC_BP 112 int minVerticalFrontPorch = 1; // MIN_V_PORCH_RND 113 float estimatedHorizontalPeriod; // H_PERIOD_EST 114 float verticalFieldTotal; // TOTAL_V_LINES 115 float estimatedFieldRate; // V_FIELD_RATE_EST 116 117 // 7. 118 estimatedHorizontalPeriod = 119 ((1 / fieldRate) - verticalSyncAndBackPorchTime) 120 / (verticalActive + (2 * topMargin) + minVerticalFrontPorch + interlace); 121 122 // 8. 123 verticalSyncAndBackPorch = roundf(verticalSyncAndBackPorchTime / estimatedHorizontalPeriod); 124 verticalSyncFrontPorch = minVerticalFrontPorch; 125 126// printf("estimatedHorizontalPeriod %.9f us, verticalSyncAndBackPorch %d\n", 127// estimatedHorizontalPeriod*1e6, verticalSyncAndBackPorch); 128 129 // 10. 130 verticalFieldTotal = verticalActive + topMargin + bottomMargin 131 + verticalSyncAndBackPorch + interlace + minVerticalFrontPorch; 132 // 11. 133 estimatedFieldRate = 1.0 / estimatedHorizontalPeriod / verticalFieldTotal; 134 135// printf("verticalFieldTotal %.9f, estimatedFieldRate %.9f\n", 136// verticalFieldTotal, estimatedFieldRate); 137 138 // 12. 139 float hPeriod = estimatedHorizontalPeriod / (fieldRate / estimatedFieldRate); 140 141 printf("hPeriod %.9f us, ", hPeriod*1e6); 142 printf("hFreq %.9f kHz\n", 1/hPeriod/1e3); 143 144 // 18. 145 float idealDutyCycle = cPrime - (mPrime * hPeriod * 1e6 / 1000.0); 146 // 19. 147 horizontalBlanking = 2 * charSize * roundf( 148 (horizontalActive * idealDutyCycle / (100.0 - idealDutyCycle) 149 / (2 * charSize))); 150 151// printf("idealDutyCycle %.9f, horizontalBlanking %d\n", idealDutyCycle, horizontalBlanking); 152 153 // 20. 154 horizontalTotal = horizontalActive + horizontalBlanking; 155 // 21. 156 float pixelFreq = horizontalTotal / hPeriod; 157 158 printf("pixFreq %.9f Mhz\n", pixelFreq/1e6); 159 160 // gtf 2.17. 161 horizontalSyncWidth = roundf(horizontalSyncPercent * horizontalTotal / charSize) * charSize; 162 163 } 164 else if (1 == genType) /******************************* CVT */ 165 { 166 float horizontalSyncPercent = 8.0/100.0; // H_SYNC_PER 167 float verticalSyncAndBackPorchTime = 550e-6; // MIN_VSYNC_BP 168 int minVerticalBackPorch = 6; // MIN_VBPORCH 169 int minVerticalFrontPorch = 3; // MIN_V_PORCH_RND 170 float estimatedHorizontalPeriod; // H_PERIOD_EST 171 float verticalFieldTotal; // TOTAL_V_LINES 172 173 // 8. 174 estimatedHorizontalPeriod = 175 ((1 / fieldRate) - verticalSyncAndBackPorchTime) 176 / (verticalActive + (topMargin + bottomMargin) + minVerticalFrontPorch + interlace); 177 // 9. 178 179 verticalSyncAndBackPorch = 1 + truncf(verticalSyncAndBackPorchTime / estimatedHorizontalPeriod); 180 181 if (verticalSyncAndBackPorch < (verticalSyncWidth + minVerticalBackPorch)) 182 verticalSyncAndBackPorch = verticalSyncWidth + minVerticalBackPorch; 183 184 // 10. 185// int verticalSyncBackPorch = verticalSyncAndBackPorch - verticalSyncWidth; 186 187 verticalSyncFrontPorch = minVerticalFrontPorch; 188 189// printf("estimatedHorizontalPeriod %.9f us, verticalSyncAndBackPorch %d\n", 190// estimatedHorizontalPeriod*1e6, verticalSyncAndBackPorch); 191 192 // 11. 193 verticalFieldTotal = verticalActive + topMargin + bottomMargin 194 + verticalSyncAndBackPorch + interlace + minVerticalFrontPorch; 195 // 12. 196 float idealDutyCycle = cPrime - (mPrime * estimatedHorizontalPeriod * 1e6 / 1000.0); 197 198 // 13. 199 if (idealDutyCycle < 20.0) 200 idealDutyCycle = 20.0; 201 202 horizontalBlanking = 2 * charSize * truncf( 203 (horizontalActive * idealDutyCycle / (100.0 - idealDutyCycle) 204 / (2 * charSize))); 205 206 // 14. 207 horizontalTotal = horizontalActive + horizontalBlanking; 208 209 // 15. 210 float frequencyStep = 0.25e6; // CLOCK_STEP 211 float pixelFrequency = frequencyStep * truncf( 212 (horizontalTotal / estimatedHorizontalPeriod) / frequencyStep); 213 214 printf("pixFreq %.9f Mhz\n", pixelFrequency/1e6); 215 216 // 16. 217 float horizontalFrequency = pixelFrequency / horizontalTotal; 218 219 printf("hPeriod %.9f us, ", (1/horizontalFrequency)*1e6); 220 printf("hFreq %.9f kHz\n", horizontalFrequency/1e3); 221 222 // gtf 2.17. 223 horizontalSyncWidth = charSize * truncf( 224 horizontalSyncPercent * horizontalTotal / charSize); 225 226 } 227 else /******************************* CVT reduced blank */ 228 { 229 float minVerticalBlankTime = 460e-6; // RB_MIN_V_BLANK 230 float estimatedHorizontalPeriod; // H_PERIOD_EST 231 int verticalBlanking; // VBI_LINES 232 int minVerticalBackPorch = 6; // MIN_VBPORCH 233 234 verticalSyncFrontPorch = 3; // RB_V_FPORCH 235 horizontalBlanking = 160; // RB_H_BLANK 236 horizontalSyncWidth = 32; // RB_H_SYNC 237 238 // 8. 239 estimatedHorizontalPeriod = ((1 / fieldRate) - minVerticalBlankTime) 240 / (verticalActive + topMargin + bottomMargin); 241 // 9. 242 verticalBlanking = truncf(minVerticalBlankTime / estimatedHorizontalPeriod) + 1; // VBI_LINES 243 244// printf("estimatedHorizontalPeriod %.9f us, verticalBlanking %d\n", 245// estimatedHorizontalPeriod*1e6, verticalBlanking); 246 247 // 10. 248 if (verticalBlanking < (verticalSyncFrontPorch + verticalSyncWidth + minVerticalBackPorch)) 249 verticalBlanking = (verticalSyncFrontPorch + verticalSyncWidth + minVerticalBackPorch); 250 251 252 verticalSyncAndBackPorch = verticalBlanking - verticalSyncFrontPorch; 253 254 // 11. 255 int verticalFieldTotal = verticalBlanking + verticalActive 256 + topMargin + bottomMargin + interlace; 257 258 // 12. 259 horizontalTotal = horizontalActive + horizontalBlanking; 260 261 // 13. 262 float frequencyStep = 0.25e6; // CLOCK_STEP 263 float pixelFrequency = frequencyStep * truncf( 264 (horizontalTotal * verticalFieldTotal * fieldRate) / frequencyStep); 265 266 printf("pixFreq %.9f Mhz\n", pixelFrequency/1e6); 267 268 // 14. 269 float horizontalFrequency = pixelFrequency / horizontalTotal; 270 271 printf("hPeriod %.9f us, ", (1/horizontalFrequency)*1e6); 272 printf("hFreq %.9f kHz\n", horizontalFrequency/1e3); 273 274 } 275 276// printf("verticalFieldTotal %.9f, estimatedFieldRate %.9f\n", 277// verticalFieldTotal, estimatedFieldRate); 278// printf("idealDutyCycle %.9f, horizontalBlanking %d\n", 279// idealDutyCycle, horizontalBlanking); 280 281 // 17. 282// float vFieldRate = hFreq / verticalFieldTotal; 283 // 18. 284// float vFrameRate = vFieldRate / interlaceFactor; 285 286 // stage 2 287 288 // 3. 289 int verticalTotal = interlaceFactor * 290 (verticalActive + topMargin + bottomMargin 291 + verticalSyncAndBackPorch + interlace + verticalSyncFrontPorch); 292 293 int horizontalSyncOffset = (horizontalBlanking / 2) - horizontalSyncWidth; 294 // 30. 295 float verticalOddBlanking = verticalSyncAndBackPorch + verticalSyncFrontPorch; 296 // 32. 297 float verticalEvenBlanking = verticalSyncAndBackPorch + 2 * interlace + verticalSyncFrontPorch; 298 // 36. 299 float verticalSyncOddFrontPorch = verticalSyncFrontPorch + interlace; 300 301 printf("hTotal %d(%d), hFP %d(%d), hBlank %d(%d), hSync %d(%d)\n", 302 horizontalTotal/8, horizontalTotal, horizontalSyncOffset/8, 303 horizontalSyncOffset, horizontalBlanking/8, horizontalBlanking, 304 horizontalSyncWidth/8, horizontalSyncWidth); 305 306 printf("vTotal %d, vFP %.1f(E:%.1f), vBlank %.1f(E:%.1f), vSync %d\n\n", 307 verticalTotal, verticalSyncOddFrontPorch, (float) verticalSyncFrontPorch, 308 verticalOddBlanking, verticalEvenBlanking, verticalSyncWidth); 309 310} 311 312 313int main (int argc, char * argv[]) 314{ 315 char * endstr; 316 boolean_t needInterlace = FALSE; 317 int requestedWidth = 1400, requestedHeight = 1050; 318 float frameRate = 60.0; 319 320 requestedWidth = strtol(argv[1], 0, 0); 321 requestedHeight = strtol(argv[2], 0, 0); 322 frameRate = strtol(argv[3], &endstr, 0); 323 needInterlace = (endstr[0] == 'i') || (endstr[0] == 'I'); 324 325 printf("\nGTF:\n\n"); 326 GenTiming( requestedWidth, requestedHeight, frameRate, needInterlace, 0 ); 327 printf("\nCVT:\n\n"); 328 GenTiming( requestedWidth, requestedHeight, frameRate, needInterlace, 1 ); 329 printf("\nCVT reduced blank:\n\n"); 330 GenTiming( requestedWidth, requestedHeight, frameRate, needInterlace, 2 ); 331 332 return(0); 333} 334 335