dvgrab patch supports playdv (libdv)
Brought to you by:
aeb,
bencollins
From: Alastair M. <ala...@aj...> - 2000-04-24 16:22:06
|
Hi, I modified dvgrab a bit (added an option) so that it can output files in a format that 'playdv' (part of libdv) will recognize directly. The patches are appended below, basically it adds a "--dv" option, i.e. dvgrab --ntsc --dv --frames 150 foo would write 150 frames to foo.dv, and then playdv foo.dv would display it. The performance of playdv has room for improvement: I get about 2 to 3 frames/second on my machine (a 233MHz winchip -- which supports MMX and 3DNow but otherwise has only about 156 bogoMips performance), this with the first release of libdv (I think there've been some improvements since). On other note -- the "pond.dv" file from the libdv folks seems to be recorded in progressive-scan mode, not interlaced. The interlaced data from my Sony TRV-103 that I've been testing with has a lot of motion (the camera was panning) so playdv spends about 40% of its time doing the 2-4-8 idct (and another 40% doing ycrcb->rgb conversion). To make the image look nicer at the low frame rate I added code to playdv to deinterlace the image just prior to display (basically just copy every second scan line to the previous one, effectively doubling the pixel height and halving the vertical resolution). I'm working on adding sound decoding now. --- here's the patch for dvgrab to output playdv-friendly files --- *** dvgrab.cc Tue Apr 18 12:28:24 2000 --- new/dvgrab.cc Fri Apr 21 23:43:22 2000 *************** *** 35,39 **** #define RAW_BUF_SIZE (10240) ! enum { PAL_FORMAT, NTSC_FORMAT, AVI_FORMAT, RAW_FORMAT, TEST_FORMAT, UNDEFINED }; int g_alldone; --- 35,39 ---- #define RAW_BUF_SIZE (10240) ! enum { PAL_FORMAT, NTSC_FORMAT, AVI_FORMAT, RAW_FORMAT, TEST_FORMAT, DV_FORMAT, UNDEFINED }; int g_alldone; *************** *** 129,133 **** } - int raw_iso_handler(raw1394handle_t handle, int channel, size_t length, quadlet_t *data) --- 129,132 ---- *************** *** 254,257 **** --- 253,258 ---- } else if (strcmp("--test", argv[i]) == 0) { g_file_format = TEST_FORMAT; + } else if (strcmp("--dv", argv[i]) == 0) { + g_file_format = DV_FORMAT; } else if (strcmp("--pal", argv[i]) == 0) { g_dv_format = PAL_FORMAT; *************** *** 567,575 **** frames_read = 0; while ((!g_alldone) && (frames_read < g_frame_count)) { raw1394_loop_iterate(handle); length = *(int*)g_frame; ! write(dst_fd, g_frame, length + 4); ! frames_read++; } close_1394_driver(handle); --- 568,631 ---- frames_read = 0; + + while ((!g_alldone) && (frames_read < g_frame_count)) { + raw1394_loop_iterate(handle); + length = *(int*)g_frame; + write(dst_fd, g_frame, length + 4); + frames_read++; + } + close_1394_driver(handle); + free(g_frame); + close(dst_fd); + + return 0; + } + + /* capture in a format suitable for playdv (part of libdv) */ + + int capture_dv() + { + int frames_read; + int length; + int dst_fd; + raw1394handle_t handle; + bool found_first_frame; + int skipped = 0; + + char filename[256]; + sprintf(filename, "%s.dv", g_dst_file_name); + if ((dst_fd = open(filename, O_WRONLY | O_CREAT, 00644)) < 0) { + perror("problem with output file"); + usage(); + exit(1); + } + + fail_null(g_frame = (unsigned char*)malloc(RAW_BUF_SIZE)); + + handle = open_1394_driver(g_channel, raw_iso_handler); + + frames_read = 0; + found_first_frame = false; + while ((!g_alldone) && (frames_read < g_frame_count)) { raw1394_loop_iterate(handle); length = *(int*)g_frame; ! if (length == 496) { ! if (!found_first_frame) { ! if (g_frame[16] == 0x1f && ! g_frame[17] == 0x07) ! found_first_frame = true; ! else skipped++; ! } ! if (skipped > 500) { ! printf("skipped too many without finding frame\n"); ! break; ! } ! if (found_first_frame) { ! write(dst_fd, (g_frame+16), length-16); ! if (g_frame[16] == 0x1f && g_frame[17] == 0x07) ! frames_read++; ! } ! } } close_1394_driver(handle); *************** *** 612,615 **** --- 668,675 ---- capture_avi(); break; + + case DV_FORMAT: + capture_dv(); + break; default: |