Bad Apple demos
-
- Super Gold Card
- Posts: 528
- Joined: Tue Mar 11, 2014 8:00 pm
- Location: Oxford, UK.
- Contact:
Re: Bad Apple demos
I've written the initial test encoder and I'm getting about a 9:1 compression ratio relative to the original screen dump files. (150*32K images > movie is ~510K) But this is a far smaller (256x256) area of change than would be needed for "Bad Apple" and possibly less complex, though there is a lot of unchanging background in that video, so it may compress well after all.
Having said that I would have to assume an average of 4KB/frame would need to be stored. The video is 5 minutes, 24 seconds in length, that's 324 seconds. What would be the minimum number of frames per second which would be acceptable? Even at one frame per second it would only just fit on a 1.44MB floppy.
Having said that I would have to assume an average of 4KB/frame would need to be stored. The video is 5 minutes, 24 seconds in length, that's 324 seconds. What would be the minimum number of frames per second which would be acceptable? Even at one frame per second it would only just fit on a 1.44MB floppy.
-
- Font of All Knowledge
- Posts: 4698
- Joined: Mon Dec 20, 2010 11:40 am
- Location: Sunny Runcorn, Cheshire, UK
Re: Bad Apple demos
Hi Stephen
Your idea about a video player sounds good in principle. I suppose each video and sound players could be separate jobs, I think the hard bit is syncronhising the video to the sound.
The Bad Apple video is a single frame PNG animation, with WAV file sync-ed to the video.
Pity the format of the frames require conversion. Could the C68 PNG Library be used to display the frames of the animation?
Your idea about a video player sounds good in principle. I suppose each video and sound players could be separate jobs, I think the hard bit is syncronhising the video to the sound.
The Bad Apple video is a single frame PNG animation, with WAV file sync-ed to the video.
Pity the format of the frames require conversion. Could the C68 PNG Library be used to display the frames of the animation?
Regards,
Derek
Derek
-
- Super Gold Card
- Posts: 528
- Joined: Tue Mar 11, 2014 8:00 pm
- Location: Oxford, UK.
- Contact:
Re: Bad Apple demos
It might be a bit too CPU/memory intensive. I'm trying to make this as light-weight as possible.Derek_Stewart wrote:Hi Stephen
Your idea about a video player sounds good in principle. I suppose each video and sound players could be separate jobs, I think the hard bit is syncronhising the video to the sound.
The Bad Apple video is a single frame PNG animation, with WAV file sync-ed to the video.
Pity the format of the frames require conversion. Could the C68 PNG Library be used to display the frames of the animation?
Of course, it might not work at all.

P.S. Hit a snag... For some unknown reason when I'm reading the first byte of the file in it's being bit-swapped (should be 0x80 and is 0x01)... on the same machine it was written on!
od(1) is showing that the contents of the file are correct! Arg! *grumble* *grumble*
P.P.S. I was stupid! I blame the cold. I was assigning the return value of the read to the variable after reading it, so overwriting with the value '1' as it read on byte!
-
- Super Gold Card
- Posts: 528
- Joined: Tue Mar 11, 2014 8:00 pm
- Location: Oxford, UK.
- Contact:
Re: Bad Apple demos
If you would like to have a look at the very early test code (which I've not managed to test on the QL yet as I'm still figuring out how to get the file onto the QL as an executable via a floppy image on the Gotek) you can download it here http://www.lingula.org.uk/~steve/share/ ... lytest.zip. It's a normal zip file and not a QL one.
Note that there's a lot of test harnessing going on and hard coded filenames etc. at the moment as it's very early code. I don't know if the decoder writes gobbledygook to the screen or not but the test version produces debug output which looks right. There's an XTC68 built executable of the decoder in the zip file too, along with the test encoded file (in the decoder directory).
I've included the original animated gif file and the set of QL screen dump files (which do work if I use LBYTES on SMSQmulator).
I'm not sure if I'll get any more time this weekend to work on it I'm afraid, but you may find it interesting to look at.
Note that there's a lot of test harnessing going on and hard coded filenames etc. at the moment as it's very early code. I don't know if the decoder writes gobbledygook to the screen or not but the test version produces debug output which looks right. There's an XTC68 built executable of the decoder in the zip file too, along with the test encoded file (in the decoder directory).
I've included the original animated gif file and the set of QL screen dump files (which do work if I use LBYTES on SMSQmulator).
I'm not sure if I'll get any more time this weekend to work on it I'm afraid, but you may find it interesting to look at.
Re: Bad Apple demos
A frame rate similar to the ZX Spectrum version, I suppose... or hopefully higher - after all, we have a QLstephen_usher wrote:What would be the minimum number of frames per second which would be acceptable? Even at one frame per second it would only just fit on a 1.44MB floppy.

