docs: cleanup makefiles
[gstreamer-omap:gst-ffmpeg.git] / HACKING
1 THE GOAL
2 --------
3 What we are trying to achieve:
4
5 satisfy:
6   patching of CVS checkout using our patch files placed in our CVS
7
8   passing of
9     make
10     make distcheck
11     non-srcdir build (ie, mkdir build; cd build; ../configure; make)
12
13 THE SETUP
14 ---------
15 There is a "mirror" root CVS module that contains "ffmpeg".
16 This directory contains a vendor-branch checkout of upstream FFmpeg CVS
17 of a given day.
18
19 On head, the following things have been commited on top of this:
20 * patches/, which is a directory with a set of patches, and a series file
21   listing the order, as generated by quilt
22 * the result of having all these patches commited (ie, quilt push -a) to the
23   ffmpeg tree.
24
25 The patched CVS ffmpeg code needs to be commited to CVS so that a checkout 
26 gives the patched code
27
28 The Quilt state .pc hidden directory must NOT be committed to CVS, because 
29 having CVS subdirs inside it confuses the hell out of quilt and causes it to
30 start storing diffs against CVS Entries files, and all hell breaks loose
31
32 THE WARNING
33 -----------
34
35 ***
36
37 NEVER EVER commit stuff in gst-libs/ext/ffmpeg UNLESS your quilt stack is
38 completely applied !
39 This means, ALWAYS make sure quilt push -a has been run without problems.
40
41 What's more, if you want to be on the safe side, make sure that you can
42 unapply and reapply without problems, by running quilt pop -a then
43 quilt push -a.
44
45 The ONLY exception to this is when you're working on a branch to update
46 the upstream source you're working with.
47
48 ***
49
50 THE WAY
51 -------
52 - If you want to hack on our copy of the FFmpeg code, there are some basic
53   rules you need to respect:
54   - you need to use quilt.  If you don't use quilt, you can't hack on it.
55   - we separate patches based on the functionality they patch, and whether
56     or not we want to send stuff upstream.  Make sure you work in the right
57     patch.  use "quilt applied" to check which patches are applied.
58   - before starting to hack, run cvs diff.  There should be NO diffs, and
59     NO files listed with question mark.  If there are, somebody before you
60     probably made a mistake.  To manage the state correctly, it is vital that
61     none of the files are unknown to CVS.
62
63 FIRST TIME:
64   - The quilt state is kept in a hidden dir in the gst-libs/ext/ffmpeg dir, 
65     but this hidden dir can't be kept in CVS because it confuses patch. Hence
66     when you get a clean gst-ffmpeg checkout you have an ffmpeg tree with
67     patches applied, but no quilt metadata to modify it with.
68
69   - You need to create the quilt metadata in your checkout:
70     1) Unroll the quilt patches. In gst-libs/ext/ffmpeg, run:
71
72        tac patches/series | while read p; do patch -p1 -R < "patches/$p"; done
73
74     2) Now, push all the patches to quilt and it will apply them, but now with
75        the appropriate stored metadata:
76
77        quilt push -a
78
79 - if you want to add a file to a patchset, you need to:
80   - be in the right patchset
81   - quilt add (file)
82   - cvs add .pc/(patchsetname)/(file)
83   - cvs commit .pc/(patchsetname) (to update the state of quilt in cvs)
84   - edit the file
85   - cvs add the file if it doesn't exist yet
86   - quilt refresh
87   - quilt push -a (This one is IMPORTANT, otherwise you'll have a huge diff)
88   - cvs commit
89
90 - if you want to add a patchset, you need to:
91   - go over the procedure with thomas to check it's correct
92   - decide where in the stack to put it.  ask for help if you don't know.
93   - go there in the patch stack (use quilt pop/push)
94   - quilt new (patchsetname).patch (don't forget .patch !)
95   - quilt add (files)
96   - cvs add .pc/(patchsetname) the whole tree
97   - cvs commit .pc/(patchsetname)
98   - quilt refresh
99   - quilt push -a
100   - cvs commit
101   - cvs diff (to check if any of the files are unknown to CVS; if they are,
102     you need to add them to CVS)
103
104 THE UPSTREAM
105 ------------
106 At some points you want to update the upstream snapshot code to a newer date.
107 This is easy if you follow the steps outlined here, but make sure to follow
108 them correctly !
109
110 - find a good CVS snapshot date for upstream, one that is known to work.
111   You're going to save yourself quite a bit of trouble if you verify this
112   first !
113 - check it out to a local directory:
114   cvs -z9 -d:pserver:anonymous@mplayerhq.hu:/cvsroot/ffmpeg export -D '2004-04-11 23:00 GMT' ffmpeg
115 - compile it and test it, make sure it works
116
117 - in gst-ffmpeg/gst-libs/ext/ffmpeg:
118   - Pre-flight checks:
119     - first make sure you don't have local changes, all files are either in
120       CVS or in .cvsignore patch, the whole quilt stack is applied, and stuff
121       works.
122     - do a quilt pop -a and quilt push -a to verify everything is ok.
123
124   - Branch and rollback:
125     - tag HEAD with the branch root point:
126       cvs tag BRANCH-UPDATE-CVS-2004-04-11-23-00-ROOT
127     - branch:
128       cvs tag -b BRANCH-UPDATE-CVS-2004-04-11-23-00
129     - FIXME: lock cvs HEAD
130     - update local copy to branch:
131       cvs update -r BRANCH-UPDATE-CVS-2004-04-11-23-00
132     - peel off all patches:
133       quilt pop -a
134     - commit this
135       cvs commit
136     - check
137       cvs diff
138       you should only have ? for files that are generated somehow (binaries,
139       build files, ...)
140       you get warnings about cvs not finding files to diff that are in .pc
141       or generated by your patches
142
143   
144     - if you want, you can now compare this state of CVS (which should 
145       be last upstream CVS combined with your local unapplied quilt state)
146     - remember to NOT do cvs update from here on, since you popped your quilt
147       state all your added files that are also in CVS are not locally present.
148
149   - sync with upstream:
150     - in a temp dir, redo the export:
151       cd ..
152       mkdir tmp
153       cd tmp
154       cvs -z9 -d:pserver:anonymous@mplayerhq.hu:/cvsroot/ffmpeg export -D '2004-04-11 23:00 GMT' ffmpeg
155     - rsync it over the old ffmpeg tree
156       rsync -arv ffmpeg ..
157     - go back and commit this new snapshot
158       cd ../ffmpeg
159       cvs commit
160     - check if any new files got added that you should add to cvs
161       cvs diff
162       This will list a lot of local files missing, from your quilt state,
163       which you shouldn't worry about.  Just inspect all the ?'s and add
164       files to cvs that belong to upstream and should be in cvs.
165     - if everything's ok and commited, tag the state:
166       cvs tag UPSTREAM-CVS-2004-04-11-23-00
167
168   - reapply and fix quilt patches one by one
169     - try applying one
170       quilt push
171     - if that didn't work, inspect the patch and figure out how to fix it:
172       - if the patch got applied upstream completely, quilt push will tell
173         you the patch looks like a reverse patch.  In that case you can
174         remove the patch from your patches file (patches/series), and
175         remove the .pc/$(patchname) and patches/$(patchname).patch files from
176         cvs.
177       - if the patch conflicts somehow, you can force application with
178         quilt push -f
179         and then resolve all the rejects, and fix the patch completely.
180         Then refresh quilt state with 
181         quilt refresh
182      - when the patch is succesfully removed or reworked, commit current state
183        to CVS, then check again if nothing is missing using cvs diff, and
184        resolve problems/apply missing files from your quilt state/...
185
186   - after reapplying your complete quilt state, test locally if the complete
187     gst-ffmpeg module now works.  Compile and test.  Resolve all problems
188     (upstream errors, missing symbols, missing files, ...) until you have
189     a working module.  commit again.
190
191   - merge to head:
192     - update locally back to head
193       cvs update -A
194     - FIXME: unlock cvs HEAD
195     - merge from your branch
196       cvs update -j BRANCH-UPDATE-CVS-2004-04-11-23-00
197     - commit
198       cvs commit
199     - check for diffs
200       cvs diff
201     - tag merge point
202       cvs tag BRANCH-UPDATE-CVS-2004-04-11-23-00-MERGE
203     - add upstream date to "THE RECORDS" below
204
205   - get a drink
206
207 THE PLUGIN
208 ----------
209 Some notes on how ffmpeg wrapping inside GStreamer currently works:
210 * gstffmpeg{dec,enc,demux,mux}.c are wrappers for specific element types from
211     their ffmpeg counterpart. If you want to wrap a new type of element in
212     wrapper file.
213     The ffmpeg element types, define a whole *list* of elements (in 
214     GStreamer, each decoder etc. needs to be its own element). 
215     We use a set of tricks for that to keep coding simple: codec 
216     mapping and dynamic type creation.
217
218 * ffmpeg uses CODEC_ID_* enumerations for their codecs. GStreamer uses caps,
219     which consists of a mimetype and a defined set of properties. In ffmpeg,
220     these properties live in a AVCodecContext struct, which contains anything
221     that could configure any codec (which makes it rather messy, but ohwell).
222     To convert from one to the other, we use codec mapping, which is done in
223     gstffmpegcodecmap.[ch]. This is the most important file in the whole
224     ffmpeg wrapping process! It contains functions to go from a codec type
225     (video or audio - used as the output format for decoding or the input
226     format for encoding), a codec id (to identify each format) or a format id
227     (a string identifying a file format - usually the file format extension)
228     to a GstCaps, and the other way around.
229
230 * to define multiple elements in one source file (which all behave similarly),
231     we dynamically create types for each plugin and let all of them operate on
232     the same struct (GstFFMpegDec, GstFFMpegEnc, ...). The functions in
233     gstffmpeg{dec,enc,demux,mux}.c called gst_ffmpeg*_register() do this.
234     The magic is as follows: for each codec or format, ffmpeg has a single
235     AVCodec or AV{Input,Output}Format, which are packed together in a list of
236     supported codecs/formats. We simply walk through the list, for each of
237     those, we check whether gstffmpegcodecmap.c knows about this single one.
238     If it does, we get the GstCaps for each pad template that belongs to it,
239     and register a type for all of those together. We also leave this inside
240     a caching struct, that will later be used by the base_init() function to
241     fill in information about this specific codec in the class struct of this
242     element (pad templates and codec/format information). Since the actual
243     codec information is the only thing that really makes each codec/format
244     different (they all behave the same through the ffmpeg API), we don't
245     really need to do anything else that is codec-specific, so all other
246     functions are rather simple.
247
248 * one particular thing that needs mention is how gstffmpeg{mux,demux}.c and
249     gstffmpegprotocol.c interoperate. ffmpeg uses URLProtocols for data input
250     and output. Now, of course, we want to use the *GStreamer* way of doing
251     input and output (filesrc, ...) rather than the ffmpeg way. Therefore, we
252     wrap up a GstPad as a URLProtocol and register this with ffmpeg. This is
253     what gstffmpegprotocol.c does. The URL is called gstreamer://%p, where %p
254     is the address of a GstPad. gstffmpeg{mux,demux}.c then open a file called
255     gstreamer://%p, with %p being their source/sink pad, respectively. This
256     way, we use GStreamer for data input/output through the ffmpeg API. It's
257     rather ugly, but it has worked quite well so far.
258
259 * there's lots of things that still need doing. See the TODO file for more
260     information.
261
262 THE RECORDS
263 -----------
264 - list of snapshots used:
265
266   CVS-2004-04-11-23-00
267   * other updates people didn't enter :)
268   CVS-2006-02-17-04-00
269
270 THE REMINDERS
271 -------------
272 * the initial ffmpeg checkout was imported using:
273   - get CVS ffmpeg
274     cvs -z3 -d:pserver:anonymous@mplayerhq.hu:/cvsroot/ffmpeg co -D '2004-03-09 06:00 GMT' ffmpeg