cev.sdf.org ...

About & contact, blog, blog archive, github, mastodon, now, or e-mail me: cev@sdf.org.


Tron (1982)

1980s, scifi, screenshot, vhs, video // 2017-08-06

The TV announcer voice says: And now: Tron. Starring Jeff Bridges and Bruce Boxleitner.

Tron Title Title card indicating the film has been edited.
Fox49 KPDX notice at bottom of screen

Taped off TV - Fox 49 KPDX - some time in 1995. (There's an advertisement for the Jerky Boys movie during one of the commercial breaks, which conveniently dates the broadcast). The screenshots you see here are of an x264 (CRF 23) digital recording of an EP Mode VHS tape. I wonder how many generations down the line this is.

This is how I've always watched Tron. Low-res, 4:3 pan & scan, edited, with commercials.

Clu in tank Light glider Tron presents an identity disc

Odin Photon Space Sailer Starlight

1980s, anime, scifi, screenshot, vhs, video // 2017-04-04

Odin: Photon Space Sailer Starlight, 1985. Taped off the Sci-Fi channel some time in the '90s. Subsequently copied and recopied; screenshots below are from a digital recording of a beat up EP mode VHS tape.

Concert on the Bridge Feels Like A Typhoon
Odin Awaits You

An infamously bad movie with some beautiful visuals. Remembered as a boring rehash of ideas and imagery better presented in Space Battleship Yamato. Features a couple of songs ("Gotta Fight", "Odin") by Loudness.

See the Anime World Order podcast for a great discussion of this movie (and how terrible it is).

Lovely World D23 RR499
Mizzenmast

What's Your Pleasure?

1980s, horror, screenshot, vhs, video // 2016-12-18

Screengrab from the end of Hellraiser

Hellraiser, 1987, VHS. Second generation, dubbed onto a "Hollywood Video" branded tape. Subtitles from opensubtitles. The VCR used for playback during the dubbing process left a little gift you can see below. Fortunately it only happens once during the movie.

Second screengrab from Hellraiser


FFmpeg, bktr, and frame read timing

freebsd, screenshot, vhs, video // 2016-12-16

An incorrectly captured video frame Real video frame A
Real video frame B

There's something wrong with the picture on the left.

Freebsd bktr(4), as configured by libavdevice/bktr.c, reads data coming off the card, fills a memory buffer, then signals libavdevice/bktr.c that a frame is complete. libavdevice is then supposed to copy the frame and process it, while bktr(4) reads new data.

It turns out that libavdevice doesn't wait for that signal before reading a frame. It sleeps for a period of time calculated from the video FPS; a signal from bktr(4) will interrupt this sleep. If no signal is received, meaning the video frame is taking longer to be delivered than expected, then libavdevice will complete the sleep and copy the video buffer anyway.

The above image on the left is the result of copying the video buffer early, without waiting for that frame-complete signal. An image composed of one video frame partially overwritten with another. In this case a fully interlaced frame (above right top) and a non-interlaced frame (above right bottom).

If you've ever tried to record video with ffmpeg's bktr device, this is what that "SLEPT NO signals" message means. It means that libavdevice/bktr.c bktr_getframe() called usleep() for the expected amount of time, didn't receive a signal, and proceeded to read a frame early.

This infuriated me for about a month and a half. After reading the bktr(4) driver and libavdevice/bktr.c about 50 times, I came to the conclusion above. I "fixed" it by altering bktr_getframe() in libavdevice to fully block until bktr(4) sends the frame-complete signal. Which should force a kind of hard frame synchronisation.

My bktr_getframe() looks like this:

static void bktr_getframe(uint64_t per_frame)
{
uint64_t curtime;
curtime = av_gettime();

while (nsignals == 0) {
/* 834 is 1/40th the duration of an NTSC frame.
* More likely I'm an idiot and it's an arbitrary number. */
usleep(834);
}

nsignals = 0;
last_frame_time = curtime;
}

And that works for me to record interlaced NTSC video without broken frames.

To be clear: this is over my head. I'm not entirely sure my explanation above correctly describes what is going wrong. If I said I fully understood what's happening here I'd be lying.


FreeBSD, FFmpeg, and a bt848 capture card

freebsd, vhs, video // 2016-07-31

FreeBSD supports the (now old) Brooktree 848 series of video capture devices with the bktr(4) driver. I've owned one of these since the early 2000s, for recording VHS tapes and watching analog video in general.

FFmpeg supports the FreeBSD bktr driver, but for the longest time I couldn't figure out how to select the correct video input. Recording with FFmpeg always produced a video of the noise present at the (unused) coaxial input of my tuner card. There's no mention of input selection in the ffmpeg documentation. But a careful reading of libavdevice/bktr.c revealed that FFmpeg reads several (undocumented) environment variables to set options on the capture card. Notably, BKTR_DEV.

BKTR_DEV is used to select the analog video input on the tuner card. The value of BKTR_DEV is an index into an array defined at line ~83 of libavdevice/bktr.c. Some experimentation is needed to find the correct value; in my case it was '0'. The default is '1'.

In case this isn't completely obvious, a working bourne shell one-liner looks something like:

BKTR_DEV=0 ffmpeg -f bktr -i /dev/bktr0 -c:v libx264 -preset fast test.mkv

And that's it. I've written this up so I won't forget, and on the off chance it might help somebody else. Happy recording.

Blurry Photo of a Hauppage bt848 Card