build ffplay so we can use it to test stuff
[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 WAY
33 -------
34
35 - If you want to hack on our copy of the FFmpeg code, there are some basic
36   rules you need to respect:
37   - you need to use quilt.  If you don't use quilt, you can't hack on it.
38   - we separate patches based on the functionality they patch, and whether
39     or not we want to send stuff upstream.  Make sure you work in the right
40     patch.  use "quilt applied" to check which patches are applied.
41   - before starting to hack, run cvs diff.  There should be NO diffs, and
42     NO files listed with question mark.  If there are, somebody before you
43     probably made a mistake.  To manage the state correctly, it is vital that
44     none of the files are unknown to CVS.
45   - if you want to add a file to a patchset, you need to:
46     - be in the right patchset
47     - quilt add (file)
48     - cvs add .pc/(patchsetname)/(file)
49     - cvs commit .pc/(patchsetname) (to update the state of quilt in cvs)
50     - edit the file
51     - cvs add the file if it doesn't exist yet
52     - quilt refresh
53     - quilt push -a (This one is IMPORTANT, otherwise you'll have a huge diff)
54     - cvs commit
55   - if you want to add a patchset, you need to:
56     - go over the procedure with thomas to check it's correct
57     - decide where in the stack to put it.  ask for help if you don't know.
58     - go there in the patch stack (use quilt pop/push)
59     - quilt new (patchsetname).patch (don't forget .patch !)
60     - quilt add (files)
61     - cvs add .pc/(patchsetname) the whole tree
62     - cvs commit .pc/(patchsetname)
63     - quilt refresh
64     - quilt push -a
65     - cvs commit
66     - cvs diff (to check if any of the files are unknown to CVS; if they are,
67       you need to add them to CVS)
68
69 THE PLUGIN
70 ----------
71 Some notes on how ffmpeg wrapping inside GStreamer currently works:
72 * gstffmpeg{dec,enc,demux,mux}.c are wrappers for specific element types from
73     their ffmpeg counterpart. If you want to wrap a new type of element in
74     ffmpeg (e.g. the URLProtocol things), then you'd need to write a new
75     wrapper file.
76
77 * gstffmpegcolorspace.c is a wrapper for one specific function in ffmpeg:
78     colorspace conversion. This works different from the previously mentioned
79     ones, and we'll come to that in the next item. If you want to wrap one
80     specific function, then that, too, belongs in a new wrapper file.
81
82 * the important difference between all those is that the colorspace element
83     contains one element, so there is a 1<->1 mapping. This makes for a fairly
84     basic element implementation. gstffmpegcolorspace.c, therefore, doesn't
85     differ much from other colorspace elements. The ffmpeg element types,
86     however, define a whole *list* of elements (in GStreamer, each decoder etc.
87     needs to be its own element). We use a set of tricks for that to keep
88     coding simple: codec mapping and dynamic type creation.
89
90 * ffmpeg uses CODEC_ID_* enumerations for their codecs. GStreamer uses caps,
91     which consists of a mimetype and a defined set of properties. In ffmpeg,
92     these properties live in a AVCodecContext struct, which contains anything
93     that could configure any codec (which makes it rather messy, but ohwell).
94     To convert from one to the other, we use codec mapping, which is done in
95     gstffmpegcodecmap.[ch]. This is the most important file in the whole
96     ffmpeg wrapping process! It contains functions to go from a codec type
97     (video or audio - used as the output format for decoding or the input
98     format for encoding), a codec id (to identify each format) or a format id
99     (a string identifying a file format - usually the file format extension)
100     to a GstCaps, and the other way around.
101
102 * to define multiple elements in one source file (which all behave similarly),
103     we dynamically create types for each plugin and let all of them operate on
104     the same struct (GstFFMpegDec, GstFFMpegEnc, ...). The functions in
105     gstffmpeg{dec,enc,demux,mux}.c called gst_ffmpeg*_register() do this.
106     The magic is as follows: for each codec or format, ffmpeg has a single
107     AVCodec or AV{Input,Output}Format, which are packed together in a list of
108     supported codecs/formats. We simply walk through the list, for each of
109     those, we check whether gstffmpegcodecmap.c knows about this single one.
110     If it does, we get the GstCaps for each pad template that belongs to it,
111     and register a type for all of those together. We also leave this inside
112     a caching struct, that will later be used by the base_init() function to
113     fill in information about this specific codec in the class struct of this
114     element (pad templates and codec/format information). Since the actual
115     codec information is the only thing that really makes each codec/format
116     different (they all behave the same through the ffmpeg API), we don't
117     really need to do anything else that is codec-specific, so all other
118     functions are rather simple.
119
120 * one particular thing that needs mention is how gstffmpeg{mux,demux}.c and
121     gstffmpegprotocol.c interoperate. ffmpeg uses URLProtocols for data input
122     and output. Now, of course, we want to use the *GStreamer* way of doing
123     input and output (filesrc, ...) rather than the ffmpeg way. Therefore, we
124     wrap up a GstPad as a URLProtocol and register this with ffmpeg. This is
125     what gstffmpegprotocol.c does. The URL is called gstreamer://%p, where %p
126     is the address of a GstPad. gstffmpeg{mux,demux}.c then open a file called
127     gstreamer://%p, with %p being their source/sink pad, respectively. This
128     way, we use GStreamer for data input/output through the ffmpeg API. It's
129     rather ugly, but it has worked quite well so far.
130
131 * there's lots of things that still need doing. See the TODO file for more
132     information.