Skip to content

After a random time, decode.c raise an assert when multiple video files are decoded at the same time

I'm trying to play (I'm getting video frames using callback) multiple video files at the same time. After a random time, the program crashes. I wrote a minimal example that causes these crashes. Crashes occur both on OS Windows 10/11 and KDE Neon (*buntu 20.04). Not tested on other systems. I was able to get crashes from 5 files playing at the same time. I did not find patterns in the frequency of falling from the number of simultaneously played files

After that I built vlc with debug symbols and got the following results:

Vlc build options: $ ./configure --enable-debug --program-prefix=/home/user/dev/libvlc-local/ --disable-lua --disable-a52

System configuration:

# cpu: i7 2700K
# memory: 24Gb

$ lsb_release -a
No LSB modules are available.
Distributor ID: Neon
Description:    KDE neon User - 5.24
Release:        20.04
Codename:       focal

$ uname -a
Linux desktop 5.15.0-33-generic #34~20.04.1-Ubuntu SMP Thu May 19 15:51:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Compiler and library:

# gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
# vlc-3.0.17.3

LOG:

[h264 @ 0x6190001a2780] get_buffer() failed
[h264 @ 0x6190001a2780] thread_get_buffer() failed
[h264 @ 0x6190001a2780] decode_slice_header error
[h264 @ 0x6190001a2780] no frame!
...
[h264 @ 0x6190004f1f80] get_buffer() failed
[h264 @ 0x6190004f1f80] thread_get_buffer() failed
[h264 @ 0x6190004f1f80] decode_slice_header error
[h264 @ 0x6190004f1f80] no frame!
[h264 @ 0x6190004f1080] reference picture missing during reorder
[h264 @ 0x6190004f1080] reference picture missing during reorder
[h264 @ 0x6190004f1080] Missing reference picture, default is 65782
[h264 @ 0x6190004f1080] Missing reference picture, default is 65782
[h264 @ 0x6190004f1080] mmco: unref short failure
[h264 @ 0x619000422c80] get_buffer() failed
[h264 @ 0x619000422c80] thread_get_buffer() failed
[h264 @ 0x619000422c80] decode_slice_header error
[h264 @ 0x619000422c80] no frame!
[h264 @ 0x619000421380] reference picture missing during reorder
[h264 @ 0x619000421380] reference picture missing during reorder
[h264 @ 0x619000421380] Missing reference picture, default is 65644
[h264 @ 0x619000421380] Missing reference picture, default is 65644
[h264 @ 0x619000421880] reference picture missing during reorder
[h264 @ 0x619000421880] Missing reference picture, default is 65648
[h264 @ 0x619000422280] mmco: unref short failure
libvlc-crash: input/decoder.c:566: vout_new_buffer: Assertion `p_owner->p_vout' failed.

input/deocde.c:

static picture_t *vout_new_buffer( decoder_t *p_dec )
{
    decoder_owner_sys_t *p_owner = p_dec->p_owner;
    assert( p_owner->p_vout ); // Line: 566 

    return vout_GetPicture( p_owner->p_vout );
}

Stack trace(1):

1  __GI_raise         raise.c          50   0x7f902815000b 
2  __GI_abort         abort.c          79   0x7f902812f859 
3  __assert_fail_base assert.c         92   0x7f902812f729 
4  __GI___assert_fail assert.c         101  0x7f9028140fd6 
5  vout_new_buffer    decoder.c        566  0x7f902801b57c 
6  vout_new_buffer    decoder.c        563  0x7f902801b57c 
7  decoder_NewPicture vlc_codec.h      291  0x7f9023588494 
8  DecodeBlock        video.c          1189 0x7f9023588494 
9  DecodeVideo        video.c          1272 0x7f9023588494 
10 DecoderDecode      decoder.c        1343 0x7f902801cd28 
11 DecoderProcess     decoder.c        1466 0x7f902801c96b 
12 DecoderThread      decoder.c        1622 0x7f902801cfa9 
13 start_thread       pthread_create.c 477  0x7f90280e2609 
14 clone              clone.S          95   0x7f902822c133 

Stack tracke(2):

1  __GI_raise         raise.c          50   0x7f2d0cf5600b 
2  __GI_abort         abort.c          79   0x7f2d0cf35859 
3  __assert_fail_base assert.c         92   0x7f2d0cf35729 
4  __GI___assert_fail assert.c         101  0x7f2d0cf46fd6 
5  vout_new_buffer    decoder.c        566  0x7f2d0ce2157c 
6  vout_new_buffer    decoder.c        563  0x7f2d0ce2157c 
7  decoder_NewPicture vlc_codec.h      291  0x7f2d0838ac55 
8  lavc_GetFrame      video.c          1518 0x7f2d0838ac55 
9  ??                                       0x7f2d06f33a4b 
10 ??                                       0x7f2d072f97be 
11 ??                                       0x7f2d0704a280 
12 ??                                       0x7f2d0704e758 
13 ??                                       0x7f2d07053958 
14 ??                                       0x7f2d072f884b 
15 start_thread       pthread_create.c 477  0x7f2d0cee8609 
16 clone              clone.S          95   0x7f2d0d032133 

Minimal example (C++):

#include <iostream>
#include <cassert>
#include <chrono>
#include <thread>
#include <vector>
#include <vlc/vlc.h>


const char *const libvlc_arguments[] = {
    "--input-repeat=65545",
    "--ignore-config",
    "--vout", "vmem",
    //, "--avcodec-hw=none"
};
const int libvlc_argument_count = sizeof(libvlc_arguments) / sizeof(char *);


#define FILENAMES_PATH "/home/user/videos/"
const char *const filenames[] = {
    FILENAMES_PATH "depositphotos_13491438-stock-video-close-up-shot-of-a.mp4",
    FILENAMES_PATH "depositphotos_265641526_stock_video_gambling_poker_cards_dices_chips.mp4",
    FILENAMES_PATH "depositphotos_349096750_stock_video_low_angle_closeup_view_male.mp4",
    FILENAMES_PATH "depositphotos_349097566_stock_video_low_angle_closeup_view_male.mp4",
    FILENAMES_PATH "depositphotos_375036286_stock_video_poker_chips_falling_on_casino.mp4",
    FILENAMES_PATH "depositphotos_557707632_stock_video_super_slow_motion_rolling_gaming.mp4",
    FILENAMES_PATH "depositphotos_565763494_stock_video_unrecognizable_male_gambler.mp4",
    FILENAMES_PATH "depositphotos_565763828_stock_video_unrecognizable_male_gambler.mp4"
};
const int widths[] = {
    608,
    608,
    608,
    608,
    608,
    608,
    608,
    608
};
const int heights[] = {
    342,
    342,
    342,
    342,
    342,
    342,
    342,
    342
};
const int filename_count = sizeof(filenames) / sizeof(char *);


static void *cbLock(void *opaque, void **planes)
{
    *planes = opaque;
    return nullptr;
}


static void cbUnlock(void *, void *, void *const *)
{
}


static void cbDisplay(void *, void *)
{
}


int main()
{
    libvlc_instance_t *const vlc = libvlc_new(libvlc_argument_count, libvlc_arguments);
    assert(vlc);

    for (int j = 0; j < 100; ++j) {
        std::vector<char *> buffers;
        std::vector<libvlc_media_player_t *> players;

        for (int k = 0; k < 1; ++k) {
            for (int i = 0; i < filename_count; ++i) {
                char *const buffer = new char[heights[i]*widths[i] * 4];
                assert(buffer);

                libvlc_media_player_t *const player = libvlc_media_player_new(vlc);
                assert(player);

                libvlc_video_set_key_input(player, false);
                libvlc_video_set_mouse_input(player, false);
                libvlc_audio_set_volume(player, 0);

                libvlc_video_set_callbacks(player, cbLock, cbUnlock, cbDisplay, buffer);
                libvlc_video_set_format(player, "RV32", widths[i], heights[i], widths[i] * 4);

                libvlc_media_t *const media = libvlc_media_new_path(vlc, filenames[i]);
                assert(media);
                libvlc_media_player_set_media(player, media);
                libvlc_media_release(media);

                const int play_status = libvlc_media_player_play(player);
                assert(play_status == 0);

                buffers.push_back(buffer);
                players.push_back(player);
            }
        }

        std::this_thread::sleep_for(std::chrono::seconds(60 * 60 * 5));

        for (int i = 0; i < filename_count; ++i) {
            libvlc_media_player_stop(players[i]);
            libvlc_media_player_release(players[i]);
            delete []buffers[i];
        }
    }

    libvlc_release(vlc);

    return 0;
}

Test files: test-set-video-part1.zip test-set-video-part2.zip

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information