1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
|
<chapter> <title> The video output layer </title>
<sect1> <title> Data structures and main loop </title>
<para>
Important data structures are defined in <filename> include/video.h
</filename> and <filename> include/video_output.h</filename>. The main
data structure is <type> picture_t</type>, which describes everything a
video decoder thread needs. Please refer to this file for more
information. Typically, <parameter> p_data </parameter> will be a
pointer to YUV planar picture.
</para>
<para>
Note also the <type> subpicture_t </type> structure. In fact the VLC SPU
decoder only parses the SPU header, and converts the SPU graphical data
to an internal format which can be rendered much faster. So a part of
the "real" SPU decoder lies in
<filename> src/video_output/video_spu.c</filename>.
</para>
<para>
The <type> vout_thread_t </type> structure is much more complex, but
you needn't understand everything. Basically the video output thread
manages a heap of pictures and subpictures (5 by default). Every
picture has a status (displayed, destroyed, empty...) and eventually
a presentation time. The main job of the video output is an infinite
loop to : [this is subject to change in the near future]
</para>
<orderedlist>
<listitem> <para> Find the next picture to display in the heap.
</para> </listitem>
<listitem> <para> Find the current subpicture to display.
</para> </listitem>
<listitem> <para> Render the picture (if the video output plug-in
doesn't support YUV overlay). Rendering will call an optimized
YUV plug-in, which will also do the scaling, add subtitles and
an optional picture information field.
</para> </listitem>
<listitem> <para> Sleep until the specified date.
</para> </listitem>
<listitem> <para> Display the picture (plug-in function). For
outputs which display RGB data, it is often accomplished with
a buffer switching. <parameter> p_vout->p_buffer </parameter>
is an array of two buffers where the YUV transform takes place,
and p_vout->i_buffer_index indicates the currently displayed
buffer.
</para> </listitem>
<listitem> <para> Manage events.
</para> </listitem>
</orderedlist>
</sect1>
<sect1> <title> Methods used by video decoders </title>
<para>
The video output exports a bunch of functions so that decoders can send
their decoded data. The most important function is
<function>vout_CreatePicture</function> which allocates the picture
buffer to the size indicated by the video decoder. It then just needs
to feed <type> (void *) </type><parameter> p_picture->p_data </parameter>
with the decoded data, and call <function> vout_DisplayPicture </function>
and <function> vout_DatePicture </function> upon necessary.
</para>
<itemizedlist>
<listitem> <para> <type> picture_t * </type> <function>
vout_CreatePicture </function>
<parameter> ( vout_thread_t *p_vout, int i_type, int i_width,
int i_height ) </parameter> :
Returns an allocated picture buffer. <parameter> i_type </parameter>
will be for instance <constant> YUV_420_PICTURE</constant>, and
i_width and i_height are in pixels.
</para>
<warning> <para> If no picture is available in the heap,
<function> vout_CreatePicture </function> will return NULL.
</para> </warning>
</listitem>
<listitem> <para> <function> vout_LinkPicture </function>
<parameter> ( vout_thread_t *p_vout, picture_t *p_pic ) </parameter> :
Increases the refcount of the picture, so that it doesn't get
accidently freed while the decoder still needs it. For instance,
an I or P picture can still be needed after displaying to decode
interleaved B pictures.
</para> </listitem>
<listitem> <para> <function> vout_UnlinkPicture </function>
<parameter> ( vout_thread_t *p_vout, picture_t *p_pic ) </parameter> :
Decreases the refcount of the picture. An unlink must be done
for every link previously made.
</para> </listitem>
<listitem> <para> <function> vout_DatePicture </function>
<parameter> ( vout_thread_t *p_vout, picture_t *p_pic ) </parameter> :
Gives the picture a presentation date. You can start working on
a picture before knowing precisely at what time it will be
displayed. For instance to date an I or P picture, you must wait
until you have decoded all previous B pictures (which are
indeed placed after - decoding order != presentation order).
</para> </listitem>
<listitem> <para> <function> vout_DisplayPicture </function>
<parameter> ( vout_thread_t *p_vout, picture_t *p_pic ) </parameter> :
Tells the video output that a picture has been completely decoded
and is ready to be rendered. It can be called before or after
<function> vout_DatePicture</function>.
</para> </listitem>
<listitem> <para> <function> vout_DestroyPicture </function>
<parameter> ( vout_thread_t *p_vout, picture_t *p_pic ) </parameter> :
Marks the picture as empty (useful in case of a stream parsing
error).
</para> </listitem>
<listitem> <para> <type> subpicture_t * </type> <function>
vout_CreateSubPicture </function> <parameter> ( vout_thread_t *p_vout,
int i_type, int i_size ) </parameter> :
Returns an allocated subpicture buffer. <parameter> i_type
</parameter> is <constant> DVD_SUBPICTURE </constant> or
<constant> TEXT_SUBPICTURE</constant>, <parameter> i_size
</parameter> is the length in bytes of the packet.
</para> </listitem>
<listitem> <para> <function> vout_DisplaySubPicture </function>
<parameter> ( vout_thread_t *p_vout, subpicture_t *p_subpic )
</parameter> :
Tells the video output that a subpicture has been completely
decoded. It obsoletes the previous subpicture.
</para> </listitem>
<listitem> <para> <function> vout_DestroySubPicture </function>
<parameter> ( vout_thread_t *p_vout, subpicture_t *p_subpic )
</parameter> :
Marks the subpicture as empty.
</para> </listitem>
</itemizedlist>
</sect1>
<sect1> <title> How to write a video output plug-in </title>
<para>
A video output takes care of the system calls to display the pictures and
manage the output window. Have a look at <filename>
plugins/x11/vout_x11.c</filename>. You must write the following
functions :
</para>
<orderedlist>
<listitem> <para> <type> int </type> <function> vout_Probe </function>
<parameter> ( probedata_t *p_data ) </parameter> :
Returns a score between 0 and 999 to indicate whether it can
run on the architecture. 999 is the best. <parameter> p_data
</parameter> is currently unused.
</para> </listitem>
<listitem> <para> <type> int </type> <function> vout_Create </function>
<parameter> ( vout_thread_t *p_vout ) </parameter> :
Basically, initializes and opens a new window. Returns TRUE if
it failed.
</para> </listitem>
<listitem> <para> <type> int </type> <function> vout_Init </function>
<parameter> ( vout_thread_t *p_vout ) </parameter> :
Creates optional picture buffers (for instance ximages or
xvimages). Returns TRUE if it failed.
</para> </listitem>
<listitem> <para> <function> vout_End </function> <parameter>
( vout_thread_t *p_vout ) </parameter> :
Frees optional picture buffers.
</para> </listitem>
<listitem> <para> <function> vout_Destroy </function> <parameter>
( vout_thread_t *p_vout ) </parameter> :
Unmaps the window and frees all allocated resources.
</para> </listitem>
<listitem> <para> <type> int </type> <function> vout_Manage
</function> <parameter> ( vout_thread_t *p_vout ) </parameter> :
Manages events (including for instance resize events).
</para> </listitem>
<listitem> <para> <function> vout_Display </function> <parameter>
( vout_thread_t *p_vout ) </parameter> :
Displays a previously rendered buffer.
</para> </listitem>
<listitem> <para> <function> vout_SetPalette </function>
<parameter> ( vout_thread_t *p_vout, u16 *red, u16 *green,
u16 *blue, u16 *transp ) </parameter> :
Sets the 8 bpp palette. <parameter> red, green </parameter>
and <parameter> blue </parameter> are arrays of 256 <type>
unsigned shorts</type>.
</para> </listitem>
</orderedlist>
</sect1>
<sect1> <title> How to write a YUV plug-in </title>
<para>
Look at the C source <filename> plugins/yuv/transforms_yuv.c</filename>.
You need to redefine just the same transformations. Basically, it is a
matrix multiply operation. Good luck.
</para>
</sect1>
</chapter>
|