3 What we are trying to achieve:
6 patching of CVS checkout using our patch files placed in our CVS
11 non-srcdir build (ie, mkdir build; cd build; ../configure; make)
15 There is a "mirror" root CVS module that contains "ffmpeg".
16 This directory contains a vendor-branch checkout of upstream FFmpeg CVS
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
25 The patched CVS ffmpeg code needs to be commited to CVS so that a checkout
26 gives the patched code
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
37 NEVER EVER commit stuff in gst-libs/ext/ffmpeg UNLESS your quilt stack is
39 This means, ALWAYS make sure quilt push -a has been run without problems.
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
45 The ONLY exception to this is when you're working on a branch to update
46 the upstream source you're working with.
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.
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.
69 - You need to create the quilt metadata in your checkout:
70 1) Unroll the quilt patches. In gst-libs/ext/ffmpeg, run:
72 tac patches/series | while read p; do patch -p1 -R < "patches/$p"; done
74 2) Now, push all the patches to quilt and it will apply them, but now with
75 the appropriate stored metadata:
79 - if you want to add a file to a patchset, you need to:
80 - be in the right patchset
82 - cvs add .pc/(patchsetname)/(file)
83 - cvs commit .pc/(patchsetname) (to update the state of quilt in cvs)
85 - cvs add the file if it doesn't exist yet
87 - quilt push -a (This one is IMPORTANT, otherwise you'll have a huge diff)
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 !)
96 - cvs add .pc/(patchsetname) the whole tree
97 - cvs commit .pc/(patchsetname)
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)
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
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
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
117 - in gst-ffmpeg/gst-libs/ext/ffmpeg:
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
122 - do a quilt pop -a and quilt push -a to verify everything is ok.
124 - Branch and rollback:
125 - tag HEAD with the branch root point:
126 cvs tag BRANCH-UPDATE-CVS-2004-04-11-23-00-ROOT
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:
138 you should only have ? for files that are generated somehow (binaries,
140 you get warnings about cvs not finding files to diff that are in .pc
141 or generated by your patches
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.
149 - sync with upstream:
150 - in a temp dir, redo the export:
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
157 - go back and commit this new snapshot
160 - check if any new files got added that you should add to cvs
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
168 - reapply and fix quilt patches one by one
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
177 - if the patch conflicts somehow, you can force application with
179 and then resolve all the rejects, and fix the patch completely.
180 Then refresh quilt state with
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/...
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.
192 - update locally back to head
194 - FIXME: unlock cvs HEAD
195 - merge from your branch
196 cvs update -j BRANCH-UPDATE-CVS-2004-04-11-23-00
202 cvs tag BRANCH-UPDATE-CVS-2004-04-11-23-00-MERGE
203 - add upstream date to "THE RECORDS" below
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
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.
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.
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.
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.
259 * there's lots of things that still need doing. See the TODO file for more
264 - list of snapshots used:
267 * other updates people didn't enter :)
272 * the initial ffmpeg checkout was imported using:
274 cvs -z3 -d:pserver:anonymous@mplayerhq.hu:/cvsroot/ffmpeg co -D '2004-03-09 06:00 GMT' ffmpeg