File: index.h

package info (click to toggle)
vdr-plugin-markad 4.2.15-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,084 kB
  • sloc: cpp: 22,441; python: 613; makefile: 270; sh: 95
file content (261 lines) | stat: -rw-r--r-- 9,002 bytes parent folder | download | duplicates (2)
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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
/*
 * index.h: A program for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *
 */

#ifndef __index_h_
#define __index_h_

#include <stdlib.h>
#include <algorithm>
#include <inttypes.h>
#include <vector>

#include "global.h"
#include "debug.h"


extern "C" {
#include <libavcodec/avcodec.h>
}

/**
 * element of the video index
*/
typedef struct sIndexElement {
    int fileNumber    = -1;             //!< number of TS file
    //!<
    int packetNumber  = -1;             //!< video packet number
    //!<
    int64_t pts       = -1;             //!< pts of i-frame
    //!<
    bool rollover     = false;          //!< true for packets after PTS/DTS rollover
    //!<
    bool isPTSinSlice = true;           //!< false if H.264 packet and any PTS from P/B frame after has before slice start, only stop cut if true
    //!<
} sIndexElement;

/**
 * recording index class
 * store offset from start in ms of each i-frame
 */
class cIndex {
public:
    /**
     * recording index class
     * @param fullDecodeParam full decode state of decoder
     */
    explicit cIndex(const bool fullDecodeParam);
    ~cIndex();

    /**
     * add new frame to index
     * @param fileNumber         number of ts file
     * @param packetNumber       number of packet
     * @param pts                frame PTS
     */
    void Add(const int fileNumber, const int packetNumber, const int64_t pts);

    /**
     * get key packet number before PTS
     * @param pts           packet PTS
     * @param beforePTS     PTS of key packet number before PTS
     * @param isPTSinSlice  false if H.264 packet and any PTS from P/B frame after has before slice start, only stop cut if true
     * @return key packet number before pts
     */
    int GetKeyPacketNumberBeforePTS(const int64_t pts, int64_t *beforePTS = nullptr, const bool isPTSinSlice = false);

    /**
     * get key packet number after PTS
     * @param pts frame PTS
     * @param afterPTS  PTS of found packet
     * @param isPTSinSlice  false if H.264 packet and any PTS from P/B frame after has before slice start, only stop cut if true
     * @return frame number after pts
     */
    int GetKeyPacketNumberAfterPTS(const int64_t pts,  int64_t *afterPTS = nullptr, const bool isPTSinSlice = false);

    /**
     * get last packet from key packet index
     * @return last packet of key packet index
     */
    sIndexElement *GetLastPacket();

    /**
     * get packet number after packet
     * @param packetNumber number of packet
     * @return if fullDecode packet number direct after packetNumber, else number of next key packet
     */
    int GetPacketNumberAfter(int packetNumber);

    /**
     * get packet number before packet number
     * @param packetNumber number of packet
     * @return if fullDecode packet number direct before packetNumber, else key packet number before
     */
    int GetPacketNumberBefore(int packetNumber);

    /**
     * get key packet before frameNumber
     * @param packetNumber number of packet
     * @param beforePTS    PTS of key packet number before
     * @return             number of key packet before packetNumber
     */
    int GetKeyPacketNumberBefore(int packetNumber, int64_t *beforePTS = nullptr);

    /**
     * get key packet after packetNumber
     * @param packetNumber packet number
     * @param afterPTS     PTS of key packet number after
     * @return             number of key packet frame after packetNumber
     */
    int GetKeyPacketNumberAfter(int packetNumber, int64_t *afterPTS = nullptr);

    /**
     * get offset time from recording start in ms from PTS
     * @param pts  presentation timestamp
     * @return offset time from recoring start in ms
     */
    int GetTimeOffsetFromPTS(int64_t pts);

    /**
     * get offset time from recording start in ms from key packet number after
     * @param packetNumber number of the packet
     * @return offset time from recoring start in ms
     */
    int GetTimeOffsetFromKeyPacketAfter(const int packetNumber);

    /**
     * get frame number to offset of recording start
     * @param offset_ms packet number
     * @return frame number to offset of recording start
     */
    int GetFrameFromOffset(int offset_ms);

