Back to Home

VLC based video player. Part 2: using Direct3D

VLC · C ++ · DirectX

VLC based video player. Part 2: using Direct3D

    Introduction


    Hello habra

    In my previous article, I started talking about the development of a player based on VLC. In this article I will talk about the main aspects and difficulties that I had to face when writing a player. Here's what the main program window looks like:

    image
    The main program window

    Rendering a frame to the screen using Direct3D


    So, as I already said, LibVLC library is used to decode streaming video, which is the main part of the VLC player. The VMem plugin allows you to decode a video stream by applying various filters to it and finally save it to the user’s memory area. In order to speed up the output of the picture, I used Direct3D 9. In Direct3D there is the concept of surfaces and textures. Surface - is an array of bytes having a size of width x height:

    image
    Schematic representation of the surface

    Ie in fact, the surface is a bitmap. The
    texture differs from the surface in that it can be “superimposed” on primitives (polygons). The texture also has mip-map levels - reduced copies of the texture (used in 3D graphics)

    To display a film frame on the screen, we need to create an off-screen surface, transfer the pointer to the memory area to the VMem plugin, then copy the surface into the texture and draw a rectangle with the texture stretched over it. Schematically, this can be represented as follows:

    image
    The process of rendering

    Intermediate copying of a surface into a texture is necessary due to the peculiarities of access to surfaces and textures in Direct3D.
    The numbers in brackets during rendering are the texture coordinates; they show how the texture will be superimposed on the primitive.

    The problem of multithreading and window stretching


    When stretching the window, the back buffer used for rendering remains the same size, and therefore when resizing the window, the image is stretched and blurred. To prevent this from happening, you need to recreate the buffer. In Direct3D, this is done by calling IDIrect3DDevice9 :: Reset. In this case, a prerequisite for the successful re-creation of the buffer is the removal of all resources from the video memory. And since LibVLC works in a separate stream and writes data to our video surface, it is necessary to synchronize the mutexes or sections (to whom it is more convenient).
    You also need to solve the issue of rendering. Since in addition to rendering video, the application had elements that needed to be animated with a frequency> 25 frames sec. You can implement it this way: GUI elements during rendering cause the window to be redrawn as well as the video stream. Or the window is constantly redrawn with a simple application (as is done in games). In the first method, the stream decoding the video should send messages to the main stream that the application needs to be redrawn, which additionally loads the message queue. With the second method, you do not need to send messages - the application is always redrawn.

    User interface


    All buttons and other controls are drawn by displaying translucent primitives with textures stretched over them. Each element has a bounding box, when clicked, the “attached” slot is called up with the desired action.
    The kinetic scrolling technology was used for the transmission channel:

    image
    The kinetic scrolling

    technology is used for scrolling. The scrolling technology is quite simple, especially on the Internet there are many articles on the implementation of this effect.
    There is nothing more to say about the user interface, except that I had to rack my brains over some effects such as the "fading" name of the TV show.

    image

    Conclusion


    No matter how I tried, but the presentation of my thoughts turned out to be rather messy - I wanted to talk about many things, but at the same time not write a whole Talmud on how to write applications on DirectX. If you have questions or suggestions - I will be glad!
    PS (edit:) Pictures were initially uploaded to the dropbox, which led to the blocking of the account. The source files were not saved, so I redrawn the circuit.

    Read Next