Some video file -> Atari thoughts
- From: bill@xxxxxxxxxxxxxxxxxxxx (Bill Kendrick)
- Date: 01 Aug 2009 21:29:58 GMT
So I saw a highly amusing video on YouTube the other day:
http://www.youtube.com/watch?v=I1qHVVbYG8Y
It's a cartoon, black on a white background, with not a ton of
detail, and motion that's usually focused on one small area.
I decided it'd be perfect to try and convert to something you could
watch on an Atari. :)
I used 'mplayer' on Linux, with the option '-vo png'
(aka "video out: save each frame as a separate PNG file") to extract
the frames.
Then I created a shell script that iterated every other frame (just to
keep the size down) and used some NetPBM tools to do the following:
(1) scale the frame to 160x180
(the video, shrunk down to 320px wide, was 180 tall;
but I'm targetting GRAPHICS 15 (aka 7.5), so needed it 1/2 as wide)
pngtopnm png/$j.png | pnmscale -xsize=160 -ysize=180
(2) map the colors to 4 shades of grey, using a small 2x2 image I made:
ppmquant -mapfile grey_palette.pgm
(3) cut out the left/right borders; I want to display in a narrow playfield,
and most of the action in the cartoon is toward the center
pnmcut -left 32 -width 128
(4) convert the file to a Portable Greymap (.pgm), which is 1 byte per pixel
(rather than 3 bytes, like a Portable Pixmap (.ppm))
(5) compare the current frame to the previous frame, getting the difference
pnmarith -difference gr15/$oldj.pgm gr15/$j.pgm > diff.pnm
(6a) crop any solid border from the 'difference'; I do this to get the
position and dimensions of "what has changed", which I'll crop out of
the actual current frame in step 7
pnmcrop -verbose diff.pnm > crop.pnm 2> crop.txt
(6b) determine the dimensions; if nothing was cropped, we know that the
boundaries of what has changed includes the entire size of the frame
allbkgd=`grep "The image is entirely background" crop.tt | cut -d ":" -f 1`
if [ "$allbgkd" = "pnmcrop" ]; then
top=0
bottom=179
left=0
right=124
else
top=`grep "off the top" crop.txt | cut -d " " -f 3`
if [ "$top" = "" ]; then
top=0
fi
# ... etc.
(7) calculate the position and size of the crop; keeping in mind that
we get 4 pixels per byte in GRAPHICS 15 mode:
left=`expr \( $left / 4 \) \* 4`
right=`expr \( $right / 4 \) \* 4`
width=`expr 128 - $right - $left`
height=`expr 180 - $bottom - $top`
(8) crop the current frame, to get the delta frame that we'll actually
store:
pnmcut -top $top -height $height -left $left -width -$width gr15/$j.pgm > crop.pgm
(9) finally, add that image to a 'stream' of data that the Atari will load
and display; also need to tell it where, on the screen, to load into!
./add_to_stream $left $top crop.pgm >> stream.dat
And "add_to_stream" is a little C program I wrote that dumps a few bytes
of info, followed by data for a GRAPHICS 15 display. It gets appended to
the 'stream.dat' file, via the ">>" in the shell command, above.
(1) Determing starting position (relative to the top of screen memory):
left = atoi(argv[1]);
top = atoi(argv[2]);
start = (top * 128 + left) / 4;
start_lsb = start % 256;
start_msb = start / 256;
(2) open the PGM image file, read its dimensions
fi = fopen(argv[3], "r");
fscanf(fi, "%s %d %d %s", tmp, &width, &height, tmp);
(3) write the position and size of data, so the Atari knows how much to
read, and where to put it on the screen:
fwrite(&start_lsb, 1, 1, stdout);
fwrite(&start_msb, 1, 1, stdout);
w = width / 4;
fwrite(&w, 1, 1 ,stdout);
fwrite(&height, 1, 1, stdout);
(4) read all of the PGM data, convert it to GRAPHICS 15, and spit it out:
for (y = 0; y < height; y++) {
fread(data, 1, width, fi);
for (x = 0; x < width; x = x + 4) {
p1 = data[x] / 64;
p2 = data[x + 1] / 64;
p3 = data[x + 2] / 64;
p4 = data[x + 3] / 64;
p = (p1 << 6) + (p2 << 4) + (p3 << 2) + p4;
fwrite(&p, 1, 1, stdout);
}
}
And finally, so far, I've written a TurboBASIC XL program that mostly works,
though it's slow, and I haven't set up a proper display list to get
all of the GRAPHICS 15 display working in narrow mode. Tips welcome! :)
10 GRAPHICS 31
15 POKE 708,5:POKE 709,10:POKE 710,15:POKE 712,0
20 REM POKE 559,33
30 SC=DPEEK(88)
31 REM SET UP DL HERE
40 OPEN #1,4,0,"D:STREAM.DAT"
50 GET #1,SL:GET #1,SM:S=(SM*256)+SL
51 X=(S MOD 32):Y=INT(S/32):S=(Y*40)+X:REM WORKAROUND UNTIL NARROW SUPPORT
60 GET #1,W:GET #1,H
70 FOR Y=0 TO H-1
80 BGET #1,SC+S+Y*40,W:REM WOULD BE 32 IN NARROW
90 NEXT Y
99 GOTO 50
I need to do the following:
* Figure out GRAPHICS 15 display list in narrow playfield mode
* Figure out a way to make a very large (~512KB) ATR disk image
(and/or skip more frames from the original video,
and/or apply some kind of RLE or other compression?)
* Figure out my 1200XL's 512KB RAM disk in MyDOS :)
* Rewrite the viewer in Action!
Although, sadly, I doubt I could redistribute the video. Just fun project
for myself. ;)
But hey, with the appropriate tools (youtube-dl, netbpm, bash, and a C
compiler), anyone could take the same video (or others) off of YouTube
and figure it out themselves.
Should I set up a page with downloads for the actual shell script and
C and Atari (TBXL and/or Action!) source?
--
-bill!
Sent from my computer
.
- Follow-Ups:
- Re: Some video file -> Atari thoughts
- From: Bill Kendrick
- Re: Some video file -> Atari thoughts
- Next by Date: Re: Some video file -> Atari thoughts
- Next by thread: Re: Some video file -> Atari thoughts
- Index(es):
Relevant Pages
|
Loading