updates
[platform/upstream/gst-libav.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 * .pc/, which is a tree of files that quilt uses to keep control of its state.
23   It contains a list of applied patches, and one directory per patch,
24   containing a tree of hardlinked files that were added to the patchset, and
25   a .pc file listing all files part of the patchset.
26 * the result of having all these patches commited (ie, quilt push -a) to the
27   ffmpeg tree.
28
29 Both the actually patched CVS ffmpeg code as well as the .pc dir need to be
30 commited to CVS so the state of quilt wrt. the source is in sync.
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
64 - if you want to add a file to a patchset, you need to:
65   - be in the right patchset
66   - quilt add (file)
67   - cvs add .pc/(patchsetname)/(file)
68   - cvs commit .pc/(patchsetname) (to update the state of quilt in cvs)
69   - edit the file
70   - cvs add the file if it doesn't exist yet
71   - quilt refresh
72   - quilt push -a (This one is IMPORTANT, otherwise you'll have a huge diff)
73   - cvs commit
74
75 - if you want to add a patchset, you need to:
76   - go over the procedure with thomas to check it's correct
77   - decide where in the stack to put it.  ask for help if you don't know.
78   - go there in the patch stack (use quilt pop/push)
79   - quilt new (patchsetname).patch (don't forget .patch !)
80   - quilt add (files)
81   - cvs add .pc/(patchsetname) the whole tree
82   - cvs commit .pc/(patchsetname)
83   - quilt refresh
84   - quilt push -a
85   - cvs commit
86   - cvs diff (to check if any of the files are unknown to CVS; if they are,
87     you need to add them to CVS)
88
89 THE UPSTREAM
90 ------------
91 At some points you want to update the upstream snapshot code to a newer date.
92 This is easy if you follow the steps outlined here, but make sure to follow
93 them correctly !
94
95 - find a good CVS snapshot date for upstream, one that is known to work.
96   You're going to save yourself quite a bit of trouble if you verify this
97   first !
98 - check it out to a local directory:
99   cvs -z9 -d:pserver:anonymous@mplayerhq.hu:/cvsroot/ffmpeg export -D '2004-04-11 23:00 GMT' ffmpeg
100 - compile it and test it, make sure it works
101
102 - in gst-ffmpeg/gst-libs/ext/ffmpeg:
103   - Pre-flight checks:
104     - first make sure you don't have local changes, all files are either in
105       CVS or in .cvsignore patch, the whole quilt stack is applied, and stuff
106       works.
107     - do a quilt pop -a and quilt push -a to verify everything is ok.
108
109   - Branch and rollback:
110     - tag HEAD with the branch root point:
111       cvs tag BRANCH-UPDATE-CVS-2004-04-11-23-00-ROOT
112     - branch:
113       cvs tag -b BRANCH-UPDATE-CVS-2004-04-11-23-00
114     - FIXME: lock cvs HEAD
115     - update local copy to branch:
116       cvs update -r BRANCH-UPDATE-CVS-2004-04-11-23-00
117     - peel off all patches:
118       quilt pop -a
119     - commit this
120       cvs commit
121     - check
122       cvs diff
123       you should only have ? for files that are generated somehow (binaries,
124       build files, ...)
125       you get warnings about cvs not finding files to diff that are in .pc
126       or generated by your patches
127
128   
129     - if you want, you can now compare this state of CVS (which should 
130       be last upstream CVS combined with your local unapplied quilt state)
131     - remember to NOT do cvs update from here on, since you popped your quilt
132       state all your added files that are also in CVS are not locally present.
133
134   - sync with upstream:
135     - in a temp dir, redo the export:
136       cd ..
137       mkdir tmp
138       cd tmp
139       cvs -z9 -d:pserver:anonymous@mplayerhq.hu:/cvsroot/ffmpeg export -D '2004-04-11 23:00 GMT' ffmpeg
140     - rsync it over the old ffmpeg tree
141       rsync -arv ffmpeg ..
142     - go back and commit this new snapshot
143       cd ../ffmpeg
144       cvs commit
145     - check if any new files got added that you should add to cvs
146       cvs diff
147       This will list a lot of local files missing, from your quilt state,
148       which you shouldn't worry about.  Just inspect all the ?'s and add
149       files to cvs that belong to upstream and should be in cvs.
150     - if everything's ok and commited, tag the state:
151       cvs tag UPSTREAM-CVS-2004-04-11-23-00
152
153   - reapply and fix quilt patches one by one
154     - try applying one
155       quilt push
156     - if that didn't work, inspect the patch and figure out how to fix it:
157       - if the patch got applied upstream completely, quilt push will tell
158         you the patch looks like a reverse patch.  In that case you can
159         remove the patch from your patches file (patches/series), and
160         remove the .pc/$(patchname) and patches/$(patchname).patch files from
161         cvs.
162       - if the patch conflicts somehow, you can force application with
163         quilt push -f
164         and then resolve all the rejects, and fix the patch completely.
165         Then refresh quilt state with 
166         quilt refresh
167      - when the patch is succesfully removed or reworked, commit current state
168        to CVS, then check again if nothing is missing using cvs diff, and
169        resolve problems/apply missing files from your quilt state/...
170
171   - after reapplying your complete quilt state, test locally if the complete
172     gst-ffmpeg module now works.  Compile and test.  Resolve all problems
173     (upstream errors, missing symbols, missing files, ...) until you have
174     a working module.  commit again.
175
176   - merge to head:
177     - update locally back to head
178       cvs update -A
179     - FIXME: unlock cvs HEAD
180     - merge from your branch
181       cvs update -j BRANCH-UPDATE-CVS-2004-04-11-23-00
182     - commit
183       cvs commit
184     - check for diffs
185       cvs diff
186     - tag merge point
187       cvs tag BRANCH-UPDATE-CVS-2004-04-11-23-00-MERGE
188     - add upstream date to "THE RECORDS" below
189
190   - get a drink
191
192 THE PLUGIN
193 ----------
194 Some notes on how ffmpeg wrapping inside GStreamer currently works:
195 * gstffmpeg{dec,enc,demux,mux}.c are wrappers for specific element types from
196     their ffmpeg counterpart. If you want to wrap a new type of element in
197     wrapper file.
198
199 * gstffmpegcolorspace.c is a wrapper for one specific function in ffmpeg:
200     colorspace conversion. This works different from the previously mentioned
201     ones, and we'll come to that in the next item. If you want to wrap one
202     specific function, then that, too, belongs in a new wrapper file.
203
204 * the important difference between all those is that the colorspace element
205     contains one element, so there is a 1<->1 mapping. This makes for a fairly
206     basic element implementation. gstffmpegcolorspace.c, therefore, doesn't
207     differ much from other colorspace elements. The ffmpeg element types,
208     however, define a whole *list* of elements (in GStreamer, each decoder etc.
209     needs to be its own element). We use a set of tricks for that to keep
210     coding simple: codec mapping and dynamic type creation.
211
212 * ffmpeg uses CODEC_ID_* enumerations for their codecs. GStreamer uses caps,
213     which consists of a mimetype and a defined set of properties. In ffmpeg,
214     these properties live in a AVCodecContext struct, which contains anything
215     that could configure any codec (which makes it rather messy, but ohwell).
216     To convert from one to the other, we use codec mapping, which is done in
217     gstffmpegcodecmap.[ch]. This is the most important file in the whole
218     ffmpeg wrapping process! It contains functions to go from a codec type
219     (video or audio - used as the output format for decoding or the input
220     format for encoding), a codec id (to identify each format) or a format id
221     (a string identifying a file format - usually the file format extension)
222     to a GstCaps, and the other way around.
223
224 * to define multiple elements in one source file (which all behave similarly),
225     we dynamically create types for each plugin and let all of them operate on
226     the same struct (GstFFMpegDec, GstFFMpegEnc, ...). The functions in
227     gstffmpeg{dec,enc,demux,mux}.c called gst_ffmpeg*_register() do this.
228     The magic is as follows: for each codec or format, ffmpeg has a single
229     AVCodec or AV{Input,Output}Format, which are packed together in a list of
230     supported codecs/formats. We simply walk through the list, for each of
231     those, we check whether gstffmpegcodecmap.c knows about this single one.
232     If it does, we get the GstCaps for each pad template that belongs to it,
233     and register a type for all of those together. We also leave this inside
234     a caching struct, that will later be used by the base_init() function to
235     fill in information about this specific codec in the class struct of this
236     element (pad templates and codec/format information). Since the actual
237     codec information is the only thing that really makes each codec/format
238     different (they all behave the same through the ffmpeg API), we don't
239     really need to do anything else that is codec-specific, so all other
240     functions are rather simple.
241
242 * one particular thing that needs mention is how gstffmpeg{mux,demux}.c and
243     gstffmpegprotocol.c interoperate. ffmpeg uses URLProtocols for data input
244     and output. Now, of course, we want to use the *GStreamer* way of doing
245     input and output (filesrc, ...) rather than the ffmpeg way. Therefore, we
246     wrap up a GstPad as a URLProtocol and register this with ffmpeg. This is
247     what gstffmpegprotocol.c does. The URL is called gstreamer://%p, where %p
248     is the address of a GstPad. gstffmpeg{mux,demux}.c then open a file called
249     gstreamer://%p, with %p being their source/sink pad, respectively. This
250     way, we use GStreamer for data input/output through the ffmpeg API. It's
251     rather ugly, but it has worked quite well so far.
252
253 * there's lots of things that still need doing. See the TODO file for more
254     information.
255
256 THE RECORDS
257 -----------
258 - list of snapshots used:
259
260   CVS-2004-04-11-23-00
261
262
263 THE REMINDERS
264 -------------
265 * the initial ffmpeg checkout was imported using:
266   - get CVS ffmpeg
267     cvs -z3 -d:pserver:anonymous@mplayerhq.hu:/cvsroot/ffmpeg co -D '2004-03-09 06:00 GMT' ffmpeg