Atlas - edid-parse.c

Home / ext / SDL2 / src / video / x11 Lines: 81 | Size: 19841 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 * Copyright 2007 Red Hat, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 23/* Author: Soren Sandmann <[email protected]> */ 24#include "../../SDL_internal.h" 25#include "SDL_stdinc.h" 26 27#include "edid.h" 28#include <stdlib.h> 29#include <string.h> 30#include <math.h> 31#include <stdio.h> 32 33#define TRUE 1 34#define FALSE 0 35 36static int 37get_bit (int in, int bit) 38{ 39 return (in & (1 << bit)) >> bit; 40} 41 42static int 43get_bits (int in, int begin, int end) 44{ 45 int mask = (1 << (end - begin + 1)) - 1; 46 47 return (in >> begin) & mask; 48} 49 50static int 51decode_header (const uchar *edid) 52{ 53 if (memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0) 54 return TRUE; 55 return FALSE; 56} 57 58static int 59decode_vendor_and_product_identification (const uchar *edid, MonitorInfo *info) 60{ 61 int is_model_year; 62 63 /* Manufacturer Code */ 64 info->manufacturer_code[0] = get_bits (edid[0x08], 2, 6); 65 info->manufacturer_code[1] = get_bits (edid[0x08], 0, 1) << 3; 66 info->manufacturer_code[1] |= get_bits (edid[0x09], 5, 7); 67 info->manufacturer_code[2] = get_bits (edid[0x09], 0, 4); 68 info->manufacturer_code[3] = '\0'; 69 70 info->manufacturer_code[0] += 'A' - 1; 71 info->manufacturer_code[1] += 'A' - 1; 72 info->manufacturer_code[2] += 'A' - 1; 73 74 /* Product Code */ 75 info->product_code = edid[0x0b] << 8 | edid[0x0a]; 76 77 /* Serial Number */ 78 info->serial_number = 79 edid[0x0c] | edid[0x0d] << 8 | edid[0x0e] << 16 | edid[0x0f] << 24; 80 81 /* Week and Year */ 82 is_model_year = FALSE; 83 switch (edid[0x10]) 84 { 85 case 0x00: 86 info->production_week = -1; 87 break; 88 89 case 0xff: 90 info->production_week = -1; 91 is_model_year = TRUE; 92 break; 93 94 default: 95 info->production_week = edid[0x10]; 96 break; 97 } 98 99 if (is_model_year) 100 { 101 info->production_year = -1; 102 info->model_year = 1990 + edid[0x11]; 103 } 104 else 105 { 106 info->production_year = 1990 + edid[0x11]; 107 info->model_year = -1; 108 } 109 110 return TRUE; 111} 112 113static int 114decode_edid_version (const uchar *edid, MonitorInfo *info) 115{ 116 info->major_version = edid[0x12]; 117 info->minor_version = edid[0x13]; 118 119 return TRUE; 120} 121 122static int 123decode_display_parameters (const uchar *edid, MonitorInfo *info) 124{ 125 /* Digital vs Analog */ 126 info->is_digital = get_bit (edid[0x14], 7); 127 128 if (info->is_digital) 129 { 130 int bits; 131 132 static const int bit_depth[8] = 133 { 134 -1, 6, 8, 10, 12, 14, 16, -1 135 }; 136 137 static const Interface interfaces[6] = 138 { 139 UNDEFINED, DVI, HDMI_A, HDMI_B, MDDI, DISPLAY_PORT 140 }; 141 142 bits = get_bits (edid[0x14], 4, 6); 143 info->ad.digital.bits_per_primary = bit_depth[bits]; 144 145 bits = get_bits (edid[0x14], 0, 3); 146 147 if (bits <= 5) 148 info->ad.digital.interface = interfaces[bits]; 149 else 150 info->ad.digital.interface = UNDEFINED; 151 } 152 else 153 { 154 int bits = get_bits (edid[0x14], 5, 6); 155 156 static const double levels[][3] = 157 { 158 { 0.7, 0.3, 1.0 }, 159 { 0.714, 0.286, 1.0 }, 160 { 1.0, 0.4, 1.4 }, 161 { 0.7, 0.0, 0.7 }, 162 }; 163 164 info->ad.analog.video_signal_level = levels[bits][0]; 165 info->ad.analog.sync_signal_level = levels[bits][1]; 166 info->ad.analog.total_signal_level = levels[bits][2]; 167 168 info->ad.analog.blank_to_black = get_bit (edid[0x14], 4); 169 170 info->ad.analog.separate_hv_sync = get_bit (edid[0x14], 3); 171 info->ad.analog.composite_sync_on_h = get_bit (edid[0x14], 2); 172 info->ad.analog.composite_sync_on_green = get_bit (edid[0x14], 1); 173 174 info->ad.analog.serration_on_vsync = get_bit (edid[0x14], 0); 175 } 176 177 /* Screen Size / Aspect Ratio */ 178 if (edid[0x15] == 0 && edid[0x16] == 0) 179 { 180 info->width_mm = -1; 181 info->height_mm = -1; 182 info->aspect_ratio = -1.0; 183 } 184 else if (edid[0x16] == 0) 185 { 186 info->width_mm = -1; 187 info->height_mm = -1; 188 info->aspect_ratio = 100.0 / (edid[0x15] + 99); 189 } 190 else if (edid[0x15] == 0) 191 { 192 info->width_mm = -1; 193 info->height_mm = -1; 194 info->aspect_ratio = 100.0 / (edid[0x16] + 99); 195 info->aspect_ratio = 1/info->aspect_ratio; /* portrait */ 196 } 197 else 198 { 199 info->width_mm = 10 * edid[0x15]; 200 info->height_mm = 10 * edid[0x16]; 201 } 202 203 /* Gamma */ 204 if (edid[0x17] == 0xFF) 205 info->gamma = -1.0; 206 else 207 info->gamma = (edid[0x17] + 100.0) / 100.0; 208 209 /* Features */ 210 info->standby = get_bit (edid[0x18], 7); 211 info->suspend = get_bit (edid[0x18], 6); 212 info->active_off = get_bit (edid[0x18], 5); 213 214 if (info->is_digital) 215 { 216 info->ad.digital.rgb444 = TRUE; 217 if (get_bit (edid[0x18], 3)) 218 info->ad.digital.ycrcb444 = 1; 219 if (get_bit (edid[0x18], 4)) 220 info->ad.digital.ycrcb422 = 1; 221 } 222 else 223 { 224 int bits = get_bits (edid[0x18], 3, 4); 225 ColorType color_type[4] = 226 { 227 MONOCHROME, RGB, OTHER_COLOR, UNDEFINED_COLOR 228 }; 229 230 info->ad.analog.color_type = color_type[bits]; 231 } 232 233 info->srgb_is_standard = get_bit (edid[0x18], 2); 234 235 /* In 1.3 this is called "has preferred timing" */ 236 info->preferred_timing_includes_native = get_bit (edid[0x18], 1); 237 238 /* FIXME: In 1.3 this indicates whether the monitor accepts GTF */ 239 info->continuous_frequency = get_bit (edid[0x18], 0); 240 return TRUE; 241} 242 243static double 244decode_fraction (int high, int low) 245{ 246 double result = 0.0; 247 int i; 248 249 high = (high << 2) | low; 250 251 for (i = 0; i < 10; ++i) 252 result += get_bit (high, i) * SDL_pow (2, i - 10); 253 254 return result; 255} 256 257static int 258decode_color_characteristics (const uchar *edid, MonitorInfo *info) 259{ 260 info->red_x = decode_fraction (edid[0x1b], get_bits (edid[0x19], 6, 7)); 261 info->red_y = decode_fraction (edid[0x1c], get_bits (edid[0x19], 5, 4)); 262 info->green_x = decode_fraction (edid[0x1d], get_bits (edid[0x19], 2, 3)); 263 info->green_y = decode_fraction (edid[0x1e], get_bits (edid[0x19], 0, 1)); 264 info->blue_x = decode_fraction (edid[0x1f], get_bits (edid[0x1a], 6, 7)); 265 info->blue_y = decode_fraction (edid[0x20], get_bits (edid[0x1a], 4, 5)); 266 info->white_x = decode_fraction (edid[0x21], get_bits (edid[0x1a], 2, 3)); 267 info->white_y = decode_fraction (edid[0x22], get_bits (edid[0x1a], 0, 1)); 268 269 return TRUE; 270} 271 272static int 273decode_established_timings (const uchar *edid, MonitorInfo *info) 274{ 275 static const Timing established[][8] = 276 { 277 { 278 { 800, 600, 60 }, 279 { 800, 600, 56 }, 280 { 640, 480, 75 }, 281 { 640, 480, 72 }, 282 { 640, 480, 67 }, 283 { 640, 480, 60 }, 284 { 720, 400, 88 }, 285 { 720, 400, 70 } 286 }, 287 { 288 { 1280, 1024, 75 }, 289 { 1024, 768, 75 }, 290 { 1024, 768, 70 }, 291 { 1024, 768, 60 }, 292 { 1024, 768, 87 }, 293 { 832, 624, 75 }, 294 { 800, 600, 75 }, 295 { 800, 600, 72 } 296 }, 297 { 298 { 0, 0, 0 }, 299 { 0, 0, 0 }, 300 { 0, 0, 0 }, 301 { 0, 0, 0 }, 302 { 0, 0, 0 }, 303 { 0, 0, 0 }, 304 { 0, 0, 0 }, 305 { 1152, 870, 75 } 306 }, 307 }; 308 309 int i, j, idx; 310 311 idx = 0; 312 for (i = 0; i < 3; ++i) 313 { 314 for (j = 0; j < 8; ++j) 315 { 316 int byte = edid[0x23 + i]; 317 318 if (get_bit (byte, j) && established[i][j].frequency != 0) 319 info->established[idx++] = established[i][j]; 320 } 321 } 322 return TRUE; 323} 324 325static int 326decode_standard_timings (const uchar *edid, MonitorInfo *info) 327{ 328 int i; 329 330 for (i = 0; i < 8; i++) 331 { 332 int first = edid[0x26 + 2 * i]; 333 int second = edid[0x27 + 2 * i]; 334 335 if (first != 0x01 && second != 0x01) 336 { 337 int w = 8 * (first + 31); 338 int h = 0; 339 340 switch (get_bits (second, 6, 7)) 341 { 342 case 0x00: h = (w / 16) * 10; break; 343 case 0x01: h = (w / 4) * 3; break; 344 case 0x02: h = (w / 5) * 4; break; 345 case 0x03: h = (w / 16) * 9; break; 346 } 347 348 info->standard[i].width = w; 349 info->standard[i].height = h; 350 info->standard[i].frequency = get_bits (second, 0, 5) + 60; 351 } 352 } 353 354 return TRUE; 355} 356 357static void 358decode_lf_string (const uchar *s, int n_chars, char *result) 359{ 360 int i; 361 for (i = 0; i < n_chars; ++i) 362 { 363 if (s[i] == 0x0a) 364 { 365 *result++ = '\0'; 366 break; 367 } 368 else if (s[i] == 0x00) 369 { 370 /* Convert embedded 0's to spaces */ 371 *result++ = ' '; 372 } 373 else 374 { 375 *result++ = s[i]; 376 } 377 } 378} 379 380static void 381decode_display_descriptor (const uchar *desc, 382 MonitorInfo *info) 383{ 384 switch (desc[0x03]) 385 { 386 case 0xFC: 387 decode_lf_string (desc + 5, 13, info->dsc_product_name); 388 break; 389 case 0xFF: 390 decode_lf_string (desc + 5, 13, info->dsc_serial_number); 391 break; 392 case 0xFE: 393 decode_lf_string (desc + 5, 13, info->dsc_string); 394 break; 395 case 0xFD: 396 /* Range Limits */ 397 break; 398 case 0xFB: 399 /* Color Point */ 400 break; 401 case 0xFA: 402 /* Timing Identifications */ 403 break; 404 case 0xF9: 405 /* Color Management */ 406 break; 407 case 0xF8: 408 /* Timing Codes */ 409 break; 410 case 0xF7: 411 /* Established Timings */ 412 break; 413 case 0x10: 414 break; 415 } 416} 417 418static void 419decode_detailed_timing (const uchar *timing, 420 DetailedTiming *detailed) 421{ 422 int bits; 423 StereoType stereo[] = 424 { 425 NO_STEREO, NO_STEREO, FIELD_RIGHT, FIELD_LEFT, 426 TWO_WAY_RIGHT_ON_EVEN, TWO_WAY_LEFT_ON_EVEN, 427 FOUR_WAY_INTERLEAVED, SIDE_BY_SIDE 428 }; 429 430 detailed->pixel_clock = (timing[0x00] | timing[0x01] << 8) * 10000; 431 detailed->h_addr = timing[0x02] | ((timing[0x04] & 0xf0) << 4); 432 detailed->h_blank = timing[0x03] | ((timing[0x04] & 0x0f) << 8); 433 detailed->v_addr = timing[0x05] | ((timing[0x07] & 0xf0) << 4); 434 detailed->v_blank = timing[0x06] | ((timing[0x07] & 0x0f) << 8); 435 detailed->h_front_porch = timing[0x08] | get_bits (timing[0x0b], 6, 7) << 8; 436 detailed->h_sync = timing[0x09] | get_bits (timing[0x0b], 4, 5) << 8; 437 detailed->v_front_porch = 438 get_bits (timing[0x0a], 4, 7) | get_bits (timing[0x0b], 2, 3) << 4; 439 detailed->v_sync = 440 get_bits (timing[0x0a], 0, 3) | get_bits (timing[0x0b], 0, 1) << 4; 441 detailed->width_mm = timing[0x0c] | get_bits (timing[0x0e], 4, 7) << 8; 442 detailed->height_mm = timing[0x0d] | get_bits (timing[0x0e], 0, 3) << 8; 443 detailed->right_border = timing[0x0f]; 444 detailed->top_border = timing[0x10]; 445 446 detailed->interlaced = get_bit (timing[0x11], 7); 447 448 /* Stereo */ 449 bits = get_bits (timing[0x11], 5, 6) << 1 | get_bit (timing[0x11], 0); 450 detailed->stereo = stereo[bits]; 451 452 /* Sync */ 453 bits = timing[0x11]; 454 455 detailed->digital_sync = get_bit (bits, 4); 456 if (detailed->digital_sync) 457 { 458 detailed->ad.digital.composite = !get_bit (bits, 3); 459 460 if (detailed->ad.digital.composite) 461 { 462 detailed->ad.digital.serrations = get_bit (bits, 2); 463 detailed->ad.digital.negative_vsync = FALSE; 464 } 465 else 466 { 467 detailed->ad.digital.serrations = FALSE; 468 detailed->ad.digital.negative_vsync = !get_bit (bits, 2); 469 } 470 471 detailed->ad.digital.negative_hsync = !get_bit (bits, 0); 472 } 473 else 474 { 475 detailed->ad.analog.bipolar = get_bit (bits, 3); 476 detailed->ad.analog.serrations = get_bit (bits, 2); 477 detailed->ad.analog.sync_on_green = !get_bit (bits, 1); 478 } 479} 480 481static int 482decode_descriptors (const uchar *edid, MonitorInfo *info) 483{ 484 int i; 485 int timing_idx; 486 487 timing_idx = 0; 488 489 for (i = 0; i < 4; ++i) 490 { 491 int index = 0x36 + i * 18; 492 493 if (edid[index + 0] == 0x00 && edid[index + 1] == 0x00) 494 { 495 decode_display_descriptor (edid + index, info); 496 } 497 else 498 { 499 decode_detailed_timing ( 500 edid + index, &(info->detailed_timings[timing_idx++])); 501 } 502 } 503 504 info->n_detailed_timings = timing_idx; 505 506 return TRUE; 507} 508 509static void 510decode_check_sum (const uchar *edid, 511 MonitorInfo *info) 512{ 513 int i; 514 uchar check = 0; 515 516 for (i = 0; i < 128; ++i) 517 check += edid[i]; 518 519 info->checksum = check; 520} 521 522MonitorInfo * 523decode_edid (const uchar *edid) 524{ 525 MonitorInfo *info = calloc (1, sizeof (MonitorInfo)); 526 527 decode_check_sum (edid, info); 528 529 if (!decode_header (edid) || 530 !decode_vendor_and_product_identification (edid, info) || 531 !decode_edid_version (edid, info) || 532 !decode_display_parameters (edid, info) || 533 !decode_color_characteristics (edid, info) || 534 !decode_established_timings (edid, info) || 535 !decode_standard_timings (edid, info) || 536 !decode_descriptors (edid, info)) { 537 free(info); 538 return NULL; 539 } 540 541 return info; 542} 543 544static const char * 545yesno (int v) 546{ 547 return v? "yes" : "no"; 548} 549 550void 551dump_monitor_info (MonitorInfo *info) 552{ 553 int i; 554 555 printf ("Checksum: %d (%s)\n", 556 info->checksum, info->checksum? "incorrect" : "correct"); 557 printf ("Manufacturer Code: %s\n", info->manufacturer_code); 558 printf ("Product Code: 0x%x\n", info->product_code); 559 printf ("Serial Number: %u\n", info->serial_number); 560 561 if (info->production_week != -1) 562 printf ("Production Week: %d\n", info->production_week); 563 else 564 printf ("Production Week: unspecified\n"); 565 566 if (info->production_year != -1) 567 printf ("Production Year: %d\n", info->production_year); 568 else 569 printf ("Production Year: unspecified\n"); 570 571 if (info->model_year != -1) 572 printf ("Model Year: %d\n", info->model_year); 573 else 574 printf ("Model Year: unspecified\n"); 575 576 printf ("EDID revision: %d.%d\n", info->major_version, info->minor_version); 577 578 printf ("Display is %s\n", info->is_digital? "digital" : "analog"); 579 if (info->is_digital) 580 { 581 const char *interface; 582 if (info->ad.digital.bits_per_primary != -1) 583 printf ("Bits Per Primary: %d\n", info->ad.digital.bits_per_primary); 584 else 585 printf ("Bits Per Primary: undefined\n"); 586 587 switch (info->ad.digital.interface) 588 { 589 case DVI: interface = "DVI"; break; 590 case HDMI_A: interface = "HDMI-a"; break; 591 case HDMI_B: interface = "HDMI-b"; break; 592 case MDDI: interface = "MDDI"; break; 593 case DISPLAY_PORT: interface = "DisplayPort"; break; 594 case UNDEFINED: interface = "undefined"; break; 595 default: interface = "unknown"; break; 596 } 597 printf ("Interface: %s\n", interface); 598 599 printf ("RGB 4:4:4: %s\n", yesno (info->ad.digital.rgb444)); 600 printf ("YCrCb 4:4:4: %s\n", yesno (info->ad.digital.ycrcb444)); 601 printf ("YCrCb 4:2:2: %s\n", yesno (info->ad.digital.ycrcb422)); 602 } 603 else 604 { 605 const char *s; 606 printf ("Video Signal Level: %f\n", info->ad.analog.video_signal_level); 607 printf ("Sync Signal Level: %f\n", info->ad.analog.sync_signal_level); 608 printf ("Total Signal Level: %f\n", info->ad.analog.total_signal_level); 609 610 printf ("Blank to Black: %s\n", 611 yesno (info->ad.analog.blank_to_black)); 612 printf ("Separate HV Sync: %s\n", 613 yesno (info->ad.analog.separate_hv_sync)); 614 printf ("Composite Sync on H: %s\n", 615 yesno (info->ad.analog.composite_sync_on_h)); 616 printf ("Serration on VSync: %s\n", 617 yesno (info->ad.analog.serration_on_vsync)); 618 619 switch (info->ad.analog.color_type) 620 { 621 case UNDEFINED_COLOR: s = "undefined"; break; 622 case MONOCHROME: s = "monochrome"; break; 623 case RGB: s = "rgb"; break; 624 case OTHER_COLOR: s = "other color"; break; 625 default: s = "unknown"; break; 626 }; 627 628 printf ("Color: %s\n", s); 629 } 630 631 if (info->width_mm == -1) 632 printf ("Width: undefined\n"); 633 else 634 printf ("Width: %d mm\n", info->width_mm); 635 636 if (info->height_mm == -1) 637 printf ("Height: undefined\n"); 638 else 639 printf ("Height: %d mm\n", info->height_mm); 640 641 if (info->aspect_ratio > 0) 642 printf ("Aspect Ratio: %f\n", info->aspect_ratio); 643 else 644 printf ("Aspect Ratio: undefined\n"); 645 646 if (info->gamma >= 0) 647 printf ("Gamma: %f\n", info->gamma); 648 else 649 printf ("Gamma: undefined\n"); 650 651 printf ("Standby: %s\n", yesno (info->standby)); 652 printf ("Suspend: %s\n", yesno (info->suspend)); 653 printf ("Active Off: %s\n", yesno (info->active_off)); 654 655 printf ("SRGB is Standard: %s\n", yesno (info->srgb_is_standard)); 656 printf ("Preferred Timing Includes Native: %s\n", 657 yesno (info->preferred_timing_includes_native)); 658 printf ("Continuous Frequency: %s\n", yesno (info->continuous_frequency)); 659 660 printf ("Red X: %f\n", info->red_x); 661 printf ("Red Y: %f\n", info->red_y); 662 printf ("Green X: %f\n", info->green_x); 663 printf ("Green Y: %f\n", info->green_y); 664 printf ("Blue X: %f\n", info->blue_x); 665 printf ("Blue Y: %f\n", info->blue_y); 666 printf ("White X: %f\n", info->white_x); 667 printf ("White Y: %f\n", info->white_y); 668 669 printf ("Established Timings:\n"); 670 671 for (i = 0; i < 24; ++i) 672 { 673 Timing *timing = &(info->established[i]); 674 675 if (timing->frequency == 0) 676 break; 677 678 printf (" %d x %d @ %d Hz\n", 679 timing->width, timing->height, timing->frequency); 680 681 } 682 683 printf ("Standard Timings:\n"); 684 for (i = 0; i < 8; ++i) 685 { 686 Timing *timing = &(info->standard[i]); 687 688 if (timing->frequency == 0) 689 break; 690 691 printf (" %d x %d @ %d Hz\n", 692 timing->width, timing->height, timing->frequency); 693 } 694 695 for (i = 0; i < info->n_detailed_timings; ++i) 696 { 697 DetailedTiming *timing = &(info->detailed_timings[i]); 698 const char *s; 699 700 printf ("Timing%s: \n", 701 (i == 0 && info->preferred_timing_includes_native)? 702 " (Preferred)" : ""); 703 printf (" Pixel Clock: %d\n", timing->pixel_clock); 704 printf (" H Addressable: %d\n", timing->h_addr); 705 printf (" H Blank: %d\n", timing->h_blank); 706 printf (" H Front Porch: %d\n", timing->h_front_porch); 707 printf (" H Sync: %d\n", timing->h_sync); 708 printf (" V Addressable: %d\n", timing->v_addr); 709 printf (" V Blank: %d\n", timing->v_blank); 710 printf (" V Front Porch: %d\n", timing->v_front_porch); 711 printf (" V Sync: %d\n", timing->v_sync); 712 printf (" Width: %d mm\n", timing->width_mm); 713 printf (" Height: %d mm\n", timing->height_mm); 714 printf (" Right Border: %d\n", timing->right_border); 715 printf (" Top Border: %d\n", timing->top_border); 716 switch (timing->stereo) 717 { 718 default: 719 case NO_STEREO: s = "No Stereo"; break; 720 case FIELD_RIGHT: s = "Field Sequential, Right on Sync"; break; 721 case FIELD_LEFT: s = "Field Sequential, Left on Sync"; break; 722 case TWO_WAY_RIGHT_ON_EVEN: s = "Two-way, Right on Even"; break; 723 case TWO_WAY_LEFT_ON_EVEN: s = "Two-way, Left on Even"; break; 724 case FOUR_WAY_INTERLEAVED: s = "Four-way Interleaved"; break; 725 case SIDE_BY_SIDE: s = "Side-by-Side"; break; 726 } 727 printf (" Stereo: %s\n", s); 728 729 if (timing->digital_sync) 730 { 731 printf (" Digital Sync:\n"); 732 printf (" composite: %s\n", yesno (timing->ad.digital.composite)); 733 printf (" serrations: %s\n", yesno (timing->ad.digital.serrations)); 734 printf (" negative vsync: %s\n", 735 yesno (timing->ad.digital.negative_vsync)); 736 printf (" negative hsync: %s\n", 737 yesno (timing->ad.digital.negative_hsync)); 738 } 739 else 740 { 741 printf (" Analog Sync:\n"); 742 printf (" bipolar: %s\n", yesno (timing->ad.analog.bipolar)); 743 printf (" serrations: %s\n", yesno (timing->ad.analog.serrations)); 744 printf (" sync on green: %s\n", yesno ( 745 timing->ad.analog.sync_on_green)); 746 } 747 } 748 749 printf ("Detailed Product information:\n"); 750 printf (" Product Name: %s\n", info->dsc_product_name); 751 printf (" Serial Number: %s\n", info->dsc_serial_number); 752 printf (" Unspecified String: %s\n", info->dsc_string); 753} 754 755
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.