Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vdr] genindex with LFS (was: Working genindex for VDR (included))



Dr. Werner Fink wrote:

>Hi,
>
>      after trying several genindex.c versions mailed on this
>list (and linux-dvb) for getting a index.vdr beeing identical
>with those of VDR, I've written a modified version of genindex.c
>which should be able to scan the mpeg files written by VDR and
>write out an indentical index.vdr.
>
>I'll need that modified version of genindex.c for burning CDROMs
>with VDR files: every CDROM inludes a 001.vdr, an symbolic link
>resume.vdr pointing to /tmp/resume.vdr, and at least an index.vdr
>matching the 001.vdr.  This should readable for VDR simply by
>mounting such a CDROM at /video/CDROM/ ...
>
>This version of genindex.c uses an increased BUFFER_SIZE for the
>ringbuffer _and_ an increased buffer size for the stdio interface
>(default is 8k, now its 128*4k).
>
>
>       Werner
>
Hi,
I'm adding LFS to genindex.c,
while 001.vdr is size of 2168592777 bit, it only throws the error:
Error while scanning file 001.vdr, broken mpeg file?
(line 188) on me.
Any hints?
(Filessize < 2GB f'works)

Florian
PS: The file 001.vdr is generated by pvainstomento from windows
PPPS: For Viewing mod vdr too, right?

-------- not an attachment --------------------------------------

/*
 * genindex.c    generates index.vdr file from mpeg files written by VDR
 *
 * Compile:    gcc -o genindex -O2 -Wall -funroll-loops genindex.c
 *
 * Authors:    varies, including me
 *
 * Changes:
 *
 *   Florian Steinel
 *   Thu Mar 19, 2002: Added LFS
 *
 *   Dr. Werner Fink
 *   Fri Mar 15, 2002: Move from random scanner to streamid scanner
 *   for getting the correct offsets of the I-Frames.  Be sure that
 *   no other multiplex than video ones will be scanned.  Increase both
 *   buffers for ringbuffer and stdio to lower I/O load and increase
 *   speed.    //werner
 *
 * Usage:
 *
 *   cd /video[<number>]/<Film>/<Title>/<date>.<time>.<prio>.<life>.rec/
 *   [mv -f index.vdr index.vdr.bak]
 *   [pathto/]genindex
 */

/* TODO: Add a ifdef for LFS */
#define _FILE_OFFSET_BITS  64
#define _LARGEFILE_SOURCE  1

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>

#define BUFFER_SIZE    4096*128

#define SC_PICTURE    0x00

#define NO_PICTURE    0
#define I_FRAME        1
#define P_FRAME        2
#define B_FRAME        3

#define PROG_STREAM_MAP    0xBC
#ifndef PRIVATE_STREAM1
#define PRIVATE_STREAM1    0xBD
#endif
#define PADDING_STREAM    0xBE
#ifndef PRIVATE_STREAM2
#define PRIVATE_STREAM2    0xBF
#endif
#define AUDIO_STREAM_S    0xC0
#define AUDIO_STREAM_E    0xDF
#define VIDEO_STREAM_S    0xE0
#define VIDEO_STREAM_E    0xEF
#define ECM_STREAM    0xF0
#define EMM_STREAM    0xF1
#define DSM_CC_STREAM    0xF2
#define ISO13522_STREAM    0xF3
#define PROG_STREAM_DIR    0xFF

/* VDR supports only offset with sizeof(int) */
struct tIndex {int offset; unsigned char type; unsigned char number; 
short reserved; };

static FILE* fp;
static FILE* idx;
/* static long Foffset; */
static off_t Foffset;
static char fname[20];
static unsigned char fbuffer[BUFFER_SIZE];

static unsigned char buf(off_t p)
{
    static unsigned char ringbuf[BUFFER_SIZE];

    if ((p >= Foffset) && (p < (Foffset + BUFFER_SIZE)))
    return ringbuf[p-Foffset];

    Foffset = p;
    if (fseeko(fp, p, SEEK_SET) == 0)
    {
    size_t n = 0;

    memset(&ringbuf, 0, sizeof(ringbuf));
    n = fread(ringbuf, 1, sizeof(ringbuf), fp);

    if ((n < sizeof(ringbuf)) && ferror(fp))
    {
        fprintf(stderr, "Could not read from %s: %s\n", fname, 
strerror(errno));
        exit(1);
    }

    return ringbuf[p-Foffset];
    }
    return 0;
}

static int readfile(const unsigned char number)
{
    off_t filesize;
    off_t c = 0;

    sprintf(fname,"%03d.vdr", number);
    fp = fopen(fname, "r");
    if (!fp)
    {
    if (errno != ENOENT && errno != EFBIG)
    {
        fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno));
        return -1;
    }
    putchar('\n');
    return 1;
    }
    setbuffer(fp, fbuffer, sizeof(fbuffer));
    if (fseeko(fp, 0, SEEK_END) < 0)
    {
    fprintf(stderr, "Could not goto end of %s: %s\n", fname, 
strerror(errno));
    return -1;
    }
    if ((filesize = ftello(fp)) < 0)
    {
        fprintf(stderr, "Could not get size of %s: %s\n", fname, 
strerror(errno));
        return -1;
    }

    if (number > 1)
    putchar('\n');
    printf("Reading %s, %Ld kB.\n", fname, (filesize >> 10));
    Foffset = filesize;

    rewind(fp); /* Even if done for p == 0 in buf() */

    while (c < filesize)
    {
    if (buf(c) == 0x00 && buf(c+1) == 0x00 && buf(c+2) == 0x01)
    {
        const long w = ((buf(c+4) << 8) | buf(c+5)) + 6;    /* width of 
frame */
        const off_t l = w + c;                /* absolute length */

        if (!((l > c) && (l <= filesize)))
        break;                        /* while c < filesize */

        switch (buf(c+3))                    /* streamid */
        {
        case PROG_STREAM_MAP:
        case PRIVATE_STREAM2:
        case PROG_STREAM_DIR:
        case ECM_STREAM     :
        case EMM_STREAM     :
        case PADDING_STREAM :
        case DSM_CC_STREAM  :
        case ISO13522_STREAM:
        case PRIVATE_STREAM1:
        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
            break;
        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
            {
            off_t off = (buf(c+8) + 9) + c;        /* absolute offset of 
frame contents */
            for (;off < l; off++)
            {
                if (buf(off) == 0x00 && buf(off+1) == 0x00 && buf(off+2) 
== 0x01 &&
                buf(off+3) == SC_PICTURE)
                {
                const unsigned char Ptype = (buf(off+5)>>3) & 0x07;
                if ((Ptype == I_FRAME) || (Ptype == P_FRAME) || (Ptype 
== B_FRAME))
                {
                    /* VDR supports only offset with sizeof(int) */
                    const struct tIndex i = {(int)c, Ptype, number, 0};

                    if (fwrite(&i, 1, sizeof(i), idx) != sizeof(i))
                    {
                    fprintf(stderr, "Error writing index file: %s\n", 
strerror(errno));
                    return -1;
                    }
                    if (Ptype == I_FRAME)
                    {
                    printf("I-Frame found at %Ld kB\r", (c >> 10));
                    fflush(stdout);
                    }
                    break;            /* while off < l */
                }                /* if Ptype == I_FRAME ... */
                }                    /* if buf(off) == 0x00 ... */
            }                    /* while off < l */
            }
            break;
        default:
            fprintf(stderr, "\nError while scanning file %s, broken mpeg 
file?\n", fname);
            break;
        }                            /* switch buf(c+3) */
        c += w;                        /* Next frame */
    }
    else                            /* if buf(c) == 0x00 ... */
        c++;                        /* Broken file, search for begin */
    }                                /* while c < filesize */
    fclose(fp);
    return 0;
}

int main()
{
    off_t c, ret;
    if (!(idx = fopen("index.vdr", "w")))
    {
    fprintf(stderr, "Could not open index.vdr: %s\n", strerror(errno));
    return -1;
    }
    for (c=1; ((ret = readfile(c)) == 0); c++)
    __asm__ __volatile__("": : :"memory");
    fclose(idx);
    return (ret > 0 ? 0 : 1);
}
/* end of genindex.c */

-----------------------------------------------------------------







Home | Main Index | Thread Index