Regarding the memory parameters and so on, could it be reasonable to consider as starting point the QL+(S)Goldcard configuration?
Re: Bad Apple demos
Yes, thank you for this clarification. The Atari STe version is a very special case. I just took it as a general example.stephen_usher wrote: The STE version uses extensive use of the Blitter and only works on that machine. Again, it's video that's using a custom codec optimised for the hardware, in this case the Blitter. It's also dependent upon the version of TOS as I don't think I managed to get it to work under TOS 2.06, only 1.62.
-
- Super Gold Card
- Posts: 528
- Joined: Tue Mar 11, 2014 8:00 pm
- Location: Oxford, UK.
- Contact:
Re: Bad Apple demos
Memory, as in terms of space, isn't the issue it's CPU time and memory bandwidth which are the limitations. You need to make the absolute minimum number of writes to video memory that you can. Because making these decisions are potentially CPU intensive it's best to offload these onto the encoder which has all the time in the world to do its job, unlike the decoder.
At the moment the code isn't caching from disk, which will be the bottleneck, but that's because it's just a proof of concept for the actual encoding/decoding.
As for machine specification, I'd say that as you need a floppy interface for it to work at all then the base should be a the amount of memory you'd usually have got in a disk interface bask in the day, which would probably be 512K, though I know that there were smaller versions of the Trump Card available.
At the moment the code isn't caching from disk, which will be the bottleneck, but that's because it's just a proof of concept for the actual encoding/decoding.
As for machine specification, I'd say that as you need a floppy interface for it to work at all then the base should be a the amount of memory you'd usually have got in a disk interface bask in the day, which would probably be 512K, though I know that there were smaller versions of the Trump Card available.
Re: Bad Apple demos
Well, I think a 512K Trumpcard is a great reference point!
Sorry for my poor competence about encoding/decoding and other tecnical issues. I would be happy to help somehow, so please feel free to ask if you need.
Thanks for your efforts, also the QL might have its merited place in the Bad Apple demo scene, hopefully.
Sorry for my poor competence about encoding/decoding and other tecnical issues. I would be happy to help somehow, so please feel free to ask if you need.
Thanks for your efforts, also the QL might have its merited place in the Bad Apple demo scene, hopefully.
-
- Super Gold Card
- Posts: 528
- Joined: Tue Mar 11, 2014 8:00 pm
- Location: Oxford, UK.
- Contact:
Re: Bad Apple demos
OK, after finding a way to make the XTC68 produced program to be executable and fixing one major bug the decoder works, at least on SMSQmulator!
Here's the updated source:
Now to try it on a real QL...
Here's the updated source:
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef __APPLE__
#include <strings.h>
#else
#include <string.h>
#include <memory.h>
#endif
#ifndef DEBUG
#include <qdos.h>
#else
#include <sys/types.h>
#endif
#include "../include/m4v.h"
#ifdef DEBUG
#define TESTFILE "test.m4v"
#else
#define TESTFILE "flp1_test.m4v"
#endif
#ifdef DEBUG
unsigned char screen[256][128];
#else
unsigned char *screen = (unsigned char *) 0x20000;
#endif
int main()
{
int fd;
int i, j, k, count;
int cur_line = 0;
unsigned char databyte;
unsigned char *address;
struct difference {
unsigned char address;
unsigned char value;
} diffdat;
unsigned int value;
unsigned char line_buffer[128];
#ifndef DEBUG
unsigned char *scr_line_ptrs[256];
for (i = 0; i < 256; i++)
scr_line_ptrs[i] = (unsigned char *)(screen + (128 * i));
#else
unsigned char *scr_line_ptrs[256];
for (i = 0; i < 256; i++)
scr_line_ptrs[i] = screen[i];
#endif
if ((fd = open(TESTFILE, O_RDONLY)) < 0)
{
fprintf(stderr, "Can't open %s\n", TESTFILE);
return -1;
}
while((read(fd, &databyte, sizeof(unsigned char))) == sizeof(unsigned char))
{
#ifdef DEBUG
fprintf(stderr, "databyte is 0x%02x\n", databyte);
#endif
if (isnewframe(databyte) == 1)
{
cur_line = 0;
#ifndef DEBUG
mt_susjb(-1,1,NULL);
#else
fprintf(stderr, "***************************** NEW BALLS PLEASE! ********************************\n");
#endif
}
else
{
if (cur_line == 256)
{
fprintf(stderr, "ERROR! got a frame with more than 256 lines!\n");
return -1;
}
}
#ifdef DEBUG
fprintf(stderr, "Line number: %d: \n", cur_line);
#endif
if (isdiffline(databyte) == 1)
{
count = (databyte & 0x3f);
#ifdef DEBUG
fprintf(stderr, "We have a differential line with %d changes.\n", count);
#endif
for (i = 0; i < count; i++)
{
if (read(fd, &diffdat, sizeof(struct difference)) != sizeof(struct difference))
{
fprintf(stderr, "Bad read of difference block.\n");
return -1;
}
#ifdef DEBUG
fprintf(stderr, "Change at line %d, block %d: %02x\n", cur_line, diffdat.address, diffdat.value);
#endif
address = (unsigned char *)(scr_line_ptrs[cur_line] + (diffdat.address * 2));
*address = diffdat.value;
*(address + 1) = diffdat.value;
}
}
else
{
#ifdef DEBUG
fprintf(stderr, "Got a full scanline.\n");
#endif
for (i = 0; i < 128; i++)
{
if (read(fd, &databyte, sizeof(unsigned char)) != sizeof(unsigned char))
{
fprintf(stderr, "Misread of fill line data.\n");
return -1;
}
line_buffer[i++] = (unsigned char)((unsigned char) databyte);
line_buffer[i] = (unsigned char)((unsigned char) databyte);
}
bcopy((char *)line_buffer, (char *)scr_line_ptrs[cur_line], 128);
}
cur_line++;
databyte = 0x00;
}
#ifdef DEBUG
fprintf(stderr, "End of file, I think.\n");
#endif
close(fd);
}
-
- Super Gold Card
- Posts: 528
- Joined: Tue Mar 11, 2014 8:00 pm
- Location: Oxford, UK.
- Contact:
Re: Bad Apple demos
Still a bug (only writing half the screen width and there's a screen offset issue which may be in the encoder or somewhere else).
However, (a) disk access speed is an issue, however, (b) even when run from a RAM disk it's too slow, about 1 fps on the most complex frames with an SGC clone!
On a better note, if the differences between frames is small then it's really quite fast.
P.S. Here's a video: https://youtu.be/zwvraMqqUec
However, (a) disk access speed is an issue, however, (b) even when run from a RAM disk it's too slow, about 1 fps on the most complex frames with an SGC clone!
On a better note, if the differences between frames is small then it's really quite fast.
P.S. Here's a video: https://youtu.be/zwvraMqqUec