static int read_chd(void *file, int frame, bitmap_yuy16 &bitmap, INT16 *lsound, INT16 *rsound, int &samples) { chd_file *chdfile = reinterpret_cast<chd_file *>(file); // loop over fields int interlace_factor = chdinterlaced ? 2 : 1; samples = 0; for (int fieldnum = 0; fieldnum < interlace_factor; fieldnum++) { // make a fake bitmap for this field avhuff_decompress_config avconfig; avconfig.video.wrap(&bitmap.pix16(fieldnum), bitmap.width(), bitmap.height() / interlace_factor, bitmap.rowpixels() * interlace_factor); // configure the codec UINT32 numsamples; avconfig.maxsamples = 48000; avconfig.actsamples = &numsamples; avconfig.audio[0] = &lsound[samples]; avconfig.audio[1] = &rsound[samples]; // configure the decompressor for this frame chdfile->codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig); // read the frame chd_error chderr = chdfile->read_hunk(frame * interlace_factor + fieldnum, NULL); if (chderr != CHDERR_NONE) return false; // account for samples read samples += numsamples; } return true; }
static int read_chd(void *file, int frame, bitmap_yuy16 &bitmap, INT16 *lsound, INT16 *rsound, int *samples) { av_codec_decompress_config avconfig; int interlace_factor = chdinterlaced ? 2 : 1; bitmap_yuy16 fakebitmap; UINT32 numsamples; chd_error chderr; int fieldnum; /* loop over fields */ *samples = 0; for (fieldnum = 0; fieldnum < interlace_factor; fieldnum++) { /* make a fake bitmap for this field */ avconfig.video.wrap(&bitmap.pix16(fieldnum), bitmap.width(), bitmap.height() / interlace_factor, bitmap.rowpixels() * interlace_factor); /* configure the codec */ avconfig.maxsamples = 48000; avconfig.actsamples = &numsamples; avconfig.audio[0] = &lsound[*samples]; avconfig.audio[1] = &rsound[*samples]; /* configure the decompressor for this frame */ chd_codec_config((chd_file *)file, AV_CODEC_DECOMPRESS_CONFIG, &avconfig); /* read the frame */ chderr = chd_read((chd_file *)file, frame * interlace_factor + fieldnum, NULL); if (chderr != CHDERR_NONE) return FALSE; /* account for samples read */ *samples += numsamples; } return TRUE; }
void laserdisc_device::fillbitmap_yuy16(bitmap_yuy16 &bitmap, UINT8 yval, UINT8 cr, UINT8 cb) { UINT16 color0 = (yval << 8) | cb; UINT16 color1 = (yval << 8) | cr; // write 32 bits of color (2 pixels at a time) for (int y = 0; y < bitmap.height(); y++) { UINT16 *dest = &bitmap.pix16(y); for (int x = 0; x < bitmap.width() / 2; x++) { *dest++ = color0; *dest++ = color1; } } }
void laserdisc_device::fillbitmap_yuy16(bitmap_yuy16 &bitmap, uint8_t yval, uint8_t cr, uint8_t cb) { uint16_t color0 = (yval << 8) | cb; uint16_t color1 = (yval << 8) | cr; // write 32 bits of color (2 pixels at a time) for (int y = 0; y < bitmap.height(); y++) { uint16_t *dest = &bitmap.pix16(y); for (int x = 0; x < bitmap.width() / 2; x++) { *dest++ = color0; *dest++ = color1; } } }
static void verify_video(video_info &video, int frame, bitmap_yuy16 &bitmap) { // loop over fields const int fields_per_frame = 2; for (int fieldnum = 0; fieldnum < fields_per_frame; fieldnum++) { // output status if (frame % 10 == 0 && fieldnum == 0) fprintf(stderr, "%6d.%d...\r", frame, fieldnum); // parse the VBI data vbi_metadata metadata; vbi_parse_all(&bitmap.pix16(fieldnum), bitmap.rowpixels() * 2, bitmap.width(), 8, &metadata); // if we have data in both 17 and 18, it should match if (metadata.line17 != 0 && metadata.line18 != 0 && metadata.line17 != metadata.line18) { printf("%6d.%d: line 17 and 18 data does not match (17=%06X 18=%06X) (WARNING)\n", frame, fieldnum, metadata.line17, metadata.line18); printf("%6d.%d: selected %06X based on bit confidence\n", frame, fieldnum, metadata.line1718); } // is this a lead-in code? if (metadata.line1718 == VBI_CODE_LEADIN) { // if we haven't seen lead-in yet, detect it if (!video.saw_leadin) { video.saw_leadin = TRUE; printf("%6d.%d: lead-in code detected\n", frame, fieldnum); } // if we've previously seen chapters/frames, that's weird if (video.last_frame != -1 || video.last_chapter != -1) printf("%6d.%d: lead-in code detected after frame/chapter data (WARNING)\n", frame, fieldnum); } // is this a lead-out code? if (metadata.line1718 == VBI_CODE_LEADOUT) { // if we haven't seen lead-in yet, detect it if (!video.saw_leadout) { video.saw_leadout = TRUE; printf("%6d.%d: lead-out code detected\n", frame, fieldnum); if (video.last_frame != -1) printf("%6d.%d: final frame number was %d\n", frame, fieldnum, video.last_frame); else printf("%6d.%d: never detected any frame numbers (ERROR)\n", frame, fieldnum); } // if we've previously seen chapters/frames, that's weird if (video.last_frame == -1) printf("%6d.%d: lead-out code detected with no frames detected beforehand (WARNING)\n", frame, fieldnum); } // is this a frame code? if ((metadata.line1718 & VBI_MASK_CAV_PICTURE) == VBI_CODE_CAV_PICTURE) { int framenum = VBI_CAV_PICTURE(metadata.line1718); // did we see any leadin? if (!video.saw_leadin) { printf("%6d.%d: detected frame number but never saw any lead-in (WARNING)\n", frame, fieldnum); video.saw_leadin = TRUE; } // if this is the first frame, make sure it's 1 if (video.last_frame == -1) { if (framenum == 0) printf("%6d.%d: detected frame 0\n", frame, fieldnum); else if (framenum == 1) printf("%6d.%d: detected frame 1\n", frame, fieldnum); else printf("%6d.%d: first frame number is not 0 or 1 (%d) (ERROR)\n", frame, fieldnum, framenum); } // print an update every 10000 frames if (framenum != 0 && framenum % 10000 == 0) printf("%6d.%d: detected frame %d\n", frame, fieldnum, framenum); // if this frame is not consecutive, it's an error if (video.last_frame != -1 && framenum != video.last_frame + 1) printf("%6d.%d: gap in frame number sequence (%d->%d) (ERROR)\n", frame, fieldnum, video.last_frame, framenum); // remember the frame number video.last_frame = framenum; // if we've seen a white flag before, but it's not here, warn if (video.first_whitefield != -1 && !metadata.white) printf("%6d.%d: detected frame number but no white flag (WARNING)\n", frame, fieldnum); } // is the whiteflag set? int field = frame * fields_per_frame + fieldnum; if (metadata.white) { // if this is the first white flag we see, count it if (video.first_whitefield == -1) { video.first_whitefield = field; printf("%6d.%d: first white flag seen\n", frame, fieldnum); } // if we've seen frame numbers before, but not here, warn if (video.last_frame != -1 && (metadata.line1718 & VBI_MASK_CAV_PICTURE) != VBI_CODE_CAV_PICTURE) printf("%6d.%d: detected white flag but no frame number (WARNING)\n", frame, fieldnum); } // if this is the start of a frame, handle cadence if (metadata.white || (metadata.line1718 & VBI_MASK_CAV_PICTURE) == VBI_CODE_CAV_PICTURE) { // if we've seen frames, but we're not yet to the lead-out, check the cadence if (video.last_frame != -1 && !video.saw_leadout) { // make sure we have a proper history if (video.prev_whitefield != -1) video.cadence_history = (video.cadence_history << 4) | ((field - video.prev_whitefield) & 0x0f); video.prev_whitefield = field; // if we don't know our cadence yet, determine it if (video.cadence == -1 && (video.cadence_history & 0xf00) != 0) { if ((video.cadence_history & 0xfff) == 0x222) { printf("%6d.%d: detected 2:2 cadence\n", frame, fieldnum); video.cadence = 4; } else if ((video.cadence_history & 0xfff) == 0x323) { printf("%6d.%d: detected 3:2 cadence\n", frame, fieldnum); video.cadence = 5; } else if ((video.cadence_history & 0xfff) == 0x232) { printf("%6d.%d: detected 2:3 cadence\n", frame, fieldnum); video.cadence = 5; } else { printf("%6d.%d: unknown cadence (history %d:%d:%d) (WARNING)\n", frame, fieldnum, (video.cadence_history >> 8) & 15, (video.cadence_history >> 4) & 15, video.cadence_history & 15); } } // if we know our cadence, make sure we stick to it if (video.cadence != -1) { if (video.cadence == 4 && (video.cadence_history & 0xfff) != 0x222) { printf("%6d.%d: missed cadence (history %d:%d:%d) (WARNING)\n", frame, fieldnum, (video.cadence_history >> 8) & 15, (video.cadence_history >> 4) & 15, video.cadence_history & 15); video.cadence = -1; video.cadence_history = 0; } else if (video.cadence == 5 && (video.cadence_history & 0xfff) != 0x323 && (video.cadence_history & 0xfff) != 0x232) { printf("%6d.%d: missed cadence (history %d:%d:%d) (WARNING)\n", frame, fieldnum, (video.cadence_history >> 8) & 15, (video.cadence_history >> 4) & 15, video.cadence_history & 15); video.cadence = -1; video.cadence_history = 0; } } }