1 /*
2     Lower-level definitions for building DVD authoring structures
3 */
4 /*
5  * Copyright (C) 2002 Scott Smith (trckjunky@users.sourceforge.net)
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or (at
10  * your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20  * MA 02110-1301 USA.
21  */
22 
23 #ifndef __DA_INTERNAL_H_
24 #define __DA_INTERNAL_H_
25 
26 #include "common.h"
27 
28 enum {VM_NONE=0,VM_MPEG1=1,VM_MPEG2=2}; /* values for videodesc.vmpeg */
29 enum {VS_NONE=0,VS_720H=1,VS_704H=2,VS_352H=3,VS_352L=4}; /* values for videodesc.vres */
30 enum {VA_NONE=0,VA_4x3=1,VA_16x9=2}; /* values for videodesc.vaspect */
31 enum {VW_NONE=0,VW_NOLETTERBOX=1,VW_NOPANSCAN=2,VW_CROP=3}; /* values for videodesc.vwidescreen */
32 enum {VR_NONE=0,VR_NTSCFILM=1,VR_FILM=2,VR_PAL=3,VR_NTSC=4,VR_30=5,VR_PALFIELD=6,VR_NTSCFIELD=7,VR_60=8}; /* values for videodesc.vframerate */
33 
34 enum {AF_NONE=0,AF_AC3=1,AF_MP2=2,AF_PCM=3,AF_DTS=4}; /* values for audiodesc.aformat */
35 enum {AQ_NONE=0,AQ_16=1,AQ_20=2,AQ_24=3,AQ_DRC=4}; /* values for audiodesc.aquant */
36 enum {AD_NONE=0,AD_SURROUND=1}; /* values for audiodesc.adolby */
37 enum {AL_NONE=0,AL_NOLANG=1,AL_LANG=2}; /* values for audiodesc.alangpresent and subpicdesc.slangpresent */
38 enum {AS_NONE=0,AS_48KHZ=1,AS_96KHZ=2}; /* values for audiodesc.asample */
39 enum /* values for audiodesc.acontent */
40   {
41     ACONTENT_UNSPEC = 0, /* unspecified */
42     ACONTENT_NORMAL = 1, /* normal */
43     ACONTENT_IMPAIRED = 2, /* visually impaired */
44     ACONTENT_COMMENTS1 = 3, /* director's comments */
45     ACONTENT_COMMENTS2 = 4, /* alternate director's comments */
46   };
47 enum /* values for subpicdesc.scontent */
48   {
49     SCONTENT_UNSPEC = 0, /* unspecified */
50     SCONTENT_NORMAL = 1, /* normal */
51     SCONTENT_LARGE = 2, /* large */
52     SCONTENT_CHILDREN = 3, /* children */
53     SCONTENT_NORMAL_CC = 5, /* normal captions */
54     SCONTENT_LARGE_CC = 6, /* large captions */
55     SCONTENT_CHILDREN_CC = 7, /* children's captions */
56     SCONTENT_FORCED = 9, /* forced */
57     SCONTENT_DIRECTOR = 13, /* director comments */
58     SCONTENT_LARGE_DIRECTOR = 14, /* large director comments */
59     SCONTENT_CHILDREN_DIRECTOR = 15, /* director comments for children */
60   };
61 
62 typedef int64_t pts_t; /* timestamp in units of 90kHz clock */
63 
64 struct vobuinfo { /* describes a VOBU in a VOB */
65     int sector; /* starting sector number within input file */
66     int lastsector; /* ending sector number within input file */
67     int fsect; /* sector number within output VOB file */
68     int fnum; /* number of VOB file within titleset */
69     int vobcellid; /* cell ID in low byte, VOB ID in rest */
70     int firstvobuincell,lastvobuincell,hasseqend,hasvideo;
71     pts_t videopts[2],sectpts[2],firstvideopts;
72     int numref; /* nr entries in lastrefsect */
73     int firstIfield;
74     int numfields;
75     int lastrefsect[3]; // why on earth do they want the LAST sector of the ref (I, P) frame?
76     unsigned char sectdata[0x26]; // PACK and system header, so we don't have to reread it
77 };
78 
79 struct colorinfo { /* a colour table for subpictures */
80     int refcount; /* shared structure */
81     int color[16];
82 };
83 
84 struct videodesc { /* describes a video stream, info from a <video> tag */
85     int vmpeg,vres,vformat,vaspect,vwidescreen,vframerate,vcaption;
86 };
87 
88 struct audiodesc { /* describes an audio stream, info from an <audio> tag */
89     int aformat;
90     int aquant;
91     int adolby;
92     int achannels;
93     int alangpresent;
94     int asample;
95     int aid;
96     char lang[2];
97     int acontent;
98 };
99 
100 struct subpicdesc {
101   /* describes a <subpicture> track at the pgcgroup level. This groups one or more
102     streams, being alternative representations of the subpicture for different modes. */
103     int slangpresent;
104     char lang[2];
105     int scontent;
106     unsigned char idmap[4];
107       /* stream ID for each of normal, widescreen, letterbox, and panscan respectively,
108         (128 | id) if defined, else 0 */
109 };
110 
111 struct cell {
112   /* describes a cell within a source video file--generated from <cell> tags & "chapters"
113     attributes, or by default if none of these */
114     pts_t startpts,endpts;
115     cell_chapter_types ischapter; // 1 = chapter&program, 2 = program only, 0 = neither
116     int pauselen;
117     int scellid; /* ID assigned to cell */
118     int ecellid; /* ID assigned to next cell */
119       /* DVD-Video spec allows for cells to be grouped into programs nonsequentially,
120         and for the same cell to be part of more than one program. dvdauthor doesn't
121         currently support any of that, so cell IDs will always be sequential. */
122     struct vm_statement *commands;
123 };
124 
125 struct source { /* describes an input video file, corresponding to a single <vob> directive */
126     char *fname; /* name of file */
127     int numcells; /* nr elements in cells */
128     struct cell *cells; /* array */
129     struct vob *vob; /* pointer to created vob */
130 };
131 
132 struct audpts { /* describes a packet in an audio stream */
133     pts_t pts[2]; /* start and end time of packet */
134     int asect; /* sector number in source file */
135 };
136 
137 struct audchannel { /* describes information collected from an audio stream */
138     struct audpts *audpts; /* array */
139     int numaudpts; /* used portion of audpts array */
140     int maxaudpts; /* allocated size of audpts array */
141     struct audiodesc ad,adwarn; // use for quant and channels
142 };
143 
144 struct vob { /* one entry created for each source in each pgc */
145     char *fname; /* name of input file, copied from source */
146     int numvobus; /* used portion of vobu array */
147     int maxvobus; /* allocated size of vobu array */
148     int vobid,numcells;
149     struct pgc *progchain; /* backpointer to PGC, used for colorinfo and buttons */
150     struct vobuinfo *vobu; /* array of VOBUs in the VOB */
151     struct audchannel audch[64]; /* vob-wide audio and subpicture mapping */
152       /* index meaning:
153         0-31: top two bits are the audio type (0 => AC3, 1 => MPEG, 2 => PCM, 3 => DTS),
154             bottom 3 bits are the channel id
155         32-63: bottom five bits are subpicture id */
156     unsigned char buttoncoli[24]; /* 3 groups of SL_COLI (button colour) info for PCI packets */
157 };
158 
159 struct buttoninfo { /* describes a button within a single subpicture stream */
160     int substreamid; /* substream ID as specified to spumux */
161     bool autoaction; /* true for auto-action button */
162     int x1,y1,x2,y2; /* button bounds */
163     char *up,*down,*left,*right; /* names of neighbouring buttons */
164     int grp;
165 };
166 
167 #define MAXBUTTONSTREAM 3
168 struct button { /* describes a button including versions across different subpicture streams */
169     char *name; /* button name */
170     struct vm_statement *commands; /* associated commands */
171     struct buttoninfo stream[MAXBUTTONSTREAM]; /* stream-specific descriptions */
172     int numstream; /* nr of stream entries actually used */
173 };
174 
175 struct pgc { /* describes a program chain corresponding to a <pgc> directive */
176     int numsources; /* length of sources array */
177     int numbuttons; /* length of buttons array */
178     int numchapters,numprograms,numcells,pauselen;
179     int entries; /* bit mask of applicable menu entry types, or, in a titleset, nonzero if non-title PGC */
180     struct source **sources; /* array of <vob> directives seen */
181     struct button *buttons; /* array */
182     struct vm_statement *prei,*posti;
183     struct colorinfo *colors;
184     struct pgcgroup *pgcgroup; /* back-pointer to containing pgcgroup */
185     unsigned char subpmap[32][4];
186       /* per-PGC explicit mapping of subpicture streams to alternative display modes for same
187         <subpicture> track. Each entry is (128 | id) if present; 127 if not present. */
188 };
189 
190 struct pgcgroup { /* common info across a set of menus or a set of titles (<menus> and <titles> directives) */
191     vtypes pstype; // 0 - vts, 1 - vtsm, 2 - vmgm
192     struct pgc **pgcs; /* array[numpgcs] of pointers */
193     int numpgcs;
194     int allentries; /* mask of entry types present */
195     int numentries; /* number of entry types present */
196     struct vobgroup *pg_vg; /* only for pstype==VTYPE_VTS, otherwise shared menugroup.mg_vg field is used */
197 };
198 
199 struct langgroup { /* contents of a <menus> directive */
200     char lang[3]; /* value of the "lang" attribute */
201     struct pgcgroup *pg;
202 };
203 
204 struct menugroup { /* contents specific to all collections of <menus> directives, either VTSM or VMGM */
205     int numgroups; /* length of groups array */
206     struct langgroup *groups; /* array, one entry per <menus> directive */
207     struct vobgroup *mg_vg; /* common among all groups[i]->pg elements */
208       /* fixme: I don't think this works right with multiple <menus> ... </menus> sections,
209         which the XML does allow */
210 };
211 
212 struct vobgroup { /* contents of a menuset or titleset (<menus> or <titles>) */
213     int numaudiotracks; /* nr <audio> tags seen = size of used part of ad/adwarn arrays */
214     int numsubpicturetracks; /* nr <subpicture> tags seen = size of used part of sp/spwarn arrays */
215     int numvobs; /* size of vobs array */
216     int numallpgcs; /* size of allpgcs array */
217     struct pgc **allpgcs; /* array of pointers to PGCs */
218     struct vob **vobs; /* array of pointers to VOBs */
219     struct videodesc vd; /* describes the video stream, one <video> tag only */
220     struct videodesc vdwarn; /* for saving attribute value mismatches */
221     struct audiodesc ad[8]; /* describes the audio streams, one per <audio> tag */
222     struct audiodesc adwarn[8]; /* for saving attribute value mismatches */
223     struct subpicdesc sp[32]; /* describes the subpicture streams, one per <subpicture> tag */
224     struct subpicdesc spwarn[32]; /* for saving attribute value mismatches */
225 };
226 
227 struct vtsdef { /* describes a VTS */
228     bool hasmenu;
229     int numtitles; /* length of numchapters array */
230     int *numchapters; /* number of chapters in each title */
231     int numsectors;
232     char vtssummary[0x300]; /* copy of VTS attributes (bytes 0x100 onwards of VTS IFO) */
233     char vtscat[4]; /* VTS_CAT (copy of bytes 0x22 .. 0x25 of VTS IFO) */
234 };
235 
236 // keeps TT_SRPT within 1 sector
237 #define MAXVTS 170
238 
239 struct toc_summary {
240     struct vtsdef vts[MAXVTS];
241     int numvts;
242 };
243 
244 struct workset { /* overall parameters for generation of a domain (VMG or VTS) */
245     const struct toc_summary *titlesets; /* VMG only */
246     const struct menugroup *menus; /* VMG and VTS */
247     const struct pgcgroup *titles; /* VTS only */
248 };
249 
250 /* following implemented in dvdauthor.c */
251 
252 extern const char * const entries[]; /* PGC menu entry types */
253 extern bool
254     jumppad, /* reserve registers and set up code to allow convenient jumping between titlesets */
255     allowallreg; /* don't reserve any registers for convenience purposes */
256 extern const char * const pstypes[]; /* names of PGC types, indexed by vtypes values */
257 
258 void write8(unsigned char *p,unsigned char d0,unsigned char d1,
259             unsigned char d2,unsigned char d3,
260             unsigned char d4,unsigned char d5,
261             unsigned char d6,unsigned char d7);
262 void write4(unsigned char *p,unsigned int v);
263 void write2(unsigned char *p,unsigned int v);
264 unsigned int read4(const unsigned char *p);
265 unsigned int read2(const unsigned char *p);
266 int getsubpmask(const struct videodesc *vd);
267 int getratedenom(const struct vobgroup *va);
268 int findvobu(const struct vob *va,pts_t pts,int l,int h);
269 pts_t getptsspan(const struct pgc *ch);
270 pts_t getframepts(const struct vobgroup *va);
271 unsigned int buildtimeeven(const struct vobgroup *va,int64_t num);
272 int getaudch(const struct vobgroup *va,int a);
273 int findcellvobu(const struct vob *va,int cellid);
274 pts_t getcellpts(const struct vob *va,int cellid);
275 int vobgroup_set_video_attr(struct vobgroup *va,int attr,const char *s);
276 int vobgroup_set_video_framerate(struct vobgroup *va,int rate);
277 int audiodesc_set_audio_attr(struct audiodesc *ad,struct audiodesc *adwarn,int attr,const char *s);
278 
279 /* following implemented in dvdcompile.c */
280 
281 unsigned char *vm_compile
282   (
283     const unsigned char *obuf, /* start of buffer for computing instruction numbers for branches */
284     unsigned char *buf, /* where to insert new compiled code */
285     const struct workset *ws,
286     const struct pgcgroup *curgroup,
287     const struct pgc *curpgc,
288     const struct vm_statement *cs,
289     vtypes ismenu
290   );
291   /* compiles the parse tree cs into actual VM instructions. */
292 void vm_optimize(const unsigned char *obuf, unsigned char *buf, unsigned char **end);
293   /* does various peephole optimizations on the part of obuf from buf to *end. */
294 struct vm_statement *vm_parse(const char *b);
295 
296 /* following implemented in dvdifo.c */
297 
298 void WriteIFOs(const char *fbase,const struct workset *ws);
299 void TocGen(const struct workset *ws,const struct pgc *fpc,const char *fname);
300 
301 /* following implemented in dvdpgc.c */
302 
303 int CreatePGC(FILE *h,const struct workset *ws,vtypes ismenu);
304 
305 /* following implemented in dvdvob.c */
306 
307 int FindVobus(const char *fbase,struct vobgroup *va,vtypes ismenu);
308 void MarkChapters(struct vobgroup *va);
309 void FixVobus(const char *fbase,const struct vobgroup *va,const struct workset *ws,vtypes ismenu);
310 int calcaudiogap(const struct vobgroup *va,int vcid0,int vcid1,int ach);
311 
312 #endif
313