    /**
     * get number of i-frames between beginFrame and endFrame
     * @param beginFrame frame number start of the range
     * @param endFrame   frame number end of the range
     * return number of i-frames between beginFrame and endFrame
     */
    int GetIFrameRangeCount(int beginFrame, int endFrame);

    /**
     * add packet to packet number and PTS ring buffer
     * @param packetNumber number of the packet
     * @param pts          presentation timestamp of the packet
     */
    void AddPTS(const int packetNumber, const int64_t pts);

#ifdef DEBUG_DECODER
    /** video packet number from called PTS
     * @param pts  presentation timestamp
     * @return video packet number from given presentation timestamp
     */
    int GetPacketNumberFromPTS(const int64_t pts);
#endif

    /** video packet number before called PTS
     * @param pts       presentation timestamp
     * @param beforePTS PTS of video packet before PTS
     * @return          video packet number before given presentation timestamp
     */
    int GetPacketNumberBeforePTS(const int64_t pts, int64_t *beforePTS = nullptr);

    /** video packet number after given PTS of called PTS
     * @param pts      presentation timestamp
     * @param afterPTS PTS of video packet after PTS
     * @return         video packet number after given presentation timestamp
     */
    int GetPacketNumberAfterPTS(const int64_t pts, int64_t *afterPTS = nullptr);

    /** return PTS from packet if called with an key packet number, otherwise from packet before
     * @param    frameNumber frame number
     * @return   presentation timestamp of frame
     */
    int64_t GetPTSBeforeKeyPacketNumber(const int frameNumber);

    /** return PTS from packet if called with an key packet number, otherwise from packet after
     * @param    frameNumber frame number
     * @return   presentation timestamp of frame
     */
    int64_t GetPTSAfterKeyPacketNumber(const int frameNumber);

    /** return PTS from packet if called with an key packet number, otherwise from packet after
     * @param    frameNumber frame number
     * @return   presentation timestamp of frame
     */
    int64_t GetPTSFromKeyPacketNumber(const int frameNumber);

    /** return PTS from packet
     * @param    packetNumber packet number
     * @return   presentation timestamp of frame
     */
    int64_t GetPTSFromPacketNumber(const int packetNumber);

    /** return PTS from of key packet before
     * @param    pts presentation timestamp
     * @return   presentation timestamp of key packet before
     */
    int64_t GetKeyPacketPTSBeforePTS(int64_t pts);

    /** set start PTS of video stream
     * @param start_time_param  PTS start time of video stream
     * @param time_base_param   time base of video stream
     */
    void SetStartPTS(const int64_t start_time_param, const AVRational time_base_param);

    /** set start PTS of video stream
     *  @return  start PTS of video stream
     */
    int64_t GetStartPTS() const;

    /** add PTS from start of p-slice to index
     * @param pts  start of p-slice
     */
    void AddPSlice(const int64_t pts);

    /** get PTS from start of p-slice after given PTS
     * @param pts        given PTS
     * @param pSlicePTS  PTS of key packet found
     * @return           key packet number from start of p-slice
     */
    int GetPSliceKeyPacketNumberAfterPTS(const int64_t pts, int64_t *pSlicePTS);

private:
    /** get index element of given PTS
     * @param pts  given PTS
     * @return  pointer to index element
     */
    sIndexElement *GetIndexElementFromPTS(const int64_t pts);

    bool fullDecode       = false;               //!< decoder full decode modi
    //!<
    int64_t start_time    = 0;                   //!< PTS of video stream start
    //!<
    AVRational time_base  = {0};                 //!<  time base of video stream
    //!<
    bool rollover         = false;               //!< true after PTS/DTS rollover
    //!<
    std::vector<sIndexElement> indexVector;      //!< recording index
    //!<
    std::vector<int64_t> pSliceVector;           //!< p-slice index
    //!<

    /**
     * ring buffer element to store frame presentation timestamp
     */
    struct sPTS_RingbufferElement {
        int packetNumber = -1;                    //!< packet number
        //!<
        int64_t pts      = 0;                     //!< presentation timestamp of the frame
        //!<
        bool rollover    = false;                 //!< true for packets after PTS/DTS rollover
    };
    std::vector<sPTS_RingbufferElement> ptsRing; //!< ring buffer for PTS per frameA
    //!<

#define MAX_PTSRING 200                          // maximum Element in ptsRing Ring Buffer
};
#endif