View Single Post
Old 22nd Jul 2011, 2:19 am   #80
Kat Manton
Retired Dormant Member
 
Kat Manton's Avatar
 
Join Date: Jul 2005
Location: West Yorkshire, UK.
Posts: 1,700
Default Re: Simple memory card player idea

Hi,

It doesn't seem possible to get interlaced raw video out of ffmpeg.

However, the following does produce interlaced raw video, with 503 pixels per line, 377 lines, and each line padded to 512 bytes.

Script to drive ffmpeg (save as 'video2raw.sh'):
Code:
#!/bin/sh

# video2raw.sh

CUT=""
VFOPTS=""

# Comment out to convert whole file, or edit as required.
CUT="-ss 00:04:00 -t 00:00:04"

# Comment out if source is 4:3
VFOPTS="crop=0.75*in_w,"

# Edit as required
VFOPTS="${VFOPTS}format=gray,scale=503:377"

nice -n 10 ionice -c3 ffmpeg \
-i "$1" $CUT \
-vf $VFOPTS \
-vcodec rawvideo \
-pix_fmt gray \
-threads 0 -y \
-f rawvideo - | ./reinterlace > "$2"
Note the last line; the output of ffmpeg is stdout; this is piped into stdin of 'reinterlace'; stdout of that, in turn, is directed to whatever's specified as the second argument when calling the script.

What is 'reinterlace'? This is 'reinterlace' (save as 'reinterlace.c' and compile it.)
Code:
#include <stdio.h>
#include <string.h>

/*
 * reinterlace.c
 *
 * compile with:
 *  gcc -Wall -o reinterlace reinterlace.c
 *
 * Read progressive video from stdin
 * Write interlaced video to stdout
 * Adjust #defines as required
 */
    
#define HRES    503
#define VRES    377
#define BLOCK   512

int main()
{
    char line[BLOCK];
    char efield[VRES/2][BLOCK];
    int odd, lcnt, elcnt, fcnt;
    lcnt = 0;
    elcnt = 0;
    fcnt = 0;
    odd = 1;

    while ((fread(line, 1, HRES, stdin)) != 0 )
    {
        if (odd)
        {
            fwrite(line, 1, BLOCK, stdout);
        }
        else
        {
            memcpy(efield[elcnt], line, HRES);
            elcnt++;
        }
        odd ^= 1;
        lcnt++;
        if (lcnt >= VRES)
        {
            lcnt = 0;
            elcnt = 0;
            odd = 1;
            fcnt++;
            fwrite(efield, 1, BLOCK * (VRES/2), stdout);
        }
    }
    fflush(stdout);

    fprintf(stderr, "\n\nreinterlaced %d frames\n", fcnt);
    
    return 0;
}
Yes, I'll freely admit that it's extremely nasty, has no error checking, pads lines to 512 bytes with uninitialised data and needs editing to alter the resolution it handles. But it's a quick and dirty hack which produces data in the right format. Feel free to expand on it, it's a start

Usage: Run 'video2raw.sh' with two arguments; the first is the video file to convert and the second is the file to write.

It's highly probable that you could pass the CF card device as the second argument thus writing converted data directly to it, but I haven't tried that.

I've verified the output of the above mess is correct with an even nastier hacked-together mess of Python which reads the data, displays it, and allows one to step frame-by-frame. It's utterly dreadful so I'm not posting it. The C program is bad enough; I have some standards...

Kat
Kat Manton is offline