plans: | |
- The primary object that applications deal with is a GstPipeline. A | |
given pipeline is connected to a particular main loop (GMainLoop for | |
glib, etc.). Calls to gst_ functions for objects owned by that | |
pipeline must be done from the context of the pipeline's main loop. | |
Signals fired by elements are marshalled in the pipeline's main | |
loop. | |
Notably, this means the gst_ API is not necessarily thread-safe. | |
However, it is safe to operate on different GstPipelines from | |
different threads. This makes it possible, for example, for | |
rhythmbox to play music and gather metadata from different threads | |
using different pipelines. Likewise, it's also possible to do | |
both in the same thread. | |
- The primary method of scheduling an element is through a generic | |
'iterate()' method. The iterate method explicitly tells the core | |
what it is waiting for (a specific time, pads to have available | |
data, etc.), and the core calls the iterate method when these | |
"triggers" happen. GstElement subclasses will be created to | |
emulate 0.8-style get/chain/loop methods. Existing elements will | |
be converted to the new subclasses rather than implement the | |
iterate method directly, unless there is a compelling reason to | |
do so. Iterate implementations are expected not to block, ever. | |
Rationale: This makes it possible to create completely non-blocking | |
elements. | |
- Scheduling elements will be done in either a threaded or | |
non-threaded way. The idle handler that is called by a pipeline's | |
main loop determines which elements are ready to be iterated | |
(based on their triggers), and puts them into a ready queue. In | |
the non-threaded case, the idle handler then calls the iterate() | |
method on each element in the ready queue. In the threaded case, | |
additional helper threads (which are completely owned by the | |
pipeline) are used to call the iterate methods. | |
Note that in the threaded case, elements may not always be run | |
in the same thread. | |
Some elements are much easier to write if they run in the same | |
thread as the main loop (i.e., elements that are also GUI widgets). | |
An element flag can be set to make the manager always call the | |
iterate method in the manager context (i.e., in the main loop | |
thread). Also, elements like spider need to make core calls | |
which may not be allowed from other threads. | |
Rationale: Doing all bookkeeping in a single thread/context makes | |
the core code _much_ simpler. This bookkeeping takes only a | |
minimal amount of CPU time, less than 5% of the CPU time in a | |
rhythmbox pipeline. There is very little benefit to spreading | |
this over multiple CPUs until the number of CPUs is greater than | |
~16, and you have _huge_ pipelines. Also, a single-threaded | |
manager significantly decreases the number of locks necessary | |
in the core, decreasing lock contention (if any) and making it | |
easier to understand deadlocks (if any). | |
- There are essentially two types of objects/structures. One type | |
includes objects that are derived from GObject, and are passed in | |
function calls similarly to gtk. The other type includes objects | |
(structures, really) that are not reference counted and passed | |
around similar to how GstCaps works in 0.8. That is, functions | |
that take 'const GstCaps *' do not take ownership of the passed | |
object, whereas functions that take 'GstCaps *' do. Similar is | |
true for return values. | |
- The concept of GstBuffer from 0.8 will be split into two types. | |
One type will focus solely on holding information pertaining to | |
ownership of a memory area (call this GstMemBuffer), and the | |
other type will focus solely in transfering information between | |
elements (call this GstPipeBuffer). In case you get confused, | |
GstMemBuffers _are not_ transferred between elements, and | |
GstPipeBuffers _do not_ own the memory they point to. | |
In general, GstPipeBuffers point to (and reference) a GstMemBuffer. | |
GstMemBuffers are GObjects. GstPipeBuffers are structs, like | |
GstCaps. GstPipeBuffers have timestamps, durations, and flags. | |
GstMemBuffers contain read/write flags. There are no subbuffers | |
for either type, because they are not necessary. Essentially, | |
GstPipeBuffers completely replace the concept of subbuffers. | |
(I'd like to continue to use the name GstBuffer for GstPipeBuffers, | |
since its usage is much more common in elements.) | |
Rationale: Memory regions need an ultimate owner and reference | |
counting. However, chunks passed around between elements need | |
to be small and efficient. These goals are non-overlapping and | |
conflicting, and thus are inappropriate to be combined in the | |
same class. | |
- Core objects should have very few (if any) public fields. This | |
means that accessor macros will all be eliminated and replaced | |
with accessor functions. | |
Rationale: This makes it possible to change the core more during | |
an ABI-stable series. | |
- Remove pluggable scheduling. | |
Rationale: We need one good scheduler. Having multiple schedulers | |
is directly opposed to this goal. | |
- 0.8-style element states are split up. One state (AppState) | |
indicates what the application wants the element to be doing, | |
and is completely under the control of the application. The | |
other state (ElementState) indicates what the element is actually | |
doing, and is under control of the element. If the application | |
wants an element to pause, it sets the AppState to PAUSED, and | |
the element eventually changes its ElementState to PAUSED (and | |
fires a signal). If the element has an error or EOS, it sets | |
its ElementState to SOME_STATE and fires a signal, while the | |
AppState remains at PLAYING. The actual number and descriptions | |
of states has not been discussed. | |
Rationale: It's pretty obvious that we're mixing concepts for | |
elements states in 0.8. | |
- getcaps() methods will be replaced by an element_allowed_caps() | |
field in the pad. The primary reason for this is because | |
renegotiation only needs to happen when circumstances change. | |
This is more easily done by a field in GstPad and notification | |
of peers when this changes. | |
Somewhere, there's a document I wrote about completely redoing | |
caps. | |