Coverage Report

Created: 2026-01-10 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/src/input/decoder_prevframe.c
Line
Count
Source
1
/*****************************************************************************
2
 * decoder_prevframe.c: decoder previous frame helpers
3
 *****************************************************************************
4
 * Copyright (C) 2025 VLC authors, VideoLAN and Videolabs SAS
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU Lesser General Public License as published by
8
 * the Free Software Foundation; either version 2.1 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this program; if not, write to the Free Software Foundation,
18
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19
 *****************************************************************************/
20
 #ifdef HAVE_CONFIG_H
21
 # include "config.h"
22
 #endif
23
24
#include <vlc_picture.h>
25
#include "decoder_prevframe.h"
26
27
void
28
decoder_prevframe_Init(struct decoder_prevframe *pf)
29
0
{
30
0
    pf->pic = NULL;
31
0
    pf->req_count = 0;
32
0
    pf->failed = false;
33
0
    pf->flushing = false;
34
0
    pf->seek_steps = DEC_PF_SEEK_STEPS_INITIAL;
35
0
}
36
37
void
38
decoder_prevframe_Flush(struct decoder_prevframe *pf)
39
0
{
40
0
    if (pf->pic != NULL)
41
0
    {
42
0
        picture_Release(pf->pic);
43
0
        pf->pic = NULL;
44
0
    }
45
0
    pf->flushing = false;
46
0
    pf->failed = false;
47
0
}
48
49
void
50
decoder_prevframe_Reset(struct decoder_prevframe *pf)
51
0
{
52
0
    decoder_prevframe_Flush(pf);
53
0
    pf->seek_steps = DEC_PF_SEEK_STEPS_INITIAL;
54
0
    pf->req_count = 0;
55
0
}
56
57
void
58
decoder_prevframe_Request(struct decoder_prevframe *pf, int *seek_steps)
59
0
{
60
0
    if (pf->req_count == 0)
61
0
    {
62
0
        *seek_steps = pf->seek_steps;
63
0
        pf->flushing = true;
64
0
    }
65
0
    else
66
0
        *seek_steps = DEC_PF_SEEK_STEPS_NONE;
67
0
    pf->req_count++;
68
0
}
69
70
picture_t *
71
decoder_prevframe_AddPic(struct decoder_prevframe *pf, picture_t *pic,
72
                         vlc_tick_t *inout_pts, int *seek_steps)
73
0
{
74
0
    vlc_tick_t pts = *inout_pts;
75
0
    *seek_steps = DEC_PF_SEEK_STEPS_NONE;
76
77
0
    if (pf->flushing)
78
0
    {
79
0
        if (pic != NULL)
80
0
            picture_Release(pic);
81
0
        return NULL;
82
0
    }
83
84
0
    if (pic != NULL && pts <= pic->date && pf->pic != NULL)
85
0
    {
86
        /* Reached the previous frame */
87
0
        picture_t *resume_pic = pic;
88
89
0
        pic = pf->pic;
90
0
        pf->req_count--;
91
0
        pf->pic = NULL;
92
93
0
        *inout_pts = pic->date;
94
95
        /* Update seek request if needed */
96
0
        if (pf->req_count > 0)
97
0
        {
98
0
            *seek_steps = pf->seek_steps;
99
0
            pf->flushing = true;
100
0
        }
101
102
0
        assert(pic->p_next == NULL);
103
        /* Store the first pic to use if normal playback is resumed */
104
0
        pic->p_next = resume_pic;
105
106
0
        return pic;
107
0
    }
108
109
0
    if (pic == NULL || pic->date >= pts)
110
0
    {
111
0
        if (pf->pic == NULL && !pf->failed && pf->req_count > 0)
112
0
        {
113
            /* We need to seek again, and further */
114
0
            pf->seek_steps += DEC_PF_SEEK_STEPS_INITIAL * 2;
115
0
            pf->failed = true;
116
0
            pf->flushing = true;
117
0
            *seek_steps = pf->seek_steps;
118
0
        }
119
120
0
        if (pic != NULL)
121
0
            picture_Release(pic);
122
0
        return NULL;
123
0
    }
124
125
0
    if (pf->pic != NULL)
126
0
        picture_Release(pf->pic);
127
    /* Store the pic as the potential previous-frame (we know it only from
128
     * the next pic date) */
129
0
    pf->pic = pic;
130
131
    return NULL;
132
0
}