vdr  2.0.6
vdr-genindex.c
Go to the documentation of this file.
1 /*
2  * genindex.c generates index.vdr file from mpeg files written by VDR
3  *
4  * Compile: gcc -o genindex -O2 -Wall -funroll-loops genindex.c
5  *
6  * Authors: varies, including me (Werner Fink <werner@suse.de>)
7  *
8  * Changes:
9  *
10  * Fri Mar 15, 2002: Move from random scanner to streamid scanner
11  * for getting the correct offsets of the I-Frames. Be sure that
12  * no other multiplex than video ones will be scanned. Increase both
13  * buffers for ringbuffer and stdio to lower I/O load and increase
14  * speed. //werner
15  *
16  * Usage:
17  *
18  * cd /video[<number>]/<Film>/<Title>/<date>.<time>.<prio>.<life>.rec/
19  * [mv -f index.vdr index.vdr.bak]
20  * [pathto/]genindex
21  */
22 #include <stdio.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <stdlib.h>
26 
27 #define BUFFER_SIZE 4096*128
28 
29 #define SC_PICTURE 0x00
30 
31 #define NO_PICTURE 0
32 #define I_FRAME 1
33 #define P_FRAME 2
34 #define B_FRAME 3
35 
36 #define PROG_STREAM_MAP 0xBC
37 #ifndef PRIVATE_STREAM1
38 #define PRIVATE_STREAM1 0xBD
39 #endif
40 #define PADDING_STREAM 0xBE
41 #ifndef PRIVATE_STREAM2
42 #define PRIVATE_STREAM2 0xBF
43 #endif
44 #define AUDIO_STREAM_S 0xC0
45 #define AUDIO_STREAM_E 0xDF
46 #define VIDEO_STREAM_S 0xE0
47 #define VIDEO_STREAM_E 0xEF
48 #define ECM_STREAM 0xF0
49 #define EMM_STREAM 0xF1
50 #define DSM_CC_STREAM 0xF2
51 #define ISO13522_STREAM 0xF3
52 #define PROG_STREAM_DIR 0xFF
53 
54 /* VDR supports only offset with sizeof(int) */
55 struct tIndex {int offset; unsigned char type; unsigned char number; short reserved; };
56 
57 static FILE* fp;
58 static FILE* idx;
59 static long Foffset;
60 static char fname[20];
61 static unsigned char fbuffer[BUFFER_SIZE];
62 
63 static unsigned char buf(long p)
64 {
65  static unsigned char ringbuf[BUFFER_SIZE];
66 
67  if ((p >= Foffset) && (p < (Foffset + BUFFER_SIZE)))
68  return ringbuf[p-Foffset];
69 
70  Foffset = p;
71  if (fseek(fp, p, SEEK_SET) == 0)
72  {
73  size_t n = 0;
74 
75  memset(&ringbuf, 0, sizeof(ringbuf));
76  n = fread(ringbuf, 1, sizeof(ringbuf), fp);
77 
78  if ((n < sizeof(ringbuf)) && ferror(fp))
79  {
80  fprintf(stderr, "Could not read from %s: %s\n", fname, strerror(errno));
81  exit(1);
82  }
83 
84  return ringbuf[p-Foffset];
85  }
86  return 0;
87 }
88 
89 static int readfile(const unsigned char number)
90 {
91  long filesize;
92  long c = 0;
93 
94  sprintf(fname,"%03d.vdr", number);
95  fp = fopen(fname, "r");
96  if (!fp)
97  {
98  if (errno != ENOENT)
99  {
100  fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno));
101  return -1;
102  }
103  putchar('\n');
104  return 1;
105  }
106  setbuffer(fp, (char*)fbuffer, sizeof(fbuffer));
107  if (fseek(fp, 0, SEEK_END) < 0)
108  {
109  fprintf(stderr, "Could not goto end of %s: %s\n", fname, strerror(errno));
110  return -1;
111  }
112  if ((filesize = ftell(fp)) < 0)
113  {
114  fprintf(stderr, "Could not get size of %s: %s\n", fname, strerror(errno));
115  return -1;
116  }
117 
118  if (number > 1)
119  putchar('\n');
120  printf("Reading %s, %ld kB.\n", fname, (filesize >> 10));
121  Foffset = filesize;
122 
123  rewind(fp); /* Even if done for p == 0 in buf() */
124 
125  while (c < filesize)
126  {
127  if (buf(c) == 0x00 && buf(c+1) == 0x00 && buf(c+2) == 0x01)
128  {
129  const long w = ((buf(c+4) << 8) | buf(c+5)) + 6; /* width of frame */
130  const long l = w + c; /* absolute length */
131 
132  if (!((l > c) && (l <= filesize)))
133  break; /* while c < filesize */
134 
135  switch (buf(c+3)) /* streamid */
136  {
137  case PROG_STREAM_MAP:
138  case PRIVATE_STREAM2:
139  case PROG_STREAM_DIR:
140  case ECM_STREAM :
141  case EMM_STREAM :
142  case PADDING_STREAM :
143  case DSM_CC_STREAM :
144  case ISO13522_STREAM:
145  case PRIVATE_STREAM1:
147  break;
149  {
150  long off = (buf(c+8) + 9) + c; /* absolute offset of frame contents */
151  for (;off < l; off++)
152  {
153  if (buf(off) == 0x00 && buf(off+1) == 0x00 && buf(off+2) == 0x01 &&
154  buf(off+3) == SC_PICTURE)
155  {
156  const unsigned char Ptype = (buf(off+5)>>3) & 0x07;
157  if ((Ptype == I_FRAME) || (Ptype == P_FRAME) || (Ptype == B_FRAME))
158  {
159  /* VDR supports only offset with sizeof(int) */
160  const struct tIndex i = {(int)c, Ptype, number, 0};
161 
162  if (fwrite(&i, 1, sizeof(i), idx) != sizeof(i))
163  {
164  fprintf(stderr, "Error writing index file: %s\n", strerror(errno));
165  return -1;
166  }
167  if (Ptype == I_FRAME)
168  {
169  printf("I-Frame found at %ld kB\r", (c >> 10));
170  fflush(stdout);
171  }
172  break; /* while off < l */
173  } /* if Ptype == I_FRAME ... */
174  } /* if buf(off) == 0x00 ... */
175  } /* while off < l */
176  }
177  break;
178  default:
179  fprintf(stderr, "\nError while scanning file %s, broken mpeg file?\n", fname);
180  break;
181  } /* switch buf(c+3) */
182  c += w; /* Next frame */
183  }
184  else /* if buf(c) == 0x00 ... */
185  c++; /* Broken file, search for begin */
186  } /* while c < filesize */
187  fclose(fp);
188  return 0;
189 }
190 
191 int main()
192 {
193  int c, ret;
194  if (!(idx = fopen("index.vdr", "w")))
195  {
196  fprintf(stderr, "Could not open index.vdr: %s\n", strerror(errno));
197  return -1;
198  }
199  for (c=1; ((ret = readfile(c)) == 0); c++)
200  __asm__ __volatile__("": : :"memory");
201  fclose(idx);
202  return (ret > 0 ? 0 : 1);
203 }
static char fname[20]
Definition: vdr-genindex.c:60
static unsigned char buf(long p)
Definition: vdr-genindex.c:63
#define B_FRAME
Definition: vdr-genindex.c:34
#define AUDIO_STREAM_S
Definition: vdr-genindex.c:44
#define I_FRAME
Definition: vdr-genindex.c:32
#define VIDEO_STREAM_E
Definition: vdr-genindex.c:47
#define BUFFER_SIZE
Definition: vdr-genindex.c:27
#define EMM_STREAM
Definition: vdr-genindex.c:49
unsigned char type
Definition: vdr-genindex.c:55
static FILE * fp
Definition: vdr-genindex.c:57
#define PROG_STREAM_DIR
Definition: vdr-genindex.c:52
#define P_FRAME
Definition: vdr-genindex.c:33
#define SC_PICTURE
Definition: vdr-genindex.c:29
int offset
Definition: vdr-genindex.c:55
static FILE * idx
Definition: vdr-genindex.c:58
#define DSM_CC_STREAM
Definition: vdr-genindex.c:50
static unsigned char fbuffer[BUFFER_SIZE]
Definition: vdr-genindex.c:61
#define VIDEO_STREAM_S
Definition: vdr-genindex.c:46
#define ISO13522_STREAM
Definition: vdr-genindex.c:51
short reserved
Definition: vdr-genindex.c:55
#define PROG_STREAM_MAP
Definition: vdr-genindex.c:36
#define AUDIO_STREAM_E
Definition: vdr-genindex.c:45
#define PRIVATE_STREAM1
Definition: vdr-genindex.c:38
int main()
Definition: vdr-genindex.c:191
static long Foffset
Definition: vdr-genindex.c:59
unsigned char number
Definition: vdr-genindex.c:55
#define PRIVATE_STREAM2
Definition: vdr-genindex.c:42
#define PADDING_STREAM
Definition: vdr-genindex.c:40
#define ECM_STREAM
Definition: vdr-genindex.c:48
static int readfile(const unsigned char number)
Definition: vdr-genindex.c:89