<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.videolan.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Zil0</id>
	<title>VideoLAN Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.videolan.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Zil0"/>
	<link rel="alternate" type="text/html" href="https://wiki.videolan.org/Special:Contributions/Zil0/"/>
	<updated>2026-11-04T18:03:42Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://wiki.videolan.org/index.php?title=Hacker_Guide/Video_Output&amp;diff=33448</id>
		<title>Hacker Guide/Video Output</title>
		<link rel="alternate" type="text/html" href="https://wiki.videolan.org/index.php?title=Hacker_Guide/Video_Output&amp;diff=33448"/>
		<updated>2017-08-01T12:03:34Z</updated>

		<summary type="html">&lt;p&gt;Zil0: Update paths.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= The video output layer  =&lt;br /&gt;
&lt;br /&gt;
== Data structures and main loop  ==&lt;br /&gt;
&lt;br /&gt;
Important data structures are defined under include/ in the files vlc_picture.h, vlc_subpicture.h and vlc_vout.h. &lt;br /&gt;
&lt;br /&gt;
=== picture_t  ===&lt;br /&gt;
&lt;br /&gt;
The main data structure is &#039;&#039;picture_t&#039;&#039;, which describes everything a video decoder thread needs. Please, refer to those files for more information. Typically, p_data will be a pointer to YUV planar picture. &lt;br /&gt;
&lt;br /&gt;
=== subpicture_t and SPU  ===&lt;br /&gt;
&lt;br /&gt;
Note also the &#039;&#039;subpicture_t&#039;&#039; structure. In fact the VLC SPU (&#039;&#039;SubPicture Unit&#039;&#039;) 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 &amp;quot;actual&amp;quot; SPU decoder lies in src/video_output/vout_subpictures.c. &lt;br /&gt;
&lt;br /&gt;
=== vout_thread_t  ===&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;vout_thread_t&#039;&#039; structure is much more complex, but you needn&#039;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&amp;amp;nbsp;: [this is subject to change in the near future] &lt;br /&gt;
&lt;br /&gt;
#Find the next picture to display in the heap. &lt;br /&gt;
#Find the current subpicture to display. &lt;br /&gt;
#Render the picture (if the video output plug-in doesn&#039;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. &lt;br /&gt;
#Sleep until the specified date. &lt;br /&gt;
#Display the picture (plug-in function). For outputs which display RGB data, it is often accomplished with a buffer switching. p_vout-&amp;amp;gt;p_buffer is an array of two buffers where the YUV transform takes place, and p_vout-&amp;amp;gt;i_buffer_index indicates the currently displayed buffer. &lt;br /&gt;
#Manage events.&lt;br /&gt;
&lt;br /&gt;
== Methods used by video decoders  ==&lt;br /&gt;
&lt;br /&gt;
The video output exports a bunch of functions so that decoders can send their decoded data. The most important function is vout_CreatePicture which allocates the picture buffer to the size indicated by the video decoder. It then just needs to feed (void *) p_picture-&amp;amp;gt;p_data with the decoded data, and call vout_DisplayPicture and vout_DatePicture upon necessary. &lt;br /&gt;
&lt;br /&gt;
*picture_t * vout_CreatePicture ( vout_thread_t *p_vout, int i_type, int i_width, int i_height )&amp;amp;nbsp;: Returns an allocated picture buffer. i_type will be for instance YUV_420_PICTURE, and i_width and i_height are in pixels.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If no picture is available in the heap, vout_CreatePicture will return NULL. &lt;br /&gt;
&lt;br /&gt;
*vout_LinkPicture ( vout_thread_t *p_vout, picture_t *p_pic )&amp;amp;nbsp;: Increases the refcount of the picture, so that it doesn&#039;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. &lt;br /&gt;
*vout_UnlinkPicture ( vout_thread_t *p_vout, picture_t *p_pic )&amp;amp;nbsp;: Decreases the refcount of the picture. An unlink must be done for every link previously made. &lt;br /&gt;
*vout_DatePicture ( vout_thread_t *p_vout, picture_t *p_pic )&amp;amp;nbsp;: 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&amp;amp;nbsp;!= presentation order). &lt;br /&gt;
*vout_DisplayPicture ( vout_thread_t *p_vout, picture_t *p_pic )&amp;amp;nbsp;: Tells the video output that a picture has been completely decoded and is ready to be rendered. It can be called before or after vout_DatePicture. &lt;br /&gt;
*vout_DestroyPicture ( vout_thread_t *p_vout, picture_t *p_pic )&amp;amp;nbsp;: Marks the picture as empty (useful in case of a stream parsing error). &lt;br /&gt;
*subpicture_t * vout_CreateSubPicture ( vout_thread_t *p_vout, int i_channel, int i_type )&amp;amp;nbsp;: Returns an allocated subpicture buffer. i_channel is the ID of the subpicture channel, i_type is DVD_SUBPICTURE or TEXT_SUBPICTURE, i_size is the length in bytes of the packet. &lt;br /&gt;
*vout_DisplaySubPicture ( vout_thread_t *p_vout, subpicture_t *p_subpic )&amp;amp;nbsp;: Tells the video output that a subpicture has been completely decoded. It obsoletes the previous subpicture. &lt;br /&gt;
*vout_DestroySubPicture ( vout_thread_t *p_vout, subpicture_t *p_subpic )&amp;amp;nbsp;: Marks the subpicture as empty.&lt;br /&gt;
&lt;br /&gt;
== How to write a video output plug-in  ==&lt;br /&gt;
&lt;br /&gt;
A video output takes care of the system calls to display the pictures and manage the output window. For the most minimalistic framework, look at vmem.c, which just &amp;quot;renders&amp;quot; to dummy internal memory. From there, go on to directfb.c and svgalib.c, and finally go for x11 and windows. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Video outputs reside in the modules/video_output/ directory. modules/video_output/x11/xcommon.c gives example of functions you must write&amp;amp;nbsp;: &lt;br /&gt;
&lt;br /&gt;
*int Activate ( vlc_object_t *p_this ) &lt;br /&gt;
**As for any VLC module, this function verifies if the module suits VLC core needs, by interrogating p_this structure. &lt;br /&gt;
**In case of success, Activate sets up callback functions needed to run the video output (needed functions explained below), and returns VLC_SUCCESS &lt;br /&gt;
**In case of failure, Activate frees memory and returns an error code (VLC_EGENERIC, VLC_ENOMEM, ...) &lt;br /&gt;
*void Deactivate ( vlc_object_t *p_this ) &lt;br /&gt;
**Called to destroy the module: Deactivate needs to free all allocated memory and destroys cleanly the video output thread&lt;br /&gt;
&lt;br /&gt;
The callback functions you need to implement are (callback name, function prototype)&amp;amp;nbsp;: &lt;br /&gt;
&lt;br /&gt;
*(p_vout-&amp;amp;gt;pf_init, static int InitVideo ( vout_thread_t * );) &lt;br /&gt;
**Called at the beginning of the output thread and each time the window is resized, it creates a buffer of output pictures &lt;br /&gt;
*(p_vout-&amp;amp;gt;pf_end, static void EndVideo ( vout_thread_t * );) &lt;br /&gt;
**&amp;amp;nbsp;Destroys output pictures created by InitVideo &lt;br /&gt;
*(p_vout-&amp;amp;gt;pf_manage, static int ManageVideo ( vout_thread_t * );) &lt;br /&gt;
**Manage X11 events, and handle window resizing &lt;br /&gt;
*(p_vout-&amp;amp;gt;pf_render, static void RenderVideo ( vout_thread_t *, picture_t * );) &lt;br /&gt;
**Optional (set p_vout-&amp;amp;gt;pf_render to NULL if not implemented); Used when pictures from the decoder need to be rendered before display &lt;br /&gt;
*(p_vout-&amp;amp;gt;pf_display, static void DisplayVideo ( vout_thread_t *, picture_t * );) &lt;br /&gt;
**&amp;amp;nbsp;Does the actual display of pictures onto screen &lt;br /&gt;
*(p_vout-&amp;amp;gt;pf_control, static int Control ( vout_thread_t *, int, va_list );) &lt;br /&gt;
**Control facility for the video output&lt;br /&gt;
&lt;br /&gt;
== How to write a YUV plug-in  ==&lt;br /&gt;
&lt;br /&gt;
Look at the C source plugins/yuv/transforms_yuv.c. You need to redefine just the same transformations. Basically, it is a matrix multiply operation. Good luck.&lt;br /&gt;
&lt;br /&gt;
{{Hacker_Guide}}&lt;/div&gt;</summary>
		<author><name>Zil0</name></author>
	</entry>
</feed>